UNPKG

@spectrum-css/checkbox

Version:

The Spectrum CSS checkbox component

170 lines (163 loc) 4.27 kB
import { Template as Icon } from "@spectrum-css/icon/stories/template.js"; import { Container, getRandomId } from "@spectrum-css/preview/decorators"; import { html } from "lit"; import { classMap } from "lit/directives/class-map.js"; import { ifDefined } from "lit/directives/if-defined.js"; import { styleMap } from "lit/directives/style-map.js"; import { when } from "lit/directives/when.js"; import "../index.css"; import "../themes/spectrum.css"; /* Must be imported last */ import "../themes/express.css"; export const Template = ({ rootClass = "spectrum-Checkbox", size = "m", label, isChecked = false, isEmphasized = false, isHovered = false, isIndeterminate = false, isDisabled = false, isInvalid = false, isReadOnly = false, title, value, id = getRandomId("checkbox"), ariaLabelledby, customStyles = {}, customClasses = [], } = {}, context = {}) => { const { updateArgs } = context; let iconSize = "75"; switch (size) { case "s": iconSize = "50"; break; case "l": iconSize = "100"; break; case "xl": iconSize = "200"; break; default: iconSize = "75"; } return html` <label class=${classMap({ [rootClass]: true, [`${rootClass}--size${size?.toUpperCase()}`]: typeof size !== "undefined", [`${rootClass}--emphasized`]: isEmphasized, ["is-indeterminate"]: isIndeterminate, ["is-disabled"]: isDisabled, ["is-invalid"]: isInvalid, ["is-hover"]: isHovered && !isDisabled, ["is-readOnly"]: isReadOnly, ...customClasses.reduce((a, c) => ({ ...a, [c]: true }), {}), })} id=${ifDefined(id)} style=${styleMap(customStyles)} > <input type="checkbox" class="${rootClass}-input" aria-labelledby=${ifDefined(ariaLabelledby)} aria-disabled=${ifDefined(isReadOnly ? "true" : undefined)} ?checked=${isChecked} ?disabled=${isDisabled} title=${ifDefined(title)} value=${ifDefined(value)} @change=${(e) => { if (isReadOnly) { // Make checked value immutable for read-only. e.preventDefault(); e.target.checked = !e.target.checked; } if (isDisabled || isReadOnly) return; updateArgs?.({ isChecked: e.target.checked }); }} id=${ifDefined(id ? `${id}-input` : undefined)} /> <span class="${rootClass}-box"> ${Icon({ size, iconName: `Checkmark${iconSize}`, setName: "ui", customClasses: [`${rootClass}-checkmark`], }, context)} ${Icon({ size, iconName: `Dash${iconSize}`, setName: "ui", customClasses: [`${rootClass}-partialCheckmark`], }, context)} </span> ${when( label, () => html`<span class="${rootClass}-label">${label}</span>` )} </label> `; }; /* Shows multiple checkboxes in various states of selected, unselected, indeterminate, etc. */ export const DocsCheckboxGroup = (args, context) => Container({ direction: "column", withBorder: false, content: html` ${Template({ ...args, context, iconName: undefined, label: "Unchecked", })} ${Template({ ...args, context, isChecked: true, label: "Checked", })} ${Template({ ...args, context, isIndeterminate: true, label: "Indeterminate", })} ${Template({ ...args, context, label: "Checkbox with a long label that should wrap.", customStyles: { "max-inline-size": "200px" }, })} ` }, context); /* This template group showcases multiple CheckboxGroups in various states of disabled, read-only, invalid, etc. */ export const AllVariantsCheckboxGroup = (args, context) => Container({ withBorder: false, content: html` ${Container({ withBorder: false, direction: "column", heading: "Default", content: DocsCheckboxGroup(args, context) }, context)} ${Container({ withBorder: false, direction: "column", heading: "Invalid", content: DocsCheckboxGroup({...args, isInvalid: true }, context) }, context)} ${Container({ withBorder: false, direction: "column", heading: "Disabled", content: DocsCheckboxGroup({...args, isDisabled: true }, context) }, context)} ${Container({ withBorder: false, direction: "column", heading: "Read-only", content: DocsCheckboxGroup({...args, isReadOnly: true }, context) }, context)} ` }, context);