From d53488b9d2969bdd55a8dabb09d3bf68080963e0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 13:39:33 +0200 Subject: [PATCH 1/4] Version Packages (#1543) Co-authored-by: github-actions[bot] --- .changeset/ninety-comics-poke.md | 5 ----- .changeset/tough-papayas-sip.md | 5 ----- .changeset/yellow-tools-press.md | 5 ----- packages/components/combobox/CHANGELOG.md | 6 ++++++ packages/components/combobox/package.json | 2 +- packages/components/grid/CHANGELOG.md | 6 ++++++ packages/components/grid/package.json | 2 +- packages/components/menu/CHANGELOG.md | 6 ++++++ packages/components/menu/package.json | 2 +- 9 files changed, 21 insertions(+), 18 deletions(-) delete mode 100644 .changeset/ninety-comics-poke.md delete mode 100644 .changeset/tough-papayas-sip.md delete mode 100644 .changeset/yellow-tools-press.md diff --git a/.changeset/ninety-comics-poke.md b/.changeset/ninety-comics-poke.md deleted file mode 100644 index 455d43ce4b..0000000000 --- a/.changeset/ninety-comics-poke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@sl-design-system/menu': patch ---- - -Set initial aria-details and aria-expanded on the menu button diff --git a/.changeset/tough-papayas-sip.md b/.changeset/tough-papayas-sip.md deleted file mode 100644 index e2d16b07f1..0000000000 --- a/.changeset/tough-papayas-sip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@sl-design-system/combobox': patch ---- - -Show a message when there are no filter matches diff --git a/.changeset/yellow-tools-press.md b/.changeset/yellow-tools-press.md deleted file mode 100644 index d7b7c2f067..0000000000 --- a/.changeset/yellow-tools-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@sl-design-system/grid': patch ---- - -Fix error in code when flattening column groups diff --git a/packages/components/combobox/CHANGELOG.md b/packages/components/combobox/CHANGELOG.md index 9de2fb252f..994160de0e 100644 --- a/packages/components/combobox/CHANGELOG.md +++ b/packages/components/combobox/CHANGELOG.md @@ -1,5 +1,11 @@ # @sl-design-system/combobox +## 0.0.2 + +### Patch Changes + +- [#1539](https://github.com/sl-design-system/components/pull/1539) [`48cd7d6`](https://github.com/sl-design-system/components/commit/48cd7d60f994fb9517b89c3c4d2d674c5491aa30) - Show a message when there are no filter matches + ## 0.0.1 ### Patch Changes diff --git a/packages/components/combobox/package.json b/packages/components/combobox/package.json index fa143816b4..412aec4ebe 100644 --- a/packages/components/combobox/package.json +++ b/packages/components/combobox/package.json @@ -1,6 +1,6 @@ { "name": "@sl-design-system/combobox", - "version": "0.0.1", + "version": "0.0.2", "description": "Combobox component for the SL Design System", "license": "Apache-2.0", "publishConfig": { diff --git a/packages/components/grid/CHANGELOG.md b/packages/components/grid/CHANGELOG.md index 517007e369..8ab4972b24 100644 --- a/packages/components/grid/CHANGELOG.md +++ b/packages/components/grid/CHANGELOG.md @@ -1,5 +1,11 @@ # @sl-design-system/grid +## 0.1.15 + +### Patch Changes + +- [#1547](https://github.com/sl-design-system/components/pull/1547) [`89e8cbc`](https://github.com/sl-design-system/components/commit/89e8cbceeb1b2a9e1f498a26e251a956e04bb246) - Fix error in code when flattening column groups + ## 0.1.14 ### Patch Changes diff --git a/packages/components/grid/package.json b/packages/components/grid/package.json index 6f0b0c75b8..a00893a2d1 100644 --- a/packages/components/grid/package.json +++ b/packages/components/grid/package.json @@ -1,6 +1,6 @@ { "name": "@sl-design-system/grid", - "version": "0.1.14", + "version": "0.1.15", "description": "Grid components for the SL Design System", "license": "Apache-2.0", "publishConfig": { diff --git a/packages/components/menu/CHANGELOG.md b/packages/components/menu/CHANGELOG.md index 1eb0065568..0f7dbeed8f 100644 --- a/packages/components/menu/CHANGELOG.md +++ b/packages/components/menu/CHANGELOG.md @@ -1,5 +1,11 @@ # @sl-design-system/menu +## 0.1.2 + +### Patch Changes + +- [#1540](https://github.com/sl-design-system/components/pull/1540) [`d52af39`](https://github.com/sl-design-system/components/commit/d52af39c81ca5e8ed2e5b27a79dc3bf3ad162899) - Set initial aria-details and aria-expanded on the menu button + ## 0.1.1 ### Patch Changes diff --git a/packages/components/menu/package.json b/packages/components/menu/package.json index 0318e6948e..78ce0b5442 100644 --- a/packages/components/menu/package.json +++ b/packages/components/menu/package.json @@ -1,6 +1,6 @@ { "name": "@sl-design-system/menu", - "version": "0.1.1", + "version": "0.1.2", "description": "Menu components for the SL Design System", "license": "Apache-2.0", "publishConfig": { From ae44384129f1a787a82fd35262f3f24e0883df58 Mon Sep 17 00:00:00 2001 From: Jeroen Zwartepoorte Date: Mon, 30 Sep 2024 13:07:14 +0200 Subject: [PATCH 2/4] Fix missing types in NPM packages (#1563) --- .changeset/twelve-waves-explain.md | 10 ++++++++++ tsconfig.all.json | 6 ++++++ 2 files changed, 16 insertions(+) create mode 100644 .changeset/twelve-waves-explain.md diff --git a/.changeset/twelve-waves-explain.md b/.changeset/twelve-waves-explain.md new file mode 100644 index 0000000000..7eb57af508 --- /dev/null +++ b/.changeset/twelve-waves-explain.md @@ -0,0 +1,10 @@ +--- +'@sl-design-system/combobox': patch +'@sl-design-system/emoji': patch +'@sl-design-system/listbox': patch +'@sl-design-system/panel': patch +'@sl-design-system/search-field': patch +'@sl-design-system/tool-bar': patch +--- + +Fix missing types in NPM package diff --git a/tsconfig.all.json b/tsconfig.all.json index 587f00203b..3006a08bcc 100644 --- a/tsconfig.all.json +++ b/tsconfig.all.json @@ -25,19 +25,24 @@ { "path": "./packages/components/button-bar" }, { "path": "./packages/components/card" }, { "path": "./packages/components/checkbox" }, + { "path": "./packages/components/combobox" }, { "path": "./packages/components/dialog" }, { "path": "./packages/components/drawer" }, { "path": "./packages/components/editor" }, + { "path": "./packages/components/emoji" }, { "path": "./packages/components/form" }, { "path": "./packages/components/format-date" }, { "path": "./packages/components/grid" }, { "path": "./packages/components/icon" }, { "path": "./packages/components/inline-message" }, + { "path": "./packages/components/listbox" }, { "path": "./packages/components/menu" }, { "path": "./packages/components/message-dialog" }, + { "path": "./packages/components/panel" }, { "path": "./packages/components/popover" }, { "path": "./packages/components/progress-bar" }, { "path": "./packages/components/radio-group" }, + { "path": "./packages/components/search-field" }, { "path": "./packages/components/select" }, { "path": "./packages/components/shared" }, { "path": "./packages/components/skeleton" }, @@ -49,6 +54,7 @@ { "path": "./packages/components/text-field"}, { "path": "./packages/components/toggle-button" }, { "path": "./packages/components/toggle-group" }, + { "path": "./packages/components/tool-bar" }, { "path": "./packages/components/tooltip" }, { "path": "./packages/locales" }, { "path": "./packages/themes/bingel-dc" }, From 99d6174945e6189125271d30a79028134c4ebeae Mon Sep 17 00:00:00 2001 From: Jeroen Zwartepoorte Date: Mon, 30 Sep 2024 13:43:09 +0200 Subject: [PATCH 3/4] Hide the combobox placeholder when there is a selection in multiple mode (#1551) --- .changeset/sour-adults-refuse.md | 5 +++++ packages/components/combobox/src/combobox.spec.ts | 12 ++++++++++++ packages/components/combobox/src/combobox.ts | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .changeset/sour-adults-refuse.md diff --git a/.changeset/sour-adults-refuse.md b/.changeset/sour-adults-refuse.md new file mode 100644 index 0000000000..59c7cd037e --- /dev/null +++ b/.changeset/sour-adults-refuse.md @@ -0,0 +1,5 @@ +--- +'@sl-design-system/combobox': patch +--- + +Hide the placeholder when there is a selection in multiple mode diff --git a/packages/components/combobox/src/combobox.spec.ts b/packages/components/combobox/src/combobox.spec.ts index 2001945dbc..6ed9ee0961 100644 --- a/packages/components/combobox/src/combobox.spec.ts +++ b/packages/components/combobox/src/combobox.spec.ts @@ -585,6 +585,18 @@ describe('sl-combobox', () => { expect(el.multiple).to.be.true; }); + it('should not have a placeholder when there is a selection', async () => { + el.placeholder = 'Placeholder'; + await el.updateComplete; + + expect(input).to.have.attribute('placeholder', 'Placeholder'); + + el.value = ['Lorem']; + await el.updateComplete; + + expect(input).to.have.attribute('placeholder', ''); + }); + it('should set the value when an option is selected', async () => { input.click(); await el.updateComplete; diff --git a/packages/components/combobox/src/combobox.ts b/packages/components/combobox/src/combobox.ts index 1a5f69c243..176cec49d1 100644 --- a/packages/components/combobox/src/combobox.ts +++ b/packages/components/combobox/src/combobox.ts @@ -288,7 +288,7 @@ export class Combobox extends FormControlMixin(ScopedElementsMixin( ?disabled=${this.disabled} ?readonly=${this.selectOnly} ?required=${this.required} - placeholder=${ifDefined(this.placeholder)} + placeholder=${ifDefined(this.multiple && this.currentSelection.length ? undefined : this.placeholder)} size=${ifDefined(this.size)} > ${this.multiple && this.currentSelection.length From f8c6b8609ed138033cb76a475a9301c1a523a85a Mon Sep 17 00:00:00 2001 From: Jeroen Zwartepoorte Date: Thu, 3 Oct 2024 09:55:52 +0200 Subject: [PATCH 4/4] Add `ellipsizeText` property to grid and column for automatically ellipsizing long text (#1567) --- .changeset/good-eggs-pay.md | 10 +++ .changeset/spicy-mangos-marry.md | 5 ++ packages/components/ellipsize-text/index.ts | 1 + .../components/ellipsize-text/package.json | 49 ++++++++++++ .../components/ellipsize-text/register.ts | 3 + .../ellipsize-text/src/ellipsize-text.scss | 6 ++ .../ellipsize-text/src/ellipsize-text.spec.ts | 54 +++++++++++++ .../src/ellipsize-text.stories.ts | 19 +++++ .../ellipsize-text/src/ellipsize-text.ts | 78 +++++++++++++++++++ .../components/ellipsize-text/tsconfig.json | 8 ++ packages/components/grid/package.json | 1 + packages/components/grid/src/column.spec.ts | 27 +++++++ packages/components/grid/src/column.ts | 20 +++-- packages/components/grid/src/grid.ts | 13 ++++ .../grid/src/stories/basics.stories.ts | 32 ++++++-- tsconfig.all.json | 1 + yarn.lock | 12 +++ 17 files changed, 328 insertions(+), 11 deletions(-) create mode 100644 .changeset/good-eggs-pay.md create mode 100644 .changeset/spicy-mangos-marry.md create mode 100644 packages/components/ellipsize-text/index.ts create mode 100644 packages/components/ellipsize-text/package.json create mode 100644 packages/components/ellipsize-text/register.ts create mode 100644 packages/components/ellipsize-text/src/ellipsize-text.scss create mode 100644 packages/components/ellipsize-text/src/ellipsize-text.spec.ts create mode 100644 packages/components/ellipsize-text/src/ellipsize-text.stories.ts create mode 100644 packages/components/ellipsize-text/src/ellipsize-text.ts create mode 100644 packages/components/ellipsize-text/tsconfig.json diff --git a/.changeset/good-eggs-pay.md b/.changeset/good-eggs-pay.md new file mode 100644 index 0000000000..98e8c5fd51 --- /dev/null +++ b/.changeset/good-eggs-pay.md @@ -0,0 +1,10 @@ +--- +'@sl-design-system/grid': patch +--- + +Add `ellipsizeText` property to grid and column + +When set on either `` or `` (or any of their variants), the `ellipsizeText` property +will render the table data using the `` component, which truncates text with an ellipsis when it +overflows its container. This is useful for tables with long text that would otherwise cause row height to grow. +The component also automatically adds a tooltip to the truncated text so that it can still be viewed. diff --git a/.changeset/spicy-mangos-marry.md b/.changeset/spicy-mangos-marry.md new file mode 100644 index 0000000000..7cba853b26 --- /dev/null +++ b/.changeset/spicy-mangos-marry.md @@ -0,0 +1,5 @@ +--- +'@sl-design-system/ellipsize-text': patch +--- + +New utility `` component diff --git a/packages/components/ellipsize-text/index.ts b/packages/components/ellipsize-text/index.ts new file mode 100644 index 0000000000..c974ccb86f --- /dev/null +++ b/packages/components/ellipsize-text/index.ts @@ -0,0 +1 @@ +export * from './src/ellipsize-text.js'; diff --git a/packages/components/ellipsize-text/package.json b/packages/components/ellipsize-text/package.json new file mode 100644 index 0000000000..1215380729 --- /dev/null +++ b/packages/components/ellipsize-text/package.json @@ -0,0 +1,49 @@ +{ + "name": "@sl-design-system/ellipsize-text", + "version": "0.0.0", + "description": "Utility component that ellipsizes text if it doesn't fit", + "license": "Apache-2.0", + "publishConfig": { + "registry": "https://npm.pkg.github.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/sl-design-system/components.git", + "directory": "packages/components/ellipsize-text" + }, + "homepage": "https://sanomalearning.design/components/ellipsize-text", + "bugs": { + "url": "https://github.com/sl-design-system/components/issues" + }, + "type": "module", + "main": "./index.js", + "module": "./index.js", + "types": "./index.d.ts", + "customElements": "custom-elements.json", + "exports": { + ".": "./index.js", + "./package.json": "./package.json", + "./register.js": "./register.js" + }, + "files": [ + "**/*.d.ts", + "**/*.js", + "**/*.js.map", + "custom-elements.json" + ], + "sideEffects": [ + "register.js" + ], + "scripts": { + "test": "echo \"Error: run tests from monorepo root.\" && exit 1" + }, + "dependencies": { + "@sl-design-system/tooltip": "^1.1.0" + }, + "devDependencies": { + "@open-wc/scoped-elements": "^3.0.5" + }, + "peerDependencies": { + "@open-wc/scoped-elements": "^3.0.5" + } +} diff --git a/packages/components/ellipsize-text/register.ts b/packages/components/ellipsize-text/register.ts new file mode 100644 index 0000000000..1f4a748d48 --- /dev/null +++ b/packages/components/ellipsize-text/register.ts @@ -0,0 +1,3 @@ +import { EllipsizeText } from './src/ellipsize-text.js'; + +customElements.define('sl-ellipsize-text', EllipsizeText); diff --git a/packages/components/ellipsize-text/src/ellipsize-text.scss b/packages/components/ellipsize-text/src/ellipsize-text.scss new file mode 100644 index 0000000000..742f8350dd --- /dev/null +++ b/packages/components/ellipsize-text/src/ellipsize-text.scss @@ -0,0 +1,6 @@ +:host { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/packages/components/ellipsize-text/src/ellipsize-text.spec.ts b/packages/components/ellipsize-text/src/ellipsize-text.spec.ts new file mode 100644 index 0000000000..e6d3ea16cf --- /dev/null +++ b/packages/components/ellipsize-text/src/ellipsize-text.spec.ts @@ -0,0 +1,54 @@ +import { expect, fixture } from '@open-wc/testing'; +import { html } from 'lit'; +import '../register.js'; +import { type EllipsizeText } from './ellipsize-text.js'; + +describe('sl-ellipsize-text', () => { + let el: EllipsizeText; + + beforeEach(async () => { + el = await fixture(html`This is a long text that should be truncated`); + }); + + it('should render a slot with the text', () => { + const slot = el.renderRoot.querySelector('slot'); + + expect(slot).to.exist; + expect( + slot + ?.assignedNodes() + .map(node => node.textContent?.trim()) + .join('') + ).to.equal('This is a long text that should be truncated'); + }); + + it('should not have a tooltip by default', () => { + expect(el).not.to.have.attribute('aria-describedby'); + }); + + describe('tooltip', () => { + beforeEach(async () => { + el.style.width = '100px'; + + // Wait for the resize observer to trigger + await new Promise(resolve => setTimeout(resolve, 100)); + + // Trigger a focus event to create the tooltip + el.dispatchEvent(new Event('focusin')); + }); + + it('should have a tooltip when there is not enough space', () => { + const tooltip = el.nextElementSibling; + + expect(tooltip).to.exist; + expect(tooltip).to.match('sl-tooltip'); + expect(el).to.have.attribute('aria-describedby', tooltip?.id); + }); + + it('should remove the tooltip when the element is removed from the DOM', () => { + el.remove(); + + expect(document.querySelector('sl-tooltip')).not.to.exist; + }); + }); +}); diff --git a/packages/components/ellipsize-text/src/ellipsize-text.stories.ts b/packages/components/ellipsize-text/src/ellipsize-text.stories.ts new file mode 100644 index 0000000000..5dd5ce6c6b --- /dev/null +++ b/packages/components/ellipsize-text/src/ellipsize-text.stories.ts @@ -0,0 +1,19 @@ +import { type Meta, type StoryObj } from '@storybook/web-components'; +import { html } from 'lit'; +import '../register.js'; + +type Props = { text: string; width: number }; +type Story = StoryObj; + +export default { + title: 'Utilities/Ellipsize Text', + tags: ['draft'], + render: ({ text, width }) => html`${text}` +} satisfies Meta; + +export const Basic: Story = { + args: { + width: 200, + text: 'This is a long text that should be truncated' + } +}; diff --git a/packages/components/ellipsize-text/src/ellipsize-text.ts b/packages/components/ellipsize-text/src/ellipsize-text.ts new file mode 100644 index 0000000000..7a77aefbdd --- /dev/null +++ b/packages/components/ellipsize-text/src/ellipsize-text.ts @@ -0,0 +1,78 @@ +import { type ScopedElementsMap, ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js'; +import { Tooltip } from '@sl-design-system/tooltip'; +import { type CSSResultGroup, LitElement, type TemplateResult, html } from 'lit'; +import styles from './ellipsize-text.scss.js'; + +declare global { + interface HTMLElementTagNameMap { + 'sl-ellipsize-text': EllipsizeText; + } +} + +/** + * Small utility component to add ellipsis to text that overflows + * its container. It also adds a tooltip with the full text. + */ +export class EllipsizeText extends ScopedElementsMixin(LitElement) { + /** @internal */ + static get scopedElements(): ScopedElementsMap { + return { + 'sl-tooltip': Tooltip + }; + } + + /** @internal */ + static override styles: CSSResultGroup = styles; + + /** Observe size changes. */ + #observer = new ResizeObserver(() => this.#onResize()); + + /** The lazy tooltip. */ + #tooltip?: Tooltip | (() => void); + + override connectedCallback(): void { + super.connectedCallback(); + + this.#observer.observe(this); + } + + override disconnectedCallback(): void { + this.#observer.disconnect(); + + if (this.#tooltip instanceof Tooltip) { + this.#tooltip.remove(); + } else if (this.#tooltip) { + this.#tooltip(); + } + + this.#tooltip = undefined; + + super.disconnectedCallback(); + } + + override render(): TemplateResult { + return html``; + } + + #onResize(): void { + if (this.offsetWidth < this.scrollWidth) { + this.#tooltip ||= Tooltip.lazy( + this, + tooltip => { + this.#tooltip = tooltip; + tooltip.position = 'bottom'; + tooltip.textContent = this.textContent?.trim() || ''; + }, + { context: this.shadowRoot! } + ); + } else if (this.#tooltip instanceof Tooltip) { + this.removeAttribute('aria-describedby'); + + this.#tooltip.remove(); + this.#tooltip = undefined; + } else if (this.#tooltip) { + this.#tooltip(); + this.#tooltip = undefined; + } + } +} diff --git a/packages/components/ellipsize-text/tsconfig.json b/packages/components/ellipsize-text/tsconfig.json new file mode 100644 index 0000000000..386c2cfcb7 --- /dev/null +++ b/packages/components/ellipsize-text/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "rootDir": "./" + }, + "include": ["index.ts", "register.ts", "src/**/*.ts"] +} \ No newline at end of file diff --git a/packages/components/grid/package.json b/packages/components/grid/package.json index a00893a2d1..1921ba313b 100644 --- a/packages/components/grid/package.json +++ b/packages/components/grid/package.json @@ -39,6 +39,7 @@ }, "dependencies": { "@sl-design-system/checkbox": "^2.0.0", + "@sl-design-system/ellipsize-text": "^0.0.0", "@sl-design-system/icon": "^1.0.2", "@sl-design-system/popover": "^1.1.0", "@sl-design-system/select": "^1.1.1", diff --git a/packages/components/grid/src/column.spec.ts b/packages/components/grid/src/column.spec.ts index b7bb754f6c..9fb0da4f19 100644 --- a/packages/components/grid/src/column.spec.ts +++ b/packages/components/grid/src/column.spec.ts @@ -57,6 +57,33 @@ describe('sl-column', () => { 'data age' ]); }); + + it('should not ellipsize the text in the cells', () => { + expect(el.renderRoot.querySelector('sl-ellipsize-text')).not.to.exist; + }); + + it('should ellipsize the text in the cells when set', async () => { + el.ellipsizeText = true; + await el.updateComplete; + + expect( + Array.from(el.renderRoot.querySelectorAll('tbody tr:first-of-type td')).map( + cell => cell.firstElementChild?.tagName === 'SL-ELLIPSIZE-TEXT' + ) + ).to.deep.equal([true, true, false]); + }); + + it('should ellipsize the text in the cells when set on the column', async () => { + el.querySelector('sl-grid-column')!.ellipsizeText = true; + el.requestUpdate(); + await el.updateComplete; + + expect( + Array.from(el.renderRoot.querySelectorAll('tbody tr:first-of-type td')).map( + cell => cell.firstElementChild?.tagName === 'SL-ELLIPSIZE-TEXT' + ) + ).to.deep.equal([true, false, false]); + }); }); describe('custom renderer', () => { diff --git a/packages/components/grid/src/column.ts b/packages/components/grid/src/column.ts index 2e5106efc3..eb85e204db 100644 --- a/packages/components/grid/src/column.ts +++ b/packages/components/grid/src/column.ts @@ -62,6 +62,9 @@ export class GridColumn extends LitElement { /** @internal Emits when the column definition has changed. */ @event({ name: 'sl-column-update' }) columnUpdateEvent!: EventEmitter>; + /** This will ellipsize the text in the `` elements when it overflows. */ + @property({ type: Boolean, attribute: 'ellipsize-text' }) ellipsizeText?: boolean; + /** The parent grid instance. */ @property({ attribute: false }) set grid(value: Grid | undefined) { @@ -150,11 +153,18 @@ export class GridColumn extends LitElement { renderData(item: T): TemplateResult { const parts = ['data', ...this.getParts(item)]; - return html` - - ${this.renderer ? this.renderer(item) : this.path ? getValueByPath(item, this.path) : 'No path set'} - - `; + let data: unknown; + if (this.renderer) { + data = this.renderer(item); + } else if (this.path) { + data = getValueByPath(item, this.path); + } + + if (this.ellipsizeText && typeof data === 'string') { + return html`${data}`; + } else { + return html`${data || 'No path set'}`; + } } renderStyles(): CSSResult | void {} diff --git a/packages/components/grid/src/grid.ts b/packages/components/grid/src/grid.ts index 797302c176..c616b428ba 100644 --- a/packages/components/grid/src/grid.ts +++ b/packages/components/grid/src/grid.ts @@ -2,6 +2,7 @@ import { localized } from '@lit/localize'; import { type VirtualizerHostElement, virtualize, virtualizerRef } from '@lit-labs/virtualizer/virtualize.js'; import { type ScopedElementsMap, ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js'; +import { EllipsizeText } from '@sl-design-system/ellipsize-text'; import { ArrayDataSource, type DataSource, @@ -96,6 +97,7 @@ export class Grid extends ScopedElementsMixin(LitElement) { /** @internal */ static get scopedElements(): ScopedElementsMap { return { + 'sl-ellipsize-text': EllipsizeText, 'sl-grid-group-header': GridGroupHeader }; } @@ -191,6 +193,9 @@ export class Grid extends ScopedElementsMixin(LitElement) { /** @internal Provides clarity when 'between-or-on-top' is the active draggableRows value. */ @property({ reflect: true, attribute: 'drop-target-mode' }) dropTargetMode?: 'between' | 'on-grid' | 'on-top'; + /** This will ellipsize the text in the `` elements if it overflows. */ + @property({ type: Boolean, reflect: true, attribute: 'ellipsize-text' }) ellipsizeText?: boolean; + /** Custom renderer for group headers. */ @property({ attribute: false }) groupHeaderRenderer?: GridGroupHeaderRenderer; @@ -279,6 +284,10 @@ export class Grid extends ScopedElementsMixin(LitElement) { if (changes.has('scopedElements')) { this.#addScopedElements(this.scopedElements); } + + if (changes.has('ellipsizeText')) { + this.view.headerRows.at(-1)?.forEach(col => (col.ellipsizeText = this.ellipsizeText)); + } } override render(): TemplateResult { @@ -692,6 +701,10 @@ export class Grid extends ScopedElementsMixin(LitElement) { col.itemsChanged(); } + if (this.ellipsizeText) { + col.ellipsizeText = this.ellipsizeText; + } + if (col instanceof GridFilterColumn) { const { value } = this.dataSource?.filters.get(col.id) || {}; if (value) { diff --git a/packages/components/grid/src/stories/basics.stories.ts b/packages/components/grid/src/stories/basics.stories.ts index ff7aedce02..4c47448e25 100644 --- a/packages/components/grid/src/stories/basics.stories.ts +++ b/packages/components/grid/src/stories/basics.stories.ts @@ -16,11 +16,11 @@ export default { parameters: { // Disables Chromatic's snapshotting on a story level chromatic: { disableSnapshot: true } - } + }, + loaders: [async () => ({ people: (await getPeople()).people })] }; export const Simple: Story = { - loaders: [async () => ({ people: (await getPeople()).people })], render: (_, { loaded: { people } }) => html` @@ -46,7 +46,6 @@ export const Few: Story = { }; export const Small: Story = { - loaders: [async () => ({ people: (await getPeople()).people })], render: (_, { loaded: { people } }) => html` @@ -56,7 +55,6 @@ export const Small: Story = { }; export const ColumnGroups: Story = { - loaders: [async () => ({ people: (await getPeople()).people })], render: (_, { loaded: { people } }) => html` @@ -76,8 +74,31 @@ export const ColumnGroups: Story = { ` }; +export const EllipsizeTextAllColumns: Story = { + render: (_, { loaded: { people } }) => html` + + + + + + + + ` +}; + +export const EllipsizeTextSingleColumn: Story = { + render: (_, { loaded: { people } }) => html` + + + + + + + + ` +}; + export const CustomRenderers: Story = { - loaders: [async () => ({ people: (await getPeople()).people })], render: (_, { loaded: { people } }) => { const avatarRenderer: GridColumnDataRenderer = ({ firstName, lastName }) => { return html``; @@ -121,7 +142,6 @@ export const CustomRenderers: Story = { }; export const CustomHeader: Story = { - loaders: [async () => ({ people: (await getPeople()).people })], render: (_, { loaded: { people } }) => html`