diff --git a/src/components/chip/ChipGroup.js b/src/components/chip/ChipGroup.js index e32e4573..60b36006 100644 --- a/src/components/chip/ChipGroup.js +++ b/src/components/chip/ChipGroup.js @@ -55,7 +55,24 @@ export class LeuChipGroup extends LeuElement { } get value() { - return this.items.filter((i) => i.selected).map((i) => i.value) + return this.items.filter((i) => i.checked).map((i) => i.value) + } + + /** + * Checks the items with the given values. + * If the selectionMode is single, only the first item with the given value is checked. + * @param {string[]} valueList + */ + set value(valueList) { + let hasChanged = false + + for (const item of this.items) { + item.checked = hasChanged ? false : valueList.includes(item.value) + + if (this.selectionMode === SELECTION_MODES.single && item.checked) { + hasChanged = true + } + } } /** @@ -78,7 +95,7 @@ export class LeuChipGroup extends LeuElement { handleInput = (e) => { if (this.selectionMode === SELECTION_MODES.single) { this.items.forEach((item) => { - item.selected = item === e.target // eslint-disable-line no-param-reassign + item.checked = item === e.target // eslint-disable-line no-param-reassign }) } } diff --git a/src/components/chip/ChipSelectable.js b/src/components/chip/ChipSelectable.js index c01c6547..03262d12 100644 --- a/src/components/chip/ChipSelectable.js +++ b/src/components/chip/ChipSelectable.js @@ -18,6 +18,8 @@ export const VARIANTS = { * @slot - The content of the chip * @prop {keyof typeof SIZES} size - The size of the chip. Not supported for radio variant. * @prop {keyof typeof VARIANTS} variant - `toggle` or `radio`. Determines if only one or multiple chips can be selected. + * @prop {boolean} checked - Whether the chip is selected. + * @prop {string} value - The value of the chip. */ export class LeuChipSelectable extends LeuChipBase { static properties = { @@ -25,7 +27,7 @@ export class LeuChipSelectable extends LeuChipBase { size: { type: String, reflect: true }, variant: { type: String, reflect: true }, - selected: { type: Boolean, reflect: true }, + checked: { type: Boolean, reflect: true }, value: { type: String, reflect: true }, } @@ -40,7 +42,7 @@ export class LeuChipSelectable extends LeuChipBase { * @default "toggle" */ this.variant = VARIANTS.toggle - this.selected = false + this.checked = false if (this.variant === VARIANTS.radio && this.size === SIZES.small) { console.warn("Small size has no effect on radio variant") @@ -48,19 +50,19 @@ export class LeuChipSelectable extends LeuChipBase { } handleClick() { - let nextSelectedState = this.selected + let nextcheckedState = this.checked if (this.variant === VARIANTS.radio) { - nextSelectedState = true + nextcheckedState = true } else { - nextSelectedState = !this.selected + nextcheckedState = !this.checked } - if (nextSelectedState !== this.selected) { - this.selected = nextSelectedState + if (nextcheckedState !== this.checked) { + this.checked = nextcheckedState this.dispatchEvent( new CustomEvent("input", { - detail: { selected: this.selected }, + detail: { checked: this.checked }, bubbles: true, composed: true, }) @@ -70,9 +72,9 @@ export class LeuChipSelectable extends LeuChipBase { render() { return html`` diff --git a/src/components/chip/chip.css b/src/components/chip/chip.css index 0c46da4e..a52c45db 100644 --- a/src/components/chip/chip.css +++ b/src/components/chip/chip.css @@ -8,17 +8,17 @@ :host { --chip-background-color-default: var(--leu-color-black-transp-10); --chip-background-color-hover: var(--leu-color-black-transp-20); - --chip-background-color-selected: var(--leu-color-black-100); - --chip-background-color-selected-hover: var(--leu-color-black-transp-80); + --chip-background-color-checked: var(--leu-color-black-100); + --chip-background-color-checked-hover: var(--leu-color-black-transp-80); --chip-color-default: var(--leu-color-black-transp-60); --chip-color-hover: var(--leu-color-black-100); - --chip-color-selected: var(--leu-color-black-0); + --chip-color-checked: var(--leu-color-black-0); --chip-radio-border-default: var(--leu-color-black-transp-40); - --chip-radio-border-selected: var(--leu-color-black-0); + --chip-radio-border-checked: var(--leu-color-black-0); --chip-radio-background-default: var(--leu-color-black-0); - --chip-radio-background-selected: var(--leu-color-func-cyan); + --chip-radio-background-checked: var(--leu-color-func-cyan); --chip-font-regular: var(--leu-font-family-regular); --chip-font-black: var(--leu-font-family-black); @@ -42,14 +42,14 @@ --chip-color-default: var(--leu-color-black-0); --chip-color-hover: var(--leu-color-black-0); - --chip-color-selected: var(--leu-color-black-0); + --chip-color-checked: var(--leu-color-black-0); } -:host([selected]) { - --chip-background-color: var(--chip-background-color-selected); - --chip-color: var(--chip-color-selected); - --chip-radio-border: var(--chip-radio-border-selected); - --chip-radio-background: var(--chip-radio-background-selected); +:host([checked]) { + --chip-background-color: var(--chip-background-color-checked); + --chip-color: var(--chip-color-checked); + --chip-radio-border: var(--chip-radio-border-checked); + --chip-radio-background: var(--chip-radio-background-checked); } .button { @@ -95,10 +95,10 @@ text-decoration: none; } -:host([selected]) .button:hover, -:host([selected]) .button:focus-visible { - --chip-background-color: var(--chip-background-color-selected-hover); - --chip-color: var(--chip-color-selected); +:host([checked]) .button:hover, +:host([checked]) .button:focus-visible { + --chip-background-color: var(--chip-background-color-checked-hover); + --chip-color: var(--chip-color-checked); } :host([href][size="large"]) .button { @@ -126,7 +126,7 @@ border-radius: 50%; } -:host([variant="radio"][selected]) .button::before { +:host([variant="radio"][checked]) .button::before { border-width: 3px; } diff --git a/src/components/chip/stories/chip-group.stories.js b/src/components/chip/stories/chip-group.stories.js index 45a83536..30d0215d 100644 --- a/src/components/chip/stories/chip-group.stories.js +++ b/src/components/chip/stories/chip-group.stories.js @@ -95,7 +95,8 @@ function DefaultTemplate(args) { const content = html` ${chips.map( (chip) => html` - + + ${chip} ` )} @@ -112,8 +113,8 @@ function SingleTemplate(args) { ?inverted=${args.inverted} variant=${SELECTABLE_VARIANTS.radio} value="chip-${chip}" - label=${chip} > + ${chip} ` )} @@ -126,11 +127,8 @@ function MultipleTemplate(args) { const content = html` ${chips.map( (chip) => html` - + + ${chip} ` )} @@ -143,8 +141,7 @@ function LabeledTemplate(args) { const content = html` ${links.map( (chip) => html` - - + ${chip} ` )} ` diff --git a/src/components/chip/stories/chip-selectable.stories.js b/src/components/chip/stories/chip-selectable.stories.js index 9898d09a..8bb5847f 100644 --- a/src/components/chip/stories/chip-selectable.stories.js +++ b/src/components/chip/stories/chip-selectable.stories.js @@ -38,7 +38,7 @@ function Template(args) { ${args.label} diff --git a/src/components/chip/test/chip-group.test.js b/src/components/chip/test/chip-group.test.js index e210c468..8b812969 100644 --- a/src/components/chip/test/chip-group.test.js +++ b/src/components/chip/test/chip-group.test.js @@ -106,4 +106,71 @@ describe("LeuChipGroup", () => { await expect(event).to.exist }) + + it("checks only chip when the value of the group is set (selection-mode=single)", async () => { + const el = await singleSelectionFixture() + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.false + expect(el.items[2].checked).to.be.false + + el.value = ["2"] + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.true + expect(el.items[2].checked).to.be.false + + // Should check the first item with the given value and not first item of the value list + el.value = ["2", "1"] + + expect(el.items[0].checked).to.be.true + expect(el.items[1].checked).to.be.false + + el.value = [] + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.false + expect(el.items[2].checked).to.be.false + + el.value = ["asdf"] + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.false + expect(el.items[2].checked).to.be.false + expect(el.value).to.deep.equal([]) + }) + + it("checks chips when the value of the group is set (selection-mode=multiple)", async () => { + const el = await multipleSelectionFixture() + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.false + expect(el.items[2].checked).to.be.false + + el.value = ["2"] + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.true + expect(el.items[2].checked).to.be.false + + // Should check the first item with the given value and not first item of the value list + el.value = ["2", "1"] + + expect(el.items[0].checked).to.be.true + expect(el.items[1].checked).to.be.true + expect(el.items[2].checked).to.be.false + + el.value = [] + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.false + expect(el.items[2].checked).to.be.false + + el.value = ["asdf"] + + expect(el.items[0].checked).to.be.false + expect(el.items[1].checked).to.be.false + expect(el.items[2].checked).to.be.false + expect(el.value).to.deep.equal([]) + }) }) diff --git a/src/components/chip/test/chip-selectable.test.js b/src/components/chip/test/chip-selectable.test.js index 47c3acc6..29eec3d8 100644 --- a/src/components/chip/test/chip-selectable.test.js +++ b/src/components/chip/test/chip-selectable.test.js @@ -11,7 +11,7 @@ async function defaultFixture(args = {}) { Publikationen ` @@ -73,21 +73,21 @@ describe("LeuChipSelectable", () => { expect(event).to.exist }) - it("removes the selected state when the button is clicked", async () => { - const el = await defaultFixture({ selected: true }) + it("removes the checked state when the button is clicked", async () => { + const el = await defaultFixture({ checked: true }) const button = el.shadowRoot.querySelector("button") button.click() - expect(el.selected).to.be.false + expect(el.checked).to.be.false }) - it("doesn't remove the selected state of a selected radio chip", async () => { - const el = await defaultFixture({ variant: "radio", selected: true }) + it("doesn't remove the checked state of a checked radio chip", async () => { + const el = await defaultFixture({ variant: "radio", checked: true }) const button = el.shadowRoot.querySelector("button") button.click() - expect(el.selected).to.be.true + expect(el.checked).to.be.true }) })