diff --git a/src/components/select/bl-select.css b/src/components/select/bl-select.css index ab6b1d1f4..4fadb1680 100644 --- a/src/components/select/bl-select.css +++ b/src/components/select/bl-select.css @@ -348,6 +348,7 @@ legend span { padding: var(--bl-size-xs) 0; background: var(--background-color); z-index: 1; + font: var(--bl-font-title-3-regular); /* Make sure option focus doesn't overflow */ box-shadow: 10px 0 0 var(--background-color), -10px 0 0 var(--background-color); diff --git a/src/components/select/bl-select.test.ts b/src/components/select/bl-select.test.ts index a58fd23e3..7b2ad8d40 100644 --- a/src/components/select/bl-select.test.ts +++ b/src/components/select/bl-select.test.ts @@ -3,6 +3,7 @@ import { sendKeys } from "@web/test-runner-commands"; import BlSelect from "./bl-select"; import BlButton from "../button/bl-button"; import BlCheckbox from "../checkbox-group/checkbox/bl-checkbox"; +import "../checkbox-group/checkbox/bl-checkbox"; import type BlSelectOption from "./option/bl-select-option"; describe("bl-select", () => { @@ -595,5 +596,33 @@ describe("bl-select", () => { expect(selectAll.indeterminate).to.be.true; expect(selectAll.checked).to.be.false; }); + + it('should uncheck "select all" checkbox when all available options are selected', async () => { + const el = await fixture(html` + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + `); + + const selectAll = el.shadowRoot!.querySelector(".select-all")!; + + expect(selectAll.indeterminate).to.be.true; + expect(selectAll.checked).to.be.false; + + setTimeout(() => selectAll.dispatchEvent( + new CustomEvent("bl-checkbox-change", { detail: true })) + ); + + const event = await oneEvent(el, "bl-select"); + + expect(event).to.exist; + expect(event.detail.length).to.equal(0); + expect(el.selectedOptions.length).to.equal(0); + + expect(selectAll.indeterminate).to.be.false; + expect(selectAll.checked).to.be.false; + }); }); }); diff --git a/src/components/select/bl-select.ts b/src/components/select/bl-select.ts index 76bc1d00a..eabe009a6 100644 --- a/src/components/select/bl-select.ts +++ b/src/components/select/bl-select.ts @@ -7,6 +7,7 @@ import { FormControlMixin, requiredValidator } from "@open-wc/form-control"; import { FormValue } from "@open-wc/form-helpers"; import "element-internals-polyfill"; import { event, EventDispatcher } from "../../utilities/event"; +import BlCheckbox from "../checkbox-group/checkbox/bl-checkbox"; import "../icon/bl-icon"; import style from "../select/bl-select.css"; import "../select/option/bl-select-option"; @@ -289,20 +290,6 @@ export default class BlSelect extends Form }); } - private _handleSelectAll(e: CustomEvent) { - const checked = e.detail; - - this._connectedOptions.forEach(option => { - if (option.disabled) { - return; - } - - option.selected = checked; - }); - - this._handleMultipleSelect(); - } - connectedCallback(): void { super.connectedCallback(); @@ -490,6 +477,34 @@ export default class BlSelect extends Form } } + private _handleSelectAll(e: CustomEvent) { + const checked = e.detail; + const isAllSelectedOrDisabled = this._connectedOptions.every( + option => option.disabled || option.selected + ); + + // Prevent checkbox to be checked when unselected disabled options are present and all remaining are selected + if (checked && isAllSelectedOrDisabled) { + setTimeout(() => { + const selectAll = this.shadowRoot?.querySelector(".select-all") as BlCheckbox; + const checkbox = selectAll?.shadowRoot?.querySelector("input"); + + checkbox?.click(); + }, 0); + return; + } + + this._connectedOptions.forEach(option => { + if (option.disabled) { + return; + } + + option.selected = checked; + }); + + this._handleMultipleSelect(); + } + private _onClickRemove(e: MouseEvent) { e.stopPropagation();