@m3e/web 2.5.5 → 2.5.7
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/README.md +1 -1
- package/dist/all.js +511 -248
- package/dist/all.js.map +1 -1
- package/dist/all.min.js +31 -31
- package/dist/all.min.js.map +1 -1
- package/dist/autocomplete.js +3 -3
- package/dist/autocomplete.js.map +1 -1
- package/dist/autocomplete.min.js.map +1 -1
- package/dist/bottom-sheet.js +5 -5
- package/dist/bottom-sheet.js.map +1 -1
- package/dist/bottom-sheet.min.js.map +1 -1
- package/dist/breadcrumb.js +1 -1
- package/dist/breadcrumb.js.map +1 -1
- package/dist/breadcrumb.min.js.map +1 -1
- package/dist/button.js +7 -8
- package/dist/button.js.map +1 -1
- package/dist/button.min.js +1 -1
- package/dist/button.min.js.map +1 -1
- package/dist/calendar.js +1 -1
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.min.js.map +1 -1
- package/dist/card.js +1 -1
- package/dist/card.js.map +1 -1
- package/dist/card.min.js.map +1 -1
- package/dist/checkbox.js +10 -9
- package/dist/checkbox.js.map +1 -1
- package/dist/checkbox.min.js +1 -1
- package/dist/checkbox.min.js.map +1 -1
- package/dist/chips.js +17 -16
- package/dist/chips.js.map +1 -1
- package/dist/chips.min.js +1 -1
- package/dist/chips.min.js.map +1 -1
- package/dist/core.js +5 -5
- package/dist/core.js.map +1 -1
- package/dist/core.min.js.map +1 -1
- package/dist/css-custom-data.json +314 -314
- package/dist/custom-elements.json +5222 -4838
- package/dist/datepicker.js +26 -2
- package/dist/datepicker.js.map +1 -1
- package/dist/datepicker.min.js +1 -1
- package/dist/datepicker.min.js.map +1 -1
- package/dist/dialog.js +5 -5
- package/dist/dialog.js.map +1 -1
- package/dist/dialog.min.js.map +1 -1
- package/dist/drawer-container.js +1 -1
- package/dist/drawer-container.js.map +1 -1
- package/dist/drawer-container.min.js.map +1 -1
- package/dist/expansion-panel.js +5 -5
- package/dist/expansion-panel.js.map +1 -1
- package/dist/expansion-panel.min.js.map +1 -1
- package/dist/fab-menu.js +1 -1
- package/dist/fab-menu.js.map +1 -1
- package/dist/fab-menu.min.js.map +1 -1
- package/dist/fab.js +1 -1
- package/dist/fab.js.map +1 -1
- package/dist/fab.min.js.map +1 -1
- package/dist/html-custom-data.json +296 -291
- package/dist/icon-button.js +7 -8
- package/dist/icon-button.js.map +1 -1
- package/dist/icon-button.min.js +1 -1
- package/dist/icon-button.min.js.map +1 -1
- package/dist/list.js +17 -16
- package/dist/list.js.map +1 -1
- package/dist/list.min.js +1 -1
- package/dist/list.min.js.map +1 -1
- package/dist/menu.js +3 -3
- package/dist/menu.js.map +1 -1
- package/dist/menu.min.js.map +1 -1
- package/dist/nav-bar.js +12 -9
- package/dist/nav-bar.js.map +1 -1
- package/dist/nav-bar.min.js +1 -1
- package/dist/nav-bar.min.js.map +1 -1
- package/dist/nav-menu.js +5 -5
- package/dist/nav-menu.js.map +1 -1
- package/dist/nav-menu.min.js.map +1 -1
- package/dist/nav-rail.js +3 -1
- package/dist/nav-rail.js.map +1 -1
- package/dist/nav-rail.min.js.map +1 -1
- package/dist/paginator.js +1 -1
- package/dist/paginator.js.map +1 -1
- package/dist/paginator.min.js.map +1 -1
- package/dist/radio-group.js +12 -9
- package/dist/radio-group.js.map +1 -1
- package/dist/radio-group.min.js +1 -1
- package/dist/radio-group.min.js.map +1 -1
- package/dist/segmented-button.js +12 -11
- package/dist/segmented-button.js.map +1 -1
- package/dist/segmented-button.min.js +1 -1
- package/dist/segmented-button.min.js.map +1 -1
- package/dist/select.js +9 -9
- package/dist/select.js.map +1 -1
- package/dist/select.min.js +1 -1
- package/dist/select.min.js.map +1 -1
- package/dist/slide-group.js +6 -1
- package/dist/slide-group.js.map +1 -1
- package/dist/slide-group.min.js +1 -1
- package/dist/slide-group.min.js.map +1 -1
- package/dist/slider.js +46 -25
- package/dist/slider.js.map +1 -1
- package/dist/slider.min.js +1 -1
- package/dist/slider.min.js.map +1 -1
- package/dist/split-pane.js +17 -19
- package/dist/split-pane.js.map +1 -1
- package/dist/split-pane.min.js +1 -1
- package/dist/split-pane.min.js.map +1 -1
- package/dist/src/autocomplete/AutocompleteElement.d.ts +3 -3
- package/dist/src/autocomplete/AutocompleteQueryEventDetail.d.ts +1 -1
- package/dist/src/autocomplete/QueryEventDetail.d.ts +1 -1
- package/dist/src/bottom-sheet/BottomSheetElement.d.ts +5 -5
- package/dist/src/breadcrumb/BreadcrumbItemElement.d.ts +1 -1
- package/dist/src/button/ButtonElement.d.ts +2 -1
- package/dist/src/button/ButtonElement.d.ts.map +1 -1
- package/dist/src/calendar/CalendarElement.d.ts +1 -1
- package/dist/src/card/CardElement.d.ts +1 -1
- package/dist/src/checkbox/CheckboxElement.d.ts +5 -4
- package/dist/src/checkbox/CheckboxElement.d.ts.map +1 -1
- package/dist/src/chips/AssistChipElement.d.ts +1 -1
- package/dist/src/chips/FilterChipElement.d.ts +4 -3
- package/dist/src/chips/FilterChipElement.d.ts.map +1 -1
- package/dist/src/chips/FilterChipSetElement.d.ts +3 -2
- package/dist/src/chips/FilterChipSetElement.d.ts.map +1 -1
- package/dist/src/chips/InputChipElement.d.ts +2 -2
- package/dist/src/chips/InputChipSetElement.d.ts +1 -1
- package/dist/src/chips/SuggestionChipElement.d.ts +1 -1
- package/dist/src/core/shared/primitives/CollapsibleElement.d.ts +4 -4
- package/dist/src/core/shared/primitives/TextHighlightElement.d.ts +1 -1
- package/dist/src/datepicker/DatepickerElement.d.ts +6 -0
- package/dist/src/datepicker/DatepickerElement.d.ts.map +1 -1
- package/dist/src/dialog/DialogElement.d.ts +5 -5
- package/dist/src/drawer-container/DrawerContainerElement.d.ts +1 -1
- package/dist/src/expansion-panel/ExpansionHeaderElement.d.ts +1 -1
- package/dist/src/expansion-panel/ExpansionPanelElement.d.ts +4 -4
- package/dist/src/fab/FabElement.d.ts +1 -1
- package/dist/src/fab-menu/FabMenuItemElement.d.ts +1 -1
- package/dist/src/icon-button/IconButtonElement.d.ts +2 -1
- package/dist/src/icon-button/IconButtonElement.d.ts.map +1 -1
- package/dist/src/list/ExpandableListItemElement.d.ts +4 -4
- package/dist/src/list/ListActionElement.d.ts +1 -1
- package/dist/src/list/ListOptionElement.d.ts +4 -3
- package/dist/src/list/ListOptionElement.d.ts.map +1 -1
- package/dist/src/list/SelectionListElement.d.ts +3 -2
- package/dist/src/list/SelectionListElement.d.ts.map +1 -1
- package/dist/src/menu/MenuItemCheckboxElement.d.ts +1 -1
- package/dist/src/menu/MenuItemElement.d.ts +1 -1
- package/dist/src/menu/MenuItemRadioElement.d.ts +1 -1
- package/dist/src/nav-bar/NavBarElement.d.ts +3 -1
- package/dist/src/nav-bar/NavBarElement.d.ts.map +1 -1
- package/dist/src/nav-bar/NavItemElement.d.ts +4 -3
- package/dist/src/nav-bar/NavItemElement.d.ts.map +1 -1
- package/dist/src/nav-menu/NavMenuItemElement.d.ts +5 -5
- package/dist/src/nav-rail/NavRailElement.d.ts +3 -1
- package/dist/src/nav-rail/NavRailElement.d.ts.map +1 -1
- package/dist/src/paginator/PageEventDetail.d.ts +1 -1
- package/dist/src/paginator/PaginatorElement.d.ts +1 -1
- package/dist/src/paginator/PaginatorPageEventDetail.d.ts +1 -1
- package/dist/src/paginator/PaginatorPageEventDetail.d.ts.map +1 -1
- package/dist/src/radio-group/RadioElement.d.ts +4 -3
- package/dist/src/radio-group/RadioElement.d.ts.map +1 -1
- package/dist/src/radio-group/RadioGroupElement.d.ts +3 -1
- package/dist/src/radio-group/RadioGroupElement.d.ts.map +1 -1
- package/dist/src/search/SearchViewQueryEventDetail.d.ts +1 -1
- package/dist/src/segmented-button/ButtonSegmentElement.d.ts +4 -3
- package/dist/src/segmented-button/ButtonSegmentElement.d.ts.map +1 -1
- package/dist/src/segmented-button/SegmentedButtonElement.d.ts +3 -2
- package/dist/src/segmented-button/SegmentedButtonElement.d.ts.map +1 -1
- package/dist/src/select/SelectElement.d.ts +3 -2
- package/dist/src/select/SelectElement.d.ts.map +1 -1
- package/dist/src/slide-group/SlideGroupElement.d.ts.map +1 -1
- package/dist/src/slider/SliderElement.d.ts +4 -0
- package/dist/src/slider/SliderElement.d.ts.map +1 -1
- package/dist/src/slider/SliderThumbElement.d.ts +4 -3
- package/dist/src/slider/SliderThumbElement.d.ts.map +1 -1
- package/dist/src/split-pane/SplitPaneElement.d.ts +3 -2
- package/dist/src/split-pane/SplitPaneElement.d.ts.map +1 -1
- package/dist/src/stepper/StepElement.d.ts +4 -3
- package/dist/src/stepper/StepElement.d.ts.map +1 -1
- package/dist/src/stepper/StepperElement.d.ts +5 -1
- package/dist/src/stepper/StepperElement.d.ts.map +1 -1
- package/dist/src/switch/SwitchElement.d.ts +4 -3
- package/dist/src/switch/SwitchElement.d.ts.map +1 -1
- package/dist/src/tabs/TabElement.d.ts +4 -3
- package/dist/src/tabs/TabElement.d.ts.map +1 -1
- package/dist/src/tabs/TabsElement.d.ts +5 -2
- package/dist/src/tabs/TabsElement.d.ts.map +1 -1
- package/dist/src/theme/ThemeElement.d.ts.map +1 -1
- package/dist/src/toc/TocItemElement.d.ts +1 -1
- package/dist/src/tree/TreeElement.d.ts +1 -1
- package/dist/src/tree/TreeItemElement.d.ts +5 -5
- package/dist/stepper.js +26 -17
- package/dist/stepper.js.map +1 -1
- package/dist/stepper.min.js +1 -1
- package/dist/stepper.min.js.map +1 -1
- package/dist/switch.js +9 -8
- package/dist/switch.js.map +1 -1
- package/dist/switch.min.js +1 -1
- package/dist/switch.min.js.map +1 -1
- package/dist/tabs.js +198 -24
- package/dist/tabs.js.map +1 -1
- package/dist/tabs.min.js +1 -1
- package/dist/tabs.min.js.map +1 -1
- package/dist/theme.js +34 -13
- package/dist/theme.js.map +1 -1
- package/dist/theme.min.js +23 -23
- package/dist/theme.min.js.map +1 -1
- package/dist/toc.js +1 -1
- package/dist/toc.js.map +1 -1
- package/dist/toc.min.js.map +1 -1
- package/dist/tree.js +6 -6
- package/dist/tree.js.map +1 -1
- package/dist/tree.min.js.map +1 -1
- package/package.json +1 -1
package/dist/select.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.min.js","sources":["../../src/select/SelectElement.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */\r\nimport { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query } from \"lit/decorators.js\";\r\n\r\nimport {\r\n AttachInternals,\r\n Labelled,\r\n ConstraintValidation,\r\n Dirty,\r\n Disabled,\r\n FormAssociated,\r\n Required,\r\n RequiredConstraintValidation,\r\n Touched,\r\n DesignToken,\r\n formValue,\r\n M3eFocusRingElement,\r\n scrollIntoViewIfNeeded,\r\n Role,\r\n Focusable,\r\n prefersReducedMotion,\r\n forcedColorsActive,\r\n deleteCustomState,\r\n addCustomState,\r\n setCustomState,\r\n customElement,\r\n MutationController,\r\n} from \"@m3e/web/core\";\r\n\r\nimport { ListKeyManager } from \"@m3e/web/core/a11y\";\r\n\r\nimport type { M3eFormFieldElement, FormFieldControl } from \"@m3e/web/form-field\";\r\nimport { M3eOptionElement, M3eOptionPanelElement } from \"@m3e/web/option\";\r\n\r\n/**\r\n * A form control that allows users to select a value from a set of predefined options.\r\n *\r\n * @description\r\n * The `m3e-select` component follows Material Design 3 principles and provides a comprehensive\r\n * selection interface for capturing user input. It supports both single and multiple selection modes,\r\n * customizable validation states, and accessible keyboard navigation. The component integrates seamlessly\r\n * with form field containers and dynamically positions its option list menu to ensure optimal viewport\r\n * visibility. Selection changes are communicated through standard form events, enabling predictable integration\r\n * with form submission and reactive state management systems.\r\n *\r\n * @example\r\n * The following demonstrates a `m3e-select` component wrapped in a `m3e-form-field` with a slotted label.\r\n * The label is associated with the select via the `for` and `id` attributes, ensuring accessible form semantics.\r\n * Each `m3e-option` defines an option within the dropdown.\r\n *\r\n * ```html\r\n * <m3e-form-field>\r\n * <label slot=\"label\" for=\"select\">Choose your favorite fruit</label>\r\n * <m3e-select id=\"select\">\r\n * <m3e-option>Apples</m3e-option>\r\n * <m3e-option>Oranges</m3e-option>\r\n * <m3e-option>Bananas</m3e-option>\r\n * <m3e-option>Grapes</m3e-option>\r\n * </m3e-select>\r\n * </m3e-form-field>\r\n * ```\r\n *\r\n * @tag m3e-select\r\n *\r\n * @slot - Renders the options of the select.\r\n * @slot arrow - Renders the dropdown arrow.\r\n * @slot value - Renders the selected value(s).\r\n *\r\n * @attr disabled - Whether the element is disabled.\r\n * @attr hide-selection-indicator - Whether to hide the selection indicator for single select options.\r\n * @attr multi - Whether multiple options can be selected.\r\n * @attr name - The name that identifies the element when submitting the associated form.\r\n * @attr panel-class - Class or list of classes to be applied to the select's overlay panel.\r\n * @attr required - Whether the element is required.\r\n *\r\n * @fires input - Emitted when the selected state changes.\r\n * @fires change - Emitted when the selected state changes.\r\n *\r\n * @cssprop --m3e-form-field-font-size - The font size of the select control.\r\n * @cssprop --m3e-form-field-font-weight - The font weight of the select control.\r\n * @cssprop --m3e-form-field-line-height - The line height of the select control.\r\n * @cssprop --m3e-form-field-tracking - The letter spacing of the select control.\r\n * @cssprop --m3e-select-container-shape - The corner radius of the select container.\r\n * @cssprop --m3e-select-disabled-color - The text color when the select is disabled.\r\n * @cssprop --m3e-select-disabled-color-opacity - The opacity level applied to the disabled text color.\r\n * @cssprop --m3e-select-icon-size - The size of the dropdown arrow icon.\r\n */\r\n@customElement(\"m3e-select\")\r\nexport class M3eSelectElement\r\n extends Focusable(\r\n Labelled(\r\n RequiredConstraintValidation(\r\n Dirty(\r\n Touched(\r\n Required(ConstraintValidation(FormAssociated(Disabled(AttachInternals(Role(LitElement, \"combobox\")))))),\r\n ),\r\n ),\r\n ),\r\n ),\r\n )\r\n implements FormFieldControl\r\n{\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: inline-flex;\r\n vertical-align: middle;\r\n outline: none;\r\n position: relative;\r\n font-size: var(--m3e-form-field-font-size, ${DesignToken.typescale.standard.body.large.fontSize});\r\n font-weight: var(--m3e-form-field-font-weight, ${DesignToken.typescale.standard.body.large.fontWeight});\r\n line-height: var(--m3e-form-field-line-height, ${DesignToken.typescale.standard.body.large.lineHeight});\r\n letter-spacing: var(--m3e-form-field-tracking, ${DesignToken.typescale.standard.body.large.tracking});\r\n min-height: var(--m3e-form-field-line-height, ${DesignToken.typescale.standard.body.large.lineHeight});\r\n border-radius: var(--m3e-select-container-shape, ${DesignToken.shape.corner.extraSmall});\r\n }\r\n :host(:not(:disabled)) {\r\n cursor: pointer;\r\n }\r\n :host(:disabled) {\r\n color: color-mix(\r\n in srgb,\r\n var(--m3e-select-disabled-color, ${DesignToken.color.onSurface}) var(--m3e-select-disabled-color-opacity, 38%),\r\n transparent\r\n );\r\n }\r\n .options {\r\n display: none;\r\n }\r\n .base {\r\n flex: 1 1 auto;\r\n display: inline-flex;\r\n align-items: center;\r\n overflow: hidden;\r\n }\r\n .arrow-wrapper {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin-top: var(--_select-arrow-margin-top);\r\n }\r\n ::slotted([slot=\"arrow\"]),\r\n .arrow {\r\n vertical-align: middle;\r\n width: 1em;\r\n height: 1em;\r\n font-size: var(--m3e-select-icon-size, 1.5rem);\r\n }\r\n :host(:is(:state(--open), :--open)) .focus-ring {\r\n display: none;\r\n }\r\n `;\r\n\r\n /** @private */ static __nextId = 0;\r\n\r\n /** @private */ private _options = new Array<M3eOptionElement>();\r\n /** @private */ #clone?: HTMLElement;\r\n\r\n /** @private */ #menu?: M3eOptionPanelElement;\r\n /** @private */ #ignoreKeyUp = false;\r\n /** @private */ #ignoreFocusVisible = false;\r\n\r\n /** @private */ readonly #id = `m3e-select-${M3eSelectElement.__nextId++}`;\r\n /** @private */ readonly #listId = `${this.#id}-list`;\r\n\r\n /** @private */ readonly #clickHandler = (e: Event) => this.#handleClick(e);\r\n /** @private */ readonly #keyDownHandler = (e: KeyboardEvent) => this.#handleKeyDown(e);\r\n /** @private */ readonly #keyUpHandler = (e: KeyboardEvent) => this.#handleKeyUp(e);\r\n /** @private */ readonly #menuToggleHandler = (e: ToggleEvent) => this.#handleMenuToggle(e);\r\n /** @private */ readonly #menuPointerDownHandler = (e: PointerEvent) => this.#handleMenuPointerDown(e);\r\n /** @private */ readonly #menuPointerUpHandler = (e: PointerEvent) => this.#handleMenuPointerUp(e);\r\n /** @private */ #menuPressedOption?: M3eOptionElement;\r\n\r\n /** @private */ private readonly _listKeyManager = new ListKeyManager<M3eOptionElement>()\r\n .withWrap()\r\n .withHomeAndEnd()\r\n .withPageUpAndDown()\r\n .withVerticalOrientation()\r\n .withTypeahead()\r\n .onActiveItemChange(() => {\r\n if (this._listKeyManager.activeItem) {\r\n this.#activateOption(this._listKeyManager.activeItem);\r\n }\r\n });\r\n\r\n /** @private */ @query(\".focus-ring\") private readonly _focusRing?: M3eFocusRingElement;\r\n\r\n constructor() {\r\n super();\r\n\r\n new MutationController(this, {\r\n config: {\r\n childList: true,\r\n subtree: true,\r\n },\r\n callback: () => this.#handleMutation(),\r\n });\r\n }\r\n\r\n /**\r\n * Whether to hide the selection indicator for single select options.\r\n * @default false\r\n */\r\n @property({ attribute: \"hide-selection-indicator\", type: Boolean }) hideSelectionIndicator = false;\r\n\r\n /**\r\n * Whether multiple options can be selected.\r\n * @default false\r\n */\r\n @property({ type: Boolean }) multi = false;\r\n\r\n /**\r\n * Class or list of classes to be applied to the select's overlay panel.\r\n * @default \"\"\r\n */\r\n @property({ attribute: \"panel-class\" }) panelClass = \"\";\r\n\r\n get #options(): readonly M3eOptionElement[] {\r\n return this._listKeyManager?.items ?? [];\r\n }\r\n\r\n get #selected(): readonly M3eOptionElement[] {\r\n return this.#options.filter((x) => x.selected);\r\n }\r\n\r\n /** The options that can be selected. */\r\n get options(): readonly M3eOptionElement[] {\r\n return this._options ?? [];\r\n }\r\n\r\n /** The selected option(s). */\r\n get selected(): readonly M3eOptionElement[] {\r\n return this.options.filter((x) => x.selected);\r\n }\r\n\r\n /** The selected (enabled) value(s). */\r\n get value(): string | readonly string[] | null {\r\n const values = this.selected.filter((x) => !x.disabled).map((x) => x.value);\r\n switch (values.length) {\r\n case 0:\r\n return null;\r\n case 1:\r\n return values[0];\r\n default:\r\n return values;\r\n }\r\n }\r\n\r\n /** @inheritdoc @internal */\r\n override get [formValue]() {\r\n const values = this.value;\r\n if (Array.isArray(values)) {\r\n const data = new FormData();\r\n for (const value of values) {\r\n data.append(this.name, value);\r\n }\r\n return data;\r\n }\r\n return <string | null>values;\r\n }\r\n\r\n /** @inheritdoc */\r\n get shouldLabelFloat(): boolean {\r\n return this.selected.filter((x) => !x.isEmpty).length > 0;\r\n }\r\n\r\n /** @private */\r\n get #formField(): M3eFormFieldElement | null {\r\n return this.closest(\"m3e-form-field\");\r\n }\r\n\r\n /** @inheritdoc */\r\n onContainerClick(): void {\r\n this.#ignoreFocusVisible = true;\r\n this.#toggleMenu();\r\n this.focus({ preventScroll: true });\r\n }\r\n\r\n /**\r\n * Clears the value of the element.\r\n * @param [restoreFocus=false] Whether to restore input focus.\r\n */\r\n clear(restoreFocus = false): void {\r\n const selected = this.#selected;\r\n const willChange = selected.length > 0;\r\n\r\n if (willChange) {\r\n selected.forEach((x) => {\r\n x.selected = false;\r\n this.#updateSelectionState(x);\r\n });\r\n this.requestUpdate();\r\n }\r\n\r\n this.#hideMenu();\r\n\r\n if (willChange) {\r\n this.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n\r\n if (restoreFocus) {\r\n this.focus();\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n\r\n this.ariaHasPopup = \"listbox\";\r\n this.ariaExpanded = \"false\";\r\n\r\n this.addEventListener(\"click\", this.#clickHandler);\r\n this.addEventListener(\"keydown\", this.#keyDownHandler);\r\n this.addEventListener(\"keyup\", this.#keyUpHandler);\r\n\r\n this.#handleMutation();\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n\r\n this.removeEventListener(\"click\", this.#clickHandler);\r\n this.removeEventListener(\"keydown\", this.#keyDownHandler);\r\n this.removeEventListener(\"keyup\", this.#keyUpHandler);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override update(changedProperties: PropertyValues<this>): void {\r\n super.update(changedProperties);\r\n\r\n if (changedProperties.has(\"hideSelectionIndicator\")) {\r\n this.#options.forEach((x) => setCustomState(x, \"--hide-selection-indicator\", this.hideSelectionIndicator));\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override firstUpdated(_changedProperties: PropertyValues<this>): void {\r\n super.firstUpdated(_changedProperties);\r\n\r\n this._focusRing?.attach(this);\r\n\r\n if (this.#formField && this._focusRing) {\r\n this._focusRing.style.display = \"none\";\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return html` <m3e-focus-ring class=\"focus-ring\"></m3e-focus-ring>\r\n <div class=\"base\">\r\n <m3e-text-overflow>\r\n <slot name=\"value\">\r\n ${this.selected\r\n .filter((x) => !x.isEmpty)\r\n .map((x, i) => (i > 0 ? html`<span>, </span>${x.label}` : x.label))}\r\n </slot>\r\n </m3e-text-overflow>\r\n <div class=\"arrow-wrapper\" aria-hidden=\"true\">\r\n <slot name=\"arrow\">\r\n <svg class=\"arrow\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M480-360 280-560h400L480-360Z\" />\r\n </svg>\r\n </slot>\r\n </div>\r\n </div>\r\n <div class=\"options\" aria-hidden=\"true\">\r\n <slot></slot>\r\n </div>`;\r\n }\r\n\r\n /** @private */\r\n #handleMutation(): void {\r\n this.#clone = <HTMLElement>this.cloneNode(true);\r\n\r\n const { added } = this._listKeyManager.setItems([...this.#clone.querySelectorAll(\"m3e-option\")]);\r\n added.forEach((x) => {\r\n x.id = x.id || `${this.#id}-option-${this._listKeyManager.items.indexOf(x)}`;\r\n setCustomState(x, \"--hide-selection-indicator\", this.hideSelectionIndicator);\r\n });\r\n\r\n this._options = [...this.querySelectorAll(\"m3e-option\")];\r\n\r\n this.#formField?.notifyControlStateChange();\r\n if (this.#menu) {\r\n this.#menu.replaceChildren(...this.#clone.childNodes);\r\n if (this._options.length == 0) {\r\n this.#hideMenu();\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleClick(e: Event): void {\r\n if (e.defaultPrevented || this.disabled) return;\r\n this.#toggleMenu();\r\n }\r\n\r\n /** @private */\r\n #handleKeyDown(e: KeyboardEvent): void {\r\n if (e.defaultPrevented) return;\r\n this.#ignoreFocusVisible = false;\r\n\r\n switch (e.key) {\r\n case \" \":\r\n case \"Enter\":\r\n e.preventDefault();\r\n if (!this.multi) {\r\n if (this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n if (this.#menu?.isOpen) {\r\n if (!prefersReducedMotion()) {\r\n setTimeout(() => this.#hideMenu(), 150);\r\n } else {\r\n this.#hideMenu();\r\n }\r\n } else {\r\n this.#showMenu();\r\n }\r\n } else if (!this.#menu) {\r\n this.#ignoreKeyUp = true;\r\n this.#toggleMenu();\r\n }\r\n\r\n break;\r\n\r\n case \"Escape\":\r\n case \"Tab\":\r\n this.#hideMenu();\r\n break;\r\n\r\n case \"Down\":\r\n case \"ArrowDown\":\r\n if (this.multi && !this.#menu) {\r\n this.#toggleMenu();\r\n } else {\r\n this._listKeyManager.onKeyDown(e);\r\n if (!this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n }\r\n break;\r\n\r\n default:\r\n this._listKeyManager.onKeyDown(e);\r\n if (!this.multi && !this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleKeyUp(e: KeyboardEvent): void {\r\n if (e.defaultPrevented) return;\r\n\r\n if (this.#ignoreKeyUp) {\r\n this.#ignoreKeyUp = false;\r\n return;\r\n }\r\n\r\n switch (e.key) {\r\n case \" \":\r\n case \"Enter\":\r\n if (!this.multi) return;\r\n e.preventDefault();\r\n if (this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleMenuPointerDown(e: PointerEvent): void {\r\n this.#menuPressedOption = undefined;\r\n\r\n if (e.button === 2) return;\r\n // Prevent click to avoid stealing focus.\r\n e.preventDefault();\r\n e.stopImmediatePropagation();\r\n\r\n const option = <M3eOptionElement | undefined>(\r\n e.composedPath().find((x) => x instanceof HTMLElement && x.tagName === \"M3E-OPTION\")\r\n );\r\n\r\n if (option && !option.disabled) {\r\n this.#menuPressedOption = option;\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleMenuPointerUp(e: PointerEvent): void {\r\n const pressedOption = this.#menuPressedOption;\r\n this.#menuPressedOption = undefined;\r\n\r\n if (e.button === 2) return;\r\n\r\n if (!pressedOption) return;\r\n\r\n const option = <M3eOptionElement | undefined>(\r\n e.composedPath().find((x) => x instanceof HTMLElement && x.tagName === \"M3E-OPTION\")\r\n );\r\n\r\n if (option === pressedOption) {\r\n this.#selectOption(option);\r\n this._listKeyManager.setActiveItem(option);\r\n if (this.multi) {\r\n this.requestUpdate();\r\n }\r\n }\r\n\r\n if (!this.multi) {\r\n if (!prefersReducedMotion()) {\r\n setTimeout(() => this.#hideMenu(), 150);\r\n } else {\r\n this.#hideMenu();\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleMenuToggle(e: ToggleEvent): void {\r\n if (!this.#menu) return;\r\n\r\n if (e.newState !== \"closed\") {\r\n const option = this.#selected.find((x) => !x.disabled) ?? this._listKeyManager.items.find((x) => !x.disabled);\r\n this._listKeyManager.setActiveItem(option);\r\n if (option) {\r\n scrollIntoViewIfNeeded(option, this.#menu, { block: \"nearest\", behavior: \"instant\" });\r\n }\r\n this.dispatchEvent(\r\n new ToggleEvent(\"toggle\", {\r\n oldState: e.oldState,\r\n newState: e.newState,\r\n }),\r\n );\r\n } else {\r\n if (prefersReducedMotion()) {\r\n this.#destroyMenu(e);\r\n } else {\r\n // NOTE: use transitionend is preferred but doesn't fire when used here.\r\n // This is a workaround until that is fixed.\r\n setTimeout(() => this.#destroyMenu(e), 100);\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #destroyMenu(e: ToggleEvent): void {\r\n if (!this.#menu) return;\r\n\r\n this.#clone?.replaceChildren(...this.#menu.childNodes);\r\n this.#menu.remove();\r\n this.#menu.removeEventListener(\"toggle\", this.#menuToggleHandler);\r\n this.#menu.removeEventListener(\"pointerdown\", this.#menuPointerDownHandler);\r\n this.#menu.removeEventListener(\"pointerup\", this.#menuPointerUpHandler);\r\n this.#menu = undefined;\r\n\r\n this.ariaExpanded = \"false\";\r\n this.removeAttribute(\"aria-controls\");\r\n this.removeAttribute(\"aria-owns\");\r\n this.removeAttribute(\"aria-activedescendant\");\r\n this.requestUpdate();\r\n\r\n deleteCustomState(this, \"--open\");\r\n this.#formField?.notifyControlStateChange();\r\n\r\n this.dispatchEvent(\r\n new ToggleEvent(\"toggle\", {\r\n oldState: e.oldState,\r\n newState: e.newState,\r\n }),\r\n );\r\n }\r\n\r\n /** @private */\r\n #toggleMenu(): void {\r\n if (this.disabled) return;\r\n if (this.#menu) {\r\n this.#hideMenu();\r\n } else {\r\n this.#showMenu();\r\n }\r\n }\r\n\r\n /** @private */\r\n #showMenu(): void {\r\n if (this.#menu || this._options.length == 0) return;\r\n\r\n this.#menu = document.createElement(\"m3e-option-panel\");\r\n if (this.multi) {\r\n this.#menu.ariaMultiSelectable = \"true\";\r\n }\r\n\r\n this.#menu.id = this.#listId;\r\n\r\n if (this.panelClass) {\r\n for (const klass of this.panelClass\r\n .split(/\\s+/)\r\n .map((d) => d.trim())\r\n .filter(Boolean)) {\r\n this.#menu.classList.add(klass);\r\n }\r\n }\r\n\r\n this.#menu.style.overflowX = \"hidden\";\r\n this.#menu.fitAnchorWidth = true;\r\n this.#menu.addEventListener(\"toggle\", this.#menuToggleHandler);\r\n this.#menu.addEventListener(\"pointerdown\", this.#menuPointerDownHandler);\r\n this.#menu.addEventListener(\"pointerup\", this.#menuPointerUpHandler);\r\n\r\n if (this.#clone) {\r\n this.#menu.replaceChildren(...this.#clone.childNodes);\r\n }\r\n\r\n (this.#formField ?? this).insertAdjacentElement(\"afterend\", this.#menu);\r\n\r\n this.ariaExpanded = \"true\";\r\n this.setAttribute(\"aria-controls\", this.#listId);\r\n this.setAttribute(\"aria-owns\", this.#listId);\r\n this.#formField?.notifyControlStateChange();\r\n\r\n setTimeout(() => {\r\n this.#menu?.show(this, this.#formField?.menuAnchor);\r\n addCustomState(this, \"--open\");\r\n });\r\n }\r\n\r\n /** @private */\r\n #hideMenu(): void {\r\n if (!this.#menu) return;\r\n\r\n this.#menu.hide();\r\n deleteCustomState(this, \"--open\");\r\n }\r\n\r\n /** @private */\r\n #activateOption(option: M3eOptionElement): void {\r\n this.setAttribute(\"aria-activedescendant\", option.id);\r\n if (this.#menu) {\r\n scrollIntoViewIfNeeded(option, this.#menu, { block: \"nearest\", behavior: \"instant\" });\r\n\r\n const focusVisible = !this.#ignoreFocusVisible && (this.matches(\":focus-visible\") || forcedColorsActive());\r\n\r\n this.#options.forEach((x) => {\r\n const active = x === option && focusVisible;\r\n if (active) {\r\n x.focusRing?.show();\r\n x.stateLayer?.show(\"focused\");\r\n } else {\r\n x.focusRing?.hide();\r\n x.stateLayer?.hide(\"focused\");\r\n }\r\n });\r\n }\r\n }\r\n\r\n /** @private */\r\n #updateSelectionState(clone: M3eOptionElement): void {\r\n const option = this._options[this._listKeyManager.items.indexOf(clone)];\r\n if (option) {\r\n option.selected = clone.selected;\r\n }\r\n }\r\n\r\n /** @private */\r\n #selectOption(option: M3eOptionElement): void {\r\n const selected = this.multi ? !option.selected : true;\r\n if (option.selected === selected) return;\r\n\r\n option.selected = selected;\r\n this.#updateSelectionState(option);\r\n\r\n if (this.dispatchEvent(new Event(\"input\", { bubbles: true, composed: true, cancelable: true }))) {\r\n if (!this.multi) {\r\n this.#selected\r\n .filter((x) => x !== option)\r\n .forEach((x) => {\r\n x.selected = false;\r\n this.#updateSelectionState(x);\r\n });\r\n }\r\n\r\n this.requestUpdate();\r\n this.#formField?.notifyControlStateChange();\r\n this.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n } else {\r\n option.selected = !selected;\r\n this.#updateSelectionState(option);\r\n }\r\n }\r\n}\r\n\r\ninterface M3eSelectElementEventMap extends HTMLElementEventMap {\r\n toggle: ToggleEvent;\r\n}\r\n\r\nexport interface M3eSelectElement {\r\n addEventListener<K extends keyof M3eSelectElementEventMap>(\r\n type: K,\r\n listener: (this: M3eSelectElement, ev: M3eSelectElementEventMap[K]) => void,\r\n options?: boolean | AddEventListenerOptions,\r\n ): void;\r\n\r\n addEventListener(\r\n type: string,\r\n listener: EventListenerOrEventListenerObject,\r\n options?: boolean | AddEventListenerOptions,\r\n ): void;\r\n\r\n removeEventListener<K extends keyof M3eSelectElementEventMap>(\r\n type: K,\r\n listener: (this: M3eSelectElement, ev: M3eSelectElementEventMap[K]) => void,\r\n options?: boolean | EventListenerOptions,\r\n ): void;\r\n\r\n removeEventListener(\r\n type: string,\r\n listener: EventListenerOrEventListenerObject,\r\n options?: boolean | EventListenerOptions,\r\n ): void;\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-select\": M3eSelectElement;\r\n }\r\n}\r\n"],"names":["M3eSelectElement","M3eSelectElement_1","Focusable","Labelled","RequiredConstraintValidation","Dirty","Touched","Required","ConstraintValidation","FormAssociated","Disabled","AttachInternals","Role","LitElement","constructor","super","this","_options","Array","_M3eSelectElement_clone","set","_M3eSelectElement_menu","_M3eSelectElement_ignoreKeyUp","_M3eSelectElement_ignoreFocusVisible","_M3eSelectElement_id","__nextId","_M3eSelectElement_listId","__classPrivateFieldGet","_M3eSelectElement_clickHandler","e","call","_M3eSelectElement_keyDownHandler","_M3eSelectElement_keyUpHandler","_M3eSelectElement_menuToggleHandler","_M3eSelectElement_menuPointerDownHandler","_M3eSelectElement_menuPointerUpHandler","_M3eSelectElement_menuPressedOption","_listKeyManager","ListKeyManager","withWrap","withHomeAndEnd","withPageUpAndDown","withVerticalOrientation","withTypeahead","onActiveItemChange","activeItem","_M3eSelectElement_instances","_M3eSelectElement_activateOption","hideSelectionIndicator","multi","panelClass","MutationController","config","childList","subtree","callback","_M3eSelectElement_handleMutation","options","selected","filter","x","value","values","disabled","map","length","WeakMap","WeakSet","_M3eSelectElement_options_get","items","_M3eSelectElement_selected_get","formValue","isArray","data","FormData","append","name","shouldLabelFloat","isEmpty","onContainerClick","__classPrivateFieldSet","_M3eSelectElement_toggleMenu","focus","preventScroll","clear","restoreFocus","willChange","forEach","_M3eSelectElement_updateSelectionState","requestUpdate","_M3eSelectElement_hideMenu","dispatchEvent","Event","bubbles","connectedCallback","ariaHasPopup","ariaExpanded","addEventListener","disconnectedCallback","removeEventListener","update","changedProperties","has","setCustomState","firstUpdated","_changedProperties","_focusRing","attach","_M3eSelectElement_formField_get","style","display","render","html","i","label","closest","cloneNode","added","setItems","querySelectorAll","id","indexOf","notifyControlStateChange","replaceChildren","childNodes","defaultPrevented","key","preventDefault","_M3eSelectElement_selectOption","isOpen","prefersReducedMotion","setTimeout","_M3eSelectElement_showMenu","onKeyDown","undefined","button","stopImmediatePropagation","option","composedPath","find","HTMLElement","tagName","pressedOption","setActiveItem","newState","scrollIntoViewIfNeeded","block","behavior","ToggleEvent","oldState","_M3eSelectElement_destroyMenu","remove","removeAttribute","deleteCustomState","document","createElement","ariaMultiSelectable","klass","split","d","trim","Boolean","classList","add","overflowX","fitAnchorWidth","insertAdjacentElement","setAttribute","show","menuAnchor","addCustomState","hide","focusVisible","matches","forcedColorsActive","focusRing","stateLayer","clone","composed","cancelable","styles","css","DesignToken","typescale","standard","body","large","fontSize","fontWeight","lineHeight","tracking","shape","corner","extraSmall","color","onSurface","__decorate","query","prototype","property","attribute","type","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select.min.js","sources":["../../src/select/SelectElement.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */\r\nimport { css, CSSResultGroup, html, LitElement, PropertyValues } from \"lit\";\r\nimport { property, query } from \"lit/decorators.js\";\r\n\r\nimport {\r\n AttachInternals,\r\n Labelled,\r\n ConstraintValidation,\r\n Dirty,\r\n Disabled,\r\n FormAssociated,\r\n Required,\r\n RequiredConstraintValidation,\r\n Touched,\r\n DesignToken,\r\n formValue,\r\n M3eFocusRingElement,\r\n scrollIntoViewIfNeeded,\r\n Role,\r\n Focusable,\r\n prefersReducedMotion,\r\n forcedColorsActive,\r\n deleteCustomState,\r\n addCustomState,\r\n setCustomState,\r\n customElement,\r\n MutationController,\r\n} from \"@m3e/web/core\";\r\n\r\nimport { ListKeyManager } from \"@m3e/web/core/a11y\";\r\n\r\nimport type { M3eFormFieldElement, FormFieldControl } from \"@m3e/web/form-field\";\r\nimport { M3eOptionElement, M3eOptionPanelElement } from \"@m3e/web/option\";\r\n\r\n/**\r\n * A form control that allows users to select a value from a set of predefined options.\r\n *\r\n * @description\r\n * The `m3e-select` component follows Material Design 3 principles and provides a comprehensive\r\n * selection interface for capturing user input. It supports both single and multiple selection modes,\r\n * customizable validation states, and accessible keyboard navigation. The component integrates seamlessly\r\n * with form field containers and dynamically positions its option list menu to ensure optimal viewport\r\n * visibility. Selection changes are communicated through standard form events, enabling predictable integration\r\n * with form submission and reactive state management systems.\r\n *\r\n * @example\r\n * The following demonstrates a `m3e-select` component wrapped in a `m3e-form-field` with a slotted label.\r\n * The label is associated with the select via the `for` and `id` attributes, ensuring accessible form semantics.\r\n * Each `m3e-option` defines an option within the dropdown.\r\n *\r\n * ```html\r\n * <m3e-form-field>\r\n * <label slot=\"label\" for=\"select\">Choose your favorite fruit</label>\r\n * <m3e-select id=\"select\">\r\n * <m3e-option>Apples</m3e-option>\r\n * <m3e-option>Oranges</m3e-option>\r\n * <m3e-option>Bananas</m3e-option>\r\n * <m3e-option>Grapes</m3e-option>\r\n * </m3e-select>\r\n * </m3e-form-field>\r\n * ```\r\n *\r\n * @tag m3e-select\r\n *\r\n * @slot - Renders the options of the select.\r\n * @slot arrow - Renders the dropdown arrow.\r\n * @slot value - Renders the selected value(s).\r\n *\r\n * @attr disabled - Whether the element is disabled.\r\n * @attr hide-selection-indicator - Whether to hide the selection indicator for single select options.\r\n * @attr multi - Whether multiple options can be selected.\r\n * @attr name - The name that identifies the element when submitting the associated form.\r\n * @attr panel-class - Class or list of classes to be applied to the select's overlay panel.\r\n * @attr required - Whether the element is required.\r\n *\r\n * @fires beforeinput - Dispatched before the selected state changes.\r\n * @fires input - Dispatched when the selected state changes.\r\n * @fires change - Dispatched when the selected state changes.\r\n *\r\n * @cssprop --m3e-form-field-font-size - The font size of the select control.\r\n * @cssprop --m3e-form-field-font-weight - The font weight of the select control.\r\n * @cssprop --m3e-form-field-line-height - The line height of the select control.\r\n * @cssprop --m3e-form-field-tracking - The letter spacing of the select control.\r\n * @cssprop --m3e-select-container-shape - The corner radius of the select container.\r\n * @cssprop --m3e-select-disabled-color - The text color when the select is disabled.\r\n * @cssprop --m3e-select-disabled-color-opacity - The opacity level applied to the disabled text color.\r\n * @cssprop --m3e-select-icon-size - The size of the dropdown arrow icon.\r\n */\r\n@customElement(\"m3e-select\")\r\nexport class M3eSelectElement\r\n extends Focusable(\r\n Labelled(\r\n RequiredConstraintValidation(\r\n Dirty(\r\n Touched(\r\n Required(ConstraintValidation(FormAssociated(Disabled(AttachInternals(Role(LitElement, \"combobox\")))))),\r\n ),\r\n ),\r\n ),\r\n ),\r\n )\r\n implements FormFieldControl\r\n{\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: inline-flex;\r\n vertical-align: middle;\r\n outline: none;\r\n position: relative;\r\n font-size: var(--m3e-form-field-font-size, ${DesignToken.typescale.standard.body.large.fontSize});\r\n font-weight: var(--m3e-form-field-font-weight, ${DesignToken.typescale.standard.body.large.fontWeight});\r\n line-height: var(--m3e-form-field-line-height, ${DesignToken.typescale.standard.body.large.lineHeight});\r\n letter-spacing: var(--m3e-form-field-tracking, ${DesignToken.typescale.standard.body.large.tracking});\r\n min-height: var(--m3e-form-field-line-height, ${DesignToken.typescale.standard.body.large.lineHeight});\r\n border-radius: var(--m3e-select-container-shape, ${DesignToken.shape.corner.extraSmall});\r\n }\r\n :host(:not(:disabled)) {\r\n cursor: pointer;\r\n }\r\n :host(:disabled) {\r\n color: color-mix(\r\n in srgb,\r\n var(--m3e-select-disabled-color, ${DesignToken.color.onSurface}) var(--m3e-select-disabled-color-opacity, 38%),\r\n transparent\r\n );\r\n }\r\n .options {\r\n display: none;\r\n }\r\n .base {\r\n flex: 1 1 auto;\r\n display: inline-flex;\r\n align-items: center;\r\n overflow: hidden;\r\n }\r\n .arrow-wrapper {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin-top: var(--_select-arrow-margin-top);\r\n }\r\n ::slotted([slot=\"arrow\"]),\r\n .arrow {\r\n vertical-align: middle;\r\n width: 1em;\r\n height: 1em;\r\n font-size: var(--m3e-select-icon-size, 1.5rem);\r\n }\r\n :host(:is(:state(--open), :--open)) .focus-ring {\r\n display: none;\r\n }\r\n `;\r\n\r\n /** @private */ static __nextId = 0;\r\n\r\n /** @private */ private _options = new Array<M3eOptionElement>();\r\n /** @private */ #clone?: HTMLElement;\r\n\r\n /** @private */ #menu?: M3eOptionPanelElement;\r\n /** @private */ #ignoreKeyUp = false;\r\n /** @private */ #ignoreFocusVisible = false;\r\n\r\n /** @private */ readonly #id = `m3e-select-${M3eSelectElement.__nextId++}`;\r\n /** @private */ readonly #listId = `${this.#id}-list`;\r\n\r\n /** @private */ readonly #clickHandler = (e: Event) => this.#handleClick(e);\r\n /** @private */ readonly #keyDownHandler = (e: KeyboardEvent) => this.#handleKeyDown(e);\r\n /** @private */ readonly #keyUpHandler = (e: KeyboardEvent) => this.#handleKeyUp(e);\r\n /** @private */ readonly #menuToggleHandler = (e: ToggleEvent) => this.#handleMenuToggle(e);\r\n /** @private */ readonly #menuPointerDownHandler = (e: PointerEvent) => this.#handleMenuPointerDown(e);\r\n /** @private */ readonly #menuPointerUpHandler = (e: PointerEvent) => this.#handleMenuPointerUp(e);\r\n /** @private */ #menuPressedOption?: M3eOptionElement;\r\n\r\n /** @private */ private readonly _listKeyManager = new ListKeyManager<M3eOptionElement>()\r\n .withWrap()\r\n .withHomeAndEnd()\r\n .withPageUpAndDown()\r\n .withVerticalOrientation()\r\n .withTypeahead()\r\n .onActiveItemChange(() => {\r\n if (this._listKeyManager.activeItem) {\r\n this.#activateOption(this._listKeyManager.activeItem);\r\n }\r\n });\r\n\r\n /** @private */ @query(\".focus-ring\") private readonly _focusRing?: M3eFocusRingElement;\r\n\r\n constructor() {\r\n super();\r\n\r\n new MutationController(this, {\r\n config: {\r\n childList: true,\r\n subtree: true,\r\n },\r\n callback: () => this.#handleMutation(),\r\n });\r\n }\r\n\r\n /**\r\n * Whether to hide the selection indicator for single select options.\r\n * @default false\r\n */\r\n @property({ attribute: \"hide-selection-indicator\", type: Boolean }) hideSelectionIndicator = false;\r\n\r\n /**\r\n * Whether multiple options can be selected.\r\n * @default false\r\n */\r\n @property({ type: Boolean }) multi = false;\r\n\r\n /**\r\n * Class or list of classes to be applied to the select's overlay panel.\r\n * @default \"\"\r\n */\r\n @property({ attribute: \"panel-class\" }) panelClass = \"\";\r\n\r\n get #options(): readonly M3eOptionElement[] {\r\n return this._listKeyManager?.items ?? [];\r\n }\r\n\r\n get #selected(): readonly M3eOptionElement[] {\r\n return this.#options.filter((x) => x.selected);\r\n }\r\n\r\n /** The options that can be selected. */\r\n get options(): readonly M3eOptionElement[] {\r\n return this._options ?? [];\r\n }\r\n\r\n /** The selected option(s). */\r\n get selected(): readonly M3eOptionElement[] {\r\n return this.options.filter((x) => x.selected);\r\n }\r\n\r\n /** The selected (enabled) value(s). */\r\n get value(): string | readonly string[] | null {\r\n const values = this.selected.filter((x) => !x.disabled).map((x) => x.value);\r\n switch (values.length) {\r\n case 0:\r\n return null;\r\n case 1:\r\n return values[0];\r\n default:\r\n return values;\r\n }\r\n }\r\n\r\n /** @inheritdoc @internal */\r\n override get [formValue]() {\r\n const values = this.value;\r\n if (Array.isArray(values)) {\r\n const data = new FormData();\r\n for (const value of values) {\r\n data.append(this.name, value);\r\n }\r\n return data;\r\n }\r\n return <string | null>values;\r\n }\r\n\r\n /** @inheritdoc */\r\n get shouldLabelFloat(): boolean {\r\n return this.selected.filter((x) => !x.isEmpty).length > 0;\r\n }\r\n\r\n /** @private */\r\n get #formField(): M3eFormFieldElement | null {\r\n return this.closest(\"m3e-form-field\");\r\n }\r\n\r\n /** @inheritdoc */\r\n onContainerClick(): void {\r\n this.#ignoreFocusVisible = true;\r\n this.#toggleMenu();\r\n this.focus({ preventScroll: true });\r\n }\r\n\r\n /**\r\n * Clears the value of the element.\r\n * @param [restoreFocus=false] Whether to restore input focus.\r\n */\r\n clear(restoreFocus = false): void {\r\n const selected = this.#selected;\r\n const willChange = selected.length > 0;\r\n\r\n if (willChange) {\r\n selected.forEach((x) => {\r\n x.selected = false;\r\n this.#updateSelectionState(x);\r\n });\r\n this.requestUpdate();\r\n }\r\n\r\n this.#hideMenu();\r\n\r\n if (willChange) {\r\n this.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n\r\n if (restoreFocus) {\r\n this.focus();\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n\r\n this.ariaHasPopup = \"listbox\";\r\n this.ariaExpanded = \"false\";\r\n\r\n this.addEventListener(\"click\", this.#clickHandler);\r\n this.addEventListener(\"keydown\", this.#keyDownHandler);\r\n this.addEventListener(\"keyup\", this.#keyUpHandler);\r\n\r\n this.#handleMutation();\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n\r\n this.removeEventListener(\"click\", this.#clickHandler);\r\n this.removeEventListener(\"keydown\", this.#keyDownHandler);\r\n this.removeEventListener(\"keyup\", this.#keyUpHandler);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override update(changedProperties: PropertyValues<this>): void {\r\n super.update(changedProperties);\r\n\r\n if (changedProperties.has(\"hideSelectionIndicator\")) {\r\n this.#options.forEach((x) => setCustomState(x, \"--hide-selection-indicator\", this.hideSelectionIndicator));\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override firstUpdated(_changedProperties: PropertyValues<this>): void {\r\n super.firstUpdated(_changedProperties);\r\n\r\n this._focusRing?.attach(this);\r\n\r\n if (this.#formField && this._focusRing) {\r\n this._focusRing.style.display = \"none\";\r\n }\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n return html` <m3e-focus-ring class=\"focus-ring\"></m3e-focus-ring>\r\n <div class=\"base\">\r\n <m3e-text-overflow>\r\n <slot name=\"value\">\r\n ${this.selected\r\n .filter((x) => !x.isEmpty)\r\n .map((x, i) => (i > 0 ? html`<span>, </span>${x.label}` : x.label))}\r\n </slot>\r\n </m3e-text-overflow>\r\n <div class=\"arrow-wrapper\" aria-hidden=\"true\">\r\n <slot name=\"arrow\">\r\n <svg class=\"arrow\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M480-360 280-560h400L480-360Z\" />\r\n </svg>\r\n </slot>\r\n </div>\r\n </div>\r\n <div class=\"options\" aria-hidden=\"true\">\r\n <slot></slot>\r\n </div>`;\r\n }\r\n\r\n /** @private */\r\n #handleMutation(): void {\r\n this.#clone = <HTMLElement>this.cloneNode(true);\r\n\r\n const { added } = this._listKeyManager.setItems([...this.#clone.querySelectorAll(\"m3e-option\")]);\r\n added.forEach((x) => {\r\n x.id = x.id || `${this.#id}-option-${this._listKeyManager.items.indexOf(x)}`;\r\n setCustomState(x, \"--hide-selection-indicator\", this.hideSelectionIndicator);\r\n });\r\n\r\n this._options = [...this.querySelectorAll(\"m3e-option\")];\r\n\r\n this.#formField?.notifyControlStateChange();\r\n if (this.#menu) {\r\n this.#menu.replaceChildren(...this.#clone.childNodes);\r\n if (this._options.length == 0) {\r\n this.#hideMenu();\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleClick(e: Event): void {\r\n if (e.defaultPrevented || this.disabled) return;\r\n this.#toggleMenu();\r\n }\r\n\r\n /** @private */\r\n #handleKeyDown(e: KeyboardEvent): void {\r\n if (e.defaultPrevented) return;\r\n this.#ignoreFocusVisible = false;\r\n\r\n switch (e.key) {\r\n case \" \":\r\n case \"Enter\":\r\n e.preventDefault();\r\n if (!this.multi) {\r\n if (this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n if (this.#menu?.isOpen) {\r\n if (!prefersReducedMotion()) {\r\n setTimeout(() => this.#hideMenu(), 150);\r\n } else {\r\n this.#hideMenu();\r\n }\r\n } else {\r\n this.#showMenu();\r\n }\r\n } else if (!this.#menu) {\r\n this.#ignoreKeyUp = true;\r\n this.#toggleMenu();\r\n }\r\n\r\n break;\r\n\r\n case \"Escape\":\r\n case \"Tab\":\r\n this.#hideMenu();\r\n break;\r\n\r\n case \"Down\":\r\n case \"ArrowDown\":\r\n if (this.multi && !this.#menu) {\r\n this.#toggleMenu();\r\n } else {\r\n this._listKeyManager.onKeyDown(e);\r\n if (!this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n }\r\n break;\r\n\r\n default:\r\n this._listKeyManager.onKeyDown(e);\r\n if (!this.multi && !this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleKeyUp(e: KeyboardEvent): void {\r\n if (e.defaultPrevented) return;\r\n\r\n if (this.#ignoreKeyUp) {\r\n this.#ignoreKeyUp = false;\r\n return;\r\n }\r\n\r\n switch (e.key) {\r\n case \" \":\r\n case \"Enter\":\r\n if (!this.multi) return;\r\n e.preventDefault();\r\n if (this.#menu && this._listKeyManager.activeItem) {\r\n this.#selectOption(this._listKeyManager.activeItem);\r\n }\r\n break;\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleMenuPointerDown(e: PointerEvent): void {\r\n this.#menuPressedOption = undefined;\r\n\r\n if (e.button === 2) return;\r\n // Prevent click to avoid stealing focus.\r\n e.preventDefault();\r\n e.stopImmediatePropagation();\r\n\r\n const option = <M3eOptionElement | undefined>(\r\n e.composedPath().find((x) => x instanceof HTMLElement && x.tagName === \"M3E-OPTION\")\r\n );\r\n\r\n if (option && !option.disabled) {\r\n this.#menuPressedOption = option;\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleMenuPointerUp(e: PointerEvent): void {\r\n const pressedOption = this.#menuPressedOption;\r\n this.#menuPressedOption = undefined;\r\n\r\n if (e.button === 2) return;\r\n\r\n if (!pressedOption) return;\r\n\r\n const option = <M3eOptionElement | undefined>(\r\n e.composedPath().find((x) => x instanceof HTMLElement && x.tagName === \"M3E-OPTION\")\r\n );\r\n\r\n if (option === pressedOption) {\r\n this.#selectOption(option);\r\n this._listKeyManager.setActiveItem(option);\r\n if (this.multi) {\r\n this.requestUpdate();\r\n }\r\n }\r\n\r\n if (!this.multi) {\r\n if (!prefersReducedMotion()) {\r\n setTimeout(() => this.#hideMenu(), 150);\r\n } else {\r\n this.#hideMenu();\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #handleMenuToggle(e: ToggleEvent): void {\r\n if (!this.#menu) return;\r\n\r\n if (e.newState !== \"closed\") {\r\n const option = this.#selected.find((x) => !x.disabled) ?? this._listKeyManager.items.find((x) => !x.disabled);\r\n this._listKeyManager.setActiveItem(option);\r\n if (option) {\r\n scrollIntoViewIfNeeded(option, this.#menu, { block: \"nearest\", behavior: \"instant\" });\r\n }\r\n this.dispatchEvent(\r\n new ToggleEvent(\"toggle\", {\r\n oldState: e.oldState,\r\n newState: e.newState,\r\n }),\r\n );\r\n } else {\r\n if (prefersReducedMotion()) {\r\n this.#destroyMenu(e);\r\n } else {\r\n // NOTE: use transitionend is preferred but doesn't fire when used here.\r\n // This is a workaround until that is fixed.\r\n setTimeout(() => this.#destroyMenu(e), 100);\r\n }\r\n }\r\n }\r\n\r\n /** @private */\r\n #destroyMenu(e: ToggleEvent): void {\r\n if (!this.#menu) return;\r\n\r\n this.#clone?.replaceChildren(...this.#menu.childNodes);\r\n this.#menu.remove();\r\n this.#menu.removeEventListener(\"toggle\", this.#menuToggleHandler);\r\n this.#menu.removeEventListener(\"pointerdown\", this.#menuPointerDownHandler);\r\n this.#menu.removeEventListener(\"pointerup\", this.#menuPointerUpHandler);\r\n this.#menu = undefined;\r\n\r\n this.ariaExpanded = \"false\";\r\n this.removeAttribute(\"aria-controls\");\r\n this.removeAttribute(\"aria-owns\");\r\n this.removeAttribute(\"aria-activedescendant\");\r\n this.requestUpdate();\r\n\r\n deleteCustomState(this, \"--open\");\r\n this.#formField?.notifyControlStateChange();\r\n\r\n this.dispatchEvent(\r\n new ToggleEvent(\"toggle\", {\r\n oldState: e.oldState,\r\n newState: e.newState,\r\n }),\r\n );\r\n }\r\n\r\n /** @private */\r\n #toggleMenu(): void {\r\n if (this.disabled) return;\r\n if (this.#menu) {\r\n this.#hideMenu();\r\n } else {\r\n this.#showMenu();\r\n }\r\n }\r\n\r\n /** @private */\r\n #showMenu(): void {\r\n if (this.#menu || this._options.length == 0) return;\r\n\r\n this.#menu = document.createElement(\"m3e-option-panel\");\r\n if (this.multi) {\r\n this.#menu.ariaMultiSelectable = \"true\";\r\n }\r\n\r\n this.#menu.id = this.#listId;\r\n\r\n if (this.panelClass) {\r\n for (const klass of this.panelClass\r\n .split(/\\s+/)\r\n .map((d) => d.trim())\r\n .filter(Boolean)) {\r\n this.#menu.classList.add(klass);\r\n }\r\n }\r\n\r\n this.#menu.style.overflowX = \"hidden\";\r\n this.#menu.fitAnchorWidth = true;\r\n this.#menu.addEventListener(\"toggle\", this.#menuToggleHandler);\r\n this.#menu.addEventListener(\"pointerdown\", this.#menuPointerDownHandler);\r\n this.#menu.addEventListener(\"pointerup\", this.#menuPointerUpHandler);\r\n\r\n if (this.#clone) {\r\n this.#menu.replaceChildren(...this.#clone.childNodes);\r\n }\r\n\r\n (this.#formField ?? this).insertAdjacentElement(\"afterend\", this.#menu);\r\n\r\n this.ariaExpanded = \"true\";\r\n this.setAttribute(\"aria-controls\", this.#listId);\r\n this.setAttribute(\"aria-owns\", this.#listId);\r\n this.#formField?.notifyControlStateChange();\r\n\r\n setTimeout(() => {\r\n this.#menu?.show(this, this.#formField?.menuAnchor);\r\n addCustomState(this, \"--open\");\r\n });\r\n }\r\n\r\n /** @private */\r\n #hideMenu(): void {\r\n if (!this.#menu) return;\r\n\r\n this.#menu.hide();\r\n deleteCustomState(this, \"--open\");\r\n }\r\n\r\n /** @private */\r\n #activateOption(option: M3eOptionElement): void {\r\n this.setAttribute(\"aria-activedescendant\", option.id);\r\n if (this.#menu) {\r\n scrollIntoViewIfNeeded(option, this.#menu, { block: \"nearest\", behavior: \"instant\" });\r\n\r\n const focusVisible = !this.#ignoreFocusVisible && (this.matches(\":focus-visible\") || forcedColorsActive());\r\n\r\n this.#options.forEach((x) => {\r\n const active = x === option && focusVisible;\r\n if (active) {\r\n x.focusRing?.show();\r\n x.stateLayer?.show(\"focused\");\r\n } else {\r\n x.focusRing?.hide();\r\n x.stateLayer?.hide(\"focused\");\r\n }\r\n });\r\n }\r\n }\r\n\r\n /** @private */\r\n #updateSelectionState(clone: M3eOptionElement): void {\r\n const option = this._options[this._listKeyManager.items.indexOf(clone)];\r\n if (option) {\r\n option.selected = clone.selected;\r\n }\r\n }\r\n\r\n /** @private */\r\n #selectOption(option: M3eOptionElement): void {\r\n const selected = this.multi ? !option.selected : true;\r\n if (option.selected === selected) return;\r\n\r\n if (this.dispatchEvent(new Event(\"beforeinput\", { bubbles: true, cancelable: true }))) {\r\n option.selected = selected;\r\n this.#updateSelectionState(option);\r\n\r\n if (!this.multi) {\r\n this.#selected\r\n .filter((x) => x !== option)\r\n .forEach((x) => {\r\n x.selected = false;\r\n this.#updateSelectionState(x);\r\n });\r\n }\r\n\r\n this.requestUpdate();\r\n this.#formField?.notifyControlStateChange();\r\n\r\n this.dispatchEvent(new Event(\"input\", { bubbles: true }));\r\n this.dispatchEvent(new Event(\"change\", { bubbles: true }));\r\n }\r\n }\r\n}\r\n\r\ninterface M3eSelectElementEventMap extends HTMLElementEventMap {\r\n toggle: ToggleEvent;\r\n}\r\n\r\nexport interface M3eSelectElement {\r\n addEventListener<K extends keyof M3eSelectElementEventMap>(\r\n type: K,\r\n listener: (this: M3eSelectElement, ev: M3eSelectElementEventMap[K]) => void,\r\n options?: boolean | AddEventListenerOptions,\r\n ): void;\r\n\r\n addEventListener(\r\n type: string,\r\n listener: EventListenerOrEventListenerObject,\r\n options?: boolean | AddEventListenerOptions,\r\n ): void;\r\n\r\n removeEventListener<K extends keyof M3eSelectElementEventMap>(\r\n type: K,\r\n listener: (this: M3eSelectElement, ev: M3eSelectElementEventMap[K]) => void,\r\n options?: boolean | EventListenerOptions,\r\n ): void;\r\n\r\n removeEventListener(\r\n type: string,\r\n listener: EventListenerOrEventListenerObject,\r\n options?: boolean | EventListenerOptions,\r\n ): void;\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-select\": M3eSelectElement;\r\n }\r\n}\r\n"],"names":["M3eSelectElement","M3eSelectElement_1","Focusable","Labelled","RequiredConstraintValidation","Dirty","Touched","Required","ConstraintValidation","FormAssociated","Disabled","AttachInternals","Role","LitElement","constructor","super","this","_options","Array","_M3eSelectElement_clone","set","_M3eSelectElement_menu","_M3eSelectElement_ignoreKeyUp","_M3eSelectElement_ignoreFocusVisible","_M3eSelectElement_id","__nextId","_M3eSelectElement_listId","__classPrivateFieldGet","_M3eSelectElement_clickHandler","e","call","_M3eSelectElement_keyDownHandler","_M3eSelectElement_keyUpHandler","_M3eSelectElement_menuToggleHandler","_M3eSelectElement_menuPointerDownHandler","_M3eSelectElement_menuPointerUpHandler","_M3eSelectElement_menuPressedOption","_listKeyManager","ListKeyManager","withWrap","withHomeAndEnd","withPageUpAndDown","withVerticalOrientation","withTypeahead","onActiveItemChange","activeItem","_M3eSelectElement_instances","_M3eSelectElement_activateOption","hideSelectionIndicator","multi","panelClass","MutationController","config","childList","subtree","callback","_M3eSelectElement_handleMutation","options","selected","filter","x","value","values","disabled","map","length","WeakMap","WeakSet","_M3eSelectElement_options_get","items","_M3eSelectElement_selected_get","formValue","isArray","data","FormData","append","name","shouldLabelFloat","isEmpty","onContainerClick","__classPrivateFieldSet","_M3eSelectElement_toggleMenu","focus","preventScroll","clear","restoreFocus","willChange","forEach","_M3eSelectElement_updateSelectionState","requestUpdate","_M3eSelectElement_hideMenu","dispatchEvent","Event","bubbles","connectedCallback","ariaHasPopup","ariaExpanded","addEventListener","disconnectedCallback","removeEventListener","update","changedProperties","has","setCustomState","firstUpdated","_changedProperties","_focusRing","attach","_M3eSelectElement_formField_get","style","display","render","html","i","label","closest","cloneNode","added","setItems","querySelectorAll","id","indexOf","notifyControlStateChange","replaceChildren","childNodes","defaultPrevented","key","preventDefault","_M3eSelectElement_selectOption","isOpen","prefersReducedMotion","setTimeout","_M3eSelectElement_showMenu","onKeyDown","undefined","button","stopImmediatePropagation","option","composedPath","find","HTMLElement","tagName","pressedOption","setActiveItem","newState","scrollIntoViewIfNeeded","block","behavior","ToggleEvent","oldState","_M3eSelectElement_destroyMenu","remove","removeAttribute","deleteCustomState","document","createElement","ariaMultiSelectable","klass","split","d","trim","Boolean","classList","add","overflowX","fitAnchorWidth","insertAdjacentElement","setAttribute","show","menuAnchor","addCustomState","hide","focusVisible","matches","forcedColorsActive","focusRing","stateLayer","clone","cancelable","styles","css","DesignToken","typescale","standard","body","large","fontSize","fontWeight","lineHeight","tracking","shape","corner","extraSmall","color","onSurface","__decorate","query","prototype","property","attribute","type","customElement"],"mappings":"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"}
|
package/dist/slide-group.js
CHANGED
|
@@ -121,6 +121,7 @@ let M3eSlideGroupElement = class M3eSlideGroupElement extends ReconnectedCallbac
|
|
|
121
121
|
}
|
|
122
122
|
/** @private */
|
|
123
123
|
_updatePaging() {
|
|
124
|
+
const canPage = this._canPage;
|
|
124
125
|
if (this.disabled) {
|
|
125
126
|
this._canPage = false;
|
|
126
127
|
} else if (!this.vertical) {
|
|
@@ -139,6 +140,10 @@ let M3eSlideGroupElement = class M3eSlideGroupElement extends ReconnectedCallbac
|
|
|
139
140
|
if (!this._canPage) {
|
|
140
141
|
this._canPageStart = this._canPageEnd = false;
|
|
141
142
|
}
|
|
143
|
+
if (canPage != this._canPage) {
|
|
144
|
+
// Emit internal (undocumented) event for use with tabs.
|
|
145
|
+
this.dispatchEvent(new CustomEvent("pagination-changed"));
|
|
146
|
+
}
|
|
142
147
|
}
|
|
143
148
|
};
|
|
144
149
|
_M3eSlideGroupElement_directionalitySubscription = new WeakMap();
|
|
@@ -187,7 +192,7 @@ _M3eSlideGroupElement_pageEnd = function _M3eSlideGroupElement_pageEnd() {
|
|
|
187
192
|
}
|
|
188
193
|
};
|
|
189
194
|
/** The styles of the element. */
|
|
190
|
-
M3eSlideGroupElement.styles = css`:host { display: flex; flex-wrap: nowrap;
|
|
195
|
+
M3eSlideGroupElement.styles = css`:host { display: flex; flex-wrap: nowrap; } :host([vertical]) { flex-direction: column; } .prev-button, .next-button { flex: none; --m3e-icon-button-small-shape-round: 0px; --m3e-icon-button-small-shape-square: 0px; --m3e-icon-button-small-shape-pressed-morph: 0px; --m3e-focus-ring-visibility: hidden; } ::slotted(prev-icon), ::slotted(next-icon), .icon { width: 1em; font-size: var(--m3e-slide-group-button-icon-size, var(--m3e-icon-button-small-icon-size, 1.5rem)) !important; } :host(:not([vertical])) .prev-button, :host(:not([vertical])) .next-button { --m3e-icon-button-small-container-height: 100%; width: var(--m3e-slide-group-button-size, 2.5rem); } :host([vertical]) .prev-button, :host([vertical]) .next-button { width: unset; --m3e-icon-button-small-container-height: var(--m3e-slide-group-button-size, 2.5rem); } :host([vertical]) .prev-button .icon, :host([vertical]) .next-button .icon { transform: rotate(90deg); } .content { flex: 1 1 auto; display: inherit; flex-wrap: inherit; flex-direction: inherit; position: relative; border-top: var(--m3e-slide-group-divider-top); border-bottom: var(--m3e-slide-group-divider-bottom); scrollbar-width: none; } .content::-webkit-scrollbar { display: none; } :host([vertical]) .content { overflow-x: hidden; overflow-y: auto; } :host(:not([vertical])) .content { overflow-x: auto; overflow-y: hidden; }`;
|
|
191
196
|
__decorate([query(".content")], M3eSlideGroupElement.prototype, "scrollContainer", void 0);
|
|
192
197
|
__decorate([state()], M3eSlideGroupElement.prototype, "_canPage", void 0);
|
|
193
198
|
__decorate([state()], M3eSlideGroupElement.prototype, "_canPageStart", void 0);
|
package/dist/slide-group.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slide-group.js","sources":["../../src/slide-group/SlideGroupElement.ts"],"sourcesContent":["import { css, CSSResultGroup, html, LitElement, nothing, PropertyValues } from \"lit\";\r\nimport { property, query, state } from \"lit/decorators.js\";\r\n\r\nimport { customElement, debounce, ReconnectedCallback, ResizeController } from \"@m3e/web/core\";\r\nimport { M3eDirectionality } from \"@m3e/web/core/bidi\";\r\n\r\nimport \"@m3e/web/icon-button\";\r\n\r\n/**\r\n * Presents pagination controls used to scroll overflowing content.\r\n *\r\n * @description\r\n * The `m3e-slide-group` component presents directional pagination controls for navigating overflowing content.\r\n * It orchestrates scrollable layouts with expressive slot-based icons and adaptive orientation, revealing navigation\r\n * affordances only when content exceeds a defined threshold. It supports both horizontal and vertical flows, and\r\n * encodes accessibility through customizable labels and interaction states.\r\n *\r\n * @example\r\n * The following example illustrates a horizontally scrollable group of items with directional pagination buttons.\r\n * The scroll controls appear when content exceeds the `48px` threshold.\r\n * ```html\r\n * <m3e-slide-group threshold=\"48\">\r\n * <div>Item 1</div>\r\n * <div>Item 2</div>\r\n * <div>Item 3</div>\r\n * <div>Item 4</div>\r\n * <div>Item 5</div>\r\n * </m3e-slide-group>\r\n * ```\r\n *\r\n * @tag m3e-slide-group\r\n *\r\n * @slot - Renders the content to paginate.\r\n * @slot next-icon - Renders the icon to present for the next button.\r\n * @slot prev-icon - Renders the icon to present for the previous button.\r\n *\r\n * @attr disabled - Whether scroll buttons are disabled.\r\n * @attr next-page-label - The accessible label given to the button used to move to the previous page.\r\n * @attr previous-page-label - The accessible label given to the button used to move to the next page.\r\n * @attr threshold - A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @attr vertical - Whether content is oriented vertically.\r\n *\r\n * @cssprop --m3e-slide-group-button-icon-size - Sets icon size for scroll buttons; overrides default small icon size.\r\n * @cssprop --m3e-slide-group-button-size - Defines scroll button size; used for width (horizontal) or height (vertical).\r\n * @cssprop --m3e-slide-group-divider-top - Adds top border to content container for visual separation.\r\n * @cssprop --m3e-slide-group-divider-bottom - Adds bottom border to content container for visual separation.\r\n */\r\n@customElement(\"m3e-slide-group\")\r\nexport class M3eSlideGroupElement extends ReconnectedCallback(LitElement) {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: flex;\r\n flex-wrap: nowrap;\r\n overflow: hidden;\r\n }\r\n :host([vertical]) {\r\n flex-direction: column;\r\n }\r\n .prev-button,\r\n .next-button {\r\n flex: none;\r\n --m3e-icon-button-small-shape-round: 0px;\r\n --m3e-icon-button-small-shape-square: 0px;\r\n --m3e-icon-button-small-shape-pressed-morph: 0px;\r\n --m3e-focus-ring-visibility: hidden;\r\n }\r\n ::slotted(prev-icon),\r\n ::slotted(next-icon),\r\n .icon {\r\n width: 1em;\r\n font-size: var(--m3e-slide-group-button-icon-size, var(--m3e-icon-button-small-icon-size, 1.5rem)) !important;\r\n }\r\n :host(:not([vertical])) .prev-button,\r\n :host(:not([vertical])) .next-button {\r\n --m3e-icon-button-small-container-height: 100%;\r\n width: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button,\r\n :host([vertical]) .next-button {\r\n width: unset;\r\n --m3e-icon-button-small-container-height: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button .icon,\r\n :host([vertical]) .next-button .icon {\r\n transform: rotate(90deg);\r\n }\r\n .content {\r\n flex: 1 1 auto;\r\n display: inherit;\r\n flex-wrap: inherit;\r\n flex-direction: inherit;\r\n overflow: inherit;\r\n position: relative;\r\n border-top: var(--m3e-slide-group-divider-top);\r\n border-bottom: var(--m3e-slide-group-divider-bottom);\r\n }\r\n `;\r\n\r\n /** @private */ #directionalitySubscription?: () => void;\r\n\r\n /** @private */\r\n readonly #resizeController = new ResizeController(this, {\r\n target: null,\r\n callback: () => this._updatePaging(),\r\n });\r\n\r\n /** @internal A reference to the container used to scroll content. */\r\n @query(\".content\") scrollContainer!: HTMLElement;\r\n\r\n /** @private */ @state() private _canPage = false;\r\n /** @private */ @state() private _canPageStart = false;\r\n /** @private */ @state() private _canPageEnd = false;\r\n\r\n /**\r\n * Whether scroll buttons are disabled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) disabled = false;\r\n\r\n /**\r\n * Whether content is oriented vertically.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) vertical = false;\r\n\r\n /**\r\n * A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @default 0\r\n */\r\n @property({ type: Number }) threshold = 0;\r\n\r\n /**\r\n * The accessible label given to the button used to move to the previous page.\r\n * @default \"Previous page\"\r\n */\r\n @property({ attribute: \"previous-page-label\" }) previousPageLabel = \"Previous page\";\r\n\r\n /**\r\n * The accessible label given to the button used to move to the next page.\r\n * @default \"Next page\"\r\n */\r\n @property({ attribute: \"next-page-label\" }) nextPageLabel = \"Next page\";\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n this.#directionalitySubscription = M3eDirectionality.observe(() => this.requestUpdate());\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this.#directionalitySubscription?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n override reconnectedCallback(): void {\r\n super.reconnectedCallback();\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override firstUpdated(_changedProperties: PropertyValues): void {\r\n super.firstUpdated(_changedProperties);\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n const prevButton = html`<m3e-icon-button\r\n class=\"prev-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.previousPageLabel}\"\r\n ?disabled=\"${!this._canPageStart}\"\r\n @click=\"${this.#pageStart}\"\r\n >\r\n <slot name=\"prev-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n const nextButton = html`<m3e-icon-button\r\n class=\"next-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.nextPageLabel}\"\r\n ?disabled=\"${!this._canPageEnd}\"\r\n @click=\"${this.#pageEnd}\"\r\n >\r\n <slot name=\"next-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n return html`${this._canPage ? prevButton : nothing}\r\n <div class=\"content\" @scroll=\"${this._updatePaging}\"><slot></slot></div>\r\n ${this._canPage ? nextButton : nothing}`;\r\n }\r\n\r\n /** @private */\r\n #pageStart(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft - this.scrollContainer.clientWidth;\r\n if (left <= this.threshold) {\r\n left = 0;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop - this.scrollContainer.clientHeight;\r\n if (top <= this.threshold) {\r\n top = 0;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n #pageEnd(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft + this.scrollContainer.clientWidth;\r\n if (left >= this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth - this.threshold) {\r\n left = this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop + this.scrollContainer.clientHeight;\r\n if (top >= this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight - this.threshold) {\r\n top = this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n @debounce(40)\r\n private _updatePaging(): void {\r\n if (this.disabled) {\r\n this._canPage = false;\r\n } else if (!this.vertical) {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollWidth) > Math.round(this.scrollContainer.clientWidth) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollLeft) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollLeft) + this.threshold <\r\n Math.round(this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth);\r\n }\r\n } else {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollHeight) > Math.round(this.scrollContainer.clientHeight) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollTop) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollTop) + +this.threshold <\r\n Math.round(this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight);\r\n }\r\n }\r\n\r\n if (!this._canPage) {\r\n this._canPageStart = this._canPageEnd = false;\r\n }\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-slide-group\": M3eSlideGroupElement;\r\n }\r\n}\r\n"],"names":["M3eSlideGroupElement","ReconnectedCallback","LitElement","constructor","_M3eSlideGroupElement_directionalitySubscription","set","_M3eSlideGroupElement_resizeController","ResizeController","target","callback","_updatePaging","_canPage","_canPageStart","_canPageEnd","disabled","vertical","threshold","previousPageLabel","nextPageLabel","connectedCallback","__classPrivateFieldSet","M3eDirectionality","observe","requestUpdate","disconnectedCallback","__classPrivateFieldGet","call","reconnectedCallback","scrollContainer","firstUpdated","_changedProperties","render","prevButton","html","_M3eSlideGroupElement_instances","_M3eSlideGroupElement_pageStart","current","nextButton","_M3eSlideGroupElement_pageEnd","nothing","Math","round","scrollWidth","clientWidth","scrollLeft","scrollHeight","clientHeight","scrollTop","left","scrollTo","behavior","top","styles","css","__decorate","query","prototype","state","property","type","Boolean","reflect","Number","attribute","debounce","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slide-group.js","sources":["../../src/slide-group/SlideGroupElement.ts"],"sourcesContent":["import { css, CSSResultGroup, html, LitElement, nothing, PropertyValues } from \"lit\";\r\nimport { property, query, state } from \"lit/decorators.js\";\r\n\r\nimport { customElement, debounce, ReconnectedCallback, ResizeController } from \"@m3e/web/core\";\r\nimport { M3eDirectionality } from \"@m3e/web/core/bidi\";\r\n\r\nimport \"@m3e/web/icon-button\";\r\n\r\n/**\r\n * Presents pagination controls used to scroll overflowing content.\r\n *\r\n * @description\r\n * The `m3e-slide-group` component presents directional pagination controls for navigating overflowing content.\r\n * It orchestrates scrollable layouts with expressive slot-based icons and adaptive orientation, revealing navigation\r\n * affordances only when content exceeds a defined threshold. It supports both horizontal and vertical flows, and\r\n * encodes accessibility through customizable labels and interaction states.\r\n *\r\n * @example\r\n * The following example illustrates a horizontally scrollable group of items with directional pagination buttons.\r\n * The scroll controls appear when content exceeds the `48px` threshold.\r\n * ```html\r\n * <m3e-slide-group threshold=\"48\">\r\n * <div>Item 1</div>\r\n * <div>Item 2</div>\r\n * <div>Item 3</div>\r\n * <div>Item 4</div>\r\n * <div>Item 5</div>\r\n * </m3e-slide-group>\r\n * ```\r\n *\r\n * @tag m3e-slide-group\r\n *\r\n * @slot - Renders the content to paginate.\r\n * @slot next-icon - Renders the icon to present for the next button.\r\n * @slot prev-icon - Renders the icon to present for the previous button.\r\n *\r\n * @attr disabled - Whether scroll buttons are disabled.\r\n * @attr next-page-label - The accessible label given to the button used to move to the previous page.\r\n * @attr previous-page-label - The accessible label given to the button used to move to the next page.\r\n * @attr threshold - A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @attr vertical - Whether content is oriented vertically.\r\n *\r\n * @cssprop --m3e-slide-group-button-icon-size - Sets icon size for scroll buttons; overrides default small icon size.\r\n * @cssprop --m3e-slide-group-button-size - Defines scroll button size; used for width (horizontal) or height (vertical).\r\n * @cssprop --m3e-slide-group-divider-top - Adds top border to content container for visual separation.\r\n * @cssprop --m3e-slide-group-divider-bottom - Adds bottom border to content container for visual separation.\r\n */\r\n@customElement(\"m3e-slide-group\")\r\nexport class M3eSlideGroupElement extends ReconnectedCallback(LitElement) {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: flex;\r\n flex-wrap: nowrap;\r\n }\r\n :host([vertical]) {\r\n flex-direction: column;\r\n }\r\n .prev-button,\r\n .next-button {\r\n flex: none;\r\n --m3e-icon-button-small-shape-round: 0px;\r\n --m3e-icon-button-small-shape-square: 0px;\r\n --m3e-icon-button-small-shape-pressed-morph: 0px;\r\n --m3e-focus-ring-visibility: hidden;\r\n }\r\n ::slotted(prev-icon),\r\n ::slotted(next-icon),\r\n .icon {\r\n width: 1em;\r\n font-size: var(--m3e-slide-group-button-icon-size, var(--m3e-icon-button-small-icon-size, 1.5rem)) !important;\r\n }\r\n :host(:not([vertical])) .prev-button,\r\n :host(:not([vertical])) .next-button {\r\n --m3e-icon-button-small-container-height: 100%;\r\n width: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button,\r\n :host([vertical]) .next-button {\r\n width: unset;\r\n --m3e-icon-button-small-container-height: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button .icon,\r\n :host([vertical]) .next-button .icon {\r\n transform: rotate(90deg);\r\n }\r\n .content {\r\n flex: 1 1 auto;\r\n display: inherit;\r\n flex-wrap: inherit;\r\n flex-direction: inherit;\r\n position: relative;\r\n border-top: var(--m3e-slide-group-divider-top);\r\n border-bottom: var(--m3e-slide-group-divider-bottom);\r\n scrollbar-width: none;\r\n }\r\n .content::-webkit-scrollbar {\r\n display: none;\r\n }\r\n :host([vertical]) .content {\r\n overflow-x: hidden;\r\n overflow-y: auto;\r\n }\r\n :host(:not([vertical])) .content {\r\n overflow-x: auto;\r\n overflow-y: hidden;\r\n }\r\n `;\r\n\r\n /** @private */ #directionalitySubscription?: () => void;\r\n\r\n /** @private */\r\n readonly #resizeController = new ResizeController(this, {\r\n target: null,\r\n callback: () => this._updatePaging(),\r\n });\r\n\r\n /** @internal A reference to the container used to scroll content. */\r\n @query(\".content\") scrollContainer!: HTMLElement;\r\n\r\n /** @private */ @state() private _canPage = false;\r\n /** @private */ @state() private _canPageStart = false;\r\n /** @private */ @state() private _canPageEnd = false;\r\n\r\n /**\r\n * Whether scroll buttons are disabled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) disabled = false;\r\n\r\n /**\r\n * Whether content is oriented vertically.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) vertical = false;\r\n\r\n /**\r\n * A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @default 0\r\n */\r\n @property({ type: Number }) threshold = 0;\r\n\r\n /**\r\n * The accessible label given to the button used to move to the previous page.\r\n * @default \"Previous page\"\r\n */\r\n @property({ attribute: \"previous-page-label\" }) previousPageLabel = \"Previous page\";\r\n\r\n /**\r\n * The accessible label given to the button used to move to the next page.\r\n * @default \"Next page\"\r\n */\r\n @property({ attribute: \"next-page-label\" }) nextPageLabel = \"Next page\";\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n this.#directionalitySubscription = M3eDirectionality.observe(() => this.requestUpdate());\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this.#directionalitySubscription?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n override reconnectedCallback(): void {\r\n super.reconnectedCallback();\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override firstUpdated(_changedProperties: PropertyValues): void {\r\n super.firstUpdated(_changedProperties);\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n const prevButton = html`<m3e-icon-button\r\n class=\"prev-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.previousPageLabel}\"\r\n ?disabled=\"${!this._canPageStart}\"\r\n @click=\"${this.#pageStart}\"\r\n >\r\n <slot name=\"prev-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n const nextButton = html`<m3e-icon-button\r\n class=\"next-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.nextPageLabel}\"\r\n ?disabled=\"${!this._canPageEnd}\"\r\n @click=\"${this.#pageEnd}\"\r\n >\r\n <slot name=\"next-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n return html`${this._canPage ? prevButton : nothing}\r\n <div class=\"content\" @scroll=\"${this._updatePaging}\"><slot></slot></div>\r\n ${this._canPage ? nextButton : nothing}`;\r\n }\r\n\r\n /** @private */\r\n #pageStart(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft - this.scrollContainer.clientWidth;\r\n if (left <= this.threshold) {\r\n left = 0;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop - this.scrollContainer.clientHeight;\r\n if (top <= this.threshold) {\r\n top = 0;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n #pageEnd(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft + this.scrollContainer.clientWidth;\r\n if (left >= this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth - this.threshold) {\r\n left = this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop + this.scrollContainer.clientHeight;\r\n if (top >= this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight - this.threshold) {\r\n top = this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n @debounce(40)\r\n private _updatePaging(): void {\r\n const canPage = this._canPage;\r\n if (this.disabled) {\r\n this._canPage = false;\r\n } else if (!this.vertical) {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollWidth) > Math.round(this.scrollContainer.clientWidth) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollLeft) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollLeft) + this.threshold <\r\n Math.round(this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth);\r\n }\r\n } else {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollHeight) > Math.round(this.scrollContainer.clientHeight) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollTop) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollTop) + +this.threshold <\r\n Math.round(this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight);\r\n }\r\n }\r\n\r\n if (!this._canPage) {\r\n this._canPageStart = this._canPageEnd = false;\r\n }\r\n\r\n if (canPage != this._canPage) {\r\n // Emit internal (undocumented) event for use with tabs.\r\n this.dispatchEvent(new CustomEvent(\"pagination-changed\"));\r\n }\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-slide-group\": M3eSlideGroupElement;\r\n }\r\n}\r\n"],"names":["M3eSlideGroupElement","ReconnectedCallback","LitElement","constructor","_M3eSlideGroupElement_directionalitySubscription","set","_M3eSlideGroupElement_resizeController","ResizeController","target","callback","_updatePaging","_canPage","_canPageStart","_canPageEnd","disabled","vertical","threshold","previousPageLabel","nextPageLabel","connectedCallback","__classPrivateFieldSet","M3eDirectionality","observe","requestUpdate","disconnectedCallback","__classPrivateFieldGet","call","reconnectedCallback","scrollContainer","firstUpdated","_changedProperties","render","prevButton","html","_M3eSlideGroupElement_instances","_M3eSlideGroupElement_pageStart","current","nextButton","_M3eSlideGroupElement_pageEnd","nothing","canPage","Math","round","scrollWidth","clientWidth","scrollLeft","scrollHeight","clientHeight","scrollTop","dispatchEvent","CustomEvent","left","scrollTo","behavior","top","styles","css","__decorate","query","prototype","state","property","type","Boolean","reflect","Number","attribute","debounce","customElement"],"mappings":"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"}
|
package/dist/slide-group.min.js
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Copyright (c) 2025–2026 matraic
|
|
4
4
|
* See LICENSE file in the project root for full license text.
|
|
5
5
|
*/
|
|
6
|
-
import{__classPrivateFieldSet as t,__classPrivateFieldGet as e,__decorate as o}from"tslib";import{LitElement as i,html as l,nothing as s,css as
|
|
6
|
+
import{__classPrivateFieldSet as t,__classPrivateFieldGet as e,__decorate as o}from"tslib";import{LitElement as i,html as l,nothing as s,css as n}from"lit";import{query as r,state as a,property as c}from"lit/decorators.js";import{ReconnectedCallback as h,ResizeController as d,debounce as p,customElement as u}from"@m3e/web/core";import{M3eDirectionality as v}from"@m3e/web/core/bidi";import"@m3e/web/icon-button";var g,b,m,C,f;let P=class extends(h(i)){constructor(){super(...arguments),g.add(this),b.set(this,void 0),m.set(this,new d(this,{target:null,callback:()=>this._updatePaging()})),this._canPage=!1,this._canPageStart=!1,this._canPageEnd=!1,this.disabled=!1,this.vertical=!1,this.threshold=0,this.previousPageLabel="Previous page",this.nextPageLabel="Next page"}connectedCallback(){super.connectedCallback(),t(this,b,v.observe(()=>this.requestUpdate()),"f")}disconnectedCallback(){super.disconnectedCallback(),e(this,b,"f")?.call(this)}reconnectedCallback(){super.reconnectedCallback(),e(this,m,"f").observe(this.scrollContainer)}firstUpdated(t){super.firstUpdated(t),e(this,m,"f").observe(this.scrollContainer)}render(){const t=l`<m3e-icon-button class="prev-button" tabindex="-1" aria-label="${this.previousPageLabel}" ?disabled="${!this._canPageStart}" @click="${e(this,g,"m",C)}"><slot name="prev-icon">${"ltr"===v.current||this.vertical?l`<svg class="icon" viewBox="0 -960 960 960" fill="currentColor"><path d="M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z"/></svg>`:l`<svg class="icon" viewBox="0 -960 960 960" fill="currentColor"><path d="m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z"/></svg>`}</slot></m3e-icon-button>`,o=l`<m3e-icon-button class="next-button" tabindex="-1" aria-label="${this.nextPageLabel}" ?disabled="${!this._canPageEnd}" @click="${e(this,g,"m",f)}"><slot name="next-icon">${"ltr"===v.current||this.vertical?l`<svg class="icon" viewBox="0 -960 960 960" fill="currentColor"><path d="m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z"/></svg>`:l`<svg class="icon" viewBox="0 -960 960 960" fill="currentColor"><path d="M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z"/></svg>`}</slot></m3e-icon-button>`;return l`${this._canPage?t:s}<div class="content" @scroll="${this._updatePaging}"><slot></slot></div>${this._canPage?o:s}`}_updatePaging(){const t=this._canPage;this.disabled?this._canPage=!1:this.vertical?(this._canPage=Math.round(this.scrollContainer.scrollHeight)>Math.round(this.scrollContainer.clientHeight)+this.threshold,this._canPage&&(this._canPageStart=Math.round(this.scrollContainer.scrollTop)>this.threshold,this._canPageEnd=Math.round(this.scrollContainer.scrollTop)+ +this.threshold<Math.round(this.scrollContainer.scrollHeight-this.scrollContainer.clientHeight))):(this._canPage=Math.round(this.scrollContainer.scrollWidth)>Math.round(this.scrollContainer.clientWidth)+this.threshold,this._canPage&&(this._canPageStart=Math.round(this.scrollContainer.scrollLeft)>this.threshold,this._canPageEnd=Math.round(this.scrollContainer.scrollLeft)+this.threshold<Math.round(this.scrollContainer.scrollWidth-this.scrollContainer.clientWidth))),this._canPage||(this._canPageStart=this._canPageEnd=!1),t!=this._canPage&&this.dispatchEvent(new CustomEvent("pagination-changed"))}};b=new WeakMap,m=new WeakMap,g=new WeakSet,C=function(){if(this.vertical){let t=this.scrollContainer.scrollTop-this.scrollContainer.clientHeight;t<=this.threshold&&(t=0),this.scrollContainer.scrollTo({top:t,behavior:"smooth"})}else{let t=this.scrollContainer.scrollLeft-this.scrollContainer.clientWidth;t<=this.threshold&&(t=0),this.scrollContainer.scrollTo({left:t,behavior:"smooth"})}},f=function(){if(this.vertical){let t=this.scrollContainer.scrollTop+this.scrollContainer.clientHeight;t>=this.scrollContainer.scrollHeight-this.scrollContainer.clientHeight-this.threshold&&(t=this.scrollContainer.scrollHeight-this.scrollContainer.clientHeight),this.scrollContainer.scrollTo({top:t,behavior:"smooth"})}else{let t=this.scrollContainer.scrollLeft+this.scrollContainer.clientWidth;t>=this.scrollContainer.scrollWidth-this.scrollContainer.clientWidth-this.threshold&&(t=this.scrollContainer.scrollWidth-this.scrollContainer.clientWidth),this.scrollContainer.scrollTo({left:t,behavior:"smooth"})}},P.styles=n`:host { display: flex; flex-wrap: nowrap; } :host([vertical]) { flex-direction: column; } .prev-button, .next-button { flex: none; --m3e-icon-button-small-shape-round: 0px; --m3e-icon-button-small-shape-square: 0px; --m3e-icon-button-small-shape-pressed-morph: 0px; --m3e-focus-ring-visibility: hidden; } ::slotted(prev-icon), ::slotted(next-icon), .icon { width: 1em; font-size: var(--m3e-slide-group-button-icon-size, var(--m3e-icon-button-small-icon-size, 1.5rem)) !important; } :host(:not([vertical])) .prev-button, :host(:not([vertical])) .next-button { --m3e-icon-button-small-container-height: 100%; width: var(--m3e-slide-group-button-size, 2.5rem); } :host([vertical]) .prev-button, :host([vertical]) .next-button { width: unset; --m3e-icon-button-small-container-height: var(--m3e-slide-group-button-size, 2.5rem); } :host([vertical]) .prev-button .icon, :host([vertical]) .next-button .icon { transform: rotate(90deg); } .content { flex: 1 1 auto; display: inherit; flex-wrap: inherit; flex-direction: inherit; position: relative; border-top: var(--m3e-slide-group-divider-top); border-bottom: var(--m3e-slide-group-divider-bottom); scrollbar-width: none; } .content::-webkit-scrollbar { display: none; } :host([vertical]) .content { overflow-x: hidden; overflow-y: auto; } :host(:not([vertical])) .content { overflow-x: auto; overflow-y: hidden; }`,o([r(".content")],P.prototype,"scrollContainer",void 0),o([a()],P.prototype,"_canPage",void 0),o([a()],P.prototype,"_canPageStart",void 0),o([a()],P.prototype,"_canPageEnd",void 0),o([c({type:Boolean,reflect:!0})],P.prototype,"disabled",void 0),o([c({type:Boolean,reflect:!0})],P.prototype,"vertical",void 0),o([c({type:Number})],P.prototype,"threshold",void 0),o([c({attribute:"previous-page-label"})],P.prototype,"previousPageLabel",void 0),o([c({attribute:"next-page-label"})],P.prototype,"nextPageLabel",void 0),o([p(40)],P.prototype,"_updatePaging",null),P=o([u("m3e-slide-group")],P);export{P as M3eSlideGroupElement};
|
|
7
7
|
//# sourceMappingURL=slide-group.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slide-group.min.js","sources":["../../src/slide-group/SlideGroupElement.ts"],"sourcesContent":["import { css, CSSResultGroup, html, LitElement, nothing, PropertyValues } from \"lit\";\r\nimport { property, query, state } from \"lit/decorators.js\";\r\n\r\nimport { customElement, debounce, ReconnectedCallback, ResizeController } from \"@m3e/web/core\";\r\nimport { M3eDirectionality } from \"@m3e/web/core/bidi\";\r\n\r\nimport \"@m3e/web/icon-button\";\r\n\r\n/**\r\n * Presents pagination controls used to scroll overflowing content.\r\n *\r\n * @description\r\n * The `m3e-slide-group` component presents directional pagination controls for navigating overflowing content.\r\n * It orchestrates scrollable layouts with expressive slot-based icons and adaptive orientation, revealing navigation\r\n * affordances only when content exceeds a defined threshold. It supports both horizontal and vertical flows, and\r\n * encodes accessibility through customizable labels and interaction states.\r\n *\r\n * @example\r\n * The following example illustrates a horizontally scrollable group of items with directional pagination buttons.\r\n * The scroll controls appear when content exceeds the `48px` threshold.\r\n * ```html\r\n * <m3e-slide-group threshold=\"48\">\r\n * <div>Item 1</div>\r\n * <div>Item 2</div>\r\n * <div>Item 3</div>\r\n * <div>Item 4</div>\r\n * <div>Item 5</div>\r\n * </m3e-slide-group>\r\n * ```\r\n *\r\n * @tag m3e-slide-group\r\n *\r\n * @slot - Renders the content to paginate.\r\n * @slot next-icon - Renders the icon to present for the next button.\r\n * @slot prev-icon - Renders the icon to present for the previous button.\r\n *\r\n * @attr disabled - Whether scroll buttons are disabled.\r\n * @attr next-page-label - The accessible label given to the button used to move to the previous page.\r\n * @attr previous-page-label - The accessible label given to the button used to move to the next page.\r\n * @attr threshold - A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @attr vertical - Whether content is oriented vertically.\r\n *\r\n * @cssprop --m3e-slide-group-button-icon-size - Sets icon size for scroll buttons; overrides default small icon size.\r\n * @cssprop --m3e-slide-group-button-size - Defines scroll button size; used for width (horizontal) or height (vertical).\r\n * @cssprop --m3e-slide-group-divider-top - Adds top border to content container for visual separation.\r\n * @cssprop --m3e-slide-group-divider-bottom - Adds bottom border to content container for visual separation.\r\n */\r\n@customElement(\"m3e-slide-group\")\r\nexport class M3eSlideGroupElement extends ReconnectedCallback(LitElement) {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: flex;\r\n flex-wrap: nowrap;\r\n overflow: hidden;\r\n }\r\n :host([vertical]) {\r\n flex-direction: column;\r\n }\r\n .prev-button,\r\n .next-button {\r\n flex: none;\r\n --m3e-icon-button-small-shape-round: 0px;\r\n --m3e-icon-button-small-shape-square: 0px;\r\n --m3e-icon-button-small-shape-pressed-morph: 0px;\r\n --m3e-focus-ring-visibility: hidden;\r\n }\r\n ::slotted(prev-icon),\r\n ::slotted(next-icon),\r\n .icon {\r\n width: 1em;\r\n font-size: var(--m3e-slide-group-button-icon-size, var(--m3e-icon-button-small-icon-size, 1.5rem)) !important;\r\n }\r\n :host(:not([vertical])) .prev-button,\r\n :host(:not([vertical])) .next-button {\r\n --m3e-icon-button-small-container-height: 100%;\r\n width: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button,\r\n :host([vertical]) .next-button {\r\n width: unset;\r\n --m3e-icon-button-small-container-height: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button .icon,\r\n :host([vertical]) .next-button .icon {\r\n transform: rotate(90deg);\r\n }\r\n .content {\r\n flex: 1 1 auto;\r\n display: inherit;\r\n flex-wrap: inherit;\r\n flex-direction: inherit;\r\n overflow: inherit;\r\n position: relative;\r\n border-top: var(--m3e-slide-group-divider-top);\r\n border-bottom: var(--m3e-slide-group-divider-bottom);\r\n }\r\n `;\r\n\r\n /** @private */ #directionalitySubscription?: () => void;\r\n\r\n /** @private */\r\n readonly #resizeController = new ResizeController(this, {\r\n target: null,\r\n callback: () => this._updatePaging(),\r\n });\r\n\r\n /** @internal A reference to the container used to scroll content. */\r\n @query(\".content\") scrollContainer!: HTMLElement;\r\n\r\n /** @private */ @state() private _canPage = false;\r\n /** @private */ @state() private _canPageStart = false;\r\n /** @private */ @state() private _canPageEnd = false;\r\n\r\n /**\r\n * Whether scroll buttons are disabled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) disabled = false;\r\n\r\n /**\r\n * Whether content is oriented vertically.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) vertical = false;\r\n\r\n /**\r\n * A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @default 0\r\n */\r\n @property({ type: Number }) threshold = 0;\r\n\r\n /**\r\n * The accessible label given to the button used to move to the previous page.\r\n * @default \"Previous page\"\r\n */\r\n @property({ attribute: \"previous-page-label\" }) previousPageLabel = \"Previous page\";\r\n\r\n /**\r\n * The accessible label given to the button used to move to the next page.\r\n * @default \"Next page\"\r\n */\r\n @property({ attribute: \"next-page-label\" }) nextPageLabel = \"Next page\";\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n this.#directionalitySubscription = M3eDirectionality.observe(() => this.requestUpdate());\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this.#directionalitySubscription?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n override reconnectedCallback(): void {\r\n super.reconnectedCallback();\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override firstUpdated(_changedProperties: PropertyValues): void {\r\n super.firstUpdated(_changedProperties);\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n const prevButton = html`<m3e-icon-button\r\n class=\"prev-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.previousPageLabel}\"\r\n ?disabled=\"${!this._canPageStart}\"\r\n @click=\"${this.#pageStart}\"\r\n >\r\n <slot name=\"prev-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n const nextButton = html`<m3e-icon-button\r\n class=\"next-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.nextPageLabel}\"\r\n ?disabled=\"${!this._canPageEnd}\"\r\n @click=\"${this.#pageEnd}\"\r\n >\r\n <slot name=\"next-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n return html`${this._canPage ? prevButton : nothing}\r\n <div class=\"content\" @scroll=\"${this._updatePaging}\"><slot></slot></div>\r\n ${this._canPage ? nextButton : nothing}`;\r\n }\r\n\r\n /** @private */\r\n #pageStart(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft - this.scrollContainer.clientWidth;\r\n if (left <= this.threshold) {\r\n left = 0;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop - this.scrollContainer.clientHeight;\r\n if (top <= this.threshold) {\r\n top = 0;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n #pageEnd(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft + this.scrollContainer.clientWidth;\r\n if (left >= this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth - this.threshold) {\r\n left = this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop + this.scrollContainer.clientHeight;\r\n if (top >= this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight - this.threshold) {\r\n top = this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n @debounce(40)\r\n private _updatePaging(): void {\r\n if (this.disabled) {\r\n this._canPage = false;\r\n } else if (!this.vertical) {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollWidth) > Math.round(this.scrollContainer.clientWidth) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollLeft) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollLeft) + this.threshold <\r\n Math.round(this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth);\r\n }\r\n } else {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollHeight) > Math.round(this.scrollContainer.clientHeight) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollTop) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollTop) + +this.threshold <\r\n Math.round(this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight);\r\n }\r\n }\r\n\r\n if (!this._canPage) {\r\n this._canPageStart = this._canPageEnd = false;\r\n }\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-slide-group\": M3eSlideGroupElement;\r\n }\r\n}\r\n"],"names":["M3eSlideGroupElement","ReconnectedCallback","LitElement","constructor","_M3eSlideGroupElement_directionalitySubscription","set","this","_M3eSlideGroupElement_resizeController","ResizeController","target","callback","_updatePaging","_canPage","_canPageStart","_canPageEnd","disabled","vertical","threshold","previousPageLabel","nextPageLabel","connectedCallback","super","__classPrivateFieldSet","M3eDirectionality","observe","requestUpdate","disconnectedCallback","__classPrivateFieldGet","call","reconnectedCallback","scrollContainer","firstUpdated","_changedProperties","render","prevButton","html","_M3eSlideGroupElement_instances","_M3eSlideGroupElement_pageStart","current","nextButton","_M3eSlideGroupElement_pageEnd","nothing","Math","round","scrollHeight","clientHeight","scrollTop","scrollWidth","clientWidth","scrollLeft","top","scrollTo","behavior","left","styles","css","__decorate","query","prototype","state","property","type","Boolean","reflect","Number","attribute","debounce","customElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slide-group.min.js","sources":["../../src/slide-group/SlideGroupElement.ts"],"sourcesContent":["import { css, CSSResultGroup, html, LitElement, nothing, PropertyValues } from \"lit\";\r\nimport { property, query, state } from \"lit/decorators.js\";\r\n\r\nimport { customElement, debounce, ReconnectedCallback, ResizeController } from \"@m3e/web/core\";\r\nimport { M3eDirectionality } from \"@m3e/web/core/bidi\";\r\n\r\nimport \"@m3e/web/icon-button\";\r\n\r\n/**\r\n * Presents pagination controls used to scroll overflowing content.\r\n *\r\n * @description\r\n * The `m3e-slide-group` component presents directional pagination controls for navigating overflowing content.\r\n * It orchestrates scrollable layouts with expressive slot-based icons and adaptive orientation, revealing navigation\r\n * affordances only when content exceeds a defined threshold. It supports both horizontal and vertical flows, and\r\n * encodes accessibility through customizable labels and interaction states.\r\n *\r\n * @example\r\n * The following example illustrates a horizontally scrollable group of items with directional pagination buttons.\r\n * The scroll controls appear when content exceeds the `48px` threshold.\r\n * ```html\r\n * <m3e-slide-group threshold=\"48\">\r\n * <div>Item 1</div>\r\n * <div>Item 2</div>\r\n * <div>Item 3</div>\r\n * <div>Item 4</div>\r\n * <div>Item 5</div>\r\n * </m3e-slide-group>\r\n * ```\r\n *\r\n * @tag m3e-slide-group\r\n *\r\n * @slot - Renders the content to paginate.\r\n * @slot next-icon - Renders the icon to present for the next button.\r\n * @slot prev-icon - Renders the icon to present for the previous button.\r\n *\r\n * @attr disabled - Whether scroll buttons are disabled.\r\n * @attr next-page-label - The accessible label given to the button used to move to the previous page.\r\n * @attr previous-page-label - The accessible label given to the button used to move to the next page.\r\n * @attr threshold - A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @attr vertical - Whether content is oriented vertically.\r\n *\r\n * @cssprop --m3e-slide-group-button-icon-size - Sets icon size for scroll buttons; overrides default small icon size.\r\n * @cssprop --m3e-slide-group-button-size - Defines scroll button size; used for width (horizontal) or height (vertical).\r\n * @cssprop --m3e-slide-group-divider-top - Adds top border to content container for visual separation.\r\n * @cssprop --m3e-slide-group-divider-bottom - Adds bottom border to content container for visual separation.\r\n */\r\n@customElement(\"m3e-slide-group\")\r\nexport class M3eSlideGroupElement extends ReconnectedCallback(LitElement) {\r\n /** The styles of the element. */\r\n static override styles: CSSResultGroup = css`\r\n :host {\r\n display: flex;\r\n flex-wrap: nowrap;\r\n }\r\n :host([vertical]) {\r\n flex-direction: column;\r\n }\r\n .prev-button,\r\n .next-button {\r\n flex: none;\r\n --m3e-icon-button-small-shape-round: 0px;\r\n --m3e-icon-button-small-shape-square: 0px;\r\n --m3e-icon-button-small-shape-pressed-morph: 0px;\r\n --m3e-focus-ring-visibility: hidden;\r\n }\r\n ::slotted(prev-icon),\r\n ::slotted(next-icon),\r\n .icon {\r\n width: 1em;\r\n font-size: var(--m3e-slide-group-button-icon-size, var(--m3e-icon-button-small-icon-size, 1.5rem)) !important;\r\n }\r\n :host(:not([vertical])) .prev-button,\r\n :host(:not([vertical])) .next-button {\r\n --m3e-icon-button-small-container-height: 100%;\r\n width: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button,\r\n :host([vertical]) .next-button {\r\n width: unset;\r\n --m3e-icon-button-small-container-height: var(--m3e-slide-group-button-size, 2.5rem);\r\n }\r\n :host([vertical]) .prev-button .icon,\r\n :host([vertical]) .next-button .icon {\r\n transform: rotate(90deg);\r\n }\r\n .content {\r\n flex: 1 1 auto;\r\n display: inherit;\r\n flex-wrap: inherit;\r\n flex-direction: inherit;\r\n position: relative;\r\n border-top: var(--m3e-slide-group-divider-top);\r\n border-bottom: var(--m3e-slide-group-divider-bottom);\r\n scrollbar-width: none;\r\n }\r\n .content::-webkit-scrollbar {\r\n display: none;\r\n }\r\n :host([vertical]) .content {\r\n overflow-x: hidden;\r\n overflow-y: auto;\r\n }\r\n :host(:not([vertical])) .content {\r\n overflow-x: auto;\r\n overflow-y: hidden;\r\n }\r\n `;\r\n\r\n /** @private */ #directionalitySubscription?: () => void;\r\n\r\n /** @private */\r\n readonly #resizeController = new ResizeController(this, {\r\n target: null,\r\n callback: () => this._updatePaging(),\r\n });\r\n\r\n /** @internal A reference to the container used to scroll content. */\r\n @query(\".content\") scrollContainer!: HTMLElement;\r\n\r\n /** @private */ @state() private _canPage = false;\r\n /** @private */ @state() private _canPageStart = false;\r\n /** @private */ @state() private _canPageEnd = false;\r\n\r\n /**\r\n * Whether scroll buttons are disabled.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) disabled = false;\r\n\r\n /**\r\n * Whether content is oriented vertically.\r\n * @default false\r\n */\r\n @property({ type: Boolean, reflect: true }) vertical = false;\r\n\r\n /**\r\n * A value, in pixels, indicating the scroll threshold at which to begin showing pagination controls.\r\n * @default 0\r\n */\r\n @property({ type: Number }) threshold = 0;\r\n\r\n /**\r\n * The accessible label given to the button used to move to the previous page.\r\n * @default \"Previous page\"\r\n */\r\n @property({ attribute: \"previous-page-label\" }) previousPageLabel = \"Previous page\";\r\n\r\n /**\r\n * The accessible label given to the button used to move to the next page.\r\n * @default \"Next page\"\r\n */\r\n @property({ attribute: \"next-page-label\" }) nextPageLabel = \"Next page\";\r\n\r\n /** @inheritdoc */\r\n override connectedCallback(): void {\r\n super.connectedCallback();\r\n this.#directionalitySubscription = M3eDirectionality.observe(() => this.requestUpdate());\r\n }\r\n\r\n /** @inheritdoc */\r\n override disconnectedCallback(): void {\r\n super.disconnectedCallback();\r\n this.#directionalitySubscription?.();\r\n }\r\n\r\n /** @inheritdoc */\r\n override reconnectedCallback(): void {\r\n super.reconnectedCallback();\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override firstUpdated(_changedProperties: PropertyValues): void {\r\n super.firstUpdated(_changedProperties);\r\n this.#resizeController.observe(this.scrollContainer);\r\n }\r\n\r\n /** @inheritdoc */\r\n protected override render(): unknown {\r\n const prevButton = html`<m3e-icon-button\r\n class=\"prev-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.previousPageLabel}\"\r\n ?disabled=\"${!this._canPageStart}\"\r\n @click=\"${this.#pageStart}\"\r\n >\r\n <slot name=\"prev-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n const nextButton = html`<m3e-icon-button\r\n class=\"next-button\"\r\n tabindex=\"-1\"\r\n aria-label=\"${this.nextPageLabel}\"\r\n ?disabled=\"${!this._canPageEnd}\"\r\n @click=\"${this.#pageEnd}\"\r\n >\r\n <slot name=\"next-icon\">\r\n ${M3eDirectionality.current === \"ltr\" || this.vertical\r\n ? html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z\" />\r\n </svg>`\r\n : html`<svg class=\"icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\">\r\n <path d=\"M640-80 240-480l400-400 71 71-329 329 329 329-71 71Z\" />\r\n </svg>`}\r\n </slot>\r\n </m3e-icon-button>`;\r\n\r\n return html`${this._canPage ? prevButton : nothing}\r\n <div class=\"content\" @scroll=\"${this._updatePaging}\"><slot></slot></div>\r\n ${this._canPage ? nextButton : nothing}`;\r\n }\r\n\r\n /** @private */\r\n #pageStart(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft - this.scrollContainer.clientWidth;\r\n if (left <= this.threshold) {\r\n left = 0;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop - this.scrollContainer.clientHeight;\r\n if (top <= this.threshold) {\r\n top = 0;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n #pageEnd(): void {\r\n if (!this.vertical) {\r\n let left = this.scrollContainer.scrollLeft + this.scrollContainer.clientWidth;\r\n if (left >= this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth - this.threshold) {\r\n left = this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth;\r\n }\r\n this.scrollContainer.scrollTo({ left, behavior: \"smooth\" });\r\n } else {\r\n let top = this.scrollContainer.scrollTop + this.scrollContainer.clientHeight;\r\n if (top >= this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight - this.threshold) {\r\n top = this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight;\r\n }\r\n this.scrollContainer.scrollTo({ top, behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n /** @private */\r\n @debounce(40)\r\n private _updatePaging(): void {\r\n const canPage = this._canPage;\r\n if (this.disabled) {\r\n this._canPage = false;\r\n } else if (!this.vertical) {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollWidth) > Math.round(this.scrollContainer.clientWidth) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollLeft) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollLeft) + this.threshold <\r\n Math.round(this.scrollContainer.scrollWidth - this.scrollContainer.clientWidth);\r\n }\r\n } else {\r\n this._canPage =\r\n Math.round(this.scrollContainer.scrollHeight) > Math.round(this.scrollContainer.clientHeight) + this.threshold;\r\n if (this._canPage) {\r\n this._canPageStart = Math.round(this.scrollContainer.scrollTop) > this.threshold;\r\n this._canPageEnd =\r\n Math.round(this.scrollContainer.scrollTop) + +this.threshold <\r\n Math.round(this.scrollContainer.scrollHeight - this.scrollContainer.clientHeight);\r\n }\r\n }\r\n\r\n if (!this._canPage) {\r\n this._canPageStart = this._canPageEnd = false;\r\n }\r\n\r\n if (canPage != this._canPage) {\r\n // Emit internal (undocumented) event for use with tabs.\r\n this.dispatchEvent(new CustomEvent(\"pagination-changed\"));\r\n }\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n \"m3e-slide-group\": M3eSlideGroupElement;\r\n }\r\n}\r\n"],"names":["M3eSlideGroupElement","ReconnectedCallback","LitElement","constructor","_M3eSlideGroupElement_directionalitySubscription","set","this","_M3eSlideGroupElement_resizeController","ResizeController","target","callback","_updatePaging","_canPage","_canPageStart","_canPageEnd","disabled","vertical","threshold","previousPageLabel","nextPageLabel","connectedCallback","super","__classPrivateFieldSet","M3eDirectionality","observe","requestUpdate","disconnectedCallback","__classPrivateFieldGet","call","reconnectedCallback","scrollContainer","firstUpdated","_changedProperties","render","prevButton","html","_M3eSlideGroupElement_instances","_M3eSlideGroupElement_pageStart","current","nextButton","_M3eSlideGroupElement_pageEnd","nothing","canPage","Math","round","scrollHeight","clientHeight","scrollTop","scrollWidth","clientWidth","scrollLeft","dispatchEvent","CustomEvent","top","scrollTo","behavior","left","styles","css","__decorate","query","prototype","state","property","type","Boolean","reflect","Number","attribute","debounce","customElement"],"mappings":"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"}
|
package/dist/slider.js
CHANGED
|
@@ -42,9 +42,10 @@ var _M3eSliderThumbElement_instances, _M3eSliderThumbElement_labelText_get;
|
|
|
42
42
|
* @attr name - The name that identifies the element when submitting the associated form.
|
|
43
43
|
* @attr value - The value of the thumb.
|
|
44
44
|
*
|
|
45
|
-
* @fires
|
|
46
|
-
* @fires
|
|
47
|
-
* @fires
|
|
45
|
+
* @fires beforeinput - Dispatched before the value changes.
|
|
46
|
+
* @fires input - Dispatched when the value changes.
|
|
47
|
+
* @fires change - Dispatched when the value changes.
|
|
48
|
+
* @fires click - Dispatched when the element is clicked.
|
|
48
49
|
*
|
|
49
50
|
* @cssprop --m3e-slider-thumb-width - Width of the slider thumb.
|
|
50
51
|
* @cssprop --m3e-slider-thumb-padding - Horizontal padding around the thumb.
|
|
@@ -117,7 +118,7 @@ __decorate([property({
|
|
|
117
118
|
})], M3eSliderThumbElement.prototype, "value", void 0);
|
|
118
119
|
M3eSliderThumbElement = __decorate([customElement("m3e-slider-thumb")], M3eSliderThumbElement);
|
|
119
120
|
|
|
120
|
-
var _M3eSliderElement_instances, _M3eSliderElement_directionalitySubscription, _M3eSliderElement_thumbs, _M3eSliderElement_activeThumb, _M3eSliderElement_cachedWidth, _M3eSliderElement_cachedThumbWidth, _M3eSliderElement_cachedLeft, _M3eSliderElement_renderTick, _M3eSliderElement_handleSlotChange, _M3eSliderElement_updateThumbs, _M3eSliderElement_pointFromValue, _M3eSliderElement_valueFromPoint, _M3eSliderElement_updateCachedDimensions, _M3eSliderElement_updateDimensions, _M3eSliderElement_updateTicks, _M3eSliderElement_handlePointerDown, _M3eSliderElement_handlePointerMove, _M3eSliderElement_handlePointerUp, _M3eSliderElement_handleKeyDown, _M3eSliderElement_handleThumbChange, _M3eSliderElement_changeThumb;
|
|
121
|
+
var _M3eSliderElement_instances, _M3eSliderElement_directionalitySubscription, _M3eSliderElement_changedThumbs, _M3eSliderElement_thumbs, _M3eSliderElement_activeThumb, _M3eSliderElement_cachedWidth, _M3eSliderElement_cachedThumbWidth, _M3eSliderElement_cachedLeft, _M3eSliderElement_renderTick, _M3eSliderElement_handleSlotChange, _M3eSliderElement_updateThumbs, _M3eSliderElement_pointFromValue, _M3eSliderElement_valueFromPoint, _M3eSliderElement_updateCachedDimensions, _M3eSliderElement_updateDimensions, _M3eSliderElement_updateTicks, _M3eSliderElement_handlePointerDown, _M3eSliderElement_handlePointerMove, _M3eSliderElement_handlePointerUp, _M3eSliderElement_handleKeyDown, _M3eSliderElement_handleKeyUp, _M3eSliderElement_handleThumbChange, _M3eSliderElement_changeThumb, _M3eSliderElement_commitThumb;
|
|
121
122
|
/**
|
|
122
123
|
* Allows for the selection of numeric values from a range.
|
|
123
124
|
*
|
|
@@ -155,6 +156,10 @@ var _M3eSliderElement_instances, _M3eSliderElement_directionalitySubscription, _
|
|
|
155
156
|
* @attr step - The value at which the thumb will snap.
|
|
156
157
|
* @attr size - The size of the slider.
|
|
157
158
|
*
|
|
159
|
+
* @fires beforeinput - Dispatched before the value of a thumb changes.
|
|
160
|
+
* @fires input - Dispatched when the value of a thumb changes.
|
|
161
|
+
* @fires change - Dispatched when the value of a thumb changes.
|
|
162
|
+
*
|
|
158
163
|
* @cssprop --m3e-slider-min-width - Minimum inline size of the slider host.
|
|
159
164
|
* @cssprop --m3e-slider-small-height - Height of the slider when size is small or extra-small.
|
|
160
165
|
* @cssprop --m3e-slider-medium-height - Height of the slider when size is medium.
|
|
@@ -199,6 +204,8 @@ let M3eSliderElement = class M3eSliderElement extends AttachInternals(LitElement
|
|
|
199
204
|
/** @private */
|
|
200
205
|
this._ticks = new Array();
|
|
201
206
|
/** @private */
|
|
207
|
+
_M3eSliderElement_changedThumbs.set(this, new Set());
|
|
208
|
+
/** @private */
|
|
202
209
|
_M3eSliderElement_thumbs.set(this, new Array());
|
|
203
210
|
/** @private */
|
|
204
211
|
_M3eSliderElement_activeThumb.set(this, void 0);
|
|
@@ -280,6 +287,7 @@ let M3eSliderElement = class M3eSliderElement extends AttachInternals(LitElement
|
|
|
280
287
|
/** @inheritdoc */
|
|
281
288
|
disconnectedCallback() {
|
|
282
289
|
super.disconnectedCallback();
|
|
290
|
+
__classPrivateFieldGet(this, _M3eSliderElement_changedThumbs, "f").clear();
|
|
283
291
|
__classPrivateFieldGet(this, _M3eSliderElement_directionalitySubscription, "f")?.call(this);
|
|
284
292
|
}
|
|
285
293
|
/** @inheritdoc */
|
|
@@ -291,10 +299,11 @@ let M3eSliderElement = class M3eSliderElement extends AttachInternals(LitElement
|
|
|
291
299
|
}
|
|
292
300
|
/** @inheritdoc */
|
|
293
301
|
render() {
|
|
294
|
-
return html`<div class="base" tabindex="${ifDefined(!this.disabled ? "-1" : undefined)}" @pointerdown="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handlePointerDown)}" @pointermove="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handlePointerMove)}" @pointerup="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handlePointerUp)}" @keydown="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handleKeyDown)}" @value-change="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handleThumbChange)}"><div class="track" aria-hidden="true"><div class="track-inactive start"></div><div class="track-active"></div><div class="track-inactive end"></div></div><div class="ticks" aria-hidden="true">${this._ticks.map(x => __classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_renderTick).call(this, x))}</div><slot @slotchange="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handleSlotChange)}"></slot></div>`;
|
|
302
|
+
return html`<div class="base" tabindex="${ifDefined(!this.disabled ? "-1" : undefined)}" @pointerdown="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handlePointerDown)}" @pointermove="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handlePointerMove)}" @pointerup="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handlePointerUp)}" @keydown="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handleKeyDown)}" @keyup="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handleKeyUp)}" @value-change="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handleThumbChange)}"><div class="track" aria-hidden="true"><div class="track-inactive start"></div><div class="track-active"></div><div class="track-inactive end"></div></div><div class="ticks" aria-hidden="true">${this._ticks.map(x => __classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_renderTick).call(this, x))}</div><slot @slotchange="${__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_handleSlotChange)}"></slot></div>`;
|
|
295
303
|
}
|
|
296
304
|
};
|
|
297
305
|
_M3eSliderElement_directionalitySubscription = new WeakMap();
|
|
306
|
+
_M3eSliderElement_changedThumbs = new WeakMap();
|
|
298
307
|
_M3eSliderElement_thumbs = new WeakMap();
|
|
299
308
|
_M3eSliderElement_activeThumb = new WeakMap();
|
|
300
309
|
_M3eSliderElement_cachedWidth = new WeakMap();
|
|
@@ -405,6 +414,7 @@ _M3eSliderElement_handlePointerDown = function _M3eSliderElement_handlePointerDo
|
|
|
405
414
|
if (e.target instanceof HTMLElement) {
|
|
406
415
|
e.target.setPointerCapture(e.pointerId);
|
|
407
416
|
}
|
|
417
|
+
__classPrivateFieldGet(this, _M3eSliderElement_changedThumbs, "f").clear();
|
|
408
418
|
__classPrivateFieldSet(this, _M3eSliderElement_activeThumb, e.composedPath().find(x => x instanceof M3eSliderThumbElement), "f");
|
|
409
419
|
if (__classPrivateFieldGet(this, _M3eSliderElement_activeThumb, "f")) {
|
|
410
420
|
return;
|
|
@@ -465,6 +475,7 @@ _M3eSliderElement_handlePointerUp = function _M3eSliderElement_handlePointerUp(e
|
|
|
465
475
|
e.target.releasePointerCapture(e.pointerId);
|
|
466
476
|
}
|
|
467
477
|
if (__classPrivateFieldGet(this, _M3eSliderElement_activeThumb, "f") && !__classPrivateFieldGet(this, _M3eSliderElement_activeThumb, "f").disabled) {
|
|
478
|
+
__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_commitThumb).call(this, __classPrivateFieldGet(this, _M3eSliderElement_activeThumb, "f"));
|
|
468
479
|
__classPrivateFieldGet(this, _M3eSliderElement_activeThumb, "f").focus();
|
|
469
480
|
}
|
|
470
481
|
};
|
|
@@ -531,6 +542,12 @@ _M3eSliderElement_handleKeyDown = function _M3eSliderElement_handleKeyDown(e) {
|
|
|
531
542
|
break;
|
|
532
543
|
}
|
|
533
544
|
};
|
|
545
|
+
_M3eSliderElement_handleKeyUp = function _M3eSliderElement_handleKeyUp(e) {
|
|
546
|
+
const activeThumb = e.composedPath().find(x => x instanceof M3eSliderThumbElement);
|
|
547
|
+
if (activeThumb) {
|
|
548
|
+
__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_commitThumb).call(this, activeThumb);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
534
551
|
_M3eSliderElement_handleThumbChange = function _M3eSliderElement_handleThumbChange(e) {
|
|
535
552
|
e.stopPropagation();
|
|
536
553
|
__classPrivateFieldGet(this, _M3eSliderElement_instances, "m", _M3eSliderElement_updateThumbs).call(this);
|
|
@@ -538,31 +555,35 @@ _M3eSliderElement_handleThumbChange = function _M3eSliderElement_handleThumbChan
|
|
|
538
555
|
};
|
|
539
556
|
_M3eSliderElement_changeThumb = function _M3eSliderElement_changeThumb(thumb, value, animate = false) {
|
|
540
557
|
if (thumb.value === value) return;
|
|
541
|
-
|
|
542
|
-
if (animate && !prefersReducedMotion()) {
|
|
543
|
-
addCustomState(this, "--animating");
|
|
544
|
-
thumb.addEventListener("transitionend", () => {
|
|
545
|
-
thumb.style.transition = "";
|
|
546
|
-
deleteCustomState(this, "--animating");
|
|
547
|
-
}, {
|
|
548
|
-
once: true
|
|
549
|
-
});
|
|
550
|
-
thumb.style.transition = `transform ${DesignToken.motion.spring.fastEffects}`;
|
|
551
|
-
}
|
|
552
|
-
thumb.value = value;
|
|
553
|
-
thumb.markAsDirty();
|
|
554
|
-
thumb.markAsTouched();
|
|
555
|
-
if (thumb.dispatchEvent(new Event("input", {
|
|
558
|
+
if (thumb.dispatchEvent(new Event("beforeinput", {
|
|
556
559
|
bubbles: true,
|
|
557
|
-
composed: true,
|
|
558
560
|
cancelable: true
|
|
559
561
|
}))) {
|
|
562
|
+
if (animate && !prefersReducedMotion()) {
|
|
563
|
+
addCustomState(this, "--animating");
|
|
564
|
+
thumb.addEventListener("transitionend", () => {
|
|
565
|
+
thumb.style.transition = "";
|
|
566
|
+
deleteCustomState(this, "--animating");
|
|
567
|
+
}, {
|
|
568
|
+
once: true
|
|
569
|
+
});
|
|
570
|
+
thumb.style.transition = `transform ${DesignToken.motion.spring.fastEffects}`;
|
|
571
|
+
}
|
|
572
|
+
__classPrivateFieldGet(this, _M3eSliderElement_changedThumbs, "f").add(thumb);
|
|
573
|
+
thumb.value = value;
|
|
574
|
+
thumb.markAsDirty();
|
|
575
|
+
thumb.markAsTouched();
|
|
576
|
+
thumb.dispatchEvent(new Event("input", {
|
|
577
|
+
bubbles: true
|
|
578
|
+
}));
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
_M3eSliderElement_commitThumb = function _M3eSliderElement_commitThumb(thumb) {
|
|
582
|
+
if (__classPrivateFieldGet(this, _M3eSliderElement_changedThumbs, "f").has(thumb)) {
|
|
560
583
|
thumb.dispatchEvent(new Event("change", {
|
|
561
|
-
bubbles: true
|
|
562
|
-
composed: true
|
|
584
|
+
bubbles: true
|
|
563
585
|
}));
|
|
564
|
-
|
|
565
|
-
thumb.value = prev;
|
|
586
|
+
__classPrivateFieldGet(this, _M3eSliderElement_changedThumbs, "f").delete(thumb);
|
|
566
587
|
}
|
|
567
588
|
};
|
|
568
589
|
/** The styles of the element. */
|