diff --git a/packages/form-layout/src/vaadin-form-layout-mixin.js b/packages/form-layout/src/vaadin-form-layout-mixin.js index e8c93577104..51d95e4f7aa 100644 --- a/packages/form-layout/src/vaadin-form-layout-mixin.js +++ b/packages/form-layout/src/vaadin-form-layout-mixin.js @@ -91,6 +91,7 @@ export const FormLayoutMixin = (superClass) => _labelsOnTop: { type: Boolean, sync: true, + observer: '__labelsOnTopChanged', }, /** @private */ @@ -100,10 +101,6 @@ export const FormLayoutMixin = (superClass) => }; } - static get observers() { - return ['_invokeUpdateLayout(_columnCount, _labelsOnTop)']; - } - /** @protected */ ready() { // Here we attach a style element that we use for validating @@ -196,7 +193,6 @@ export const FormLayoutMixin = (superClass) => }); if (addedNodes.length > 0 || removedNodes.length > 0) { - // TODO: Optimize this to only update layout if a resize happened this._updateLayout(); } }); @@ -330,7 +326,7 @@ export const FormLayoutMixin = (superClass) => } /** @private */ - _invokeUpdateLayout() { + __labelsOnTopChanged() { this._updateLayout(); } @@ -344,117 +340,37 @@ export const FormLayoutMixin = (superClass) => return; } - [...this.children].forEach((child) => { - const colspan = child.getAttribute('colspan') || child.getAttribute('data-colspan'); - if (colspan) { - child.style.setProperty('--_grid-colspan', colspan); - } + let resetColumn = false; + [...this.children] + .filter((child) => getComputedStyle(child).display !== 'none' || child.localName === 'br') + .forEach((child) => { + if (child.localName === 'br') { + resetColumn = true; + return; + } - if (child.localName === 'vaadin-form-item') { - if (this._labelsOnTop) { - if (child.getAttribute('label-position') !== 'top') { - child.__useLayoutLabelPosition = true; - child.setAttribute('label-position', 'top'); + if (child.localName === 'vaadin-form-item') { + if (this._labelsOnTop) { + if (child.getAttribute('label-position') !== 'top') { + child.__useLayoutLabelPosition = true; + child.setAttribute('label-position', 'top'); + } + } else if (child.__useLayoutLabelPosition) { + delete child.__useLayoutLabelPosition; + child.removeAttribute('label-position'); } - } else if (child.__useLayoutLabelPosition) { - delete child.__useLayoutLabelPosition; - child.removeAttribute('label-position'); } - } - }); - // /* - // The item width formula: - - // itemWidth = colspan / columnCount * 100% - columnSpacing - - // We have to subtract columnSpacing, because the column spacing space is taken - // by item margins of 1/2 * spacing on both sides - // */ - - // const style = getComputedStyle(this); - // const columnSpacing = style.getPropertyValue('--vaadin-form-layout-column-spacing'); - - // const direction = style.direction; - // const marginStartProp = `margin-${direction === 'ltr' ? 'left' : 'right'}`; - // const marginEndProp = `margin-${direction === 'ltr' ? 'right' : 'left'}`; - - // const containerWidth = this.offsetWidth; - - // let col = 0; - // Array.from(this.children) - // .filter((child) => child.localName === 'br' || getComputedStyle(child).display !== 'none') - // .forEach((child, index, children) => { - // if (child.localName === 'br') { - // // Reset column count on line break - // col = 0; - // return; - // } - - // const attrColspan = child.getAttribute('colspan') || child.getAttribute('data-colspan'); - // let colspan; - // colspan = this._naturalNumberOrOne(parseFloat(attrColspan)); - - // // Never span further than the number of columns - // colspan = Math.min(colspan, this._columnCount); - - // const childRatio = colspan / this._columnCount; - - // // Note: using 99.9% for 100% fixes rounding errors in MS Edge - // // (< v16), otherwise the items might wrap, resizing is wobbly. - // child.style.width = `calc(${childRatio * 99.9}% - ${1 - childRatio} * ${columnSpacing})`; - - // if (col + colspan > this._columnCount) { - // // Too big to fit on this row, let's wrap it - // col = 0; - // } - - // // At the start edge - // if (col === 0) { - // child.style.setProperty(marginStartProp, '0px'); - // } else { - // child.style.removeProperty(marginStartProp); - // } - - // const nextIndex = index + 1; - // const nextLineBreak = nextIndex < children.length && children[nextIndex].localName === 'br'; - - // // At the end edge - // if (col + colspan === this._columnCount) { - // child.style.setProperty(marginEndProp, '0px'); - // } else if (nextLineBreak) { - // const colspanRatio = (this._columnCount - col - colspan) / this._columnCount; - // child.style.setProperty( - // marginEndProp, - // `calc(${colspanRatio * containerWidth}px + ${colspanRatio} * ${columnSpacing})`, - // ); - // } else { - // child.style.removeProperty(marginEndProp); - // } - - // // Move the column counter - // col = (col + colspan) % this._columnCount; - - // if (child.localName === 'vaadin-form-item') { - // if (this._labelsOnTop) { - // if (child.getAttribute('label-position') !== 'top') { - // child.__useLayoutLabelPosition = true; - // child.setAttribute('label-position', 'top'); - // } - // } else if (child.__useLayoutLabelPosition) { - // delete child.__useLayoutLabelPosition; - // child.removeAttribute('label-position'); - // } - // } - // }); - } + const colspan = child.getAttribute('colspan') || child.getAttribute('data-colspan'); + if (colspan) { + child.style.setProperty('--_grid-colspan', colspan); + } - /** @private */ - __generateContainerQueries() { - // TODO: Might use adoptedStyleSheets when supported? - // NOTE: Container queries are not worth using because - // we need to support [label-position] attribute on form-item - // which users can target in their styles. + if (resetColumn) { + child.style.setProperty('--_grid-colstart', 1); + resetColumn = false; + } + }); } /** diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index 7742e9955e5..f21a53f8153 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -42,6 +42,7 @@ export const formLayoutStyles = css` } #layout ::slotted(*) { + grid-column-start: var(--_grid-colstart, auto); grid-column-end: span min(var(--_grid-colspan, 1), var(--_grid-cols)); }