@material/web 2.4.2-nightly.95dd57c.0 → 2.4.2-nightly.a3379a3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/button/internal/_touch-target.scss +1 -1
- package/button/internal/button.d.ts +0 -4
- package/button/internal/button.js.map +1 -1
- package/button/internal/shared-styles.css +1 -1
- package/button/internal/shared-styles.css.map +1 -1
- package/button/internal/shared-styles.cssresult.js +1 -1
- package/button/internal/shared-styles.cssresult.js.map +1 -1
- package/checkbox/internal/checkbox.d.ts +0 -2
- package/checkbox/internal/checkbox.js.map +1 -1
- package/icon/internal/icon.d.ts +1 -1
- package/icon/internal/icon.js +1 -1
- package/icon/internal/icon.js.map +1 -1
- package/iconbutton/internal/icon-button.d.ts +0 -4
- package/iconbutton/internal/icon-button.js.map +1 -1
- package/labs/behaviors/form-associated.d.ts +0 -22
- package/labs/behaviors/form-associated.js +0 -11
- package/labs/behaviors/form-associated.js.map +1 -1
- package/labs/gb/components/button/button.d.ts +1 -1
- package/labs/gb/components/button/button.js +5 -5
- package/labs/gb/components/button/button.js.map +1 -1
- package/labs/gb/components/button/md-button.d.ts +1 -1
- package/labs/gb/components/button/md-button.js +9 -9
- package/labs/gb/components/button/md-button.js.map +1 -1
- package/labs/gb/components/card/card.d.ts +1 -1
- package/labs/gb/components/card/card.js +3 -3
- package/labs/gb/components/card/card.js.map +1 -1
- package/labs/gb/components/card/md-card.js +6 -6
- package/labs/gb/components/card/md-card.js.map +1 -1
- package/labs/gb/components/checkbox/checkbox.d.ts +1 -1
- package/labs/gb/components/checkbox/checkbox.js +4 -4
- package/labs/gb/components/checkbox/checkbox.js.map +1 -1
- package/labs/gb/components/checkbox/md-checkbox.d.ts +4 -4
- package/labs/gb/components/checkbox/md-checkbox.js +10 -10
- package/labs/gb/components/checkbox/md-checkbox.js.map +1 -1
- package/labs/gb/components/divider/divider.d.ts +1 -1
- package/labs/gb/components/divider/divider.js +1 -1
- package/labs/gb/components/divider/divider.js.map +1 -1
- package/labs/gb/components/fab/fab.d.ts +1 -1
- package/labs/gb/components/fab/fab.js +4 -4
- package/labs/gb/components/fab/fab.js.map +1 -1
- package/labs/gb/components/fab/md-fab.js +4 -4
- package/labs/gb/components/fab/md-fab.js.map +1 -1
- package/labs/gb/components/focus/focus-ring.js +1 -1
- package/labs/gb/components/focus/focus-ring.js.map +1 -1
- package/labs/gb/components/iconbutton/icon-button.d.ts +1 -1
- package/labs/gb/components/iconbutton/icon-button.js +5 -5
- package/labs/gb/components/iconbutton/icon-button.js.map +1 -1
- package/labs/gb/components/iconbutton/md-icon-button.d.ts +1 -1
- package/labs/gb/components/iconbutton/md-icon-button.js +7 -7
- package/labs/gb/components/iconbutton/md-icon-button.js.map +1 -1
- package/labs/gb/components/list/list.d.ts +2 -2
- package/labs/gb/components/list/list.js +4 -4
- package/labs/gb/components/list/list.js.map +1 -1
- package/labs/gb/components/list/md-list-item.d.ts +1 -1
- package/labs/gb/components/list/md-list-item.js +7 -7
- package/labs/gb/components/list/md-list-item.js.map +1 -1
- package/labs/gb/components/list/md-list.d.ts +1 -1
- package/labs/gb/components/list/md-list.js +1 -1
- package/labs/gb/components/list/md-list.js.map +1 -1
- package/labs/gb/components/menu/md-menu-group.d.ts +1 -1
- package/labs/gb/components/menu/md-menu-group.js +1 -1
- package/labs/gb/components/menu/md-menu-group.js.map +1 -1
- package/labs/gb/components/menu/md-menu-item.d.ts +1 -1
- package/labs/gb/components/menu/md-menu-item.js +8 -8
- package/labs/gb/components/menu/md-menu-item.js.map +1 -1
- package/labs/gb/components/menu/md-menu.d.ts +1 -1
- package/labs/gb/components/menu/md-menu.js +2 -2
- package/labs/gb/components/menu/md-menu.js.map +1 -1
- package/labs/gb/components/menu/menu.d.ts +2 -2
- package/labs/gb/components/menu/menu.js +4 -4
- package/labs/gb/components/menu/menu.js.map +1 -1
- package/labs/gb/components/radio/md-radio.d.ts +4 -4
- package/labs/gb/components/radio/md-radio.js +11 -11
- package/labs/gb/components/radio/md-radio.js.map +1 -1
- package/labs/gb/components/radio/radio.d.ts +1 -1
- package/labs/gb/components/radio/radio.js +4 -4
- package/labs/gb/components/radio/radio.js.map +1 -1
- package/labs/gb/components/ripple/ripple.js +5 -2
- package/labs/gb/components/ripple/ripple.js.map +1 -1
- package/labs/gb/components/splitbutton/_split-button-tokens.scss +135 -0
- package/labs/gb/components/splitbutton/md-split-button.d.ts +26 -0
- package/labs/gb/components/splitbutton/md-split-button.js +119 -0
- package/labs/gb/components/splitbutton/md-split-button.js.map +1 -0
- package/labs/gb/components/splitbutton/split-button.css +4 -0
- package/labs/gb/components/splitbutton/split-button.css.map +1 -0
- package/labs/gb/components/splitbutton/split-button.cssresult.d.ts +3 -0
- package/labs/gb/components/splitbutton/split-button.cssresult.js +14 -0
- package/labs/gb/components/splitbutton/split-button.cssresult.js.map +1 -0
- package/labs/gb/components/splitbutton/split-button.d.ts +47 -0
- package/labs/gb/components/splitbutton/split-button.js +46 -0
- package/labs/gb/components/splitbutton/split-button.js.map +1 -0
- package/labs/gb/components/splitbutton/split-button.scss +164 -0
- package/labs/gb/components/switch/md-switch.d.ts +4 -4
- package/labs/gb/components/switch/md-switch.js +12 -12
- package/labs/gb/components/switch/md-switch.js.map +1 -1
- package/labs/gb/components/switch/switch.d.ts +1 -1
- package/labs/gb/components/switch/switch.js +5 -5
- package/labs/gb/components/switch/switch.js.map +1 -1
- package/labs/gb/styles/icon/md-icon.css +1 -1
- package/labs/gb/styles/icon/md-icon.css.map +1 -1
- package/labs/gb/styles/icon/md-icon.cssresult.js +1 -1
- package/labs/gb/styles/icon/md-icon.cssresult.js.map +1 -1
- package/labs/gb/styles/icon/md-icon.d.ts +20 -0
- package/labs/gb/styles/icon/md-icon.js +24 -0
- package/labs/gb/styles/icon/md-icon.js.map +1 -0
- package/labs/gb/styles/icon/md-icon.scss +2 -1
- package/labs/gb/styles/m3.css +5 -2
- package/labs/gb/styles/m3.css.map +1 -1
- package/labs/gb/styles/m3.cssresult.js +5 -2
- package/labs/gb/styles/m3.cssresult.js.map +1 -1
- package/labs/gb/styles/m3.scss +1 -0
- package/labs/gb/styles/space/md-space-tokens.css +4 -0
- package/labs/gb/styles/space/md-space-tokens.css.map +1 -0
- package/labs/gb/styles/space/md-space-tokens.cssresult.d.ts +3 -0
- package/labs/gb/styles/space/md-space-tokens.cssresult.js +14 -0
- package/labs/gb/styles/space/md-space-tokens.cssresult.js.map +1 -0
- package/labs/gb/styles/space/md-space-tokens.scss +28 -0
- package/labs/gb/styles/tailwind.css +4 -0
- package/labs/gb/styles/tailwind.css.map +1 -0
- package/labs/gb/styles/tailwind.cssresult.d.ts +3 -0
- package/labs/gb/styles/tailwind.cssresult.js +14 -0
- package/labs/gb/styles/tailwind.cssresult.js.map +1 -0
- package/labs/gb/styles/tailwind.scss +349 -0
- package/labs/gb/styles/typography/internal/_typography-tokens.scss +85 -16
- package/labs/gb/styles/typography/md-typography-tokens.css +1 -1
- package/labs/gb/styles/typography/md-typography-tokens.css.map +1 -1
- package/labs/gb/styles/typography/md-typography-tokens.cssresult.js +1 -1
- package/labs/gb/styles/typography/md-typography-tokens.cssresult.js.map +1 -1
- package/list/internal/listitem/list-item.d.ts +4 -1
- package/list/internal/listitem/list-item.js +4 -1
- package/list/internal/listitem/list-item.js.map +1 -1
- package/menu/internal/submenu/sub-menu.d.ts +5 -1
- package/menu/internal/submenu/sub-menu.js +5 -1
- package/menu/internal/submenu/sub-menu.js.map +1 -1
- package/package.json +5 -2
- package/radio/internal/radio.d.ts +0 -2
- package/radio/internal/radio.js.map +1 -1
- package/select/internal/select.d.ts +0 -2
- package/select/internal/select.js.map +1 -1
- package/slider/internal/slider.d.ts +0 -2
- package/slider/internal/slider.js.map +1 -1
- package/switch/internal/_switch.scss +1 -0
- package/switch/internal/switch-styles.css +1 -1
- package/switch/internal/switch-styles.css.map +1 -1
- package/switch/internal/switch-styles.cssresult.js +1 -1
- package/switch/internal/switch-styles.cssresult.js.map +1 -1
- package/switch/internal/switch.d.ts +0 -2
- package/switch/internal/switch.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"md-radio.js","sourceRoot":"","sources":["md-radio.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n afterDispatch,\n setupDispatchHooks,\n} from '@material/web/internal/events/dispatch-hooks.js';\nimport {\n createValidator,\n getValidityAnchor,\n mixinConstraintValidation,\n} from '@material/web/labs/behaviors/constraint-validation.js';\nimport {\n internals,\n mixinElementInternals,\n} from '@material/web/labs/behaviors/element-internals.js';\nimport {mixinFocusable} from '@material/web/labs/behaviors/focusable.js';\nimport {\n getFormState,\n getFormValue,\n mixinFormAssociated,\n} from '@material/web/labs/behaviors/form-associated.js';\nimport {RadioValidator} from '@material/web/labs/behaviors/validators/radio-validator.js';\nimport {SingleSelectionController} from '@material/web/radio/internal/single-selection-controller.js';\nimport {css, CSSResultOrNative, html, isServer, LitElement} from 'lit';\nimport {customElement, property, query, state} from 'lit/decorators.js';\n\nimport focusRingStyles from '@material/web/labs/gb/components/focus/focus-ring.css' with {type: 'css'}; // github-only\n// import focusRingStyles from '@material/web/labs/gb/components/focus/focus-ring.cssresult.js'; // google3-only\nimport rippleStyles from '@material/web/labs/gb/components/ripple/ripple.css' with {type: 'css'}; // github-only\n// import rippleStyles from '@material/web/labs/gb/components/ripple/ripple.cssresult.js'; // google3-only\nimport radioStyles from './radio.css' with {type: 'css'}; // github-only\n// import {styles as radioStyles} from './radio.cssresult.js'; // google3-only\n\nimport {radio} from './radio.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n /** A Material Design radio component. */\n 'md-radio': Radio;\n }\n}\n\n// Separate variable needed for closure.\nconst radioBaseClass = mixinConstraintValidation(\n mixinFormAssociated(mixinElementInternals(mixinFocusable(LitElement))),\n);\n\n/**\n * A Material Design radio component.\n */\n@customElement('md-radio')\nexport class Radio extends radioBaseClass {\n static override styles: CSSResultOrNative[] = [\n focusRingStyles,\n rippleStyles,\n radioStyles,\n css`\n :host {\n display: inline-flex;\n outline: none;\n }\n .radio {\n flex: 1;\n }\n `,\n ];\n\n /**\n * Whether or not the radio is selected.\n */\n @property({type: Boolean})\n get checked() {\n return this[internals].ariaChecked === 'true';\n }\n set checked(checked: boolean) {\n const wasChecked = this.checked;\n if (wasChecked === checked) {\n return;\n }\n\n this[internals].ariaChecked = String(checked);\n this.requestUpdate('checked', wasChecked);\n this.selectionController.handleCheckedChange();\n }\n\n /**\n * The default checked state of the radio.\n */\n get defaultChecked(): boolean {\n return this.hasAttribute('checked');\n }\n set defaultChecked(value: boolean) {\n this.toggleAttribute('checked', value || false);\n }\n\n /**\n * Whether or not the radio is required. If any radio is required in a group,\n * all radios are implicitly required.\n */\n @property({type: Boolean}) required = false;\n\n /**\n * The element value to use in form submission when checked.\n */\n @property() value = 'on';\n\n @query('.radio', true) private readonly radio!: HTMLElement;\n private readonly selectionController = new SingleSelectionController(this);\n /**\n * Mimics the behavior of <input> dirty checkedness, where the `checked`\n * attribute only updates the checked state if the radio has not been\n * interacted with.\n *\n * @see https://html.spec.whatwg.org/multipage/input.html#concept-input-checked-dirty-flag\n */\n private dirtyCheckedness = false;\n @state() private isFocused = false;\n\n constructor() {\n super();\n if (isServer) return;\n this[internals].role = 'radio';\n this.addController(this.selectionController);\n setupDispatchHooks(this, 'click', 'keydown');\n this.addEventListener('click', (event) => {\n // Return if disabled, or already checked since clicking on a checked\n // radio does not dispatch events.\n if (this.disabled || this.checked) return;\n afterDispatch(event, () => {\n if (event.defaultPrevented) return;\n // Per spec, clicking on a radio input always selects it.\n this.checked = true;\n this.dirtyCheckedness = true;\n this.dispatchEvent(new Event('change', {bubbles: true}));\n this.dispatchEvent(\n new InputEvent('input', {bubbles: true, composed: true}),\n );\n });\n });\n\n this.addEventListener('keydown', (event) => {\n afterDispatch(event, () => {\n if (event.key !== ' ' || event.defaultPrevented) {\n return;\n }\n\n this.click();\n });\n });\n\n this.addEventListener('focus', () => {\n this.isFocused = true;\n });\n\n this.addEventListener('blur', () => {\n this.isFocused = false;\n });\n }\n\n protected override render() {\n return html`<div\n part=\"radio\"\n class=\"ripple-host focus-ring-host ${radio({\n checked: this.checked,\n disabled: this.disabled,\n focus: this.isFocused,\n })}\"></div>`;\n }\n\n override attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null,\n ) {\n if (name === 'checked' && this.dirtyCheckedness) {\n // The 'checked' attribute does not update radios that have been\n // interacted with.\n return;\n }\n\n super.attributeChangedCallback(name, oldValue, newValue);\n }\n\n override [getFormValue]() {\n return this.checked ? this.value : null;\n }\n\n override [getFormState]() {\n return String(this.checked);\n }\n\n override formResetCallback() {\n this.dirtyCheckedness = false;\n this.checked = this.defaultChecked;\n }\n\n override formStateRestoreCallback(state: string) {\n this.checked = state === 'true';\n }\n\n override [createValidator]() {\n return new RadioValidator(() => {\n if (!this.selectionController) {\n // Validation runs on superclass construction, so selection controller\n // might not actually be ready until this class constructs.\n return [this];\n }\n\n return this.selectionController.controls as [Radio, ...Radio[]];\n });\n }\n\n override [getValidityAnchor]() {\n return this.radio;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"md-radio.js","sourceRoot":"","sources":["md-radio.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {css, CSSResultOrNative, html, isServer, LitElement} from 'lit';\nimport {customElement, property, query, state} from 'lit/decorators.js';\nimport {\n afterDispatch,\n setupDispatchHooks,\n} from '../../../../internal/events/dispatch-hooks.js';\nimport {SingleSelectionController} from '../../../../radio/internal/single-selection-controller.js';\nimport {\n createValidator,\n getValidityAnchor,\n mixinConstraintValidation,\n} from '../../../behaviors/constraint-validation.js';\nimport {\n internals,\n mixinElementInternals,\n} from '../../../behaviors/element-internals.js';\nimport {mixinFocusable} from '../../../behaviors/focusable.js';\nimport {\n getFormState,\n getFormValue,\n mixinFormAssociated,\n} from '../../../behaviors/form-associated.js';\nimport {RadioValidator} from '../../../behaviors/validators/radio-validator.js';\n\nimport focusRingStyles from '../focus/focus-ring.css' with {type: 'css'}; // github-only\n// import focusRingStyles from '../focus/focus-ring.cssresult.js'; // google3-only\nimport rippleStyles from '../ripple/ripple.css' with {type: 'css'}; // github-only\n// import rippleStyles from '../ripple/ripple.cssresult.js'; // google3-only\nimport radioStyles from './radio.css' with {type: 'css'}; // github-only\n// import {styles as radioStyles} from './radio.cssresult.js'; // google3-only\n\nimport {radio} from './radio.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n /** A Material Design radio component. */\n 'md-radio': Radio;\n }\n}\n\n// Separate variable needed for closure.\nconst radioBaseClass = mixinConstraintValidation(\n mixinFormAssociated(mixinElementInternals(mixinFocusable(LitElement))),\n);\n\n/**\n * A Material Design radio component.\n */\n@customElement('md-radio')\nexport class Radio extends radioBaseClass {\n static override styles: CSSResultOrNative[] = [\n focusRingStyles,\n rippleStyles,\n radioStyles,\n css`\n :host {\n display: inline-flex;\n outline: none;\n }\n .radio {\n flex: 1;\n }\n `,\n ];\n\n /**\n * Whether or not the radio is selected.\n */\n @property({type: Boolean})\n get checked() {\n return this[internals].ariaChecked === 'true';\n }\n set checked(checked: boolean) {\n const wasChecked = this.checked;\n if (wasChecked === checked) {\n return;\n }\n\n this[internals].ariaChecked = String(checked);\n this.requestUpdate('checked', wasChecked);\n this.selectionController.handleCheckedChange();\n }\n\n /**\n * The default checked state of the radio.\n */\n get defaultChecked(): boolean {\n return this.hasAttribute('checked');\n }\n set defaultChecked(value: boolean) {\n this.toggleAttribute('checked', value || false);\n }\n\n /**\n * Whether or not the radio is required. If any radio is required in a group,\n * all radios are implicitly required.\n */\n @property({type: Boolean}) required = false;\n\n /**\n * The element value to use in form submission when checked.\n */\n @property() value = 'on';\n\n @query('.radio', true) private readonly radio!: HTMLElement;\n private readonly selectionController = new SingleSelectionController(this);\n /**\n * Mimics the behavior of <input> dirty checkedness, where the `checked`\n * attribute only updates the checked state if the radio has not been\n * interacted with.\n *\n * @see https://html.spec.whatwg.org/multipage/input.html#concept-input-checked-dirty-flag\n */\n private dirtyCheckedness = false;\n @state() private isFocused = false;\n\n constructor() {\n super();\n if (isServer) return;\n this[internals].role = 'radio';\n this.addController(this.selectionController);\n setupDispatchHooks(this, 'click', 'keydown');\n this.addEventListener('click', (event) => {\n // Return if disabled, or already checked since clicking on a checked\n // radio does not dispatch events.\n if (this.disabled || this.checked) return;\n afterDispatch(event, () => {\n if (event.defaultPrevented) return;\n // Per spec, clicking on a radio input always selects it.\n this.checked = true;\n this.dirtyCheckedness = true;\n this.dispatchEvent(new Event('change', {bubbles: true}));\n this.dispatchEvent(\n new InputEvent('input', {bubbles: true, composed: true}),\n );\n });\n });\n\n this.addEventListener('keydown', (event) => {\n afterDispatch(event, () => {\n if (event.key !== ' ' || event.defaultPrevented) {\n return;\n }\n\n this.click();\n });\n });\n\n this.addEventListener('focus', () => {\n this.isFocused = true;\n });\n\n this.addEventListener('blur', () => {\n this.isFocused = false;\n });\n }\n\n protected override render() {\n return html`<div\n part=\"radio\"\n class=\"ripple-host focus-ring-host ${radio({\n checked: this.checked,\n disabled: this.disabled,\n focus: this.isFocused,\n })}\"></div>`;\n }\n\n override attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null,\n ) {\n if (name === 'checked' && this.dirtyCheckedness) {\n // The 'checked' attribute does not update radios that have been\n // interacted with.\n return;\n }\n\n super.attributeChangedCallback(name, oldValue, newValue);\n }\n\n override [getFormValue]() {\n return this.checked ? this.value : null;\n }\n\n override [getFormState]() {\n return String(this.checked);\n }\n\n override formResetCallback() {\n this.dirtyCheckedness = false;\n this.checked = this.defaultChecked;\n }\n\n override formStateRestoreCallback(state: string) {\n this.checked = state === 'true';\n }\n\n override [createValidator]() {\n return new RadioValidator(() => {\n if (!this.selectionController) {\n // Validation runs on superclass construction, so selection controller\n // might not actually be ready until this class constructs.\n return [this];\n }\n\n return this.selectionController.controls as [Radio, ...Radio[]];\n });\n }\n\n override [getValidityAnchor]() {\n return this.radio;\n }\n}\n"]}
|
|
@@ -54,4 +54,4 @@ export declare function setupRadio(radio: HTMLElement, opts?: {
|
|
|
54
54
|
* `;
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
|
-
export declare const radio: (state?: RadioClassesState & import("
|
|
57
|
+
export declare const radio: (state?: RadioClassesState & import("../shared/directives.js").AdditionalClasses) => import("lit-html/directive.js").DirectiveResult;
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Copyright 2026 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { focusRingClasses } from '
|
|
7
|
-
import { rippleClasses, setupRipple
|
|
8
|
-
import { createClassMapDirective } from '
|
|
9
|
-
import { PSEUDO_CLASSES } from '
|
|
6
|
+
import { focusRingClasses } from '../focus/focus-ring.js';
|
|
7
|
+
import { rippleClasses, setupRipple } from '../ripple/ripple.js';
|
|
8
|
+
import { createClassMapDirective } from '../shared/directives.js';
|
|
9
|
+
import { PSEUDO_CLASSES } from '../shared/pseudo-classes.js';
|
|
10
10
|
/** Radio classes. */
|
|
11
11
|
export const RADIO_CLASSES = {
|
|
12
12
|
radio: 'radio',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio.js","sourceRoot":"","sources":["radio.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"radio.js","sourceRoot":"","sources":["radio.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAC,uBAAuB,EAAC,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAC;AAE3D,qBAAqB;AACrB,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,cAAc,CAAC,KAAK;IAC3B,KAAK,EAAE,cAAc,CAAC,KAAK;IAC3B,MAAM,EAAE,cAAc,CAAC,MAAM;IAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;IAC/B,QAAQ,EAAE,cAAc,CAAC,QAAQ;CACzB,CAAC;AAgBX;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,KAAK,GAAG,KAAK,EACb,KAAK,GAAG,KAAK,EACb,MAAM,GAAG,KAAK,EACd,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,MACK,EAAE;IACvB,OAAO;QACL,GAAG,aAAa,EAAE;QAClB,GAAG,gBAAgB,EAAE;QACrB,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI;QAC3B,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK;QAC5B,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK;QAC5B,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM;QAC9B,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO;QAChC,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,QAAQ;KACnC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,KAAkB,EAClB,IAA6B;IAE7B,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,uBAAuB,CAAC;IAC3C,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,UAAU;CACzB,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {type ClassInfo} from 'lit/directives/class-map.js';\nimport {focusRingClasses} from '../focus/focus-ring.js';\nimport {rippleClasses, setupRipple} from '../ripple/ripple.js';\nimport {createClassMapDirective} from '../shared/directives.js';\nimport {PSEUDO_CLASSES} from '../shared/pseudo-classes.js';\n\n/** Radio classes. */\nexport const RADIO_CLASSES = {\n radio: 'radio',\n hover: PSEUDO_CLASSES.hover,\n focus: PSEUDO_CLASSES.focus,\n active: PSEUDO_CLASSES.active,\n checked: PSEUDO_CLASSES.checked,\n disabled: PSEUDO_CLASSES.disabled,\n} as const;\n\n/** The state provided to the `radioClasses()` function. */\nexport interface RadioClassesState {\n /** Emulates `:hover`. */\n hover?: boolean;\n /** Emulates `:focus`. */\n focus?: boolean;\n /** Emulates `:active`. */\n active?: boolean;\n /** Emulates `:checked`. */\n checked?: boolean;\n /** Emulates `:disabled`. */\n disabled?: boolean;\n}\n\n/**\n * Returns the radio classes to apply to an element based on the given state.\n *\n * @param state The state of the radio.\n * @return An object of class names and truthy values if they apply.\n */\nexport function radioClasses({\n hover = false,\n focus = false,\n active = false,\n checked = false,\n disabled = false,\n}: RadioClassesState = {}): ClassInfo {\n return {\n ...rippleClasses(),\n ...focusRingClasses(),\n [RADIO_CLASSES.radio]: true,\n [RADIO_CLASSES.hover]: hover,\n [RADIO_CLASSES.focus]: focus,\n [RADIO_CLASSES.active]: active,\n [RADIO_CLASSES.checked]: checked,\n [RADIO_CLASSES.disabled]: disabled,\n };\n}\n\n/**\n * Sets up radio functionality for the given element.\n *\n * @param radio The element on which to set up radio functionality.\n * @param opts Setup options, supports a cleanup `signal`.\n */\nexport function setupRadio(\n radio: HTMLElement,\n opts?: {signal?: AbortSignal},\n): void {\n setupRipple(radio, opts);\n}\n\n/**\n * A Lit directive that adds radio styling and functionality to its element.\n *\n * @example\n * ```ts\n * html`\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * <input type=\"radio\" class=\"${radio()}\" name=\"radio-group\">\n * `;\n * ```\n */\nexport const radio = createClassMapDirective({\n getClasses: radioClasses,\n setupElement: setupRadio,\n});\n"]}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright 2026 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { createElementDirective } from '
|
|
7
|
-
import { PSEUDO_CLASSES, isDisabled
|
|
6
|
+
import { createElementDirective } from '../shared/directives.js';
|
|
7
|
+
import { PSEUDO_CLASSES, isDisabled } from '../shared/pseudo-classes.js';
|
|
8
8
|
/** Ripple classes. */
|
|
9
9
|
export const RIPPLE_CLASSES = {
|
|
10
10
|
ripple: 'ripple',
|
|
@@ -55,6 +55,9 @@ export function setupRipple(ripple, opts) {
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
+
catch {
|
|
59
|
+
// Ignore errors if the properties are already registered.
|
|
60
|
+
}
|
|
58
61
|
finally {
|
|
59
62
|
ripplePropertiesRegistered = true;
|
|
60
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ripple.js","sourceRoot":"","sources":["ripple.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"ripple.js","sourceRoot":"","sources":["ripple.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {type ClassInfo} from 'lit/directives/class-map.js';\nimport {createElementDirective} from '../shared/directives.js';\nimport {PSEUDO_CLASSES, isDisabled} from '../shared/pseudo-classes.js';\n\n/** Ripple classes. */\nexport const RIPPLE_CLASSES = {\n ripple: 'ripple',\n rippleTarget: 'ripple-target',\n rippleHost: 'ripple-host',\n hover: PSEUDO_CLASSES.hover,\n active: PSEUDO_CLASSES.active,\n disabled: PSEUDO_CLASSES.disabled,\n};\n\n/** The state provided to the `rippleClasses()` function. */\nexport interface RippleClassesState {\n /** Emulates `:hover`. */\n hover?: boolean;\n /** Emulates `:active`. */\n active?: boolean;\n /** Emulates `:disabled`. */\n disabled?: boolean;\n}\n\n/**\n * Returns the ripple classes to apply to an element based on the given state.\n *\n * @param state The state of the ripple.\n * @return An object of class names and truthy values if they apply.\n */\nexport function rippleClasses({\n hover = false,\n active = false,\n disabled = false,\n}: RippleClassesState = {}): ClassInfo {\n return {\n [RIPPLE_CLASSES.ripple]: true,\n [RIPPLE_CLASSES.hover]: hover,\n [RIPPLE_CLASSES.active]: active,\n [RIPPLE_CLASSES.disabled]: disabled,\n };\n}\n\nconst MINIMUM_PRESS_MS = 225;\nlet ripplePropertiesRegistered = false;\n\n/**\n * Sets up ripple functionality for the given element.\n *\n * @param ripple The element on which to set up ripple functionality.\n * @param opts Setup options, supports a cleanup `signal`.\n */\nexport function setupRipple(\n ripple: HTMLElement,\n opts?: {signal?: AbortSignal},\n): void {\n if (!ripplePropertiesRegistered) {\n const properties = [\n ['--ripple-scale', '0%'],\n ['--ripple-hover-opacity', '0%'],\n ['--ripple-press-opacity', '0%'],\n ['--ripple-x', '50%'],\n ['--ripple-y', '50%'],\n ];\n\n try {\n for (const [property, value] of properties) {\n CSS.registerProperty({\n name: property,\n syntax: '<percentage>',\n inherits: false,\n initialValue: value,\n });\n }\n } catch {\n // Ignore errors if the properties are already registered.\n } finally {\n ripplePropertiesRegistered = true;\n }\n }\n\n let minimumPressTimeoutId: number | undefined;\n const activateRipple = () => {\n // If the ripple is already active, restart the current press animation.\n if (ripple.classList.contains(RIPPLE_CLASSES.active)) {\n const pressAnimation = ripple\n .getAnimations()\n .find(\n (animation) =>\n (animation as Partial<CSSAnimation>).animationName ===\n 'ripple-press',\n );\n pressAnimation?.cancel();\n pressAnimation?.play();\n }\n\n // Emulate the `:active` class for a minimum press duration to show the\n // ripple effect on short clicks.\n ripple.classList.add(RIPPLE_CLASSES.active);\n clearTimeout(minimumPressTimeoutId);\n minimumPressTimeoutId = setTimeout(() => {\n ripple.classList.remove(RIPPLE_CLASSES.active);\n }, MINIMUM_PRESS_MS);\n };\n\n // Return true if the ripple is disabled, or if the ripple class has been\n // removed. This allows components to disable and re-enable ripple behavior.\n const isRippleDisabled = () =>\n isDisabled(ripple) || !ripple.matches(`.${RIPPLE_CLASSES.ripple}`);\n\n ripple.addEventListener(\n 'pointerdown',\n (event: PointerEvent): void => {\n if (isRippleDisabled()) return;\n // Set ripple position to the pointer position.\n const rect = ripple.getBoundingClientRect();\n const x = (event.clientX - rect.x) / rect.width;\n const y = (event.clientY - rect.y) / rect.height;\n ripple.style.setProperty('--ripple-x', `${x * 100}%`);\n ripple.style.setProperty('--ripple-y', `${y * 100}%`);\n activateRipple();\n },\n opts,\n );\n\n ripple.addEventListener(\n 'keydown',\n (event: KeyboardEvent): void => {\n // Reset ripple pointer position when a key is pressed.\n ripple.style.removeProperty('--ripple-x');\n ripple.style.removeProperty('--ripple-y');\n },\n opts,\n );\n\n ripple.addEventListener(\n 'click',\n (event) => {\n // A UIEvent.detail click count of 0 indicates the click was not triggered\n // by a pointer. Show the ripple press effect for these clicks as well.\n if (event.detail === 0 && !isRippleDisabled()) {\n activateRipple();\n }\n },\n opts,\n );\n}\n\n/**\n * A Lit directive that adds updates the position of a ripple to match pointer\n * interactions. Use with the `.ripple` class.\n *\n * @example\n * ```ts\n * class Component extends LitElement {\n * static styles = [rippleStyles, css`...`];\n *\n * render() {\n * return html`<button class=\"ripple\" ${ripple()}>Ripple effect</button>`;\n * }\n * }\n * ```\n *\n * Use the `.ripple-target` class if the interactive element is a parent or\n * child of the ripple element.\n *\n * The `ripple()` directive should be applied to the parent element, which may\n * be the `.ripple-target` instead of the `.ripple`.\n *\n * @example\n * ```ts\n * html`\n * <div class=\"card ripple\" ${ripple()}>\n * Child interactive element\n * <button class=\"ripple-target card-btn\"></button>\n * </div>\n *\n * <button class=\"ripple-target\" ${ripple()}>\n * Parent interactive element\n * <span class=\"ripple\"></span>\n * </button>\n * `;\n * ```\n */\nexport const ripple = createElementDirective(setupRipple);\n"]}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 Google LLC
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
@mixin root {
|
|
7
|
+
--between-space: 2px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@mixin button {
|
|
11
|
+
--icon-size: 0;
|
|
12
|
+
--inner-corner-size: 0;
|
|
13
|
+
--outer-corner-size: calc(var(--container-height) / 2);
|
|
14
|
+
--leading-space: 0;
|
|
15
|
+
--trailing-space: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@mixin button-xs {
|
|
19
|
+
--icon-size: 22px;
|
|
20
|
+
--inner-corner-size: var(--md-sys-shape-corner-xs);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@mixin button-xs-leading {
|
|
24
|
+
--leading-space: 12px;
|
|
25
|
+
--trailing-space: 10px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@mixin button-xs-trailing {
|
|
29
|
+
--leading-space: 13px;
|
|
30
|
+
--trailing-space: 13px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@mixin button-xs-hovered {
|
|
34
|
+
--inner-corner-size: var(--md-sys-shape-corner-sm);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@mixin button-xs-pressed {
|
|
38
|
+
--inner-corner-size: var(--md-sys-shape-corner-sm);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@mixin button-sm {
|
|
42
|
+
--icon-size: 22px;
|
|
43
|
+
--inner-corner-size: var(--md-sys-shape-corner-xs);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@mixin button-sm-leading {
|
|
47
|
+
--leading-space: 16px;
|
|
48
|
+
--trailing-space: 12px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@mixin button-sm-trailing {
|
|
52
|
+
--leading-space: 13px;
|
|
53
|
+
--trailing-space: 13px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@mixin button-sm-hovered {
|
|
57
|
+
--inner-corner-size: var(--md-sys-shape-corner-md);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@mixin button-sm-pressed {
|
|
61
|
+
--inner-corner-size: var(--md-sys-shape-corner-md);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@mixin button-md {
|
|
65
|
+
--icon-size: 26px;
|
|
66
|
+
--inner-corner-size: var(--md-sys-shape-corner-xs);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@mixin button-md-leading {
|
|
70
|
+
--leading-space: 24px;
|
|
71
|
+
--trailing-space: 24px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@mixin button-md-trailing {
|
|
75
|
+
--leading-space: 15px;
|
|
76
|
+
--trailing-space: 15px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@mixin button-md-hovered {
|
|
80
|
+
--inner-corner-size: var(--md-sys-shape-corner-md);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@mixin button-md-pressed {
|
|
84
|
+
--inner-corner-size: var(--md-sys-shape-corner-md);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@mixin button-lg {
|
|
88
|
+
--icon-size: 38px;
|
|
89
|
+
--inner-corner-size: var(--md-sys-shape-corner-sm);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@mixin button-lg-leading {
|
|
93
|
+
--leading-space: 48px;
|
|
94
|
+
--trailing-space: 48px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@mixin button-lg-trailing {
|
|
98
|
+
--leading-space: 29px;
|
|
99
|
+
--trailing-space: 29px;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@mixin button-lg-hovered {
|
|
103
|
+
--inner-corner-size: var(--md-sys-shape-corner-lg-increased);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@mixin button-lg-pressed {
|
|
107
|
+
--inner-corner-size: var(--md-sys-shape-corner-lg-increased);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@mixin button-xl {
|
|
111
|
+
--icon-size: 50px;
|
|
112
|
+
--inner-corner-size: var(--md-sys-shape-corner-md);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@mixin button-xl-leading {
|
|
116
|
+
--leading-space: 64px;
|
|
117
|
+
--trailing-space: 64px;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@mixin button-xl-trailing {
|
|
121
|
+
--leading-space: 43px;
|
|
122
|
+
--trailing-space: 43px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@mixin button-xl-hovered {
|
|
126
|
+
--inner-corner-size: var(--md-sys-shape-corner-lg-increased);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@mixin button-xl-pressed {
|
|
130
|
+
--inner-corner-size: var(--md-sys-shape-corner-lg-increased);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@mixin button-trailing-selected {
|
|
134
|
+
--inner-corner-size: calc(var(--container-height) / 2);
|
|
135
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { CSSResultOrNative, LitElement } from 'lit';
|
|
7
|
+
import { type SplitButtonColor, type SplitButtonSize } from './split-button.js';
|
|
8
|
+
declare global {
|
|
9
|
+
interface HTMLElementTagNameMap {
|
|
10
|
+
/** A Material Design split button component. */
|
|
11
|
+
'md-split-button': SplitButton;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A Material Design split button component.
|
|
16
|
+
*/
|
|
17
|
+
export declare class SplitButton extends LitElement {
|
|
18
|
+
static styles: CSSResultOrNative[];
|
|
19
|
+
color: SplitButtonColor;
|
|
20
|
+
size: SplitButtonSize;
|
|
21
|
+
selected: boolean;
|
|
22
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
23
|
+
private updateSlotFocusVisible;
|
|
24
|
+
private cleanupToggleListener?;
|
|
25
|
+
private handleTrailingSlotchange;
|
|
26
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { __decorate } from "tslib";
|
|
7
|
+
import { css, html, LitElement } from 'lit';
|
|
8
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
9
|
+
import { button } from '../button/button.js';
|
|
10
|
+
import focusRingStyles from '../focus/focus-ring.css' with { type: 'css' }; // github-only
|
|
11
|
+
// import focusRingStyles from '../focus/focus-ring.cssresult.js'; // google3-only
|
|
12
|
+
import rippleStyles from '../ripple/ripple.css' with { type: 'css' }; // github-only
|
|
13
|
+
// import rippleStyles from '../ripple/ripple.cssresult.js'; // google3-only
|
|
14
|
+
import buttonStyles from '../button/button.css' with { type: 'css' }; // github-only
|
|
15
|
+
// import buttonStyles from '../button/button.cssresult.js'; // google3-only
|
|
16
|
+
import splitButtonStyles from './split-button.css' with { type: 'css' }; // github-only
|
|
17
|
+
// import {styles as splitButtonStyles} from './split-button.cssresult.js'; // google3-only
|
|
18
|
+
import { splitButton, } from './split-button.js';
|
|
19
|
+
/**
|
|
20
|
+
* A Material Design split button component.
|
|
21
|
+
*/
|
|
22
|
+
let SplitButton = class SplitButton extends LitElement {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this.color = 'filled';
|
|
26
|
+
this.size = 'sm';
|
|
27
|
+
this.selected = false;
|
|
28
|
+
}
|
|
29
|
+
render() {
|
|
30
|
+
const buttonConfig = {
|
|
31
|
+
color: this.color,
|
|
32
|
+
size: this.size,
|
|
33
|
+
};
|
|
34
|
+
return html `<div part="split-btn" class="${splitButton(this)}">
|
|
35
|
+
<slot
|
|
36
|
+
name="leading"
|
|
37
|
+
part="leading-btn"
|
|
38
|
+
class="${button(buttonConfig)}"
|
|
39
|
+
@focusin=${this.updateSlotFocusVisible}
|
|
40
|
+
@focusout=${this.updateSlotFocusVisible}>
|
|
41
|
+
</slot>
|
|
42
|
+
<slot
|
|
43
|
+
name="trailing"
|
|
44
|
+
part="trailing-btn"
|
|
45
|
+
class="${button(buttonConfig)}"
|
|
46
|
+
@focusin=${this.updateSlotFocusVisible}
|
|
47
|
+
@focusout=${this.updateSlotFocusVisible}
|
|
48
|
+
@slotchange=${this.handleTrailingSlotchange}>
|
|
49
|
+
</slot>
|
|
50
|
+
<slot></slot>
|
|
51
|
+
</div>`;
|
|
52
|
+
}
|
|
53
|
+
updateSlotFocusVisible(event) {
|
|
54
|
+
const slot = event.currentTarget;
|
|
55
|
+
const hasFocusVisible = slot
|
|
56
|
+
.assignedElements()
|
|
57
|
+
.some((el) => el.matches(':focus-visible,:has(:focus-visible)'));
|
|
58
|
+
slot.classList.toggle('focus-visible', hasFocusVisible);
|
|
59
|
+
}
|
|
60
|
+
handleTrailingSlotchange(event) {
|
|
61
|
+
this.cleanupToggleListener?.abort();
|
|
62
|
+
this.cleanupToggleListener = new AbortController();
|
|
63
|
+
const slot = event.target;
|
|
64
|
+
const trailingButton = slot
|
|
65
|
+
.assignedElements()
|
|
66
|
+
.find((el) => el.matches('button'));
|
|
67
|
+
if (!trailingButton?.popoverTargetElement)
|
|
68
|
+
return;
|
|
69
|
+
trailingButton.popoverTargetElement.addEventListener('toggle', (event) => {
|
|
70
|
+
this.selected = event.newState === 'open';
|
|
71
|
+
}, { signal: this.cleanupToggleListener.signal });
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
SplitButton.styles = [
|
|
75
|
+
focusRingStyles,
|
|
76
|
+
rippleStyles,
|
|
77
|
+
buttonStyles,
|
|
78
|
+
splitButtonStyles,
|
|
79
|
+
css `
|
|
80
|
+
:host {
|
|
81
|
+
display: inline-flex;
|
|
82
|
+
}
|
|
83
|
+
.split-btn {
|
|
84
|
+
flex: 1;
|
|
85
|
+
}
|
|
86
|
+
[name='leading'] {
|
|
87
|
+
display: contents;
|
|
88
|
+
&::slotted(button) {
|
|
89
|
+
all: inherit;
|
|
90
|
+
display: flex;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
[name='trailing'] {
|
|
94
|
+
position: relative;
|
|
95
|
+
&::slotted(button) {
|
|
96
|
+
position: absolute;
|
|
97
|
+
inset: 0;
|
|
98
|
+
appearance: none;
|
|
99
|
+
background: none;
|
|
100
|
+
border: none;
|
|
101
|
+
outline: none;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
`,
|
|
105
|
+
];
|
|
106
|
+
__decorate([
|
|
107
|
+
property()
|
|
108
|
+
], SplitButton.prototype, "color", void 0);
|
|
109
|
+
__decorate([
|
|
110
|
+
property()
|
|
111
|
+
], SplitButton.prototype, "size", void 0);
|
|
112
|
+
__decorate([
|
|
113
|
+
property({ type: Boolean })
|
|
114
|
+
], SplitButton.prototype, "selected", void 0);
|
|
115
|
+
SplitButton = __decorate([
|
|
116
|
+
customElement('md-split-button')
|
|
117
|
+
], SplitButton);
|
|
118
|
+
export { SplitButton };
|
|
119
|
+
//# sourceMappingURL=md-split-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md-split-button.js","sourceRoot":"","sources":["md-split-button.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {css, CSSResultOrNative, html, LitElement} from 'lit';\nimport {customElement, property} from 'lit/decorators.js';\nimport {button} from '../button/button.js';\n\nimport focusRingStyles from '../focus/focus-ring.css' with {type: 'css'}; // github-only\n// import focusRingStyles from '../focus/focus-ring.cssresult.js'; // google3-only\nimport rippleStyles from '../ripple/ripple.css' with {type: 'css'}; // github-only\n// import rippleStyles from '../ripple/ripple.cssresult.js'; // google3-only\nimport buttonStyles from '../button/button.css' with {type: 'css'}; // github-only\n// import buttonStyles from '../button/button.cssresult.js'; // google3-only\nimport splitButtonStyles from './split-button.css' with {type: 'css'}; // github-only\n// import {styles as splitButtonStyles} from './split-button.cssresult.js'; // google3-only\n\nimport {\n splitButton,\n type SplitButtonColor,\n type SplitButtonSize,\n} from './split-button.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n /** A Material Design split button component. */\n 'md-split-button': SplitButton;\n }\n}\n\n/**\n * A Material Design split button component.\n */\n@customElement('md-split-button')\nexport class SplitButton extends LitElement {\n static override styles: CSSResultOrNative[] = [\n focusRingStyles,\n rippleStyles,\n buttonStyles,\n splitButtonStyles,\n css`\n :host {\n display: inline-flex;\n }\n .split-btn {\n flex: 1;\n }\n [name='leading'] {\n display: contents;\n &::slotted(button) {\n all: inherit;\n display: flex;\n }\n }\n [name='trailing'] {\n position: relative;\n &::slotted(button) {\n position: absolute;\n inset: 0;\n appearance: none;\n background: none;\n border: none;\n outline: none;\n }\n }\n `,\n ];\n\n @property() color: SplitButtonColor = 'filled';\n @property() size: SplitButtonSize = 'sm';\n @property({type: Boolean}) selected = false;\n\n protected override render() {\n const buttonConfig = {\n color: this.color,\n size: this.size,\n };\n\n return html`<div part=\"split-btn\" class=\"${splitButton(this)}\">\n <slot\n name=\"leading\"\n part=\"leading-btn\"\n class=\"${button(buttonConfig)}\"\n @focusin=${this.updateSlotFocusVisible}\n @focusout=${this.updateSlotFocusVisible}>\n </slot>\n <slot\n name=\"trailing\"\n part=\"trailing-btn\"\n class=\"${button(buttonConfig)}\"\n @focusin=${this.updateSlotFocusVisible}\n @focusout=${this.updateSlotFocusVisible}\n @slotchange=${this.handleTrailingSlotchange}>\n </slot>\n <slot></slot>\n </div>`;\n }\n\n private updateSlotFocusVisible(event: Event) {\n const slot = event.currentTarget as HTMLSlotElement;\n const hasFocusVisible = slot\n .assignedElements()\n .some((el) => el.matches(':focus-visible,:has(:focus-visible)'));\n slot.classList.toggle('focus-visible', hasFocusVisible);\n }\n\n private cleanupToggleListener?: AbortController;\n private handleTrailingSlotchange(event: Event) {\n this.cleanupToggleListener?.abort();\n this.cleanupToggleListener = new AbortController();\n const slot = event.target as HTMLSlotElement;\n const trailingButton = slot\n .assignedElements()\n .find((el): el is HTMLButtonElement => el.matches('button'));\n if (!trailingButton?.popoverTargetElement) return;\n trailingButton.popoverTargetElement.addEventListener(\n 'toggle',\n (event: Event) => {\n this.selected = (event as ToggleEvent).newState === 'open';\n },\n {signal: this.cleanupToggleListener.signal},\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright 2026 Google LLC
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/@layer md.sys, md.comp.ripple, md.comp.focus-ring, md.comp.button;@layer md.comp.split-button{.split-btn{--between-space: 2px}.split-btn .btn{--icon-size: 0;--inner-corner-size: 0;--outer-corner-size: calc(var(--container-height) / 2);--leading-space: 0;--trailing-space: 0}.split-btn .btn-xs{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-xs:where(:nth-child(1 of .btn)){--leading-space: 12px;--trailing-space: 10px}.split-btn .btn-xs:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-xs:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-xs:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-sm{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-sm:where(:nth-child(1 of .btn)){--leading-space: 16px;--trailing-space: 12px}.split-btn .btn-sm:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-sm:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-sm:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md{--icon-size: 26px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-md:where(:nth-child(1 of .btn)){--leading-space: 24px;--trailing-space: 24px}.split-btn .btn-md:where(:nth-last-child(1 of .btn)){--leading-space: 15px;--trailing-space: 15px}.split-btn .btn-md:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-lg{--icon-size: 38px;--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-lg:where(:nth-child(1 of .btn)){--leading-space: 48px;--trailing-space: 48px}.split-btn .btn-lg:where(:nth-last-child(1 of .btn)){--leading-space: 29px;--trailing-space: 29px}.split-btn .btn-lg:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-lg:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl{--icon-size: 50px;--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-xl:where(:nth-child(1 of .btn)){--leading-space: 64px;--trailing-space: 64px}.split-btn .btn-xl:where(:nth-last-child(1 of .btn)){--leading-space: 43px;--trailing-space: 43px}.split-btn .btn-xl:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn){--inner-corner-size: calc(var(--container-height) / 2)}.split-btn{display:inline-flex;align-items:center;gap:var(--between-space)}.split-btn :nth-child(1 of .btn){border-start-start-radius:var(--outer-corner-size);border-end-start-radius:var(--outer-corner-size);border-start-end-radius:var(--inner-corner-size);border-end-end-radius:var(--inner-corner-size)}.split-btn :nth-last-child(1 of .btn){border-start-start-radius:var(--inner-corner-size);border-end-start-radius:var(--inner-corner-size);border-start-end-radius:var(--outer-corner-size);border-end-end-radius:var(--outer-corner-size)}.split-btn :nth-last-child(1 of .btn)::before{content:"arrow_drop_down";font:var(--md-icon-size) var(--md-icon-font);display:flex;align-items:center;aspect-ratio:1;width:var(--md-icon-size);overflow:hidden}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn)::before{transform:rotate(180deg);transition:transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard)}}/*# sourceMappingURL=split-button.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["split-button.scss","_split-button-tokens.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA,GASA,kEACA,4BACE,WCLA,qBDQE,gBCJF,eACA,uBACA,uDACA,mBACA,oBDIE,qCCCF,mDDEI,gDCEJ,sBACA,uBDCI,qDCGJ,sBACA,+DAIA,6FAIA,mDDCE,mBCGF,kBACA,mDDDI,gDCKJ,sBACA,uBDFI,qDCMJ,sBACA,uBDHI,wCCOJ,mDDHI,0CCOJ,mDDFE,mBCMF,kBACA,mDDJI,gDCQJ,sBACA,uBDLI,qDCSJ,sBACA,uBDNI,wCCUJ,mDDNI,0CCUJ,mDDLE,mBCSF,kBACA,mDDPI,gDCWJ,sBACA,uBDRI,qDCYJ,sBACA,uBDTI,wCCaJ,6DDTI,0CCaJ,6DDRE,mBCYF,kBACA,mDDVI,gDCcJ,sBACA,uBDXI,qDCeJ,sBACA,uBDZI,wCCgBJ,6DDZI,0CCgBJ,6DDVI,kFCcJ,uDDPE,WACE,oBACA,mBACA,yBAGF,iCACE,mDACA,iDACA,iDACA,+CAGF,sCACE,mDACA,iDACA,iDACA,+CAEA,8CACE,0BACA,6CACA,aACA,mBACA,eACA,0BACA,gBAIJ,0FAEE,yBACA","file":"split-button.css"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
// Generated stylesheet for ./labs/gb/components/splitbutton/split-button.css.
|
|
7
|
+
import { css } from 'lit';
|
|
8
|
+
export const styles = css `/*!
|
|
9
|
+
* Copyright 2026 Google LLC
|
|
10
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
11
|
+
*/@layer md.sys, md.comp.ripple, md.comp.focus-ring, md.comp.button;@layer md.comp.split-button{.split-btn{--between-space: 2px}.split-btn .btn{--icon-size: 0;--inner-corner-size: 0;--outer-corner-size: calc(var(--container-height) / 2);--leading-space: 0;--trailing-space: 0}.split-btn .btn-xs{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-xs:where(:nth-child(1 of .btn)){--leading-space: 12px;--trailing-space: 10px}.split-btn .btn-xs:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-xs:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-xs:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-sm{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-sm:where(:nth-child(1 of .btn)){--leading-space: 16px;--trailing-space: 12px}.split-btn .btn-sm:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-sm:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-sm:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md{--icon-size: 26px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-md:where(:nth-child(1 of .btn)){--leading-space: 24px;--trailing-space: 24px}.split-btn .btn-md:where(:nth-last-child(1 of .btn)){--leading-space: 15px;--trailing-space: 15px}.split-btn .btn-md:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-lg{--icon-size: 38px;--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-lg:where(:nth-child(1 of .btn)){--leading-space: 48px;--trailing-space: 48px}.split-btn .btn-lg:where(:nth-last-child(1 of .btn)){--leading-space: 29px;--trailing-space: 29px}.split-btn .btn-lg:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-lg:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl{--icon-size: 50px;--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-xl:where(:nth-child(1 of .btn)){--leading-space: 64px;--trailing-space: 64px}.split-btn .btn-xl:where(:nth-last-child(1 of .btn)){--leading-space: 43px;--trailing-space: 43px}.split-btn .btn-xl:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn){--inner-corner-size: calc(var(--container-height) / 2)}.split-btn{display:inline-flex;align-items:center;gap:var(--between-space)}.split-btn :nth-child(1 of .btn){border-start-start-radius:var(--outer-corner-size);border-end-start-radius:var(--outer-corner-size);border-start-end-radius:var(--inner-corner-size);border-end-end-radius:var(--inner-corner-size)}.split-btn :nth-last-child(1 of .btn){border-start-start-radius:var(--inner-corner-size);border-end-start-radius:var(--inner-corner-size);border-start-end-radius:var(--outer-corner-size);border-end-end-radius:var(--outer-corner-size)}.split-btn :nth-last-child(1 of .btn)::before{content:"arrow_drop_down";font:var(--md-icon-size) var(--md-icon-font);display:flex;align-items:center;aspect-ratio:1;width:var(--md-icon-size);overflow:hidden}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn)::before{transform:rotate(180deg);transition:transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard)}}
|
|
12
|
+
`;
|
|
13
|
+
export default styles.styleSheet;
|
|
14
|
+
//# sourceMappingURL=split-button.cssresult.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-button.cssresult.js","sourceRoot":"","sources":["split-button.cssresult.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,8EAA8E;AAC9E,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;CAIxB,CAAC;AACF,eAAe,MAAM,CAAC,UAAW,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n// Generated stylesheet for ./labs/gb/components/splitbutton/split-button.css.\nimport {css} from 'lit';\nexport const styles = css`/*!\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */@layer md.sys, md.comp.ripple, md.comp.focus-ring, md.comp.button;@layer md.comp.split-button{.split-btn{--between-space: 2px}.split-btn .btn{--icon-size: 0;--inner-corner-size: 0;--outer-corner-size: calc(var(--container-height) / 2);--leading-space: 0;--trailing-space: 0}.split-btn .btn-xs{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-xs:where(:nth-child(1 of .btn)){--leading-space: 12px;--trailing-space: 10px}.split-btn .btn-xs:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-xs:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-xs:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-sm{--icon-size: 22px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-sm:where(:nth-child(1 of .btn)){--leading-space: 16px;--trailing-space: 12px}.split-btn .btn-sm:where(:nth-last-child(1 of .btn)){--leading-space: 13px;--trailing-space: 13px}.split-btn .btn-sm:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-sm:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md{--icon-size: 26px;--inner-corner-size: var(--md-sys-shape-corner-xs)}.split-btn .btn-md:where(:nth-child(1 of .btn)){--leading-space: 24px;--trailing-space: 24px}.split-btn .btn-md:where(:nth-last-child(1 of .btn)){--leading-space: 15px;--trailing-space: 15px}.split-btn .btn-md:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-md:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-lg{--icon-size: 38px;--inner-corner-size: var(--md-sys-shape-corner-sm)}.split-btn .btn-lg:where(:nth-child(1 of .btn)){--leading-space: 48px;--trailing-space: 48px}.split-btn .btn-lg:where(:nth-last-child(1 of .btn)){--leading-space: 29px;--trailing-space: 29px}.split-btn .btn-lg:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-lg:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl{--icon-size: 50px;--inner-corner-size: var(--md-sys-shape-corner-md)}.split-btn .btn-xl:where(:nth-child(1 of .btn)){--leading-space: 64px;--trailing-space: 64px}.split-btn .btn-xl:where(:nth-last-child(1 of .btn)){--leading-space: 43px;--trailing-space: 43px}.split-btn .btn-xl:where(:hover,.hover){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn .btn-xl:where(:active,.active){--inner-corner-size: var(--md-sys-shape-corner-lg-increased)}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn){--inner-corner-size: calc(var(--container-height) / 2)}.split-btn{display:inline-flex;align-items:center;gap:var(--between-space)}.split-btn :nth-child(1 of .btn){border-start-start-radius:var(--outer-corner-size);border-end-start-radius:var(--outer-corner-size);border-start-end-radius:var(--inner-corner-size);border-end-end-radius:var(--inner-corner-size)}.split-btn :nth-last-child(1 of .btn){border-start-start-radius:var(--inner-corner-size);border-end-start-radius:var(--inner-corner-size);border-start-end-radius:var(--outer-corner-size);border-end-end-radius:var(--outer-corner-size)}.split-btn :nth-last-child(1 of .btn)::before{content:\"arrow_drop_down\";font:var(--md-icon-size) var(--md-icon-font);display:flex;align-items:center;aspect-ratio:1;width:var(--md-icon-size);overflow:hidden}.split-btn:is(.split-btn-selected,:has(:popover-open)) :nth-last-child(1 of .btn)::before{transform:rotate(180deg);transition:transform var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard)}}\n`;\nexport default styles.styleSheet!;\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { type ClassInfo } from 'lit/directives/class-map.js';
|
|
7
|
+
/** Split Button color configuration types. */
|
|
8
|
+
export type SplitButtonColor = 'filled' | 'elevated' | 'tonal' | 'outlined';
|
|
9
|
+
/** Split Button size configuration types. */
|
|
10
|
+
export type SplitButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
11
|
+
/** Split Button classes. */
|
|
12
|
+
export declare const SPLIT_BUTTON_CLASSES: {
|
|
13
|
+
readonly splitButton: "split-btn";
|
|
14
|
+
readonly splitButtonSelected: "split-btn-selected";
|
|
15
|
+
};
|
|
16
|
+
/** The state provided to the `splitButtonClasses()` function. */
|
|
17
|
+
export interface SplitButtonClassesState {
|
|
18
|
+
/** Whether the split trailing button is selected. */
|
|
19
|
+
selected?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns the split button classes to apply to an element based on the given
|
|
23
|
+
* state.
|
|
24
|
+
*
|
|
25
|
+
* @param state The state of the split button.
|
|
26
|
+
* @return An object of class names and truthy values if they apply.
|
|
27
|
+
*/
|
|
28
|
+
export declare function splitButtonClasses({ selected, }?: SplitButtonClassesState): ClassInfo;
|
|
29
|
+
/**
|
|
30
|
+
* A Lit directive that adds split button styling and functionality to its
|
|
31
|
+
* element.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* html`
|
|
36
|
+
* <div class="${splitButton()}">
|
|
37
|
+
* <button class="${button({color: 'filled'})}">Label</button>
|
|
38
|
+
* <button class="${button({color: 'filled'})}" popovertarget="menu"></button>
|
|
39
|
+
* <md-menu id="menu">
|
|
40
|
+
* <md-menu-item>Option 1</md-menu-item>
|
|
41
|
+
* <md-menu-item>Option 2</md-menu-item>
|
|
42
|
+
* </md-menu>
|
|
43
|
+
* </div>
|
|
44
|
+
* `;
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const splitButton: (state?: SplitButtonClassesState & import("../shared/directives.js").AdditionalClasses) => import("lit-html/directive.js").DirectiveResult;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { createClassMapDirective } from '../shared/directives.js';
|
|
7
|
+
/** Split Button classes. */
|
|
8
|
+
export const SPLIT_BUTTON_CLASSES = {
|
|
9
|
+
splitButton: 'split-btn',
|
|
10
|
+
splitButtonSelected: 'split-btn-selected',
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Returns the split button classes to apply to an element based on the given
|
|
14
|
+
* state.
|
|
15
|
+
*
|
|
16
|
+
* @param state The state of the split button.
|
|
17
|
+
* @return An object of class names and truthy values if they apply.
|
|
18
|
+
*/
|
|
19
|
+
export function splitButtonClasses({ selected = false, } = {}) {
|
|
20
|
+
return {
|
|
21
|
+
[SPLIT_BUTTON_CLASSES.splitButton]: true,
|
|
22
|
+
[SPLIT_BUTTON_CLASSES.splitButtonSelected]: selected,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A Lit directive that adds split button styling and functionality to its
|
|
27
|
+
* element.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* html`
|
|
32
|
+
* <div class="${splitButton()}">
|
|
33
|
+
* <button class="${button({color: 'filled'})}">Label</button>
|
|
34
|
+
* <button class="${button({color: 'filled'})}" popovertarget="menu"></button>
|
|
35
|
+
* <md-menu id="menu">
|
|
36
|
+
* <md-menu-item>Option 1</md-menu-item>
|
|
37
|
+
* <md-menu-item>Option 2</md-menu-item>
|
|
38
|
+
* </md-menu>
|
|
39
|
+
* </div>
|
|
40
|
+
* `;
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export const splitButton = createClassMapDirective({
|
|
44
|
+
getClasses: splitButtonClasses,
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=split-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-button.js","sourceRoot":"","sources":["split-button.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,uBAAuB,EAAC,MAAM,yBAAyB,CAAC;AAShE,4BAA4B;AAC5B,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,WAAW,EAAE,WAAW;IACxB,mBAAmB,EAAE,oBAAoB;CACjC,CAAC;AAQX;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,GAAG,KAAK,MACW,EAAE;IAC7B,OAAO;QACL,CAAC,oBAAoB,CAAC,WAAW,CAAC,EAAE,IAAI;QACxC,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,EAAE,QAAQ;KACrD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAuB,CAAC;IACjD,UAAU,EAAE,kBAAkB;CAC/B,CAAC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {createClassMapDirective} from '../shared/directives.js';\nimport {type ClassInfo} from 'lit/directives/class-map.js';\n\n/** Split Button color configuration types. */\nexport type SplitButtonColor = 'filled' | 'elevated' | 'tonal' | 'outlined';\n\n/** Split Button size configuration types. */\nexport type SplitButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/** Split Button classes. */\nexport const SPLIT_BUTTON_CLASSES = {\n splitButton: 'split-btn',\n splitButtonSelected: 'split-btn-selected',\n} as const;\n\n/** The state provided to the `splitButtonClasses()` function. */\nexport interface SplitButtonClassesState {\n /** Whether the split trailing button is selected. */\n selected?: boolean;\n}\n\n/**\n * Returns the split button classes to apply to an element based on the given\n * state.\n *\n * @param state The state of the split button.\n * @return An object of class names and truthy values if they apply.\n */\nexport function splitButtonClasses({\n selected = false,\n}: SplitButtonClassesState = {}): ClassInfo {\n return {\n [SPLIT_BUTTON_CLASSES.splitButton]: true,\n [SPLIT_BUTTON_CLASSES.splitButtonSelected]: selected,\n };\n}\n\n/**\n * A Lit directive that adds split button styling and functionality to its\n * element.\n *\n * @example\n * ```ts\n * html`\n * <div class=\"${splitButton()}\">\n * <button class=\"${button({color: 'filled'})}\">Label</button>\n * <button class=\"${button({color: 'filled'})}\" popovertarget=\"menu\"></button>\n * <md-menu id=\"menu\">\n * <md-menu-item>Option 1</md-menu-item>\n * <md-menu-item>Option 2</md-menu-item>\n * </md-menu>\n * </div>\n * `;\n * ```\n */\nexport const splitButton = createClassMapDirective({\n getClasses: splitButtonClasses,\n});\n"]}
|