diff --git a/packages/main/src/Form.ts b/packages/main/src/Form.ts index 0ba83a4f5b20..f9aa27e822a6 100644 --- a/packages/main/src/Form.ts +++ b/packages/main/src/Form.ts @@ -3,12 +3,16 @@ import type { Slot, DefaultSlot } from "@ui5/webcomponents-base/dist/UI5Element. import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import property from "@ui5/webcomponents-base/dist/decorators/property.js"; import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; -import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; +import slot from "@ui5/webcomponents-base/dist/decorators/slot-strict.js"; import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; import type { AriaRole } from "@ui5/webcomponents-base"; import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js"; +// Utils +import { getFormItemLayoutValue, getGroupsColSpan } from "./form-utils/FormUtils.js"; +import type { Breakpoint } from "./form-utils/FormUtils.js"; + // Template import FormTemplate from "./FormTemplate.js"; @@ -22,20 +26,6 @@ import type TitleLevel from "./types/TitleLevel.js"; import { FORM_ACCESSIBLE_NAME } from "./generated/i18n/i18n-defaults.js"; -const additionalStylesMap = new Map(); - -const StepColumn = { - "S": 1, - "M": 2, - "L": 3, - "XL": 6, -}; - -const breakpoints = ["S", "M", "L", "Xl"]; -const MAX_FORM_ITEM_CELLS = 12; -const DEFAULT_FORM_ITEM_LAYOUT = "4fr 8fr 0fr"; -const DEFAULT_FORM_ITEM_LAYOUT_S = "1fr"; - /** * Interface for components that can be slotted inside `ui5-form` as items. * @public @@ -352,6 +342,10 @@ class Form extends UI5Element { * * **Note:** Mixing FormGroups and standalone FormItems (not belonging to a group) is not supported. * Either use FormGroups and make sure all FormItems are part of a FormGroup, or use just FormItems without any FormGroups. + * + * **Note:** As of version 2.21.0 the support for standalone FormItems (not belonging to a group) is deprecated. + * We recommend using FormGroups, as they provide better accessibility and layout options. + * * @public */ @slot({ @@ -368,40 +362,37 @@ class Form extends UI5Element { /** * @private */ - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) columnsS = 1; - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) labelSpanS = 12 - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) emptySpanS = 0 - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) columnsM = 1; - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) labelSpanM = 4; - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) emptySpanM = 0 - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) columnsL = 2; - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) labelSpanL = 4; - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) emptySpanL = 0 - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) columnsXl = 3; - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) labelSpanXl = 4; - @property({ type: Number }) + @property({ type: Number, noAttribute: true }) emptySpanXl = 0; onBeforeRendering() { // Parse the layout and set it to the FormGroups/FormItems. - this.setColumnLayout(); - - // Parse the labelSpan and emptySpan and set it to the FormGroups/FormItems. - this.setFormItemLayout(); + this.parseLayoutConfiguration(); // Define how many columns a group should take. this.setGroupsColSpan(); @@ -411,15 +402,11 @@ class Form extends UI5Element { } onAfterRendering() { - // Create additional CSS for number of columns that are not supported by default. - this.createAdditionalCSSStyleSheet(); - this.setFastNavGroup(); } - setColumnLayout() { - const layoutArr = this.layout.split(" "); - layoutArr.forEach((breakpoint: string) => { + parseLayoutConfiguration() { + this.layout.split(" ").forEach((breakpoint: string) => { if (breakpoint.startsWith("S")) { this.columnsS = parseInt(breakpoint.slice(1)); } else if (breakpoint.startsWith("M")) { @@ -430,9 +417,7 @@ class Form extends UI5Element { this.columnsXl = parseInt(breakpoint.slice(2)); } }); - } - parseFormItemSpan() { this.labelSpan.split(" ").forEach((breakpoint: string) => { if (breakpoint.startsWith("S")) { this.labelSpanS = parseInt(breakpoint.slice(1)); @@ -458,44 +443,25 @@ class Form extends UI5Element { }); } - setFormItemLayout() { - this.parseFormItemSpan(); - - [ - { - breakpoint: "S", - labelSpan: this.labelSpanS, - emptySpan: this.emptySpanS, - }, - { - breakpoint: "M", - labelSpan: this.labelSpanM, - emptySpan: this.emptySpanM, - }, - { - breakpoint: "L", - labelSpan: this.labelSpanL, - emptySpan: this.emptySpanL, - }, - { - breakpoint: "XL", - labelSpan: this.labelSpanXl, - emptySpan: this.emptySpanXl, - }, - ].forEach(layout => { - if (this.isValidFormItemLayout(layout.labelSpan, layout.emptySpan)) { - const formItemLayout = layout.labelSpan === MAX_FORM_ITEM_CELLS ? `1fr` : `${layout.labelSpan}fr ${MAX_FORM_ITEM_CELLS - (layout.labelSpan + layout.emptySpan)}fr ${layout.emptySpan}fr`; - this.style.setProperty(`--ui5-form-item-layout-${layout.breakpoint}`, formItemLayout); - } else { - // eslint-disable-next-line - console.warn(`Form :: invalid usage of emptySpan and/or labelSpan in ${layout.breakpoint} size. The labelSpan must be <=12 and when emptySpace is used - their combined values must not exceed 11.`) - this.style.setProperty(`--ui5-form-item-layout-${layout.breakpoint}`, layout.breakpoint === "S" ? DEFAULT_FORM_ITEM_LAYOUT_S : DEFAULT_FORM_ITEM_LAYOUT); - } - }); - } + getFormItemLayout(breakpoint: Breakpoint) { + let labelSpan, + emptySpan; + + if (breakpoint === "S") { + labelSpan = this.labelSpanS; + emptySpan = this.emptySpanS; + } else if (breakpoint === "M") { + labelSpan = this.labelSpanM; + emptySpan = this.emptySpanM; + } else if (breakpoint === "L") { + labelSpan = this.labelSpanL; + emptySpan = this.emptySpanL; + } else if (breakpoint === "XL") { + labelSpan = this.labelSpanXl; + emptySpan = this.emptySpanXl; + } - isValidFormItemLayout(labelSpan: number, emptySpan: number) { - return emptySpan === 0 ? labelSpan <= MAX_FORM_ITEM_CELLS : labelSpan + emptySpan <= MAX_FORM_ITEM_CELLS - 1; + return getFormItemLayoutValue(breakpoint, labelSpan, emptySpan); } setFastNavGroup() { @@ -517,44 +483,13 @@ class Form extends UI5Element { }); sortedItems.forEach((item: IFormItem, idx: number) => { - item.colsXl = this.getGroupsColSpan(this.columnsXl, itemsCount, idx, item); - item.colsL = this.getGroupsColSpan(this.columnsL, itemsCount, idx, item); - item.colsM = this.getGroupsColSpan(this.columnsM, itemsCount, idx, item); - item.colsS = this.getGroupsColSpan(this.columnsS, itemsCount, idx, item); + item.colsXl = getGroupsColSpan(this.columnsXl, itemsCount, idx, item); + item.colsL = getGroupsColSpan(this.columnsL, itemsCount, idx, item); + item.colsM = getGroupsColSpan(this.columnsM, itemsCount, idx, item); + item.colsS = getGroupsColSpan(this.columnsS, itemsCount, idx, item); }); } - getGroupsColSpan(cols: number, groups: number, index: number, group: IFormItem): number { - // Case 0: column span is set from outside. - if (group.columnSpan) { - return group.columnSpan; - } - - // CASE 1: The number of available columns match the number of groups, or only 1 column is available - each group takes 1 column. - // For example: 1 column - 1 group, 2 columns - 2 groups, 3 columns - 3 groups, 4columns - 4 groups - if (cols === 1 || cols <= groups) { - return 1; - } - - // CASE 2: The number of available columns IS multiple of the number of groups. - // For example: 2 column - 1 group, 3 columns - 1 groups, 4 columns - 1 group, 4 columns - 2 groups - if (cols % groups === 0) { - return cols / groups; - } - - // CASE 3: The number of available columns IS NOT multiple of the number of groups. - const MIN_COL_SPAN = 1; - const delta = cols - groups; - - // 7 cols & 4 groups => 2, 2, 2, 1 - if (delta <= groups) { - return index < delta ? MIN_COL_SPAN + 1 : MIN_COL_SPAN; - } - - // 7 cols & 3 groups => 3, 2, 2 - return index === 0 ? MIN_COL_SPAN + (delta - groups) + 1 : MIN_COL_SPAN + 1; - } - setItemsState() { this.items.forEach((item: IFormItem) => { item.itemSpacing = this.itemSpacing; @@ -600,28 +535,6 @@ class Form extends UI5Element { get groupItemsInfo(): Array { return this.items.map((groupItem: IFormItem, index: number) => { - const items = this.getItemsInfo((Array.from(groupItem.children) as Array)); - breakpoints.forEach(breakpoint => { - const cols = ((groupItem[`cols${breakpoint}` as keyof IFormItem]) as number || 1); - const rows = Math.ceil(items.length / cols); - const total = cols * rows; - const lastRowColumns = (cols - (total - items.length) - 1); // all other indecies start from 0 - let currentItem = 0; - - for (let i = 0; i < total; i++) { - const column = Math.floor(i / rows); - const row = i % rows; - - if (row === rows - 1 && column > lastRowColumns) { - // eslint-disable-next-line no-continue - continue; - } - - items[currentItem].item.style.setProperty(`--ui5-form-item-order-${breakpoint}`, `${column + row * cols}`); - currentItem++; - } - }); - const accessibleNameRef = (groupItem as FormGroup).effectiveAccessibleNameRef; return { @@ -644,88 +557,9 @@ class Form extends UI5Element { return (items || this.items).map((item: IFormItem) => { return { item, - // eslint-disable-next-line - // TODO: remove classes and classMap after deleting the hbs template - classes: item.columnSpan ? `ui5-form-item-span-${item.columnSpan}` : "", - classMap: { - [`ui5-form-item-span-${item.columnSpan}`]: item.columnSpan !== undefined, - }, }; }); } - - createAdditionalCSSStyleSheet() { - [ - { breakpoint: "S", columns: this.columnsS }, - { breakpoint: "M", columns: this.columnsM }, - { breakpoint: "L", columns: this.columnsL }, - { breakpoint: "XL", columns: this.columnsXl }, - ].forEach(step => { - const additionalStyle: string | undefined = this.getAdditionalCSS(step.breakpoint, step.columns); - - if (additionalStyle) { - this.shadowRoot!.adoptedStyleSheets = [...this.shadowRoot!.adoptedStyleSheets, this.getCSSStyleSheet(additionalStyle)]; - } - }); - } - - getAdditionalCSS(step: string, colsNumber: number): string | undefined { - if (StepColumn[step as keyof typeof StepColumn] >= colsNumber) { - return; - } - - const key = `${step}-${colsNumber}`; - - if (!additionalStylesMap.has(key)) { - let containerQuery; - let supporedColumnsNumber = StepColumn.S; - let stepSpanCSS = ""; - let cols = colsNumber; - - if (step === "S") { - supporedColumnsNumber = StepColumn.S; - containerQuery = `@container (max-width: 599px) {`; - } else if (step === "M") { - supporedColumnsNumber = StepColumn.M; - containerQuery = `@container (width > 599px) and (width < 1024px) {`; - } else if (step === "L") { - supporedColumnsNumber = StepColumn.L; - containerQuery = `@container (width > 1023px) and (width < 1439px) {`; - } else if (step === "XL") { - containerQuery = `@container (min-width: 1440px) {`; - supporedColumnsNumber = StepColumn.XL; - } - - while (cols > supporedColumnsNumber) { - stepSpanCSS += ` - :host([columns-${step.toLocaleLowerCase()}="${cols}"]) .ui5-form-layout { - grid-template-columns: repeat(${cols}, 1fr); - } - - .ui5-form-column-span${step}-${cols}, - .ui5-form-item-span-${cols} { - grid-column: span ${cols}; - } - - .ui5-form-column-span${step}-${cols} .ui5-form-group-layout { - grid-template-columns: repeat(${cols}, 1fr); - } - `; - cols--; - } - - const css = `${containerQuery}${stepSpanCSS}}`; - additionalStylesMap.set(key, css); - } - - return additionalStylesMap.get(key)!; - } - - getCSSStyleSheet(cssText: string): CSSStyleSheet { - const style = new CSSStyleSheet(); - style.replaceSync(cssText); - return style; - } } Form.define(); diff --git a/packages/main/src/FormGroup.ts b/packages/main/src/FormGroup.ts index ad4fca57e719..6b0af9eaaa78 100644 --- a/packages/main/src/FormGroup.ts +++ b/packages/main/src/FormGroup.ts @@ -74,6 +74,15 @@ class FormGroup extends UI5Element implements IFormItem { @property({ type: Number }) columnSpan?: number; + /** + * Defines column span of the component as a string. + * + * @default undefined + * @public + */ + @property() + colSpan?: string; + /** * Defines the accessible ARIA name of the component. * @default undefined diff --git a/packages/main/src/FormItem.ts b/packages/main/src/FormItem.ts index 2615cb0b2ce1..5244e6c9e1cd 100644 --- a/packages/main/src/FormItem.ts +++ b/packages/main/src/FormItem.ts @@ -56,6 +56,8 @@ class FormItem extends UI5Element implements IFormItem { * or the Form. The available columns can be affected by the FormGroup#columnSpan and/or the Form#layout. * A number bigger than the available columns won't take effect. * + * @deprecated As of version 2.21.0, this property is deprecated. + * **Note:** This property will not have any effect on the layout of the form item * @default undefined * @public */ diff --git a/packages/main/src/FormTemplate.tsx b/packages/main/src/FormTemplate.tsx index f1f2c50e238a..2e30b54ade17 100644 --- a/packages/main/src/FormTemplate.tsx +++ b/packages/main/src/FormTemplate.tsx @@ -8,6 +8,16 @@ export default function FormTemplate(this: Form) { role={this.effectiveAccessibleRole} aria-label={this.effectiveAccessibleName} aria-labelledby={this.effectiveАccessibleNameRef} + style={{ + "--ui5-form-columns-s": this.columnsS, + "--ui5-form-columns-m": this.columnsM, + "--ui5-form-columns-l": this.columnsL, + "--ui5-form-columns-xl": this.columnsXl, + "--ui5-form-item-layout-S": this.getFormItemLayout("S"), + "--ui5-form-item-layout-M": this.getFormItemLayout("M"), + "--ui5-form-item-layout-L": this.getFormItemLayout("L"), + "--ui5-form-item-layout-XL": this.getFormItemLayout("XL"), + }} > {this.hasHeader &&
@@ -19,22 +29,22 @@ export default function FormTemplate(this: Form) {
} - { this.hasGroupItems ? groupedItemsLayout.call(this) : standaloneItemsLayout.call(this) } + {this.hasGroupItems ? groupedItemsLayout.call(this) : standaloneItemsLayout.call(this)} ); } function groupedItemsLayout(this: Form) { return
- { this.groupItemsInfo.map(groupItemInfo => { + {this.groupItemsInfo.map(groupItemInfo => { const groupItem = groupItemInfo.groupItem; return
@@ -43,12 +53,12 @@ function groupedItemsLayout(this: Form) { aria-labelledby={groupItemInfo.accessibleNameRef} aria-label={groupItemInfo.accessibleName} > - { groupItem.headerText && + {groupItem.headerText &&
{groupItem.headerText}
} - { this.accessibleMode === "Edit" ? + {this.accessibleMode === "Edit" ?
@@ -67,11 +77,11 @@ function standaloneItemsLayout(this: Form) { return ( this.accessibleMode === "Edit" ?
- { standaloneItemsLayoutContent.call(this) } + {standaloneItemsLayoutContent.call(this)}
:
- { standaloneItemsLayoutContent.call(this) } + {standaloneItemsLayoutContent.call(this)}
); } @@ -80,13 +90,9 @@ function standaloneItemsLayoutContent(this: Form) { return this.itemsInfo.map(itemInfo => { const item = itemInfo.item; return ( -
+
-
+
); }); } diff --git a/packages/main/src/form-utils/FormUtils.ts b/packages/main/src/form-utils/FormUtils.ts new file mode 100644 index 000000000000..1c4665614845 --- /dev/null +++ b/packages/main/src/form-utils/FormUtils.ts @@ -0,0 +1,63 @@ +import type { IFormItem } from "../Form.js"; + +const breakpoints = ["S", "M", "L", "XL"] as const; +type Breakpoint = typeof breakpoints[number]; +const MAX_FORM_ITEM_CELLS = 12; +const DEFAULT_FORM_ITEM_LAYOUT = "4fr 8fr 0fr"; +const DEFAULT_FORM_ITEM_LAYOUT_S = "1fr"; + +function getFormItemLayoutValue(breakpoint: Breakpoint, labelSpan: number | undefined = 0, emptySpan: number | undefined = 0): string { + if (isValidFormItemLayout(labelSpan, emptySpan)) { + return labelSpan === MAX_FORM_ITEM_CELLS ? `1fr` : `${labelSpan}fr ${MAX_FORM_ITEM_CELLS - (labelSpan + emptySpan)}fr ${emptySpan}fr`; + } + + // eslint-disable-next-line + console.warn(`Form :: invalid usage of emptySpan and/or labelSpan in ${breakpoint} size. The labelSpan must be <=12 and when emptySpace is used - their combined values must not exceed 11.`); + return breakpoint === "S" ? DEFAULT_FORM_ITEM_LAYOUT_S : DEFAULT_FORM_ITEM_LAYOUT; +} + +function isValidFormItemLayout(labelSpan: number, emptySpan: number) { + return emptySpan === 0 ? labelSpan <= MAX_FORM_ITEM_CELLS : labelSpan + emptySpan <= MAX_FORM_ITEM_CELLS - 1; +} + +function getGroupsColSpan(cols: number, groups: number, index: number, group: IFormItem): number { + // Case 0: column span is set from outside. + if (group.columnSpan) { + return group.columnSpan; + } + + // CASE 1: The number of available columns match the number of groups, or only 1 column is available - each group takes 1 column. + // For example: 1 column - 1 group, 2 columns - 2 groups, 3 columns - 3 groups, 4columns - 4 groups + if (cols === 1 || cols <= groups) { + return 1; + } + + // CASE 2: The number of available columns IS multiple of the number of groups. + // For example: 2 column - 1 group, 3 columns - 1 groups, 4 columns - 1 group, 4 columns - 2 groups + if (cols % groups === 0) { + return cols / groups; + } + + // CASE 3: The number of available columns IS NOT multiple of the number of groups. + const MIN_COL_SPAN = 1; + const delta = cols - groups; + + // 7 cols & 4 groups => 2, 2, 2, 1 + if (delta <= groups) { + return index < delta ? MIN_COL_SPAN + 1 : MIN_COL_SPAN; + } + + // 7 cols & 3 groups => 3, 2, 2 + return index === 0 ? MIN_COL_SPAN + (delta - groups) + 1 : MIN_COL_SPAN + 1; +} + +export { + getFormItemLayoutValue, + getGroupsColSpan, + DEFAULT_FORM_ITEM_LAYOUT, + DEFAULT_FORM_ITEM_LAYOUT_S, +}; + +export type { + Breakpoint, +}; diff --git a/packages/main/src/themes/Form.css b/packages/main/src/themes/Form.css index d8e987cec5fb..4824f1c4ed84 100644 --- a/packages/main/src/themes/Form.css +++ b/packages/main/src/themes/Form.css @@ -30,7 +30,7 @@ } .ui5-form-group-layout { - display: grid; + display: block; column-gap: 1rem; } @@ -51,5 +51,7 @@ } dl { - all: unset; + padding: 0; + margin: 0; + border: 0 transparent; } \ No newline at end of file diff --git a/packages/main/src/themes/FormItem.css b/packages/main/src/themes/FormItem.css index ab65c77c8736..f1ba4e9970e5 100644 --- a/packages/main/src/themes/FormItem.css +++ b/packages/main/src/themes/FormItem.css @@ -3,28 +3,8 @@ width: 100%; } -:host([column-span="1"]) { - grid-column: span 1; -} - -:host([column-span="2"]) { - grid-column: span 2; -} - -:host([column-span="3"]) { - grid-column: span 3; -} - -:host([column-span="4"]) { - grid-column: span 4; -} - -:host([column-span="5"]) { - grid-column: span 5; -} - -:host([column-span="6"]) { - grid-column: span 6; +:host { + break-inside: avoid; } .ui5-form-item-root { @@ -68,34 +48,8 @@ width: 100%; } -@container (max-width: 600px) { - :host { - order: var(--ui5-form-item-order-S, unset); - } -} - -/* M - 1 column by default, up to 2 columns */ -@container (width > 600px) and (width <= 1024px) { - :host { - order: var(--ui5-form-item-order-M, unset); - } - -} - -/* L - 2 columns by default, up to 3 columns */ -@container (width > 1024px) and (width <= 1440px) { - :host { - order: var(--ui5-form-item-order-L, unset); - } -} - -/* XL - 3 columns by default, up to 6 */ -@container (min-width: 1441px) { - :host { - order: var(--ui5-form-item-order-Xl, unset); - } -} - dd { - all: unset; + padding: 0; + margin: 0; + border: 0 transparent; } \ No newline at end of file diff --git a/packages/main/src/themes/FormItemSpan.css b/packages/main/src/themes/FormItemSpan.css index c6bb111fcc11..8f06759e5ccc 100644 --- a/packages/main/src/themes/FormItemSpan.css +++ b/packages/main/src/themes/FormItemSpan.css @@ -17,34 +17,34 @@ --ui5-form-item-layout: var(--ui5-form-item-layout-S); } - :host([label-span-s="12"]) .ui5-form-item, - :host([label-span-s="12"]) .ui5-form-group { + :host(:is([label-span~="S12"], :not([label-span*="S"]))) .ui5-form-item, + :host(:is([label-span~="S12"], :not([label-span*="S"]))) .ui5-form-group { --ui5-form-item-label-justify: var(--ui5-form-item-label-justify-internal); --ui5-form-item-label-padding: var(--ui5-form-item-label-padding-internal); } } -@container (width > 600px) and (width <= 1024px) { +@container (width > 600px) and (width <=1024px) { .ui5-form-item, .ui5-form-group { --ui5-form-item-layout: var(--ui5-form-item-layout-M); } - :host([label-span-m="12"]) .ui5-form-item, - :host([label-span-m="12"]) .ui5-form-group { + :host([label-span~="M12"]) .ui5-form-item, + :host([label-span~="M12"]) .ui5-form-group { --ui5-form-item-label-justify: var(--ui5-form-item-label-justify-internal); --ui5-form-item-label-padding: var(--ui5-form-item-label-padding-internal); } } -@container (width > 1024px) and (width <= 1440px) { +@container (width > 1024px) and (width <=1440px) { .ui5-form-item, .ui5-form-group { --ui5-form-item-layout: var(--ui5-form-item-layout-L); } - :host([label-span-l="12"]) .ui5-form-item, - :host([label-span-l="12"]) .ui5-form-group { + :host([label-span~="L12"]) .ui5-form-item, + :host([label-span~="L12"]) .ui5-form-group { --ui5-form-item-label-justify: var(--ui5-form-item-label-justify-internal); --ui5-form-item-label-padding: var(--ui5-form-item-label-padding-internal); } @@ -56,9 +56,9 @@ --ui5-form-item-layout: var(--ui5-form-item-layout-XL); } - :host([label-span-xl="12"]) .ui5-form-item, - :host([label-span-xl="12"]) .ui5-form-group { + :host([label-span~="XL12"]) .ui5-form-item, + :host([label-span~="XL12"]) .ui5-form-group { --ui5-form-item-label-justify: var(--ui5-form-item-label-justify-internal); --ui5-form-item-label-padding: var(--ui5-form-item-label-padding-internal); } -} +} \ No newline at end of file diff --git a/packages/main/src/themes/FormLayout.css b/packages/main/src/themes/FormLayout.css index 30357addeab0..bd65836d39ec 100644 --- a/packages/main/src/themes/FormLayout.css +++ b/packages/main/src/themes/FormLayout.css @@ -1,159 +1,75 @@ -/* -* The Form layout is divided into one or more columns. +/* +* The Form layout is divided into one or more columns. * XL - max. 6 columns, L - max. 3 columns, M - max. 2 columns and S - 1 column. */ -/* +/* * S max-width: 600px - container padding 24px */ /* S - 1 column */ @container (max-width: 600px) { .ui5-form-layout { - grid-template-columns: 1fr; + grid-template-columns: repeat(var(--ui5-form-columns-s), 1fr); } ::slotted(*) { justify-self: start; } - ::slotted(:nth-child(2n)){ + + ::slotted(:nth-child(2n)) { margin-bottom: 0.5rem; } + + .ui5-form-column { + grid-column: span var(--ui5-form-column-span-s, 1); + } + + .ui5-form-group-layout { + column-count: var(--ui5-form-column-span-s, 1) + } } /* M - 1 column by default, up to 2 columns */ -@container (width > 600px) and (width <= 1024px) { +@container (width > 600px) and (width <=1024px) { .ui5-form-layout { - grid-template-columns: 1fr; - } - :host([columns-m="1"]) .ui5-form-layout { - grid-template-columns: 1fr; - } - :host([columns-m="2"]) .ui5-form-layout { - grid-template-columns: repeat(2, 1fr); + grid-template-columns: repeat(var(--ui5-form-columns-m), 1fr); } - .ui5-form-column-spanM-2 { - grid-column: span 2; + .ui5-form-column { + grid-column: span var(--ui5-form-column-span-m, 1); } - .ui5-form-column-spanM-2 .ui5-form-group-layout { - grid-template-columns: repeat(2, 1fr); + .ui5-form-group-layout { + column-count: var(--ui5-form-column-span-m, 1) } } /* L - 2 columns by default, up to 3 columns */ -@container (width > 1024px) and (width <= 1440px) { - +@container (width > 1024px) and (width <=1440px) { .ui5-form-layout { - grid-template-columns: repeat(2, 1fr); - } - .ui5-form-column { - grid-template-columns: 1fr; + grid-template-columns: repeat(var(--ui5-form-columns-l), 1fr); } - :host([columns-l="1"]) .ui5-form-layout { - grid-template-columns: 1fr; - } - :host([columns-l="2"]) .ui5-form-layout { - grid-template-columns: repeat(2, 1fr); - } - :host([columns-l="3"]) .ui5-form-layout { - grid-template-columns: repeat(3, 1fr); - } - - .ui5-form-column-spanL-2 { - grid-column: span 2; - } - .ui5-form-column-spanL-2 .ui5-form-group-layout { - grid-template-columns: repeat(2, 1fr); + .ui5-form-column { + grid-column: span var(--ui5-form-column-span-l, 1); } - .ui5-form-column-spanL-3 { - grid-column: span 3; - } - .ui5-form-column-spanL-3 .ui5-form-group-layout { - grid-template-columns: repeat(3, 1fr); + .ui5-form-group-layout { + column-count: var(--ui5-form-column-span-l, 1) } } /* XL - 3 columns by default, up to 6 */ @container (min-width: 1441px) { .ui5-form-layout { - grid-template-columns: repeat(3, 1fr); - } - - :host([columns-xl="1"]) .ui5-form-layout { - grid-template-columns: 1fr; - } - :host([columns-xl="2"]) .ui5-form-layout { - grid-template-columns: repeat(2, 1fr); - } - :host([columns-xl="3"]) .ui5-form-layout { - grid-template-columns: repeat(3, 1fr); - } - :host([columns-xl="4"]) .ui5-form-layout { - grid-template-columns: repeat(4, 1fr); - } - :host([columns-xl="5"]) .ui5-form-layout { - grid-template-columns: repeat(5, 1fr); + grid-template-columns: repeat(var(--ui5-form-columns-xl), 1fr); } - :host([columns-xl="6"]) .ui5-form-layout { - grid-template-columns: repeat(6, 1fr); - } - - .ui5-form-column-spanXL-2 { - grid-column: span 2; - } - .ui5-form-column-spanXL-2 .ui5-form-group-layout { - grid-template-columns: repeat(2, 1fr); - } - - .ui5-form-column-spanXL-3 { - grid-column: span 3; - } - .ui5-form-column-spanXL-3 .ui5-form-group-layout { - grid-template-columns: repeat(3, 1fr); - } - - .ui5-form-column-spanXL-4 { - grid-column: span 4; - } - .ui5-form-column-spanXL-4 .ui5-form-group-layout { - grid-template-columns: repeat(4, 1fr); - - } - - .ui5-form-column-spanXL-5 { - grid-column: span 5; - } - .ui5-form-column-spanXL-5 .ui5-form-group-layout { - grid-template-columns: repeat(5, 1fr); + .ui5-form-column { + grid-column: span var(--ui5-form-column-span-xl, 1); } - .ui5-form-column-spanXL-6 { - grid-column: span 6; - } - .ui5-form-column-spanXL-6 .ui5-form-group-layout { - grid-template-columns: repeat(6, 1fr); + .ui5-form-group-layout { + column-count: var(--ui5-form-column-span-xl, 1) } -} - -.ui5-form-item-span-2 { - grid-column: span 2; -} - -.ui5-form-item-span-3 { - grid-column: span 3; -} - -.ui5-form-item-span-4 { - grid-column: span 4; -} - -.ui5-form-item-span-5 { - grid-column: span 5; -} -.ui5-form-item-span-6 { - grid-column: span 6; -} +} \ No newline at end of file diff --git a/packages/main/test/pages/form/FormComparison.html b/packages/main/test/pages/form/FormComparison.html new file mode 100644 index 000000000000..36512dcece3c --- /dev/null +++ b/packages/main/test/pages/form/FormComparison.html @@ -0,0 +1,522 @@ + + + + + + + Form Comparison - UI5 Web Components vs OpenUI5 + + + + + + + + + + + +

Form Comparison: UI5 Web Components vs OpenUI5

+ + + + + + + \ No newline at end of file