Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Checkbox): react/wc parity #18329

Merged
merged 10 commits into from
Feb 12, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import WarningAltFilled16 from '@carbon/icons/lib/warning--alt--filled/16.js';
import CDSCheckbox from './checkbox';
import styles from './checkbox.scss?lit';
import { carbonElement as customElement } from '../../globals/decorators/carbon-element';
import { CHECKBOX_ORIENTATION } from './defs';

export { CHECKBOX_ORIENTATION };
/**
* Check box.
*
Expand Down Expand Up @@ -70,6 +72,12 @@ class CDSCheckboxGroup extends LitElement {
@property({ type: String, reflect: true, attribute: 'legend-text' })
legendText;

/**
* Provide the orientation for how the checkbox should be displayed
*/
@property({ type: String, reflect: true, attribute: 'orientation' })
orientation = CHECKBOX_ORIENTATION.VERTICAL;

/**
* Whether the CheckboxGroup should be read-only
*/
Expand Down Expand Up @@ -119,7 +127,7 @@ class CDSCheckboxGroup extends LitElement {
updated(changedProperties) {
const { selectorCheckbox } = this.constructor as typeof CDSCheckboxGroup;
const checkboxes = this.querySelectorAll(selectorCheckbox);
['disabled', 'readonly'].forEach((name) => {
['disabled', 'readonly', 'orientation'].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
Expand Down Expand Up @@ -149,6 +157,7 @@ class CDSCheckboxGroup extends LitElement {
invalidText,
legendId,
legendText,
orientation,
readonly,
warn,
warnText,
Expand Down Expand Up @@ -177,16 +186,19 @@ class CDSCheckboxGroup extends LitElement {
[`${prefix}--checkbox-group--invalid`]: !readonly && invalid,
[`${prefix}--checkbox-group--warning`]: showWarning,
[`${prefix}--checkbox-group--slug`]: hasAILabel,
[`${prefix}--checkbox-group--${orientation}`]:
orientation === 'horizontal',
});

return html`
<fieldset
class="${fieldsetClasses}"
?data-invalid=${invalid}
?disabled=${disabled}
aria-readonly=${readonly}
aria-disabled=${readonly}
?aria-labelledby=${ariaLabelledBy || legendId}
?aria-describedby=${!invalid && !warn && helper ? helperId : undefined}>
?aria-describedby=${!invalid && !warn && helper ? helperId : undefined}
orientation=${orientation}>
<legend class="${prefix}--label" id=${legendId || ariaLabelledBy}>
${legendText}
<slot name="ai-label" @slotchange="${handleSlotChange}"></slot>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ $css--plex: true !default;

:host(#{$prefix}-checkbox-group) {
display: flex;
inline-size: 100%;
}

:host(#{$prefix}-checkbox-group) .#{$prefix}--checkbox-group--slug,
Expand All @@ -90,3 +91,10 @@ $css--plex: true !default;
:host(#{$prefix}-checkbox[ai-label]) ::slotted(#{$prefix}-slug) {
align-self: center;
}

:host(#{$prefix}-checkbox-group)
.#{$prefix}--checkbox-group--horizontal
::slotted(#{$prefix}-checkbox) {
flex: none;
margin-inline-end: $spacing-05;
}
217 changes: 153 additions & 64 deletions packages/web-components/src/components/checkbox/checkbox.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import FolderOpen16 from '@carbon/icons/lib/folder--open/16.js';
import Folders16 from '@carbon/icons/lib/folders/16.js';
import '../ai-label/index';
import './index';
import { CHECKBOX_ORIENTATION } from './defs';

const checkboxLabel = 'Checkbox label';

Expand All @@ -26,6 +27,7 @@ const defaultArgs = {
readonly: false,
warn: false,
warnText: 'Warn message goes here',
orientation: 'vertical',
};

const controls = {
Expand All @@ -34,22 +36,27 @@ const controls = {
description: 'Specify whether the checkbox should be disabled.',
},
helperText: {
control: 'textNullable',
control: 'text',
description: 'Provide text for the form group for additional help.',
},
invalid: {
control: 'boolean',
description: 'Specify whether the form group is currently invalid.',
},
invalidText: {
control: 'textNullable',
control: 'text',
description:
'Provide the text that is displayed when the form group is in an invalid state.',
},
legendText: {
control: 'textNullable',
control: 'text',
description: 'Provide the text to be rendered inside of the fieldset.',
},
orientation: {
control: 'select',
description: 'Provide how checkbox should be displayed.',
options: CHECKBOX_ORIENTATION,
},
readonly: {
control: 'boolean',
description: 'Specify whether the checkbox group is read-only.',
Expand All @@ -60,30 +67,99 @@ const controls = {
'Specify whether the form group is currently in warning state.',
},
warnText: {
control: 'textNullable',
control: 'text',
description:
'Provide the text that is displayed when the form group is in warning state.',
},
};

const singleControls = {
...controls,
indeterminate: {
control: 'boolean',
description: 'Specify whether the Checkbox is in an indeterminate state',
},
defaultChecked: {
control: 'boolean',
description:
'Specify whether the underlying input should be checked by default',
},
};

export const Default = {
render: () => html`
<cds-checkbox-group legend-text="Group label">
<cds-checkbox>${checkboxLabel}</cds-checkbox>
<cds-checkbox>${checkboxLabel}</cds-checkbox>
args: defaultArgs,
argTypes: controls,
render: ({
disabled,
readonly,
onChange,
helperText,
invalid,
invalidText,
legendText,
orientation,
warn,
warnText,
}) => html`
<cds-checkbox-group
legend-text="Group label"
helper-text="${helperText}"
?disabled="${disabled}"
?invalid="${invalid}"
invalid-text="${invalidText}"
legend-text="${legendText}"
orientation="${orientation}"
?readonly="${readonly}"
?warn="${warn}"
warn-text="${warnText}">
<cds-checkbox @cds-checkbox-changed="${onChange}"
>${checkboxLabel}</cds-checkbox
>
<cds-checkbox @cds-checkbox-changed="${onChange}"
>${checkboxLabel}</cds-checkbox
>
</cds-checkbox-group>
`,
};

export const Skeleton = {
render: () => html`
<fieldset class="${prefix}--fieldset">
<cds-checkbox-skeleton>${checkboxLabel}</cds-checkbox-skeleton>
</fieldset>
export const Horizontal = {
args: defaultArgs,
argTypes: controls,
render: ({
disabled,
readonly,
onChange,
helperText,
invalid,
invalidText,
legendText,
warn,
warnText,
}) => html`
<cds-checkbox-group
legend-text="Group label"
helper-text="${helperText}"
?disabled="${disabled}"
?invalid="${invalid}"
invalid-text="${invalidText}"
legend-text="${legendText}"
orientation="horizontal"
?readonly="${readonly}"
?warn="${warn}"
warn-text="${warnText}">
<cds-checkbox @cds-checkbox-changed="${onChange}"
>${checkboxLabel}</cds-checkbox
>
<cds-checkbox @cds-checkbox-changed="${onChange}"
>${checkboxLabel}</cds-checkbox
>
</cds-checkbox-group>
`,
};

export const Single = {
args: defaultArgs,
argTypes: singleControls,
render: () => html`
<cds-checkbox helper-text="Helper text goes here"
>${checkboxLabel}</cds-checkbox
Expand All @@ -101,6 +177,16 @@ export const Single = {
`,
};

export const Skeleton = {
args: defaultArgs,
argTypes: singleControls,
render: () => html`
<fieldset class="${prefix}--fieldset">
<cds-checkbox-skeleton>${checkboxLabel}</cds-checkbox-skeleton>
</fieldset>
`,
};

const content = html`
<div slot="body-text">
<p class="secondary">AI Explained</p>
Expand Down Expand Up @@ -133,88 +219,91 @@ const actions = html`
`;

export const WithAILabel = {
render: () => html`
args: defaultArgs,
argTypes: controls,
render: ({
disabled,
readonly,
onChange,
helperText,
invalid,
invalidText,
orientation,
warn,
warnText,
}) => html`
<div style="width: 400px">
<cds-checkbox-group legend-text="Group label">
<cds-checkbox-group
legend-text="Group label"
helper-text="${helperText}"
?disabled="${disabled}"
?invalid="${invalid}"
invalid-text="${invalidText}"
orientation="${orientation}"
?readonly="${readonly}"
?warn="${warn}"
warn-text="${warnText}">
<cds-ai-label alignment="bottom-left">
${content}${actions}</cds-ai-label
>
<cds-checkbox>Checkbox label</cds-checkbox>
<cds-checkbox>Checkbox label</cds-checkbox>
<cds-checkbox>Checkbox label</cds-checkbox>
<cds-checkbox @cds-checkbox-changed="${onChange}">Checkbox label</cds-checkbox>
<cds-checkbox @cds-checkbox-changed="${onChange}">Checkbox label</cds-checkbox>
<cds-checkbox @cds-checkbox-changed="${onChange}">Checkbox label</cds-checkbox>
</cds-checkbox-group>

<cds-checkbox-group legend-text="Group label">
<cds-checkbox>
<br></br>
<cds-checkbox-group
legend-text="Group label"
helper-text="${helperText}"
?disabled="${disabled}"
?invalid="${invalid}"
invalid-text="${invalidText}"
orientation="${orientation}"
?readonly="${readonly}"
?warn="${warn}"
warn-text="${warnText}">
<cds-checkbox @cds-checkbox-changed="${onChange}">
Checkbox label
<cds-ai-label alignment="bottom-left">
${content}${actions}</cds-ai-label
>
</cds-checkbox>
<cds-checkbox>
<cds-checkbox @cds-checkbox-changed="${onChange}">
Checkbox label
<cds-ai-label alignment="bottom-left">
${content}${actions}</cds-ai-label
>
</cds-checkbox>
<cds-checkbox>Checkbox label</cds-checkbox>
<cds-checkbox @cds-checkbox-changed="${onChange}">Checkbox label</cds-checkbox>
</cds-checkbox-group>

<cds-checkbox-group legend-text="Group label">
<cds-checkbox>
<br></br>
<cds-checkbox-group
legend-text="Group label"
helper-text="${helperText}"
?disabled="${disabled}"
?invalid="${invalid}"
invalid-text="${invalidText}"
orientation="${orientation}"
?readonly="${readonly}"
?warn="${warn}"
warn-text="${warnText}">
<cds-checkbox @cds-checkbox-changed="${onChange}">
Checkbox label
<cds-ai-label alignment="bottom-left" kind="inline">
${content}${actions}
</cds-ai-label>
</cds-checkbox>
<cds-checkbox>
<cds-checkbox @cds-checkbox-changed="${onChange}">
Checkbox label
<cds-ai-label alignment="bottom-left" kind="inline">
${content}${actions}
</cds-ai-label>
</cds-checkbox>
<cds-checkbox>Checkbox label</cds-checkbox>
<cds-checkbox @cds-checkbox-changed="${onChange}">Checkbox label</cds-checkbox>
</cds-checkbox-group>
</div>
`,
};

export const Playground = {
args: defaultArgs,
argTypes: controls,
render: ({
disabled,
readonly,
onChange,
helperText,
invalid,
invalidText,
legendText,
warn,
warnText,
}) => html`
<cds-checkbox-group
helper-text="${helperText}"
?disabled="${disabled}"
?invalid="${invalid}"
invalid-text="${invalidText}"
legend-text="${legendText}"
?readonly="${readonly}"
?warn="${warn}"
warn-text="${warnText}">
<cds-checkbox checked @cds-checkbox-changed="${onChange}"
>Checkbox label</cds-checkbox
>
<cds-checkbox @cds-checkbox-changed="${onChange}"
>Checkbox label</cds-checkbox
>
<cds-checkbox disabled @cds-checkbox-changed="${onChange}"
>Checkbox label</cds-checkbox
>
</cds-checkbox-group>
`,
};

const meta = {
title: 'Components/Checkbox',
parameters: {
Expand Down
Loading
Loading