From 0d07c6290c345c2e5797d25720eb621a552d70c0 Mon Sep 17 00:00:00 2001 From: Meghea Iulian Date: Thu, 27 Apr 2023 12:54:09 +0300 Subject: [PATCH 1/7] feat(autocomplete): multiple chips BREAKING CHANGE: Show multiple chips on the same rows before input. Collapse chips that don't fit into a numbered badge. --- package-lock.json | 30 ++++---- src/autocomplete/autocomplete.ts | 18 +++-- src/autocomplete/chip.css.ts | 47 ++++++++++++ src/autocomplete/chip.ts | 74 ++++++++++++++++++ src/autocomplete/selection.ts | 107 +++++---------------------- src/autocomplete/styles.css.ts | 101 ++++++++----------------- src/autocomplete/use-autocomplete.ts | 1 + src/autocomplete/use-overflow.ts | 57 ++++++++++++++ src/autocomplete/util.ts | 17 +++++ 9 files changed, 275 insertions(+), 177 deletions(-) create mode 100644 src/autocomplete/chip.css.ts create mode 100644 src/autocomplete/chip.ts create mode 100644 src/autocomplete/use-overflow.ts diff --git a/package-lock.json b/package-lock.json index 9cccc736..49ee01a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2694,9 +2694,9 @@ "integrity": "sha512-92uQ5ARf7UXYrzaFcAX3T2rTvaS9Z1//ukV+DqjACM4c8s0ZBQd7ayJU5Dh2AFLD/Ayuyz4uMmxQec8q3U4Ong==" }, "node_modules/@lit-labs/virtualizer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@lit-labs/virtualizer/-/virtualizer-2.0.0.tgz", - "integrity": "sha512-3i33pW0fvejGFpuZ5yqvPAic2qICGwqLSi8gI0YcqFUxGPBWJC3uuFIV6uhO1UfuBPUNyj1Q8NdXPMC+eM1C9A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@lit-labs/virtualizer/-/virtualizer-2.0.1.tgz", + "integrity": "sha512-Z7OQ+TFiTTBuNSOlf81zBraGKnf5IHwbHwobWDFtlP1xHD5OnXnmx/ISwSGDLiCR5r7cDxCsWj98E4n3BGLAWQ==", "dependencies": { "lit": "^2.7.0", "tslib": "^2.0.3" @@ -2907,9 +2907,9 @@ } }, "node_modules/@neovici/cosmoz-input": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@neovici/cosmoz-input/-/cosmoz-input-3.7.0.tgz", - "integrity": "sha512-xAJOf9fKaRRXiaXFrVt4nrSm/Gwxqy29OuKvGENwoO47CVZAzCqpqmfnx9SfOYAz8vkRrLrV4fImMSzjDFTadg==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@neovici/cosmoz-input/-/cosmoz-input-3.10.0.tgz", + "integrity": "sha512-fM+fe7VaiX5HoPxg4U7HwQ/dUyrv94C22JpdURVzCyBrAz1xbv6YOG4m0RLAXDxNiwr+6CxOvZLQMPHqIz++cw==", "dependencies": { "@neovici/cosmoz-utils": "^5.1.0", "haunted": "^5.0.0", @@ -2917,9 +2917,9 @@ } }, "node_modules/@neovici/cosmoz-utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@neovici/cosmoz-utils/-/cosmoz-utils-5.27.0.tgz", - "integrity": "sha512-cGcLzdpdQZ4TulFrvZ4zZSpyK+m35hurEw3JGyfmLQoetQPG/Bk6EMt0twzpuNqiN71OpqCcRBRRJuTWQF1bfw==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@neovici/cosmoz-utils/-/cosmoz-utils-5.28.0.tgz", + "integrity": "sha512-EzksbYTQrTOaTOuwVIsdk1tnFekt8ADaJr/kzUM+5p1k6LedTGuGIuv6/y0fPGmkNqb0T726PIc2MzoghHWiOQ==", "dependencies": { "haunted": "^5.0.0" } @@ -9990,9 +9990,9 @@ } }, "node_modules/lit-html": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.2.tgz", - "integrity": "sha512-ZJCfKlA2XELu5tn7XuzOziGFGvf1SeQm+ngLWoJ8bXtSkRrrR3ms6SWy+gsdxeYwySLij5xAhdd2C3EX0ftxdQ==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.3.tgz", + "integrity": "sha512-9DyLzcn/kbRGowz2vFmSANFbRZTxYUgYYFqzie89w6GLpPUiBCDHfcdeRUV/k3Q2ueYxNjfv46yPCtKAEAPOVw==", "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -16527,9 +16527,9 @@ } }, "node_modules/sinon": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.3.tgz", - "integrity": "sha512-si3geiRkeovP7Iel2O+qGL4NrO9vbMf3KsrJEi0ghP1l5aBkB5UxARea5j0FUsSqH3HLBh0dQPAyQ8fObRUqHw==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.4.tgz", + "integrity": "sha512-uzmfN6zx3GQaria1kwgWGeKiXSSbShBbue6Dcj0SI8fiCNFbiUDqKl57WFlY5lyhxZVUKmXvzgG2pilRQCBwWg==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0", diff --git a/src/autocomplete/autocomplete.ts b/src/autocomplete/autocomplete.ts index 412fe744..f8e4e199 100644 --- a/src/autocomplete/autocomplete.ts +++ b/src/autocomplete/autocomplete.ts @@ -9,6 +9,7 @@ import { useAutocomplete, Props as Base, RProps } from './use-autocomplete'; import { listbox } from '../listbox'; import style from './styles.css'; import { selection } from './selection'; +import { useOverflow } from './use-overflow'; export interface Props extends Base { invalid?: boolean; @@ -22,7 +23,10 @@ export interface Props extends Base { itemLimit?: number; } -type AProps = Omit, keyof RProps> & RProps; +type AProps = Omit, keyof RProps> & + RProps & { + onInputRef?: (el?: Element) => void; + }; const blank = () => nothing; @@ -81,7 +85,7 @@ const autocomplete = (props: AProps) => { .label=${label} .placeholder=${isSingle ? undefined : placeholder} ?no-label-float=${noLabelFloat} - ?always-float-label=${isSingle || alwaysFloatLabel} + ?always-float-label=${value?.length > 0 || alwaysFloatLabel} ?readonly=${isSingle} ?disabled=${disabled} ?invalid=${until( @@ -105,6 +109,7 @@ const autocomplete = (props: AProps) => { @click=${onClick} autocomplete="off" exportparts=${inputParts} + ?data-one=${isOne} > @@ -123,11 +128,14 @@ const autocomplete = (props: AProps) => { ${suggestions}`; }, - Autocomplete = (props: Props) => - autocomplete({ + Autocomplete = (props: Props) => { + const thru = { ...props, ...useAutocomplete(props), - }), + }; + useOverflow(thru); + return autocomplete(thru); + }, observedAttributes = [ 'disabled', 'invalid', diff --git a/src/autocomplete/chip.css.ts b/src/autocomplete/chip.css.ts new file mode 100644 index 00000000..a2f2f697 --- /dev/null +++ b/src/autocomplete/chip.css.ts @@ -0,0 +1,47 @@ +import { tagged as css } from '@neovici/cosmoz-utils'; + +export default css` + :host { + border-radius: var(--cosmoz-autocomplete-chip-border-radius, 500px); + background: var(--cosmoz-autocomplete-chip-bg-color, #cbcfdb); + margin: 0px 0 2px 0; + display: flex; + flex-direction: row; + align-items: center; + flex: 0.0001 1 fit-content; + max-width: 18ch; + min-width: 45px; + padding: 0 4px 0 10px; + gap: 4px; + } + .content { + color: var(--cosmoz-autocomplete-chip-color, #424242); + font-size: var(--cosmoz-autocomplete-chip-text-font-size, 12px); + line-height: var(--cosmoz-autocomplete-chip-text-line-height, 22px); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + flex: auto; + min-width: 16px; + } + .clear { + background-color: var(--cosmoz-autocomplete-chip-clear-bg-color, #81899b); + border-radius: 50%; + cursor: pointer; + width: 16px; + height: 16px; + stroke: var( + --cosmoz-autocomplete-chip-clear-stroke, + var(--cosmoz-autocomplete-chip-bg-color, #cbcfdb) + ); + display: block; + flex: none; + } + .clear:hover { + filter: brightness(90%); + } + .clear svg { + display: block; + transform: translate(3.5px, 3.5px); + } +`; diff --git a/src/autocomplete/chip.ts b/src/autocomplete/chip.ts new file mode 100644 index 00000000..464229f0 --- /dev/null +++ b/src/autocomplete/chip.ts @@ -0,0 +1,74 @@ +import { html, component } from 'haunted'; +import { when } from 'lit-html/directives/when.js'; +import { ifDefined } from 'lit-html/directives/if-defined.js'; +import styles from './chip.css'; + +const clear = html` + + + + +`; + +interface Props { + onClear?: () => void; + disabled?: boolean; +} +export const Chip = ({ onClear, disabled }: Props) => html` + +
+ ${when( + !disabled, + () => + html` + ${clear} + ` + )} +`; + +customElements.define( + 'cosmoz-autocomplete-chip', + component(Chip, { observedAttributes: ['disabled'] }) +); + +interface ChipProps extends Props { + slot?: string; + className?: string; + content: unknown; +} +export const chip = ({ + content, + onClear, + disabled, + className = 'chip', + slot, +}: ChipProps) => + html`${content}`; diff --git a/src/autocomplete/selection.ts b/src/autocomplete/selection.ts index e4e0717f..d12c69cf 100644 --- a/src/autocomplete/selection.ts +++ b/src/autocomplete/selection.ts @@ -1,79 +1,9 @@ -import { html } from 'lit-html'; // eslint-disable-line object-curly-newline -import { when } from 'lit-html/directives/when.js'; +import { html } from 'lit-html'; +import { chip } from './chip'; import type { RProps } from './use-autocomplete'; type Deselect = RProps['onDeselect']; -const clear = html` - - - - -`; - -const chip = ({ - text, - onClear, - disabled, - isOne, -}: { - text: string; - onClear: () => void; - disabled?: boolean; - isOne?: boolean; -}) => html` -
- ${text} - ${when( - !disabled, - () => - html` - ${clear} - ` - )} -
-`; - -const badge = ({ - value, - onDeselect, -}: { - value: I[]; - onDeselect: Deselect; -}) => { - const len = value?.length; - return when( - len > 0, - () => html`
- ${len} - onDeselect(value)} - >${clear} -
` - ); -}; - interface Props { value: I[]; isOne: boolean; @@ -83,22 +13,23 @@ interface Props { } export const selection = ({ - value, - isOne, + value: values, onDeselect, textual, disabled, -}: Props) => { - if (isOne || value.length === 1) { - const val = value[0]; - return when(val, () => - chip({ - text: textual(val), - onClear: () => onDeselect(val), - disabled, - isOne, - }) - ); - } - return badge({ value, onDeselect }); -}; +}: Props) => [ + ...values.map((value) => + chip({ + content: textual(value), + onClear: () => onDeselect(value), + disabled, + slot: 'control', + }) + ), + chip({ + content: html``, + className: 'badge', + disabled: true, + slot: 'control', + }), +]; diff --git a/src/autocomplete/styles.css.ts b/src/autocomplete/styles.css.ts index 889d2186..0c9b7c63 100644 --- a/src/autocomplete/styles.css.ts +++ b/src/autocomplete/styles.css.ts @@ -5,84 +5,47 @@ export default css` display: block; position: relative; } - .chip { - border-radius: var(--cosmoz-autocomplete-chip-border-radius, 500px); - background: var(--cosmoz-autocomplete-chip-bg-color, #cbcfdb); - margin: 1px 4px 1px 0; - white-space: nowrap; - overflow: hidden; + + cosmoz-input::part(control) { display: flex; - flex-direction: row; - align-items: center; - flex: 0.00001 1 min-content; - max-width: 285px; - max-width: 28ch; - } - .chip[data-one] { - position: absolute; - left: 0; - top: 1px; - bottom: 1px; - right: 0; - margin: 0; - z-index: 2; - pointer-events: auto; - max-width: initial; + gap: 4px; + min-width: 35px; } - .chip-text { - color: var(--cosmoz-autocomplete-chip-color, #424242); - margin: var(--cosmoz-autocomplete-chip-text-margin, 0 10px); - font-size: var(--cosmoz-autocomplete-chip-text-font-size, 12px); - line-height: var(--cosmoz-autocomplete-chip-text-line-height, 22px); - overflow: hidden; - text-overflow: ellipsis; - flex: 1; + cosmoz-input::part(input) { + flex: 1 24px; + min-width: 0; } - .chip-clear { - margin: 2px 4px 2px -6px; - background-color: var(--cosmoz-autocomplete-chip-clear-bg-color, #81899b); - border-radius: 500px; - cursor: pointer; - width: 16px; - height: 16px; - stroke: var( - --cosmoz-autocomplete-chip-clear-stroke, - var(--cosmoz-autocomplete-chip-bg-color, #cbcfdb) - ); - display: block; + cosmoz-input::part(input):focus { + flex: 4 0.00001 50px; + min-width: 20px; } - .chip-clear svg, - .badge-clear svg { - display: block; - transform: translate(3.5px, 3.5px); + .chip { + flex: 0.00001 1 fit-content; + max-width: 18ch; + min-width: 45px; } - .badge { - background: var(--cosmoz-autocomplete-chip-bg-color, #cbcfdb); - color: var(--cosmoz-autocomplete-chip-color, #424242); - font-weight: 500; - font-size: 12px; - line-height: 22px; - padding: 0 4px 0 6px; - gap: 4px; - border-radius: 90px; + min-width: initial; + flex: none; text-align: center; - box-sizing: border-box; - /* fallback for unsupported min-content FF, Safari */ - flex: 0.01 2 30px; - flex: 0 2 min-content; - display: flex; - align-items: center; + padding: 0 3px; } - .badge-clear { - background-color: var(--cosmoz-autocomplete-chip-clear-bg-color, #81899b); - border-radius: 500px; - cursor: pointer; - width: 16px; - height: 16px; - stroke: var(--cosmoz-autocomplete-chip-bg-color, #cbcfdb); - display: block; + + [data-one]::part(input) { + flex: 0; + } + [data-one] .chip { + max-width: initial; + flex: 1; + } + + [data-one] .badge { + display: none; + } + + [hidden] { + display: none; } slot { diff --git a/src/autocomplete/use-autocomplete.ts b/src/autocomplete/use-autocomplete.ts index 6ade14dd..691a15c3 100644 --- a/src/autocomplete/use-autocomplete.ts +++ b/src/autocomplete/use-autocomplete.ts @@ -113,6 +113,7 @@ export const useAutocomplete = ({ }); return { + active, query, textual, value, diff --git a/src/autocomplete/use-overflow.ts b/src/autocomplete/use-overflow.ts new file mode 100644 index 00000000..d73a2f6a --- /dev/null +++ b/src/autocomplete/use-overflow.ts @@ -0,0 +1,57 @@ +import { useLayoutEffect, useState, useMemo } from 'haunted'; +import { useHost } from '@neovici/cosmoz-utils/hooks/use-host'; +import { raf } from './util'; + +const overflow = (host: HTMLElement) => { + const chips = host.shadowRoot!.querySelectorAll('.chip'); + const badge = host.shadowRoot!.querySelector('.badge')!; + badge.hidden = true; + for (const chip of chips) { + chip.hidden = false; + } + const input = host.shadowRoot!.querySelector('cosmoz-input')!; + if (input.matches('[data-one]')) return; + const limit = input.shadowRoot + ?.querySelector('.control') + ?.getBoundingClientRect(); + let i; + for (i = 0; i < chips.length; i++) { + const chip = chips[i]; + const bounds = chip.getBoundingClientRect(); + const isIn = bounds.x + bounds.width <= limit!.x + limit!.width - 24; + if (!isIn) { + break; + } + } + + const overflown = chips.length - i; + badge.querySelector('span')!.textContent = '+' + overflown.toString(); + badge.hidden = overflown < 1; + + for (; i < chips.length; i++) { + chips[i].hidden = true; + } +}; + +export const useOverflow = ({ + value, + active, +}: { + value: I[]; + active?: boolean; +}) => { + const host = useHost(); + const doRaf = useMemo(() => raf(() => overflow(host)), []); + const [width, setWidth] = useState(0); + + useLayoutEffect(() => { + const input = host.shadowRoot!.querySelector('cosmoz-input')!; + const observer = new ResizeObserver((e) => { + setWidth(e[0].contentRect.width); + }); + observer.observe(input); + return () => observer.disconnect(); + }, []); + + useLayoutEffect(() => doRaf(), [width, active, value]); +}; diff --git a/src/autocomplete/util.ts b/src/autocomplete/util.ts index 254a0d29..79a4dbaa 100644 --- a/src/autocomplete/util.ts +++ b/src/autocomplete/util.ts @@ -41,3 +41,20 @@ export const useNotify = ( export const EMPTY = [], EMPTY$ = Promise.resolve(EMPTY); + +type Arr = unknown[]; +type ArrFn = (...args: T) => void; +export const raf = + = ArrFn>(fn: F) => + (...args: A) => { + let id: number | undefined; + const cleanup = () => { + if (id) cancelAnimationFrame(id); + }; + cleanup(); + id = requestAnimationFrame(() => { + id = undefined; + fn(...args); + }); + return cleanup; + }; From 05fcc68da10233cdff404c03cc0c97aad753a692 Mon Sep 17 00:00:00 2001 From: Meghea Iulian Date: Thu, 27 Apr 2023 13:41:14 +0300 Subject: [PATCH 2/7] chore(test): update & fix --- .eslintignore | 1 + .../cosmoz-autocomplete.test.snap.js | 210 ++++++++++++++++++ test/cosmoz-autocomplete.test.js | 71 +----- 3 files changed, 221 insertions(+), 61 deletions(-) create mode 100644 test/__snapshots__/cosmoz-autocomplete.test.snap.js diff --git a/.eslintignore b/.eslintignore index d64c4ca2..d5c36bb1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ coverage/ dist/ +__snapshots__/ diff --git a/test/__snapshots__/cosmoz-autocomplete.test.snap.js b/test/__snapshots__/cosmoz-autocomplete.test.snap.js new file mode 100644 index 00000000..ce655ef2 --- /dev/null +++ b/test/__snapshots__/cosmoz-autocomplete.test.snap.js @@ -0,0 +1,210 @@ +/* @web/test-runner snapshot v1 */ +export const snapshots = {}; + +snapshots["cosmoz-autocomplete-ui render"] = +` + + + + + + Item 1 + + + Item 2 + + + + + + +`; +/* end snapshot cosmoz-autocomplete-ui render */ + +snapshots["cosmoz-autocomplete-ui render (limit 1)"] = +` + + + + + + Item 1 + + + + + + +`; +/* end snapshot cosmoz-autocomplete-ui render (limit 1) */ + +snapshots["cosmoz-autocomplete-ui render (listbox)"] = +` + + + + + + Item 1 + + + + + +`; +/* end snapshot cosmoz-autocomplete-ui render (listbox) */ + +snapshots["cosmoz-autocomplete render"] = +` + + + + + + Item 1 + + + + + + +`; +/* end snapshot cosmoz-autocomplete render */ + +snapshots["cosmoz-autocomplete render (deselect)"] = +` + + + + + + +`; +/* end snapshot cosmoz-autocomplete render (deselect) */ + diff --git a/test/cosmoz-autocomplete.test.js b/test/cosmoz-autocomplete.test.js index f9b320ed..70f73d02 100644 --- a/test/cosmoz-autocomplete.test.js +++ b/test/cosmoz-autocomplete.test.js @@ -42,17 +42,7 @@ describe('cosmoz-autocomplete-ui', () => { expect(input).to.include({ value: 'It', }); - expect(el).shadowDom.to.equal(` - - - -
2 - -
-
`); + await expect(el).shadowDom.to.equalSnapshot(); }); it('render (limit 1)', async () => { @@ -65,18 +55,7 @@ describe('cosmoz-autocomplete-ui', () => { .limit=${1} /> `); - expect(el).shadowDom.to.equal(` - - - -
- Item 1 - -
-
`); + expect(el).shadowDom.to.equalSnapshot(); }); it('render (listbox)', async () => { @@ -91,19 +70,7 @@ describe('cosmoz-autocomplete-ui', () => { el.shadowRoot.querySelector('cosmoz-input').focus(); await nextFrame(); await nextFrame(); - expect(el).shadowDom.to.equal(` - - - -
- Item 1 - -
-
- `); + expect(el).shadowDom.to.equalSnapshot(); document.activeElement.blur(); }); }); @@ -117,19 +84,7 @@ describe('cosmoz-autocomplete', () => { .textProperty=${'text'} /> `); - expect(el).shadowDom.to.equal(` - - - - -
- Item 1 - -
-
`); + expect(el).shadowDom.to.equalSnapshot(); }); it('render (deselect)', async () => { @@ -143,17 +98,13 @@ describe('cosmoz-autocomplete', () => { /> `); await nextFrame(); - el.shadowRoot.querySelector('.chip-clear').click(); + el.shadowRoot + .querySelector('.chip') + .shadowRoot.querySelector('.clear') + .click(); await nextFrame(); await nextFrame(); - expect(el).shadowDom.to.equal(` - - - - `); + expect(el).shadowDom.to.equalSnapshot(); }); it('onChange', async () => { @@ -188,8 +139,6 @@ describe('cosmoz-autocomplete', () => { await nextFrame(); expect(el.shadowRoot.querySelector('cosmoz-input').value).to.equal('asd'); - expect(el.shadowRoot.querySelector('.chip-text').innerText).to.equal( - 'Item 2' - ); + expect(el.shadowRoot.querySelector('.chip').innerText).to.equal('Item 2'); }); }); From 7ad8c3ac9c3d0ab4ea67038a21724fad69d26d7b Mon Sep 17 00:00:00 2001 From: Meghea Iulian Date: Thu, 27 Apr 2023 13:45:01 +0300 Subject: [PATCH 3/7] fix(autocomplete): correct focus style --- src/autocomplete/styles.css.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/autocomplete/styles.css.ts b/src/autocomplete/styles.css.ts index 0c9b7c63..2fb72007 100644 --- a/src/autocomplete/styles.css.ts +++ b/src/autocomplete/styles.css.ts @@ -15,7 +15,7 @@ export default css` flex: 1 24px; min-width: 0; } - cosmoz-input::part(input):focus { + cosmoz-input:not([data-one])::part(input):focus { flex: 4 0.00001 50px; min-width: 20px; } From 2218da1f95d997c2d8914d7fb02dac7d3cc925f6 Mon Sep 17 00:00:00 2001 From: Meghea Iulian Date: Thu, 27 Apr 2023 14:38:49 +0300 Subject: [PATCH 4/7] fix: cleanup styles --- src/autocomplete/styles.css.ts | 6 ------ stories/cosmoz-autocomplete.stories.js | 9 +++++++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/autocomplete/styles.css.ts b/src/autocomplete/styles.css.ts index 2fb72007..1730a49b 100644 --- a/src/autocomplete/styles.css.ts +++ b/src/autocomplete/styles.css.ts @@ -19,12 +19,6 @@ export default css` flex: 4 0.00001 50px; min-width: 20px; } - - .chip { - flex: 0.00001 1 fit-content; - max-width: 18ch; - min-width: 45px; - } .badge { min-width: initial; flex: none; diff --git a/stories/cosmoz-autocomplete.stories.js b/stories/cosmoz-autocomplete.stories.js index a17d1f20..0a2d8e74 100644 --- a/stories/cosmoz-autocomplete.stories.js +++ b/stories/cosmoz-autocomplete.stories.js @@ -85,3 +85,12 @@ const css = html` `; export { basic, single, hideEmpty, defaultIndex, disabled, placeholder }; + +export const overflown = () => html` ${css} + `; From e436a763da0655fc7f2e81a05fc697cfdf0bfea0 Mon Sep 17 00:00:00 2001 From: Meghea Iulian Date: Thu, 27 Apr 2023 17:50:57 +0300 Subject: [PATCH 5/7] feat: adjust spacing --- src/autocomplete/chip.css.ts | 4 ++-- src/autocomplete/styles.css.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/autocomplete/chip.css.ts b/src/autocomplete/chip.css.ts index a2f2f697..04a1e3d8 100644 --- a/src/autocomplete/chip.css.ts +++ b/src/autocomplete/chip.css.ts @@ -10,8 +10,8 @@ export default css` align-items: center; flex: 0.0001 1 fit-content; max-width: 18ch; - min-width: 45px; - padding: 0 4px 0 10px; + min-width: 40px; + padding: 0 4px 0 8px; gap: 4px; } .content { diff --git a/src/autocomplete/styles.css.ts b/src/autocomplete/styles.css.ts index 1730a49b..f74532cc 100644 --- a/src/autocomplete/styles.css.ts +++ b/src/autocomplete/styles.css.ts @@ -23,7 +23,7 @@ export default css` min-width: initial; flex: none; text-align: center; - padding: 0 3px; + padding: 0 4px; } [data-one]::part(input) { From 2a79d4786f5c8d791f23f29d9d80fa14e1587a8f Mon Sep 17 00:00:00 2001 From: Meghea Iulian Date: Thu, 27 Apr 2023 17:51:17 +0300 Subject: [PATCH 6/7] feat: set title per chip --- src/autocomplete/chip.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/autocomplete/chip.ts b/src/autocomplete/chip.ts index 464229f0..e96676da 100644 --- a/src/autocomplete/chip.ts +++ b/src/autocomplete/chip.ts @@ -70,5 +70,6 @@ export const chip = ({ exportparts="chip-text, chip-clear" ?disabled=${disabled} .onClear=${onClear} + title=${ifDefined(typeof content === 'string' ? content : undefined)} >${content}`; From 8acb31eb3c9963e55e9c749b8c8756cd164795c6 Mon Sep 17 00:00:00 2001 From: Meghea Iulian Date: Thu, 27 Apr 2023 18:16:26 +0300 Subject: [PATCH 7/7] chore(tests): update snapshots --- .../cosmoz-autocomplete.test.snap.js | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/test/__snapshots__/cosmoz-autocomplete.test.snap.js b/test/__snapshots__/cosmoz-autocomplete.test.snap.js index ce655ef2..da8245d8 100644 --- a/test/__snapshots__/cosmoz-autocomplete.test.snap.js +++ b/test/__snapshots__/cosmoz-autocomplete.test.snap.js @@ -24,6 +24,7 @@ snapshots["cosmoz-autocomplete-ui render"] = exportparts="chip-text, chip-clear" part="chip" slot="control" + title="Item 1" > Item 1 @@ -32,6 +33,7 @@ snapshots["cosmoz-autocomplete-ui render"] = exportparts="chip-text, chip-clear" part="chip" slot="control" + title="Item 2" > Item 2 @@ -74,6 +76,7 @@ snapshots["cosmoz-autocomplete-ui render (limit 1)"] = exportparts="chip-text, chip-clear" part="chip" slot="control" + title="Item 1" > Item 1 @@ -91,7 +94,7 @@ snapshots["cosmoz-autocomplete-ui render (limit 1)"] = `; /* end snapshot cosmoz-autocomplete-ui render (limit 1) */ -snapshots["cosmoz-autocomplete-ui render (listbox)"] = +snapshots["cosmoz-autocomplete render"] = ` Item 1 @@ -121,24 +125,20 @@ snapshots["cosmoz-autocomplete-ui render (listbox)"] = class="badge" disabled="" exportparts="chip-text, chip-clear" - hidden="" part="chip" slot="control" > - +0 - - `; -/* end snapshot cosmoz-autocomplete-ui render (listbox) */ +/* end snapshot cosmoz-autocomplete render */ -snapshots["cosmoz-autocomplete render"] = +snapshots["cosmoz-autocomplete render (deselect)"] = ` - - Item 1 - `; -/* end snapshot cosmoz-autocomplete render */ +/* end snapshot cosmoz-autocomplete render (deselect) */ -snapshots["cosmoz-autocomplete render (deselect)"] = +snapshots["cosmoz-autocomplete-ui render (listbox)"] = ` + + Item 1 + + +0 + + `; -/* end snapshot cosmoz-autocomplete render (deselect) */ +/* end snapshot cosmoz-autocomplete-ui render (listbox) */