Skip to content

Commit

Permalink
refactor(chip-selectable): rename selected property to checked
Browse files Browse the repository at this point in the history
docs(chip-group): fix stories and pass label into slot

feat(chip-group): implement value setter
  • Loading branch information
daenub authored Jul 8, 2024
1 parent 58e71d0 commit dd1557a
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 45 deletions.
21 changes: 19 additions & 2 deletions src/components/chip/ChipGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}

/**
Expand All @@ -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
})
}
}
Expand Down
22 changes: 12 additions & 10 deletions src/components/chip/ChipSelectable.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ 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 = {
...LeuChipBase.properties,
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 },
}

Expand All @@ -40,27 +42,27 @@ 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")
}
}

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,
})
Expand All @@ -70,9 +72,9 @@ export class LeuChipSelectable extends LeuChipBase {

render() {
return html`<button
@click=${(e) => this.handleClick(e)}
@click=${() => this.handleClick()}
class="button"
aria-pressed=${this.selected ? "true" : "false"}
aria-pressed=${this.checked ? "true" : "false"}
>
<span class="label"><slot></slot></span>
</button>`
Expand Down
32 changes: 16 additions & 16 deletions src/components/chip/chip.css
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -126,7 +126,7 @@
border-radius: 50%;
}

:host([variant="radio"][selected]) .button::before {
:host([variant="radio"][checked]) .button::before {
border-width: 3px;
}

Expand Down
15 changes: 6 additions & 9 deletions src/components/chip/stories/chip-group.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ function DefaultTemplate(args) {
const content = html`
${chips.map(
(chip) => html`
<leu-chip-removable ?inverted=${args.inverted} label=${chip}>
<leu-chip-removable ?inverted=${args.inverted}>
${chip}
</leu-chip-removable>
`
)}
Expand All @@ -112,8 +113,8 @@ function SingleTemplate(args) {
?inverted=${args.inverted}
variant=${SELECTABLE_VARIANTS.radio}
value="chip-${chip}"
label=${chip}
>
${chip}
</leu-chip-selectable>
`
)}
Expand All @@ -126,11 +127,8 @@ function MultipleTemplate(args) {
const content = html`
${chips.map(
(chip) => html`
<leu-chip-selectable
?inverted=${args.inverted}
value="chip-${chip}"
label=${chip}
>
<leu-chip-selectable ?inverted=${args.inverted} value="chip-${chip}">
${chip}
</leu-chip-selectable>
`
)}
Expand All @@ -143,8 +141,7 @@ function LabeledTemplate(args) {
const content = html`
${links.map(
(chip) => html`
<leu-chip-link ?inverted=${args.inverted} label=${chip}>
</leu-chip-link>
<leu-chip-link ?inverted=${args.inverted}> ${chip} </leu-chip-link>
`
)}
`
Expand Down
2 changes: 1 addition & 1 deletion src/components/chip/stories/chip-selectable.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function Template(args) {
<leu-chip-selectable
size=${ifDefined(args.size)}
variant=${ifDefined(args.variant)}
?selected=${args.selected}
?checked=${args.checked}
?inverted=${args.inverted}
>${args.label}</leu-chip-selectable
>
Expand Down
67 changes: 67 additions & 0 deletions src/components/chip/test/chip-group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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([])
})
})
14 changes: 7 additions & 7 deletions src/components/chip/test/chip-selectable.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async function defaultFixture(args = {}) {
<leu-chip-selectable
value="Publikationen"
variant=${ifDefined(args.variant)}
?selected=${args.selected}
?checked=${args.checked}
>Publikationen</leu-chip-selectable
>
`
Expand Down Expand Up @@ -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
})
})

0 comments on commit dd1557a

Please sign in to comment.