Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feature/1150-GridTable' into fea…
Browse files Browse the repository at this point in the history
…ture/1507-grid-apply-tokens
  • Loading branch information
Diaan committed Oct 3, 2024
2 parents b6d3c56 + 1bb101c commit 5e08ea2
Show file tree
Hide file tree
Showing 29 changed files with 383 additions and 30 deletions.
10 changes: 10 additions & 0 deletions .changeset/good-eggs-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@sl-design-system/grid': patch
---

Add `ellipsizeText` property to grid and column

When set on either `<sl-grid>` or `<sl-grid-column>` (or any of their variants), the `ellipsizeText` property
will render the table data using the `<sl-ellipsize-text>` 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.
5 changes: 0 additions & 5 deletions .changeset/ninety-comics-poke.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/sour-adults-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sl-design-system/combobox': patch
---

Hide the placeholder when there is a selection in multiple mode
5 changes: 5 additions & 0 deletions .changeset/spicy-mangos-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sl-design-system/ellipsize-text': patch
---

New utility `<sl-ellipsize-text>` component
5 changes: 0 additions & 5 deletions .changeset/tough-papayas-sip.md

This file was deleted.

10 changes: 10 additions & 0 deletions .changeset/twelve-waves-explain.md
Original file line number Diff line number Diff line change
@@ -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
5 changes: 0 additions & 5 deletions .changeset/yellow-tools-press.md

This file was deleted.

6 changes: 6 additions & 0 deletions packages/components/combobox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/components/combobox/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
12 changes: 12 additions & 0 deletions packages/components/combobox/src/combobox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion packages/components/combobox/src/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ export class Combobox<T = unknown> 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
Expand Down
1 change: 1 addition & 0 deletions packages/components/ellipsize-text/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/ellipsize-text.js';
49 changes: 49 additions & 0 deletions packages/components/ellipsize-text/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
3 changes: 3 additions & 0 deletions packages/components/ellipsize-text/register.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { EllipsizeText } from './src/ellipsize-text.js';

customElements.define('sl-ellipsize-text', EllipsizeText);
6 changes: 6 additions & 0 deletions packages/components/ellipsize-text/src/ellipsize-text.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
:host {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
54 changes: 54 additions & 0 deletions packages/components/ellipsize-text/src/ellipsize-text.spec.ts
Original file line number Diff line number Diff line change
@@ -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`<sl-ellipsize-text>This is a long text that should be truncated</sl-ellipsize-text>`);
});

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;
});
});
});
19 changes: 19 additions & 0 deletions packages/components/ellipsize-text/src/ellipsize-text.stories.ts
Original file line number Diff line number Diff line change
@@ -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<Props>;

export default {
title: 'Utilities/Ellipsize Text',
tags: ['draft'],
render: ({ text, width }) => html`<sl-ellipsize-text style="width: ${width}px">${text}</sl-ellipsize-text>`
} satisfies Meta<Props>;

export const Basic: Story = {
args: {
width: 200,
text: 'This is a long text that should be truncated'
}
};
78 changes: 78 additions & 0 deletions packages/components/ellipsize-text/src/ellipsize-text.ts
Original file line number Diff line number Diff line change
@@ -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`<slot></slot>`;
}

#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;
}
}
}
8 changes: 8 additions & 0 deletions packages/components/ellipsize-text/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"rootDir": "./"
},
"include": ["index.ts", "register.ts", "src/**/*.ts"]
}
6 changes: 6 additions & 0 deletions packages/components/grid/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 2 additions & 1 deletion packages/components/grid/package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down Expand Up @@ -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",
Expand Down
27 changes: 27 additions & 0 deletions packages/components/grid/src/column.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
Loading

0 comments on commit 5e08ea2

Please sign in to comment.