From 6b4e0fb8a0c674a65b89235252d6a81268f8f053 Mon Sep 17 00:00:00 2001 From: Anna Wen <54281166+annawen1@users.noreply.github.com> Date: Fri, 8 Dec 2023 12:56:27 -0500 Subject: [PATCH 1/6] feat(checkbox): checkbox group component and new checkbox states --- .../src/components/checkbox/checkbox-group.ts | 169 ++++++++++++++++++ .../components/checkbox/checkbox-story.mdx | 9 + .../src/components/checkbox/checkbox-story.ts | 88 +++++---- .../src/components/checkbox/checkbox.scss | 11 ++ .../src/components/checkbox/checkbox.ts | 72 ++++++++ .../src/components/checkbox/index.ts | 1 + 6 files changed, 320 insertions(+), 30 deletions(-) create mode 100644 packages/carbon-web-components/src/components/checkbox/checkbox-group.ts diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts b/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts new file mode 100644 index 00000000000..7114022dff7 --- /dev/null +++ b/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts @@ -0,0 +1,169 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { classMap } from 'lit/directives/class-map.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { LitElement, html } from 'lit'; +import { property } from 'lit/decorators.js'; +import { prefix } from '../../globals/settings'; +import WarningFilled16 from '@carbon/icons/lib/warning--filled/16'; +import WarningAltFilled16 from '@carbon/icons/lib/warning--alt--filled/16'; +import styles from './checkbox.scss'; +import { carbonElement as customElement } from '../../globals/decorators/carbon-element'; + +/** + * Check box. + * + * @element cds-checkbox + * @fires cds-checkbox-changed - The custom event fired after this changebox changes its checked state. + * @csspart input The checkbox. + * @csspart label The label. + */ +@customElement(`${prefix}-checkbox-group`) +class CDSCheckboxGroup extends LitElement { + /** + * fieldset `aria-labelledby` + */ + @property({ type: String, reflect: true, attribute: 'aria-labelledby' }) + ariaLabelledBy; + + /** + * Specify whether the form group is currently disabled + */ + @property({ type: Boolean }) + disabled; + + /** + * Provide text for the form group for additional help + */ + @property({ type: String, reflect: true, attribute: 'helper-text' }) + helperText; + + /** + * Specify whether the form group is currently invalid + */ + @property({ type: Boolean, attribute: 'invalid' }) + invalid; + + /** + * Provide the text that is displayed when the form group is in an invalid state + */ + @property({ type: String, reflect: true, attribute: 'invalid-text' }) + invalidText; + + /** + * Provide id for the fieldset which corresponds to the fieldset + * `aria-labelledby` + */ + @property({ type: String, reflect: true, attribute: 'legend-id' }) + legendId; + + /** + * Provide the text to be rendered inside of the fieldset + */ + @property({ type: String, reflect: true, attribute: 'legend-text' }) + legendText; + + /** + * Whether the CheckboxGroup should be read-only + */ + @property({ type: Boolean, reflect: true }) + readonly = false; + + /** + * Specify whether the form group is currently in warning state + */ + @property({ type: Boolean, reflect: true }) + warn = false; + + /** + * Provide the text that is displayed when the form group is in warning state + */ + @property({ type: String, reflect: true, attribute: 'warn-text' }) + warnText = ''; + + render() { + const { + ariaLabelledBy, + disabled, + helperText, + invalid, + invalidText, + legendId, + legendText, + readonly, + warn, + warnText, + } = this; + + const showWarning = !readonly && !invalid && warn; + const showHelper = !invalid && !warn; + + const checkboxGroupInstanceId = Math.random().toString(16).slice(2); + + const helperId = !helperText + ? undefined + : `checkbox-group-helper-text-${checkboxGroupInstanceId}`; + + const helper = helperText + ? html`
+ ${helperText} +
` + : null; + + const fieldsetClasses = classMap({ + [`${prefix}--checkbox-group`]: true, + [`${prefix}--checkbox-group--readonly`]: readonly, + [`${prefix}--checkbox-group--invalid`]: !readonly && invalid, + [`${prefix}--checkbox-group--warning`]: showWarning, + }); + + return html` +
+ + ${legendText} + + +
+ ${!readonly && invalid + ? html` + ${WarningFilled16({ + class: `${prefix}--checkbox__invalid-icon`, + })} +
${invalidText}
+ ` + : undefined} + ${showWarning + ? html` + ${WarningAltFilled16({ + class: `${prefix}--checkbox__invalid-icon ${prefix}--checkbox__invalid-icon--warning`, + })} +
${warnText}
+ ` + : undefined} +
+ ${showHelper ? helper : undefined} +
+ `; + } + + static shadowRootOptions = { + ...LitElement.shadowRootOptions, + delegatesFocus: true, + }; + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default CDSCheckboxGroup; diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox-story.mdx b/packages/carbon-web-components/src/components/checkbox/checkbox-story.mdx index 4938f3cf1ed..c0b733db472 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox-story.mdx +++ b/packages/carbon-web-components/src/components/checkbox/checkbox-story.mdx @@ -31,6 +31,15 @@ import '@carbon/web-components/es/components/checkbox/index.js'; ``` +Use `cds-checkbox-group` when handling multiple checkboxes + +```html + + + + +``` + ## `` attributes, properties and events Unlike regular checkbox, `` does _not_ fire `change` event. Please diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox-story.ts b/packages/carbon-web-components/src/components/checkbox/checkbox-story.ts index efd804a1e04..5681f4ed5ab 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox-story.ts +++ b/packages/carbon-web-components/src/components/checkbox/checkbox-story.ts @@ -20,11 +20,10 @@ const checkboxLabel = 'Checkbox label'; export const Default = () => { return html` -
- Group label + -
+ `; }; @@ -39,52 +38,81 @@ export const Skeleton = () => { `; }; +export const Single = () => { + return html` + +

+ +

+ +

+ + `; +}; + export const Playground = (args) => { const { - checked, disabled, - hideLabel, - indeterminate, - labelText = checkboxLabel, readonly, - title, onChange, + helperText, + invalid, + invalidText, + legendText, + warn, + warnText, } = args?.[`${prefix}-checkbox`] ?? {}; return html` -
- Group label + -
+ + `; }; Playground.parameters = { knobs: { [`${prefix}-checkbox`]: () => ({ - checked: boolean('Checked (checked)', false), + onChange: action(`${prefix}-checkbox-changed`), disabled: boolean('Disabled (disabled)', false), - hideLabel: boolean('Hide label (hide-label)', false), - indeterminate: boolean('Indeterminate (indeterminate)', false), + helperText: textNullable( + 'Helper text (helper-text)', + 'Helper text goes here' + ), + invalid: boolean('Invalid (invalid)', false), + invalidText: textNullable( + 'Invalid text (invalid-text)', + 'Invalid message goes here' + ), + legendText: textNullable('Legend text (legend-text)', 'Group label'), readonly: boolean('Read only (readonly)', false), - title: textNullable('Title (title)', ''), - onChange: action(`${prefix}-checkbox-changed`), + warn: boolean('Warn (warn)', false), + warnText: textNullable('Warn text (warn-text)', 'Warn message goes here'), }), }, }; diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.scss b/packages/carbon-web-components/src/components/checkbox/checkbox.scss index 0d24a158255..3c2478de9ab 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox.scss +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.scss @@ -23,6 +23,14 @@ $css--plex: true !default; @extend .#{$prefix}--checkbox-wrapper--readonly; } +:host(#{$prefix}-checkbox:not([readonly])[invalid]) { + @extend .#{$prefix}--checkbox-wrapper--invalid; +} + +:host(#{$prefix}-checkbox:not([readonly]):not([invalid])[warn]) { + @extend .#{$prefix}--checkbox-wrapper--warning; +} + :host(#{$prefix}-checkbox[data-table]) { margin: 0; } @@ -42,3 +50,6 @@ $css--plex: true !default; cursor: default; } } + +:host(#{$prefix}-checkbox-group[data-invalid]) { +} diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.ts b/packages/carbon-web-components/src/components/checkbox/checkbox.ts index 7be15b608fc..33c65774627 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox.ts +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.ts @@ -14,6 +14,8 @@ import { property, query } from 'lit/decorators.js'; import { prefix } from '../../globals/settings'; import FocusMixin from '../../globals/mixins/focus'; import FormMixin from '../../globals/mixins/form'; +import WarningFilled16 from '@carbon/icons/lib/warning--filled/16'; +import WarningAltFilled16 from '@carbon/icons/lib/warning--alt--filled/16'; import styles from './checkbox.scss'; import { carbonElement as customElement } from '../../globals/decorators/carbon-element'; @@ -85,6 +87,12 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { @property({ type: Boolean, reflect: true }) disabled = false; + /** + * Provide text for the form group for additional help + */ + @property({ type: String, reflect: true, attribute: 'helper-text' }) + helperText; + /** * Specify whether the checkbox should be present in the DOM, * but invisible and uninteractable. Used for data-table purposes. @@ -123,6 +131,18 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { @property({ type: Boolean, reflect: true }) readonly = false; + /** + * Specify whether the Checkbox is currently invalid + */ + @property({ type: Boolean }) + invalid = false; + + /** + * Provide the text that is displayed when the Checkbox is in an invalid state + */ + @property({ type: String, attribute: 'invalid-text' }) + invalidText; + /** * Specify a title for the node for the Checkbox */ @@ -135,20 +155,53 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { @property() value!: string; + /** + * Specify whether the Checkbox is in a warn state + */ + @property({ type: Boolean }) + warn = false; + + /** + * Provide the text that is displayed when the Checkbox is in a warn state + */ + @property({ type: String, attribute: 'warn-text' }) + warnText = false; + render() { const { checked, disabled, + helperText, hideLabel, indeterminate, + invalid, + invalidText, labelText, name, readonly, title, value, + warn, + warnText, _handleChange: handleChange, _handleClick: handleClick, } = this; + + const showWarning = !readonly && !invalid && warn; + const showHelper = !invalid && !warn; + + const checkboxGroupInstanceId = Math.random().toString(16).slice(2); + + const helperId = !helperText + ? undefined + : `checkbox-group-helper-text-${checkboxGroupInstanceId}`; + + const helper = helperText + ? html`
+ ${helperText} +
` + : null; + const labelClasses = classMap({ [`${prefix}--checkbox-label`]: true, }); @@ -178,6 +231,25 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { title="${ifDefined(title)}"> ${labelText} +
+ ${!readonly && invalid + ? html` + ${WarningFilled16({ + class: `${prefix}--checkbox__invalid-icon`, + })} +
${invalidText}
+ ` + : undefined} + ${showWarning + ? html` + ${WarningAltFilled16({ + class: `${prefix}--checkbox__invalid-icon ${prefix}--checkbox__invalid-icon--warning`, + })} +
${warnText}
+ ` + : undefined} +
+ ${showHelper ? helper : undefined} `; } diff --git a/packages/carbon-web-components/src/components/checkbox/index.ts b/packages/carbon-web-components/src/components/checkbox/index.ts index 22a69bf6a41..281b674ea3f 100644 --- a/packages/carbon-web-components/src/components/checkbox/index.ts +++ b/packages/carbon-web-components/src/components/checkbox/index.ts @@ -8,4 +8,5 @@ */ import './checkbox'; +import './checkbox-group'; import './checkbox-skeleton'; From 3d4331639b93dbf9fc3d9876b9d22c085c2e8b8e Mon Sep 17 00:00:00 2001 From: Anna Wen <54281166+annawen1@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:17:37 -0500 Subject: [PATCH 2/6] feat(checkbox): checkbox group --- .../src/components/checkbox/checkbox-group.ts | 60 +++++++++++++++++-- .../src/components/checkbox/checkbox.scss | 7 ++- .../src/components/checkbox/checkbox.ts | 16 ++--- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts b/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts index 7114022dff7..0c563feb448 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts +++ b/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts @@ -8,12 +8,13 @@ */ import { classMap } from 'lit/directives/class-map.js'; -import { ifDefined } from 'lit/directives/if-defined.js'; import { LitElement, html } from 'lit'; import { property } from 'lit/decorators.js'; import { prefix } from '../../globals/settings'; +import FormMixin from '../../globals/mixins/form'; import WarningFilled16 from '@carbon/icons/lib/warning--filled/16'; import WarningAltFilled16 from '@carbon/icons/lib/warning--alt--filled/16'; +import CDSCheckbox from './checkbox'; import styles from './checkbox.scss'; import { carbonElement as customElement } from '../../globals/decorators/carbon-element'; @@ -26,7 +27,7 @@ import { carbonElement as customElement } from '../../globals/decorators/carbon- * @csspart label The label. */ @customElement(`${prefix}-checkbox-group`) -class CDSCheckboxGroup extends LitElement { +class CDSCheckboxGroup extends FormMixin(LitElement) { /** * fieldset `aria-labelledby` */ @@ -88,6 +89,44 @@ class CDSCheckboxGroup extends LitElement { @property({ type: String, reflect: true, attribute: 'warn-text' }) warnText = ''; + /* + * Handles `slotchange` event. + */ + protected _handleSlotChange({ target }: Event) { + const hasContent = (target as HTMLSlotElement) + .assignedNodes() + .filter((elem) => + (elem as HTMLElement).matches !== undefined + ? (elem as HTMLElement).matches( + (this.constructor as typeof CDSCheckboxGroup).slugItem + ) + : false + ); + + this._hasSlug = Boolean(hasContent); + (hasContent[0] as HTMLElement).setAttribute('size', 'mini'); + this.requestUpdate(); + } + + /** + * `true` if there is a slug. + */ + protected _hasSlug = false; + + updated(changedProperties) { + const { selectorCheckbox } = this.constructor as typeof CDSCheckboxGroup; + const checkboxes = this.querySelectorAll(selectorCheckbox); + ['disabled', 'readonly'].forEach((name) => { + if (changedProperties.has(name)) { + const { [name as keyof CDSCheckboxGroup]: value } = this; + // Propagate the property to descendants until `:host-context()` gets supported in all major browsers + checkboxes.forEach((elem) => { + (elem as CDSCheckbox)[name] = value; + }); + } + }); + } + render() { const { ariaLabelledBy, @@ -100,6 +139,8 @@ class CDSCheckboxGroup extends LitElement { readonly, warn, warnText, + _hasSlug: hasSlug, + _handleSlotChange: handleSlotChange, } = this; const showWarning = !readonly && !invalid && warn; @@ -122,6 +163,7 @@ class CDSCheckboxGroup extends LitElement { [`${prefix}--checkbox-group--readonly`]: readonly, [`${prefix}--checkbox-group--invalid`]: !readonly && invalid, [`${prefix}--checkbox-group--warning`]: showWarning, + [`${prefix}--checkbox-group--slug`]: hasSlug, }); return html` @@ -134,6 +176,7 @@ class CDSCheckboxGroup extends LitElement { ?aria-describedby=${!invalid && !warn && helper ? helperId : undefined}> ${legendText} +
@@ -144,7 +187,7 @@ class CDSCheckboxGroup extends LitElement { })}
${invalidText}
` - : undefined} + : null} ${showWarning ? html` ${WarningAltFilled16({ @@ -152,13 +195,20 @@ class CDSCheckboxGroup extends LitElement { })}
${warnText}
` - : undefined} + : null}
- ${showHelper ? helper : undefined} + ${showHelper ? helper : null} `; } + /** + * A selector that will return the checkboxes. + */ + static get selectorCheckbox() { + return `${prefix}-checkbox`; + } + static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true, diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.scss b/packages/carbon-web-components/src/components/checkbox/checkbox.scss index 3c2478de9ab..52612cc856c 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox.scss +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.scss @@ -27,6 +27,10 @@ $css--plex: true !default; @extend .#{$prefix}--checkbox-wrapper--invalid; } +:host(#{$prefix}-checkbox[invalid-group]) { + @extend .#{$prefix}--checkbox-wrapper--invalid; +} + :host(#{$prefix}-checkbox:not([readonly]):not([invalid])[warn]) { @extend .#{$prefix}--checkbox-wrapper--warning; } @@ -50,6 +54,3 @@ $css--plex: true !default; cursor: default; } } - -:host(#{$prefix}-checkbox-group[data-invalid]) { -} diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.ts b/packages/carbon-web-components/src/components/checkbox/checkbox.ts index 33c65774627..ef79f6b1719 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox.ts +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.ts @@ -190,16 +190,8 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { const showWarning = !readonly && !invalid && warn; const showHelper = !invalid && !warn; - const checkboxGroupInstanceId = Math.random().toString(16).slice(2); - - const helperId = !helperText - ? undefined - : `checkbox-group-helper-text-${checkboxGroupInstanceId}`; - const helper = helperText - ? html`
- ${helperText} -
` + ? html`
${helperText}
` : null; const labelClasses = classMap({ @@ -239,7 +231,7 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { })}
${invalidText}
` - : undefined} + : null} ${showWarning ? html` ${WarningAltFilled16({ @@ -247,9 +239,9 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { })}
${warnText}
` - : undefined} + : null} - ${showHelper ? helper : undefined} + ${showHelper ? helper : null} `; } From 831a665216fe1f810f8785411a205722bb585bda Mon Sep 17 00:00:00 2001 From: Anna Wen <54281166+annawen1@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:07:53 -0500 Subject: [PATCH 3/6] feat(checkbox): add slug to checkbox --- .../src/components/checkbox/checkbox-group.ts | 7 ++ .../src/components/checkbox/checkbox.scss | 17 ++++ .../src/components/checkbox/checkbox.ts | 45 ++++++++++- .../src/components/slug/slug-example-story.ts | 79 +++++++++++++++++++ .../src/components/slug/slug-story.scss | 4 + 5 files changed, 151 insertions(+), 1 deletion(-) diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts b/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts index 0c563feb448..7e729a24a7c 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts +++ b/packages/carbon-web-components/src/components/checkbox/checkbox-group.ts @@ -209,6 +209,13 @@ class CDSCheckboxGroup extends FormMixin(LitElement) { return `${prefix}-checkbox`; } + /** + * A selector that will return the slug item. + */ + static get slugItem() { + return `${prefix}-slug`; + } + static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true, diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.scss b/packages/carbon-web-components/src/components/checkbox/checkbox.scss index 52612cc856c..908f724e27e 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox.scss +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.scss @@ -54,3 +54,20 @@ $css--plex: true !default; cursor: default; } } + +:host(#{$prefix}-checkbox-group) { + display: flex; +} + +:host(#{$prefix}-checkbox-group) .#{$prefix}--checkbox-group--slug, +:host(#{$prefix}-checkbox[slug]) { + ::slotted(#{$prefix}-slug) { + margin-inline-start: $spacing-03; + } +} + +:host(#{$prefix}-checkbox[slug]) { + .#{$prefix}--checkbox-label-text { + display: flex; + } +} diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.ts b/packages/carbon-web-components/src/components/checkbox/checkbox.ts index ef79f6b1719..98ce3595a42 100644 --- a/packages/carbon-web-components/src/components/checkbox/checkbox.ts +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.ts @@ -167,6 +167,39 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { @property({ type: String, attribute: 'warn-text' }) warnText = false; + /** + * Handles `slotchange` event. + */ + protected _handleSlotChange({ target }: Event) { + const hasContent = (target as HTMLSlotElement) + .assignedNodes() + .filter((elem) => + (elem as HTMLElement).matches !== undefined + ? (elem as HTMLElement).matches( + (this.constructor as typeof CDSCheckbox).slugItem + ) + : false + ); + + this._hasSlug = Boolean(hasContent); + const type = (hasContent[0] as HTMLElement).getAttribute('kind'); + (hasContent[0] as HTMLElement).setAttribute( + 'size', + type === 'inline' ? 'md' : 'mini' + ); + this.requestUpdate(); + } + + /** + * `true` if there is a slug. + */ + protected _hasSlug = false; + + updated() { + const { _hasSlug: hasSlug } = this; + hasSlug ? this.setAttribute('slug', '') : this.removeAttribute('slug'); + } + render() { const { checked, @@ -221,7 +254,10 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { part="label" class="${labelClasses}" title="${ifDefined(title)}"> - ${labelText} + ${labelText} +
${!readonly && invalid @@ -252,6 +288,13 @@ class CDSCheckbox extends FocusMixin(FormMixin(LitElement)) { return `${prefix}-checkbox-changed`; } + /** + * A selector that will return the slug item. + */ + static get slugItem() { + return `${prefix}-slug`; + } + static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true, diff --git a/packages/carbon-web-components/src/components/slug/slug-example-story.ts b/packages/carbon-web-components/src/components/slug/slug-example-story.ts index f82325b1a10..c196e0196eb 100644 --- a/packages/carbon-web-components/src/components/slug/slug-example-story.ts +++ b/packages/carbon-web-components/src/components/slug/slug-example-story.ts @@ -81,6 +81,85 @@ export default { title: 'Experimental/Slug/Examples', }; +export const _Checkbox = (args) => { + const { disabled, invalid, invalidText, warn, warnText } = + args?.['cds-checkbox'] ?? {}; + + return html` + +
+ + ${content}${actions} + + + + + + + + ${content}${actions} + + + ${content}${actions} + + + + + + + + ${content}${actions} + + + + + ${content}${actions} + + + + +
+ `; +}; + +_Checkbox.parameters = { + knobs: { + [`${prefix}-checkbox`]: () => ({ + disabled: boolean('Disabled (disabled)', false), + invalid: boolean('Invalid (invalid)', false), + invalidText: textNullable( + 'Invalid text (invalid-text)', + 'Error message goes here' + ), + warn: boolean('Warn (warn)', false), + warnText: textNullable( + 'Warn text (warn-text)', + 'Warning message that is really long can wrap to more lines but should not be excessively long.' + ), + }), + }, +}; + export const _Combobox = () => { return html`