From 3fa920c4d4dd587abf5e616fc2e8141b67a71c4b Mon Sep 17 00:00:00 2001 From: Diego Cardoso Date: Wed, 29 Jan 2025 11:39:15 +0200 Subject: [PATCH 01/17] refactor: initial implementation of form-layout using CSS grid --- .../src/vaadin-form-layout-styles.js | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index dee1af4a95..1f1ebccae3 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -10,12 +10,16 @@ export const formLayoutStyles = css` display: block; max-width: 100%; animation: 1ms vaadin-form-layout-appear; + align-self: stretch; + container-type: inline-size; + container-name: form-grid; + --_grid-cols: 10; /* Number of cols, defined by breakpoints. Default value is probably pointless. */ /* CSS API for host */ + /* Let's not define defaults here – that way they can be set globally */ --vaadin-form-item-label-width: 8em; --vaadin-form-item-label-spacing: 1em; --vaadin-form-item-row-spacing: 1em; - --vaadin-form-layout-column-spacing: 2em; /* (default) */ - align-self: stretch; + --vaadin-form-layout-column-spacing: 2em; } @keyframes vaadin-form-layout-appear { @@ -29,21 +33,20 @@ export const formLayoutStyles = css` } #layout { - display: flex; - - align-items: baseline; /* default \`stretch\` is not appropriate */ - - flex-wrap: wrap; /* the items should wrap */ + display: grid; + grid-template-columns: repeat(var(--_grid-cols), 1fr); + column-gap: var(--vaadin-form-layout-column-spacing); + row-gap: var(--vaadin-form-item-row-spacing); + align-items: baseline; + justify-content: stretch; + min-width: min-content; } #layout ::slotted(*) { - /* Items should neither grow nor shrink. */ - flex-grow: 0; - flex-shrink: 0; - - /* Margins make spacing between the columns */ - margin-left: calc(0.5 * var(--vaadin-form-layout-column-spacing)); - margin-right: calc(0.5 * var(--vaadin-form-layout-column-spacing)); + /* Unless auto-rows is on, each field starts on a new line */ + grid-column-start: 1; + /* Span is set via custom prop set by the WC; capped by current breakpoint's column count */ + grid-column-end: span min(var(--vaadin-form-layout-colspan), var(--_grid-cols)); } #layout ::slotted(br) { @@ -56,7 +59,6 @@ export const formItemStyles = css` display: inline-flex; flex-direction: row; align-items: baseline; - margin: calc(0.5 * var(--vaadin-form-item-row-spacing, 1em)) 0; } :host([label-position='top']) { From d394524f722a6347ed7f050f854e59e0b6317830 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Wed, 29 Jan 2025 14:28:43 +0400 Subject: [PATCH 02/17] minimize diff --- packages/form-layout/src/vaadin-form-layout-styles.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index 1f1ebccae3..94e44d5ac8 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -10,16 +10,16 @@ export const formLayoutStyles = css` display: block; max-width: 100%; animation: 1ms vaadin-form-layout-appear; - align-self: stretch; container-type: inline-size; container-name: form-grid; - --_grid-cols: 10; /* Number of cols, defined by breakpoints. Default value is probably pointless. */ + /* Number of cols, defined by breakpoints. Default value is probably pointless. */ + --_grid-cols: 10; /* CSS API for host */ - /* Let's not define defaults here – that way they can be set globally */ --vaadin-form-item-label-width: 8em; --vaadin-form-item-label-spacing: 1em; --vaadin-form-item-row-spacing: 1em; - --vaadin-form-layout-column-spacing: 2em; + --vaadin-form-layout-column-spacing: 2em; /* (default) */ + align-self: stretch; } @keyframes vaadin-form-layout-appear { @@ -37,7 +37,7 @@ export const formLayoutStyles = css` grid-template-columns: repeat(var(--_grid-cols), 1fr); column-gap: var(--vaadin-form-layout-column-spacing); row-gap: var(--vaadin-form-item-row-spacing); - align-items: baseline; + align-items: baseline; /* default \`stretch\` is not appropriate */ justify-content: stretch; min-width: min-content; } From fae59b7a4e46ba7efe08215d45c9fb809f24ea54 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Wed, 29 Jan 2025 14:30:15 +0400 Subject: [PATCH 03/17] fix linter errors --- packages/form-layout/src/vaadin-form-layout-styles.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index 94e44d5ac8..e92cf2a92d 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -35,18 +35,14 @@ export const formLayoutStyles = css` #layout { display: grid; grid-template-columns: repeat(var(--_grid-cols), 1fr); - column-gap: var(--vaadin-form-layout-column-spacing); - row-gap: var(--vaadin-form-item-row-spacing); + gap: var(--vaadin-form-item-row-spacing) var(--vaadin-form-layout-column-spacing); align-items: baseline; /* default \`stretch\` is not appropriate */ justify-content: stretch; min-width: min-content; } #layout ::slotted(*) { - /* Unless auto-rows is on, each field starts on a new line */ - grid-column-start: 1; - /* Span is set via custom prop set by the WC; capped by current breakpoint's column count */ - grid-column-end: span min(var(--vaadin-form-layout-colspan), var(--_grid-cols)); + grid-column: 1 / span min(var(--vaadin-form-layout-colspan), var(--_grid-cols)); } #layout ::slotted(br) { From 7df07bf8db464d11581349840f194901ef09c110 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Wed, 29 Jan 2025 16:35:29 +0400 Subject: [PATCH 04/17] calculate responsive steps with CSS grid --- dev/form-layout.html | 2 +- .../src/vaadin-form-layout-mixin.js | 194 ++++++++++-------- .../src/vaadin-form-layout-styles.js | 2 +- 3 files changed, 116 insertions(+), 82 deletions(-) diff --git a/dev/form-layout.html b/dev/form-layout.html index 6b0870d697..07aa94c453 100644 --- a/dev/form-layout.html +++ b/dev/form-layout.html @@ -3,7 +3,7 @@ - + Form Layout diff --git a/packages/form-layout/src/vaadin-form-layout-mixin.js b/packages/form-layout/src/vaadin-form-layout-mixin.js index 536687a97c..e8c9357710 100644 --- a/packages/form-layout/src/vaadin-form-layout-mixin.js +++ b/packages/form-layout/src/vaadin-form-layout-mixin.js @@ -81,6 +81,7 @@ export const FormLayoutMixin = (superClass) => _columnCount: { type: Number, sync: true, + observer: '__columnCountChanged', }, /** @@ -195,6 +196,7 @@ export const FormLayoutMixin = (superClass) => }); if (addedNodes.length > 0 || removedNodes.length > 0) { + // TODO: Optimize this to only update layout if a resize happened this._updateLayout(); } }); @@ -322,6 +324,11 @@ export const FormLayoutMixin = (superClass) => } } + /** @private */ + __columnCountChanged(columnCount) { + this.$.layout.style.setProperty('--_grid-cols', columnCount); + } + /** @private */ _invokeUpdateLayout() { this._updateLayout(); @@ -337,90 +344,117 @@ export const FormLayoutMixin = (superClass) => return; } - /* - 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; - } + [...this.children].forEach((child) => { + const colspan = child.getAttribute('colspan') || child.getAttribute('data-colspan'); + if (colspan) { + child.style.setProperty('--_grid-colspan', colspan); + } - // At the start edge - if (col === 0) { - child.style.setProperty(marginStartProp, '0px'); - } else { - child.style.removeProperty(marginStartProp); + 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 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); - } + // /* + // 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'); + // } + // } + // }); + } - // 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'); - } - } - }); + /** @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. } /** diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index e92cf2a92d..7742e9955e 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -42,7 +42,7 @@ export const formLayoutStyles = css` } #layout ::slotted(*) { - grid-column: 1 / span min(var(--vaadin-form-layout-colspan), var(--_grid-cols)); + grid-column-end: span min(var(--_grid-colspan, 1), var(--_grid-cols)); } #layout ::slotted(br) { From 5e5e075bbdf76a7d4a9f8e2730c2da9b9d955b42 Mon Sep 17 00:00:00 2001 From: Diego Cardoso Date: Wed, 29 Jan 2025 16:29:33 +0200 Subject: [PATCH 05/17] add support for colspan and line-breaks / clean-ups --- .../src/vaadin-form-layout-mixin.js | 140 ++++-------------- .../src/vaadin-form-layout-styles.js | 1 + 2 files changed, 29 insertions(+), 112 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-mixin.js b/packages/form-layout/src/vaadin-form-layout-mixin.js index e8c9357710..51d95e4f7a 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 7742e9955e..f21a53f815 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)); } From 1f4aefba43586ce299571aa042c2ceac1079e078 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Thu, 30 Jan 2025 10:13:47 +0400 Subject: [PATCH 06/17] remove obsolete tests --- .../form-layout/test/form-layout.common.js | 46 ------------------- 1 file changed, 46 deletions(-) diff --git a/packages/form-layout/test/form-layout.common.js b/packages/form-layout/test/form-layout.common.js index 280ab3056a..c56f16e3b2 100644 --- a/packages/form-layout/test/form-layout.common.js +++ b/packages/form-layout/test/form-layout.common.js @@ -123,52 +123,6 @@ describe('form layout', () => { expect(parseFloat(getComputedStyle(item).marginTop)).to.equal(0); expect(parseFloat(getComputedStyle(item).marginBottom)).to.equal(0); }); - - it('should apply default column-spacing', async () => { - // Override to not depend on the theme changes - layout.style.setProperty('--lumo-space-l', '2rem'); - await nextResize(layout); - expect(getParsedWidth(layout.firstElementChild).spacing).to.equal('1rem'); - expect(getComputedStyle(layout.firstElementChild).getPropertyValue('margin-left')).to.equal('0px'); // Zero because it's first - expect(getComputedStyle(layout.firstElementChild).getPropertyValue('margin-right')).to.equal('16px'); // 0.5 * 2rem in px - }); - }); - - describe('colspan', () => { - let layout; - - beforeEach(() => { - layout = fixtureSync(` - - - - - - - - - `); - }); - - function estimateEffectiveColspan(el) { - return parseFloat(getParsedWidth(el).percentage) / (100 / 3); - } - - it('should span children correctly', () => { - // Empty means 1 - expect(estimateEffectiveColspan(layout.children[0])).to.be.closeTo(1, 0.1); - - // Correct values - expect(estimateEffectiveColspan(layout.children[1])).to.be.closeTo(1, 0.1); - expect(estimateEffectiveColspan(layout.children[2])).to.be.closeTo(2, 0.1); - expect(estimateEffectiveColspan(layout.children[3])).to.be.closeTo(3, 0.1); - - // If more then a number of columns, use number of columns - expect(estimateEffectiveColspan(layout.children[4])).to.be.closeTo(3, 0.1); - - // Invalid means 1 - expect(estimateEffectiveColspan(layout.children[5])).to.be.closeTo(1, 0.1); - }); }); describe('container overflow', () => { From ceb9bc3733aae9d88b09f33e184136b4a288c57f Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Thu, 30 Jan 2025 16:10:53 +0400 Subject: [PATCH 07/17] update tests --- .../form-layout/test/form-layout.common.js | 133 ++++++------------ 1 file changed, 44 insertions(+), 89 deletions(-) diff --git a/packages/form-layout/test/form-layout.common.js b/packages/form-layout/test/form-layout.common.js index c56f16e3b2..89f66f2a59 100644 --- a/packages/form-layout/test/form-layout.common.js +++ b/packages/form-layout/test/form-layout.common.js @@ -2,42 +2,6 @@ import { expect } from '@vaadin/chai-plugins'; import { aTimeout, fixtureSync, nextFrame, nextRender, nextResize } from '@vaadin/testing-helpers'; import sinon from 'sinon'; import '@polymer/polymer/lib/elements/dom-repeat.js'; -import { html, PolymerElement } from '@polymer/polymer/polymer-element.js'; - -customElements.define( - 'mutable-layout', - class extends PolymerElement { - static get template() { - return html` - - - - - - - - - - - - `; - } - - static get properties() { - return { - items: { - type: Array, - value: () => [], - }, - }; - } - }, -); function getParsedWidth(el) { const width = el.style.getPropertyValue('width'); @@ -221,14 +185,6 @@ describe('form layout', () => { ]); }); - it('should assign width inline style on items', () => { - layout.responsiveSteps = [{ columns: 3 }]; - - const parsedWidth = getParsedWidth(layout.firstElementChild); - expect(parsedWidth.percentage).to.match(/%$/u); - expect(parseFloat(parsedWidth.percentage)).to.be.closeTo(33, 0.5); - }); - it('should set label-position attribute to child form-item elements', () => { layout.responsiveSteps = [{ columns: 1 }]; @@ -548,43 +504,53 @@ describe('form layout', () => { }); describe('mutations', () => { - let container, layout; + let container, layout, items; beforeEach(async () => { - container = fixtureSync(''); - layout = container.shadowRoot.querySelector('vaadin-form-layout'); + container = fixtureSync(` +
+ + + + + + + + + + +
+ `); + layout = container.querySelector('vaadin-form-layout'); + items = layout.querySelectorAll('vaadin-form-item'); await nextRender(container); }); - function estimateEffectiveColspan(el) { - return parseFloat(getParsedWidth(el).percentage) / (100 / 2); - } + it('should update grid-column-end after updating a colspan attribute', async () => { + expect(getComputedStyle(items[0]).gridColumnEnd).to.equal('span 1'); - it('should update layout after updating a colspan attribute', async () => { - expect(estimateEffectiveColspan(layout.children[0])).to.be.closeTo(1, 0.1); - - layout.children[0].setAttribute('colspan', 2); - await nextRender(container); - expect(estimateEffectiveColspan(layout.children[0])).to.be.closeTo(2, 0.1); + items[0].setAttribute('colspan', 2); + await nextRender(layout); + expect(getComputedStyle(items[0]).gridColumnEnd).to.equal('span 2'); }); - it('should update layout after updating a data-colspan attribute', async () => { - expect(estimateEffectiveColspan(layout.children[0])).to.be.closeTo(1, 0.1); + it('should update grid-column-end after updating a data-colspan attribute', async () => { + expect(getComputedStyle(items[0]).gridColumnEnd).to.equal('span 1'); - layout.children[0].setAttribute('data-colspan', 2); - await nextRender(container); - expect(estimateEffectiveColspan(layout.children[0])).to.be.closeTo(2, 0.1); + items[0].setAttribute('data-colspan', 2); + await nextRender(layout); + expect(getComputedStyle(items[0]).gridColumnEnd).to.equal('span 2'); }); it('should prefer colspan attribute over data-colspan when both are set', async () => { - layout.children[0].setAttribute('colspan', 2); - layout.children[0].setAttribute('data-colspan', 1); - await nextRender(container); - expect(estimateEffectiveColspan(layout.children[0])).to.be.closeTo(2, 0.1); + items[0].setAttribute('colspan', 2); + items[0].setAttribute('data-colspan', 1); + await nextRender(layout); + expect(getComputedStyle(items[0]).gridColumnEnd).to.equal('span 2'); }); it('should update style if hidden property of layout-item is changed and the element has not had style yet', async () => { - const itemWidth = layout.children[0].getBoundingClientRect().width; + const itemWidth = items[0].getBoundingClientRect().width; expect(itemWidth).to.be.above(0); const newFormItem = document.createElement('vaadin-form-item'); @@ -599,32 +565,21 @@ describe('form layout', () => { expect(unhiddenItemWidth).to.equal(itemWidth); }); - it('should update layout after updating a colspan attribute on the lazily stamped node', async () => { - container.push('items', { label: 'Email', colspan: 1 }); - await nextRender(container); - const item = layout.querySelectorAll('vaadin-form-item')[2]; - expect(estimateEffectiveColspan(item)).to.be.closeTo(1, 0.1); - - container.set('items.0.colspan', 2); - await nextRender(container); - expect(estimateEffectiveColspan(item)).to.be.closeTo(2, 0.1); + it('should update grid-column-start after adding
', async () => { + const br = document.createElement('br'); + items[0].after(br); + await nextRender(layout); + expect(getComputedStyle(items[1]).gridColumnStart).to.equal('1'); }); - it('should update layout after a new item is added', async () => { - const newFormItem = document.createElement('vaadin-form-item'); - newFormItem.innerHTML = ''; - layout.appendChild(newFormItem); - await nextRender(container); - expect(getComputedStyle(newFormItem).marginLeft).to.be.equal('0px'); - }); - - it('should update layout after an item is removed', async () => { - const itemsList = layout.querySelectorAll('vaadin-form-item'); - expect(getComputedStyle(itemsList[1]).marginLeft).to.not.be.equal('0px'); + it('should update grid-column-start after removing
', async () => { + const br = document.createElement('br'); + items[0].after(br); + await nextRender(layout); - layout.removeChild(itemsList[0]); - await nextRender(container); - expect(getComputedStyle(itemsList[1]).marginLeft).to.be.equal('0px'); + br.remove(); + await nextRender(layout); + expect(getComputedStyle(items[1]).gridColumnStart).to.equal('auto'); }); it('should not update layout when setting hidden to true', async () => { From bca7528c1e6b27f75198b21446051cef6fbb957d Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Thu, 30 Jan 2025 16:14:01 +0400 Subject: [PATCH 08/17] remove unused import --- packages/form-layout/test/form-layout.common.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/form-layout/test/form-layout.common.js b/packages/form-layout/test/form-layout.common.js index 89f66f2a59..aa7f46514b 100644 --- a/packages/form-layout/test/form-layout.common.js +++ b/packages/form-layout/test/form-layout.common.js @@ -1,7 +1,6 @@ import { expect } from '@vaadin/chai-plugins'; import { aTimeout, fixtureSync, nextFrame, nextRender, nextResize } from '@vaadin/testing-helpers'; import sinon from 'sinon'; -import '@polymer/polymer/lib/elements/dom-repeat.js'; function getParsedWidth(el) { const width = el.style.getPropertyValue('width'); From 162f594ca6c77a3e1ce9069e456b8fe9231f2e0a Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Fri, 31 Jan 2025 17:47:40 +0400 Subject: [PATCH 09/17] remove container queries --- packages/form-layout/src/vaadin-form-layout-styles.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index f21a53f815..96a48b7881 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -10,8 +10,6 @@ export const formLayoutStyles = css` display: block; max-width: 100%; animation: 1ms vaadin-form-layout-appear; - container-type: inline-size; - container-name: form-grid; /* Number of cols, defined by breakpoints. Default value is probably pointless. */ --_grid-cols: 10; /* CSS API for host */ From f2a233531928a93770368e27b753fb388121f99c Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Fri, 31 Jan 2025 18:41:16 +0400 Subject: [PATCH 10/17] minimize diff --- packages/form-layout/src/vaadin-form-layout-styles.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index 96a48b7881..fde20824be 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -35,8 +35,6 @@ export const formLayoutStyles = css` grid-template-columns: repeat(var(--_grid-cols), 1fr); gap: var(--vaadin-form-item-row-spacing) var(--vaadin-form-layout-column-spacing); align-items: baseline; /* default \`stretch\` is not appropriate */ - justify-content: stretch; - min-width: min-content; } #layout ::slotted(*) { From 18ce6a91194a987aaab45b82b62b2dfd21691bff Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Fri, 31 Jan 2025 18:46:33 +0400 Subject: [PATCH 11/17] fix: remove --_grid-colstart when removing
--- packages/form-layout/src/vaadin-form-layout-mixin.js | 2 ++ packages/form-layout/test/form-layout.test.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-mixin.js b/packages/form-layout/src/vaadin-form-layout-mixin.js index aef44b7a79..cd9fb732d2 100644 --- a/packages/form-layout/src/vaadin-form-layout-mixin.js +++ b/packages/form-layout/src/vaadin-form-layout-mixin.js @@ -374,6 +374,8 @@ export const FormLayoutMixin = (superClass) => if (resetColumn) { child.style.setProperty('--_grid-colstart', 1); resetColumn = false; + } else { + child.style.removeProperty('--_grid-colstart'); } }); } diff --git a/packages/form-layout/test/form-layout.test.js b/packages/form-layout/test/form-layout.test.js index 8ba71f0383..45ba7619d4 100644 --- a/packages/form-layout/test/form-layout.test.js +++ b/packages/form-layout/test/form-layout.test.js @@ -519,14 +519,14 @@ describe('form layout', () => { it('should update grid-column-start after adding
', async () => { const br = document.createElement('br'); - items[0].after(br); + layout.insertBefore(br, items[1]); await nextRender(layout); expect(getComputedStyle(items[1]).gridColumnStart).to.equal('1'); }); it('should update grid-column-start after removing
', async () => { const br = document.createElement('br'); - items[0].after(br); + layout.insertBefore(br, items[1]); await nextRender(layout); br.remove(); From a5a99a64f71a3d1560758e2974b862badc0ee39a Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Fri, 31 Jan 2025 18:54:15 +0400 Subject: [PATCH 12/17] fix linter errors --- packages/form-layout/src/vaadin-form-layout-styles.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index fde20824be..80d8c539c8 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -38,8 +38,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)); + grid-column: var(--_grid-colstart, auto) / span min(var(--_grid-colspan, 1), var(--_grid-cols)); } #layout ::slotted(br) { From 1daea8a96c608cc409c85f7148782ee42a5b97c8 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Tue, 4 Feb 2025 16:43:04 +0400 Subject: [PATCH 13/17] add missing nextResize --- packages/form-layout/test/form-layout.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/form-layout/test/form-layout.test.js b/packages/form-layout/test/form-layout.test.js index 0c68730f03..c105ca8b20 100644 --- a/packages/form-layout/test/form-layout.test.js +++ b/packages/form-layout/test/form-layout.test.js @@ -372,6 +372,7 @@ describe('form layout', () => { const spy = sinon.spy(layout, '_selectResponsiveStep'); await nextResize(layout); container.hidden = false; + await nextResize(layout); expect(spy).to.be.calledOnce; }); From 615b83213198cb991776f5853c43a053f789ce12 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Tue, 4 Feb 2025 17:39:24 +0400 Subject: [PATCH 14/17] revert --vaadin-form-item-row-spacing --- packages/form-layout/src/vaadin-form-layout-styles.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index 97cfe432dd..4f47a236ee 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -26,7 +26,7 @@ export const formLayoutStyles = css` #layout { display: grid; grid-template-columns: repeat(var(--_grid-cols), 1fr); - gap: var(--vaadin-form-item-row-spacing) var(--vaadin-form-layout-column-spacing); + gap: var(--vaadin-form-layout-row-spacing) var(--vaadin-form-layout-column-spacing); align-items: baseline; /* default \`stretch\` is not appropriate */ } @@ -44,6 +44,7 @@ export const formItemStyles = css` display: inline-flex; flex-direction: row; align-items: baseline; + margin: calc(0.5 * var(--vaadin-form-item-row-spacing, 1em)) 0; } :host([label-position='top']) { From fdb63d4387b6b6cb17edf99526ea0c2e4293c3e7 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Tue, 4 Feb 2025 19:03:09 +0400 Subject: [PATCH 15/17] set --vaadin-form-item-row-spacing to 0 for Material theme --- packages/form-layout/src/vaadin-form-layout-styles.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/form-layout/src/vaadin-form-layout-styles.js b/packages/form-layout/src/vaadin-form-layout-styles.js index e46f9bd933..13662b7ff1 100644 --- a/packages/form-layout/src/vaadin-form-layout-styles.js +++ b/packages/form-layout/src/vaadin-form-layout-styles.js @@ -14,6 +14,7 @@ export const formLayoutStyles = css` /* CSS API for host */ --vaadin-form-item-label-width: 8em; --vaadin-form-item-label-spacing: 1em; + --vaadin-form-item-row-spacing: 0; --vaadin-form-layout-row-spacing: 1em; --vaadin-form-layout-column-spacing: 2em; /* (default) */ align-self: stretch; From c54dcc2e30f31ef81a175eb78bee5b7216b0a7ca Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Tue, 4 Feb 2025 21:05:43 +0400 Subject: [PATCH 16/17] test: improve coverage by using native input --- test/integration/dialog-form-layout.test.js | 39 ++++++++++----------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/test/integration/dialog-form-layout.test.js b/test/integration/dialog-form-layout.test.js index 6ad376e238..c2223ae4db 100644 --- a/test/integration/dialog-form-layout.test.js +++ b/test/integration/dialog-form-layout.test.js @@ -2,7 +2,6 @@ import { expect } from '@vaadin/chai-plugins'; import { setViewport } from '@vaadin/test-runner-commands'; import { fixtureSync, nextFrame, nextRender } from '@vaadin/testing-helpers'; import './not-animated-styles.js'; -import '@vaadin/text-field'; import '@vaadin/form-layout'; import '@vaadin/form-layout/vaadin-form-item.js'; import '@vaadin/dialog'; @@ -18,25 +17,25 @@ describe('form-layout in dialog', () => { dialog = fixtureSync(``); dialog.renderer = (root) => { root.innerHTML = ` - - - - - - - - - - - - - - - - - - - `; + + + + + + + + + + + + + + + + + + + `; }; dialog.opened = true; await nextRender(); From 9ddd19249d4b8bbd58d31cb03f0f283e9d821921 Mon Sep 17 00:00:00 2001 From: Sergey Vinogradov Date: Tue, 4 Feb 2025 21:43:40 +0400 Subject: [PATCH 17/17] update Material screenshots --- .../baseline/form-layout-item-text-area.png | Bin 14981 -> 14847 bytes .../form-layout/baseline/basic.png | Bin 10584 -> 10469 bytes .../screenshots/form-layout/baseline/br.png | Bin 4024 -> 3908 bytes .../form-layout/baseline/colspan.png | Bin 3133 -> 3021 bytes .../form-layout/baseline/css-properties.png | Bin 3973 -> 4085 bytes .../required-indicator-labels-aside.png | Bin 4512 -> 4395 bytes .../required-indicator-labels-on-top.png | Bin 4776 -> 4658 bytes .../form-layout/baseline/responsive-steps.png | Bin 3074 -> 2966 bytes .../form-layout/baseline/single-column.png | Bin 4512 -> 4400 bytes 9 files changed, 0 insertions(+), 0 deletions(-) diff --git a/packages/custom-field/test/visual/material/screenshots/custom-field/baseline/form-layout-item-text-area.png b/packages/custom-field/test/visual/material/screenshots/custom-field/baseline/form-layout-item-text-area.png index 6ad97c987532e471c3991e069419d928d8713408..1cfe04514763757336a087613cf96ef05173e1f0 100644 GIT binary patch literal 14847 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 literal 10584 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 Y>CK9txZQoIfYG<1uBlGt&4+*e55(|G;{X5v diff --git a/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/br.png b/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/br.png index da12a6dc63ae3a7d37d606e1f3ffd25b0d80f4eb..84ad9e15c8351fa2429c9a961b8da35e23b4b7d5 100644 GIT binary patch delta 65 zcmdlXe?)GAxO4&s69WSS&yneKffQqLkh>GZx^prw85sEfO*C4!S&Gq*PwbQYxrOKF U^K0#t2dZK4boFyt=akR{0EEO8XaE2J delta 74 zcmX>iw?lq{xO4#r69WSSztB`RAjMc5GZx^prw85p?RCmOBaEXjD4OMJqA=F`fP V+Y~RZXay=_@O1TaS?83{1OS?76)OM$ delta 100 zcmX>rzE@&`xO4#r69WSSztB`RAjMc541=eupUXO@geCwnNg%cW diff --git a/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/css-properties.png b/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/css-properties.png index fe4589aca80c5b93b7cf5341e68088607cbd8e03..c2396f3457a4260bc2384fa464a533daac795ef5 100644 GIT binary patch delta 68 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 A;Q#;t diff --git a/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/required-indicator-labels-on-top.png b/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/required-indicator-labels-on-top.png index 57968b209dd16f4e75452f9b5ef51c850e832668..af17f3acec061092ce3400af051fd7ac6b3e639b 100644 GIT binary patch delta 66 zcmZ3Xx=Ce%xO5i>69WUoZt3-vK#H+A$lZxy-8q?;3=D#AHX5-rZZ2YcEFkue-{|?z Vt1k~8bOb75@O1TaS?83{1OT!-7I6Ro delta 83 zcmdm_vO;x&xb!RzCI$wE9cR}*0#b~{LGDfr>(0r%WMB|V+GxbixQS6lkavppqBrb7 l=>xfroB|Us>WiQF&luhJ=cCG31v#KFgQu&X%Q~loCICIU8ngfa diff --git a/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/responsive-steps.png b/packages/form-layout/test/visual/material/screenshots/form-layout/baseline/responsive-steps.png index df866e4bb296a880fa4836140b14ad3740b016ae..ccfd63a3a50431815f67815de039ceb33024724d 100644 GIT binary patch literal 2966 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 X+h1zRjHe#~)iHRw`njxgN@xNA?qL@Z delta 83 zcmdm>v_N@+xbzARCI$wEkM-OxK#H+A$lZxy-8q?;3=D!%6OC3*e!!ZwnU|4QU^0&& b9}*T2N!k6&&Gp4ikY)x?S3j3^P6