@awc-ui/core 1.0.0-beta.5 → 1.0.0-beta.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/dist/cjs/md-button_6.cjs.entry.js +17 -2
- package/dist/cjs/md-button_6.cjs.entry.js.map +1 -1
- package/dist/cjs/md-segmented-button-set.cjs.entry.js +20 -2
- package/dist/cjs/md-segmented-button-set.cjs.entry.js.map +1 -1
- package/dist/collection/components/md-button/md-button.js +17 -2
- package/dist/collection/components/md-button/md-button.js.map +1 -1
- package/dist/collection/components/md-segmented-button-set/md-segmented-button-set.js +20 -2
- package/dist/collection/components/md-segmented-button-set/md-segmented-button-set.js.map +1 -1
- package/dist/components/md-button.js +1 -1
- package/dist/components/md-date-picker.js +1 -1
- package/dist/components/md-dialog.js +1 -1
- package/dist/components/md-multi-select.js +1 -1
- package/dist/components/md-segmented-button-set.js +1 -1
- package/dist/components/md-segmented-button-set.js.map +1 -1
- package/dist/components/md-snackbar.js +1 -1
- package/dist/components/md-step.js +1 -1
- package/dist/components/md-stepper.js +1 -1
- package/dist/components/md-time-picker.js +1 -1
- package/dist/components/{p-C1RN8YA1.js → p-BTgac9TA.js} +2 -2
- package/dist/components/p-BTgac9TA.js.map +1 -0
- package/dist/components-csr/md-button.js +1 -1
- package/dist/components-csr/md-date-picker.js +1 -1
- package/dist/components-csr/md-dialog.js +1 -1
- package/dist/components-csr/md-multi-select.js +1 -1
- package/dist/components-csr/md-segmented-button-set.js +1 -1
- package/dist/components-csr/md-segmented-button-set.js.map +1 -1
- package/dist/components-csr/md-snackbar.js +1 -1
- package/dist/components-csr/md-step.js +1 -1
- package/dist/components-csr/md-stepper.js +1 -1
- package/dist/components-csr/md-time-picker.js +1 -1
- package/dist/components-csr/{p-GG1ZMEng.js → p-QF3B4ODr.js} +2 -2
- package/dist/components-csr/p-QF3B4ODr.js.map +1 -0
- package/dist/esm/md-button_6.entry.js +17 -2
- package/dist/esm/md-button_6.entry.js.map +1 -1
- package/dist/esm/md-segmented-button-set.entry.js +20 -2
- package/dist/esm/md-segmented-button-set.entry.js.map +1 -1
- package/dist/md3/md3.esm.js +1 -1
- package/dist/md3/p-91df971f.entry.js +2 -0
- package/dist/md3/p-91df971f.entry.js.map +1 -0
- package/dist/md3/p-e661754b.entry.js +2 -0
- package/dist/md3/p-e661754b.entry.js.map +1 -0
- package/dist/types/components/md-segmented-button-set/md-segmented-button-set.d.ts +16 -0
- package/hydrate/index.js +37 -4
- package/hydrate/index.mjs +37 -4
- package/package.json +2 -2
- package/dist/components/p-C1RN8YA1.js.map +0 -1
- package/dist/components-csr/p-GG1ZMEng.js.map +0 -1
- package/dist/md3/p-56ea09a4.entry.js +0 -2
- package/dist/md3/p-56ea09a4.entry.js.map +0 -1
- package/dist/md3/p-6b841f69.entry.js +0 -2
- package/dist/md3/p-6b841f69.entry.js.map +0 -1
|
@@ -12,6 +12,24 @@ const MdSegmentedButtonSet = class {
|
|
|
12
12
|
this.multiselect = false;
|
|
13
13
|
/** Density: 0 = 40px, -1 = 36px, -2 = 32px, -3 = 28px, -4 = 24px */
|
|
14
14
|
this.density = 0;
|
|
15
|
+
/**
|
|
16
|
+
* Re-assign positions whenever the slotted segments change.
|
|
17
|
+
*
|
|
18
|
+
* `componentDidLoad` alone is not enough, and the gap is visible rather than
|
|
19
|
+
* theoretical. A segment defaults to `segmentIndex: 0` of `segmentTotal: 1`,
|
|
20
|
+
* which makes it BOTH first and last — so an unsynced segment renders fully
|
|
21
|
+
* rounded on every edge. Replace a set's children after it has loaded and
|
|
22
|
+
* every segment in it becomes a lone pill: the joined bar visibly falls apart,
|
|
23
|
+
* and nothing about it looks like a stale index.
|
|
24
|
+
*
|
|
25
|
+
* Any consumer that renders segments dynamically hits this — a set whose
|
|
26
|
+
* options come from state, a framework re-render, or `replaceChildren()`. The
|
|
27
|
+
* showcase dock rebuilds its controls that way and shows the bug on the first
|
|
28
|
+
* re-render after navigation.
|
|
29
|
+
*/
|
|
30
|
+
this.handleSlotChange = () => {
|
|
31
|
+
this.syncSegments();
|
|
32
|
+
};
|
|
15
33
|
}
|
|
16
34
|
onPropsChange() {
|
|
17
35
|
this.syncSegments();
|
|
@@ -58,10 +76,10 @@ const MdSegmentedButtonSet = class {
|
|
|
58
76
|
}
|
|
59
77
|
}
|
|
60
78
|
render() {
|
|
61
|
-
return (index.h(index.Host, { key: '
|
|
79
|
+
return (index.h(index.Host, { key: '2a8bf244149352d69dfb03dd32ef0dcc24487dc4', class: {
|
|
62
80
|
'md-segmented-button-set': true,
|
|
63
81
|
[`md-segmented-button-set--density-${Math.abs(this.density)}`]: this.density !== 0,
|
|
64
|
-
}, role: this.multiselect ? 'group' : 'radiogroup' }, index.h("slot", { key: '
|
|
82
|
+
}, role: this.multiselect ? 'group' : 'radiogroup' }, index.h("slot", { key: '2d6cfc8e5a79bf9dc7d4cf92d0a087b9401bff46', onSlotchange: this.handleSlotChange })));
|
|
65
83
|
}
|
|
66
84
|
get el() { return index.getElement(this); }
|
|
67
85
|
static get watchers() { return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"md-segmented-button-set.cjs.entry.js","mappings":";;;;AAAA,MAAM,uBAAuB,GAAG,MAAM,CAAC,wRAAwR,CAAC;;MCQnT,oBAAoB,GAAA,MAAA;AALjC,IAAA,WAAA,CAAA,OAAA,EAAA;;;;AASU,QAAA,IAAA,CAAA,WAAW,GAAY,KAAK;;AAGX,QAAA,IAAA,CAAA,OAAO,GAA0B,CAAC;
|
|
1
|
+
{"file":"md-segmented-button-set.cjs.entry.js","mappings":";;;;AAAA,MAAM,uBAAuB,GAAG,MAAM,CAAC,wRAAwR,CAAC;;MCQnT,oBAAoB,GAAA,MAAA;AALjC,IAAA,WAAA,CAAA,OAAA,EAAA;;;;AASU,QAAA,IAAA,CAAA,WAAW,GAAY,KAAK;;AAGX,QAAA,IAAA,CAAA,OAAO,GAA0B,CAAC;AAgD3D;;;;;;;;;;;;;;AAcG;AACK,QAAA,IAAA,CAAA,gBAAgB,GAAG,MAAK;YAC9B,IAAI,CAAC,YAAY,EAAE;AACrB,SAAC;AA4BF;IAtFC,aAAa,GAAA;QACX,IAAI,CAAC,YAAY,EAAE;;IAGrB,gBAAgB,GAAA;QACd,IAAI,CAAC,YAAY,EAAE;;AAIrB,IAAA,kBAAkB,CAAC,KAAwD,EAAA;QACzE,KAAK,CAAC,eAAe,EAAE;AACvB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;;;;;;;;AAQnC,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,MAA+B;AACrD,QAAA,IAAI,CAAC,OAAO;YAAE;AAEd,QAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,MAAM;AAEjC,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;AACpB,YAAA,OAAO,CAAC,QAAQ,GAAG,QAAQ;;aACtB;AACL,YAAA,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE;AAC1B,gBAAA,GAAG,CAAC,QAAQ,GAAG,GAAG,KAAK,OAAO;;;AAIlC,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CACnD;;IAGK,WAAW,GAAA;AACjB,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAgC;;IAsB3F,YAAY,GAAA;AAClB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;AACnC,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM;AAE7B,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;AAC9B,YAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC;AACvB,YAAA,GAAG,CAAC,YAAY,GAAG,CAAC;AACpB,YAAA,GAAG,CAAC,YAAY,GAAG,KAAK;AACxB,YAAA,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO;AACjC,YAAA,GAAG,CAAC,kBAAkB,GAAG,IAAI,CAAC,WAAW;;;IAI7C,MAAM,GAAA;QACJ,QACEA,OAAA,CAACC,UAAI,EAAA,EAAA,GAAA,EAAA,0CAAA,EACH,KAAK,EAAE;AACL,gBAAA,yBAAyB,EAAE,IAAI;AAC/B,gBAAA,CAAC,oCAAoC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA,CAAE,GAAG,IAAI,CAAC,OAAO,KAAK,CAAC;AACnF,aAAA,EACD,IAAI,EAAE,IAAI,CAAC,WAAW,GAAG,OAAO,GAAG,YAAY,EAAA,EAE/CD,OAAA,CAAA,MAAA,EAAA,EAAA,GAAA,EAAA,0CAAA,EAAM,YAAY,EAAE,IAAI,CAAC,gBAAgB,EAAA,CAAS,CAC7C;;;;;;;;;;;;;;;;","names":["h","Host"],"sources":["src/components/md-segmented-button-set/md-segmented-button-set.css?tag=md-segmented-button-set&encapsulation=shadow","src/components/md-segmented-button-set/md-segmented-button-set.tsx"],"sourcesContent":["/* ==========================================================\n md-segmented-button-set — Container for segmented buttons\n Spec: https://m3.material.io/components/segmented-buttons/specs\n ========================================================== */\n\n:host {\n display: inline-grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n box-sizing: border-box;\n vertical-align: middle;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n :host {\n forced-color-adjust: none;\n }\n}\n\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import { Component, Host, h, Prop, Element, Event, EventEmitter, Listen, Watch } from '@stencil/core';\nimport { SegmentElement } from '../../utils/types';\n\n@Component({\n tag: 'md-segmented-button-set',\n styleUrl: 'md-segmented-button-set.css',\n shadow: true,\n})\nexport class MdSegmentedButtonSet {\n @Element() el!: HTMLElement;\n\n /** Single-select or multi-select mode */\n @Prop() multiselect: boolean = false;\n\n /** Density: 0 = 40px, -1 = 36px, -2 = 32px, -3 = 28px, -4 = 24px */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fires when the set of selected segment values changes */\n @Event() mdChange: EventEmitter<string[]>;\n\n @Watch('multiselect')\n @Watch('density')\n onPropsChange() {\n this.syncSegments();\n }\n\n componentDidLoad() {\n this.syncSegments();\n }\n\n @Listen('mdSegmentClick')\n handleSegmentClick(event: CustomEvent<{ value: string; selected: boolean }>) {\n event.stopPropagation();\n const segments = this.getSegments();\n // Match by element identity, not by `.value`. The child segment\n // emits `mdSegmentClick` from its own host, and the event re-targets\n // to that <md-segmented-button> as it crosses the shadow boundary\n // into this set. Matching by value would break whenever segments\n // share the default value of '' (which is the common case when\n // consumers omit the `value` prop — every segment would toggle\n // together because every `'' === ''` is true).\n const clicked = event.target as SegmentElement | null;\n if (!clicked) return;\n\n const { selected } = event.detail;\n\n if (this.multiselect) {\n clicked.selected = selected;\n } else {\n for (const seg of segments) {\n seg.selected = seg === clicked;\n }\n }\n\n this.mdChange.emit(\n segments.filter(s => s.selected).map(s => s.value),\n );\n }\n\n private getSegments(): SegmentElement[] {\n return Array.from(this.el.querySelectorAll('md-segmented-button')) as unknown as SegmentElement[];\n }\n\n /**\n * Re-assign positions whenever the slotted segments change.\n *\n * `componentDidLoad` alone is not enough, and the gap is visible rather than\n * theoretical. A segment defaults to `segmentIndex: 0` of `segmentTotal: 1`,\n * which makes it BOTH first and last — so an unsynced segment renders fully\n * rounded on every edge. Replace a set's children after it has loaded and\n * every segment in it becomes a lone pill: the joined bar visibly falls apart,\n * and nothing about it looks like a stale index.\n *\n * Any consumer that renders segments dynamically hits this — a set whose\n * options come from state, a framework re-render, or `replaceChildren()`. The\n * showcase dock rebuilds its controls that way and shows the bug on the first\n * re-render after navigation.\n */\n private handleSlotChange = () => {\n this.syncSegments();\n };\n\n private syncSegments() {\n const segments = this.getSegments();\n const total = segments.length;\n\n for (let i = 0; i < total; i++) {\n const seg = segments[i];\n seg.segmentIndex = i;\n seg.segmentTotal = total;\n seg.segmentDensity = this.density;\n seg.segmentMultiselect = this.multiselect;\n }\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-segmented-button-set': true,\n [`md-segmented-button-set--density-${Math.abs(this.density)}`]: this.density !== 0,\n }}\n role={this.multiselect ? 'group' : 'radiogroup'}\n >\n <slot onSlotchange={this.handleSlotChange}></slot>\n </Host>\n );\n }\n}\n"],"version":3}
|
|
@@ -130,7 +130,22 @@ export class MdButton {
|
|
|
130
130
|
before. window.open remains for a programmatic click() on a button
|
|
131
131
|
whose href is safe but whose anchor has not rendered yet. */
|
|
132
132
|
const href = sanitizeHref(this.href);
|
|
133
|
-
if (href
|
|
133
|
+
if (!href)
|
|
134
|
+
return;
|
|
135
|
+
const anchor = this.el.shadowRoot?.querySelector('.md-button__anchor');
|
|
136
|
+
/* Did this click actually pass THROUGH the anchor? composedPath sees
|
|
137
|
+
across the shadow boundary, so a real pointer click — on the label, an
|
|
138
|
+
icon, or the anchor's stretched ::after over the padding — is
|
|
139
|
+
recognised and left alone: the browser is already navigating.
|
|
140
|
+
|
|
141
|
+
A PROGRAMMATIC el.click() targets the host and never reaches the
|
|
142
|
+
anchor, so nothing would happen at all. A native <a>.click() does
|
|
143
|
+
navigate, and this component behaved that way before it grew a real
|
|
144
|
+
anchor — including keyboard activation, which routes through
|
|
145
|
+
el.click() in handleKeyDown. Falling back to window.open keeps both
|
|
146
|
+
working, and the composedPath check is what stops a real click from
|
|
147
|
+
navigating twice. */
|
|
148
|
+
if (!anchor || !e.composedPath().includes(anchor)) {
|
|
134
149
|
window.open(href, this.target, SAFE_WINDOW_FEATURES);
|
|
135
150
|
}
|
|
136
151
|
return;
|
|
@@ -195,7 +210,7 @@ export class MdButton {
|
|
|
195
210
|
context. Blanket noreferrer would also strip the Referer on ordinary
|
|
196
211
|
same-tab navigation, quietly breaking referrer-based analytics. */
|
|
197
212
|
const opensNewContext = !!this.target && this.target !== '_self';
|
|
198
|
-
return (h(Host, { key: '
|
|
213
|
+
return (h(Host, { key: 'be127994ceadc697fd589c22af7d7ecc3bc0908d', class: {
|
|
199
214
|
'md-button': true,
|
|
200
215
|
[`md-button--${this.variant}`]: true,
|
|
201
216
|
[`md-button--${this.size}`]: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"md-button.js","sourceRoot":"","sources":["../../../src/components/md-button/md-button.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Fragment, Host, h, Prop, State, Event, EventEmitter, Element, AttachInternals } from '@stencil/core';\nimport { LazyLoadingIndicator } from '../../utils/lazy-loading-indicator';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_LINK_REL, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n/**\n * Detail payload emitted by `md-button`'s `mdClick` event when the user\n * activates the button (mouse, touch, or keyboard).\n *\n * The event is **cancelable** — calling `event.preventDefault()` from a\n * listener stops the button's default side effects (toggle-state flip\n * and `href` navigation) but does NOT stop the underlying DOM click\n * event. This is the recommended hook for SPA routing and \"are you\n * sure?\" confirmation flows.\n */\nexport interface MdButtonClickDetail {\n /** The button's `value` prop (useful when grouped via `md-button-group`). */\n value: string;\n /** Whether toggle mode is enabled. */\n toggle: boolean;\n /**\n * Selected state the button WILL transition to if the click is not\n * cancelled. In non-toggle mode this is identical to `selected`.\n */\n selected: boolean;\n /** Navigation target (empty if the button is not a link). */\n href: string;\n /** Browsing context (`_self`, `_blank`, …). */\n target: string;\n /** The original DOM event that triggered the activation. */\n originalEvent: MouseEvent | KeyboardEvent;\n}\n\n/**\n * Detail payload emitted by `md-button`'s `mdChange` event when toggle\n * mode flips the selected state in response to a user activation.\n */\nexport interface MdButtonChangeDetail {\n /** New selected state. */\n selected: boolean;\n /** The button's `value` prop. */\n value: string;\n}\n\n@Component({\n tag: 'md-button',\n styleUrl: 'md-button.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdButton {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Used to submit/reset the associated form when\n * `type` is `submit`/`reset` — works across shadow boundaries, unlike a\n * native `<button>` rendered in the shadow root (which can't see the\n * light-DOM `<form>` it lives in).\n */\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Activation behavior, mirroring the native `<button type>`:\n * - `button` (default): no implicit form action.\n * - `submit`: submits the associated form (`requestSubmit`, so the form's\n * `submit` event fires and constraint validation runs).\n * - `reset`: resets the associated form.\n */\n @Prop({ reflect: true }) type: 'button' | 'submit' | 'reset' = 'button';\n\n @Prop() variant: 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal' = 'filled';\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n @Prop() shape: 'round' | 'square' = 'round';\n @Prop({ reflect: true }) disabled: boolean = false;\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n @Prop() ripple: boolean = true;\n @Prop() loading: boolean = false;\n @Prop() icon: string = '';\n @Prop() trailingIcon: string = '';\n @Prop() href: string = '';\n @Prop() target: string = '_self';\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /**\n * Mirror leading and trailing icons horizontally when the button is\n * rendered in a right-to-left context. Set this on buttons that use\n * **directional** Material Symbols (arrows, chevrons, send, reply…)\n * — non-directional icons (add, search, favorite…) should leave it\n * `false` so the glyph stays semantically correct.\n */\n @Prop({ reflect: true, attribute: 'mirror-icon' }) mirrorIcon: boolean = false;\n\n /**\n * When true, suppresses the default 180° trailing-icon rotation while\n * `aria-expanded=\"true\"`. Use when the consumer swaps the glyph (e.g.\n * docked `md-date-picker` month/year triggers use `chevron_right`).\n */\n @Prop({ reflect: true, attribute: 'suppress-expand-icon-flip' })\n suppressExpandIconFlip: boolean = false;\n\n /**\n * Stretch the button to fill its inline-axis container.\n *\n * Switches the host from `inline-flex` to `flex` and sets\n * `inline-size: 100%` so the button consumes the full width of its\n * parent — the standard pattern for primary CTAs in forms, modals,\n * and bottom sheets. The size's `min-block-size` (touch target) is\n * preserved.\n *\n * For arbitrary fixed widths or heights, set the\n * `--md-button-width`, `--md-button-height`, `--md-button-min-width`,\n * `--md-button-min-height`, or `--md-button-max-width` CSS custom\n * properties on the host instead.\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest, so Tab enters the group\n * once instead of stepping through every button. Outside a group, this\n * stays `null` and the button uses its normal tabindex behavior.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Override the default `role=\"button\"`. Used by composite widgets such as\n * `md-date-picker` day cells (`role=\"gridcell\"`). Leave empty for `button`.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fires every time the user activates the button (mouse click, touch,\n * or `Enter`/`Space` while focused). The event is **cancelable** and\n * the detail payload describes what *would* happen: the post-click\n * toggle state, the navigation `href`, and so on.\n *\n * Calling `event.preventDefault()` from a listener suppresses the\n * default side effects (toggle flip + `href` navigation) but lets\n * the underlying DOM click bubble. This is the hook to use for SPA\n * routing, \"are you sure?\" prompts, async confirmation, etc.\n *\n * The event bubbles and is composed, so listeners outside the\n * shadow tree (the typical case) receive it.\n *\n * ```ts\n * document.querySelector('md-button')!.addEventListener('mdClick', (e) => {\n * const { href, selected } = (e as CustomEvent).detail;\n * if (!confirm('Continue?')) e.preventDefault();\n * });\n * ```\n */\n @Event({ cancelable: true, bubbles: true, composed: true })\n mdClick!: EventEmitter<MdButtonClickDetail>;\n\n /**\n * Fires when toggle mode flips the `selected` state in response to a\n * user activation. Not cancelable — the state change has already\n * happened. Pair with `mdClick` (cancelable) when you need a veto.\n *\n * Bubbles and is composed.\n */\n @Event({ bubbles: true, composed: true })\n mdChange!: EventEmitter<MdButtonChangeDetail>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled || this.loading;\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const leadingSlot = shadow.querySelector('slot[name=\"leading-icon\"]') as HTMLSlotElement | null;\n const trailingSlot = shadow.querySelector('slot[name=\"trailing-icon\"]') as HTMLSlotElement | null;\n\n leadingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedLeadingIcon = leadingSlot.assignedElements().length > 0;\n });\n trailingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrailingIcon = trailingSlot.assignedElements().length > 0;\n });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n // Compute the post-click toggle state up front so the detail\n // payload describes what *would* happen — listeners can then\n // call preventDefault on the CustomEvent to veto the change.\n const nextSelected = this.toggle ? !this.selected : this.selected;\n\n const evt = this.mdClick.emit({\n value: this.value,\n toggle: this.toggle,\n selected: nextSelected,\n href: this.href,\n target: this.target,\n originalEvent: e,\n });\n\n if (evt.defaultPrevented) {\n // Suppress browser's default link navigation as well so the\n // host stays consistent. We don't flip selected and don't\n // open the href.\n e.preventDefault();\n return;\n }\n\n if (this.toggle && nextSelected !== this.selected) {\n this.selected = nextSelected;\n this.mdChange.emit({ selected: nextSelected, value: this.value });\n }\n\n /* Setting `href` makes this a link rather than a form control, so the\n branch is taken on the raw prop — an unsafe URL must not silently fall\n through to submitting the form. Only the navigation itself is refused. */\n if (this.href) {\n /* A safe href renders a REAL <a> in the shadow root, and the browser\n owns activation from there — so do nothing here. That is what makes\n middle-click, cmd/ctrl-click and \"copy link address\" work, and it is\n why cancelling mdClick above (which calls preventDefault on this very\n event) still vetoes navigation.\n\n The fallback below covers only the case where NO anchor exists: an\n href that failed sanitising renders none, so there is nothing to\n navigate and nothing to fall back to — the navigation is refused, as\n before. window.open remains for a programmatic click() on a button\n whose href is safe but whose anchor has not rendered yet. */\n const href = sanitizeHref(this.href);\n if (href && !this.el.shadowRoot?.querySelector('.md-button__anchor')) {\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n }\n return;\n }\n\n // Implicit form action, mirroring a native submit/reset button. Uses\n // ElementInternals so the associated <form> is found across the shadow\n // boundary. requestSubmit() (not submit()) so the form's submit event\n // fires and built-in constraint validation runs.\n if (this.type === 'submit') {\n this.internals.form?.requestSubmit();\n } else if (this.type === 'reset') {\n this.internals.form?.reset();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const hasLeadingIcon = !!this.icon;\n const hasTrailingIcon = !!this.trailingIcon;\n /* A component that accepts `href` must produce a real link. Sanitising\n here (not just at click time) means an unsafe URL renders NO anchor at\n all rather than an inert one. Disabled link-buttons also drop the\n anchor: there is no disabled state for <a>, and a focusable link that\n refuses to navigate is worse than no link. */\n const linkHref =\n this.href && !isEffectivelyDisabled ? sanitizeHref(this.href) : '';\n /* rel only where it means something: a target that opens a NEW browsing\n context. Blanket noreferrer would also strip the Referer on ordinary\n same-tab navigation, quietly breaking referrer-based analytics. */\n const opensNewContext = !!this.target && this.target !== '_self';\n\n return (\n <Host\n class={{\n 'md-button': true,\n [`md-button--${this.variant}`]: true,\n [`md-button--${this.size}`]: true,\n [`md-button--${this.shape}`]: true,\n 'md-button--with-leading-icon': hasLeadingIcon || this.hasSlottedLeadingIcon,\n 'md-button--with-trailing-icon': hasTrailingIcon || this.hasSlottedTrailingIcon,\n 'md-button--disabled': this.disabled || this.softDisabled,\n 'md-button--loading': this.loading,\n 'md-button--toggle': this.toggle,\n 'md-button--selected': this.selected,\n 'md-button--shape-morph': this.shapeMorph,\n 'md-button--pressed': this.shapeMorph && this.pressed,\n 'md-button--connected-left': this.connectedLeft,\n 'md-button--connected-right': this.connectedRight,\n 'md-button--full-width': this.fullWidth,\n }}\n role={this.roleOverride || (linkHref ? null : 'button')}\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n /* When a real anchor is rendered IT is the focusable element, so the\n host must not be a tab stop as well — otherwise every link button\n costs two presses of Tab and screen readers meet a button wrapping\n a link. */\n linkHref\n ? null\n : this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {linkHref ? (\n <a\n class=\"md-button__anchor\"\n part=\"anchor\"\n role=\"link\"\n href={linkHref}\n target={this.target || undefined}\n rel={opensNewContext ? SAFE_LINK_REL : undefined}\n tabindex={this.groupTabindex !== null ? String(this.groupTabindex) : '0'}\n aria-disabled={isEffectivelyDisabled ? 'true' : null}\n >\n {this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)}\n </a>\n ) : (\n this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)\n )}\n </Host>\n );\n }\n\n /** Button innards, rendered either directly in the host or inside the\n * anchor when `href` makes this a link. */\n private renderContent(\n isEffectivelyDisabled: boolean,\n hasLeadingIcon: boolean,\n hasTrailingIcon: boolean,\n ) {\n return (\n <Fragment>\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n <slot name=\"leading-icon\">\n {hasLeadingIcon && <span class=\"md-button__icon material-symbols-outlined\" part=\"icon\">{this.icon}</span>}\n </slot>\n <span class=\"md-button__label\" part=\"label\"><slot /></span>\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && <span class=\"md-button__trailing-icon material-symbols-outlined\" part=\"trailing-icon\">{this.trailingIcon}</span>}\n </slot>\n {this.loading && (\n /* md-loading-indicator, not a hand-rolled ring: never ship a custom\n loading affordance where a library component exists. It is\n md-loading-indicator rather than md-progress-indicator because the\n latter clamps its circular variant to a 24px M3 minimum, while a\n button spinner runs 10-28px -- every tier but xl would clamp up and\n lose the density taper. Same choice md-select made for its trigger.\n\n The `loader` slot lets a consumer swap it (e.g. for a circular\n md-progress-indicator). The size hooks sit on this WRAPPER so they\n cascade to whatever ends up inside it, default or slotted. */\n <span class=\"md-button__loading\" part=\"loading\" aria-hidden=\"true\">\n <slot name=\"loader\">\n <LazyLoadingIndicator class=\"md-button__loading-default\" />\n </slot>\n </span>\n )}\n </Fragment>\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"md-button.js","sourceRoot":"","sources":["../../../src/components/md-button/md-button.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Fragment, Host, h, Prop, State, Event, EventEmitter, Element, AttachInternals } from '@stencil/core';\nimport { LazyLoadingIndicator } from '../../utils/lazy-loading-indicator';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_LINK_REL, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\n/**\n * Detail payload emitted by `md-button`'s `mdClick` event when the user\n * activates the button (mouse, touch, or keyboard).\n *\n * The event is **cancelable** — calling `event.preventDefault()` from a\n * listener stops the button's default side effects (toggle-state flip\n * and `href` navigation) but does NOT stop the underlying DOM click\n * event. This is the recommended hook for SPA routing and \"are you\n * sure?\" confirmation flows.\n */\nexport interface MdButtonClickDetail {\n /** The button's `value` prop (useful when grouped via `md-button-group`). */\n value: string;\n /** Whether toggle mode is enabled. */\n toggle: boolean;\n /**\n * Selected state the button WILL transition to if the click is not\n * cancelled. In non-toggle mode this is identical to `selected`.\n */\n selected: boolean;\n /** Navigation target (empty if the button is not a link). */\n href: string;\n /** Browsing context (`_self`, `_blank`, …). */\n target: string;\n /** The original DOM event that triggered the activation. */\n originalEvent: MouseEvent | KeyboardEvent;\n}\n\n/**\n * Detail payload emitted by `md-button`'s `mdChange` event when toggle\n * mode flips the selected state in response to a user activation.\n */\nexport interface MdButtonChangeDetail {\n /** New selected state. */\n selected: boolean;\n /** The button's `value` prop. */\n value: string;\n}\n\n@Component({\n tag: 'md-button',\n styleUrl: 'md-button.css',\n shadow: true,\n formAssociated: true,\n})\nexport class MdButton {\n @Element() el!: HTMLElement;\n\n /**\n * Form-association handle. Used to submit/reset the associated form when\n * `type` is `submit`/`reset` — works across shadow boundaries, unlike a\n * native `<button>` rendered in the shadow root (which can't see the\n * light-DOM `<form>` it lives in).\n */\n @AttachInternals() internals!: ElementInternals;\n\n /**\n * Activation behavior, mirroring the native `<button type>`:\n * - `button` (default): no implicit form action.\n * - `submit`: submits the associated form (`requestSubmit`, so the form's\n * `submit` event fires and constraint validation runs).\n * - `reset`: resets the associated form.\n */\n @Prop({ reflect: true }) type: 'button' | 'submit' | 'reset' = 'button';\n\n @Prop() variant: 'filled' | 'outlined' | 'text' | 'elevated' | 'tonal' = 'filled';\n @Prop() size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = 'sm';\n @Prop() shape: 'round' | 'square' = 'round';\n @Prop({ reflect: true }) disabled: boolean = false;\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n @Prop() ripple: boolean = true;\n @Prop() loading: boolean = false;\n @Prop() icon: string = '';\n @Prop() trailingIcon: string = '';\n @Prop() href: string = '';\n @Prop() target: string = '_self';\n\n /** Enable toggle behavior (selected/unselected) */\n @Prop() toggle: boolean = false;\n\n /** Current selected state (toggle mode) */\n @Prop({ mutable: true }) selected: boolean = false;\n\n /** Enable M3 Expressive shape morphing on press and toggle */\n @Prop() shapeMorph: boolean = true;\n\n /**\n * Mirror leading and trailing icons horizontally when the button is\n * rendered in a right-to-left context. Set this on buttons that use\n * **directional** Material Symbols (arrows, chevrons, send, reply…)\n * — non-directional icons (add, search, favorite…) should leave it\n * `false` so the glyph stays semantically correct.\n */\n @Prop({ reflect: true, attribute: 'mirror-icon' }) mirrorIcon: boolean = false;\n\n /**\n * When true, suppresses the default 180° trailing-icon rotation while\n * `aria-expanded=\"true\"`. Use when the consumer swaps the glyph (e.g.\n * docked `md-date-picker` month/year triggers use `chevron_right`).\n */\n @Prop({ reflect: true, attribute: 'suppress-expand-icon-flip' })\n suppressExpandIconFlip: boolean = false;\n\n /**\n * Stretch the button to fill its inline-axis container.\n *\n * Switches the host from `inline-flex` to `flex` and sets\n * `inline-size: 100%` so the button consumes the full width of its\n * parent — the standard pattern for primary CTAs in forms, modals,\n * and bottom sheets. The size's `min-block-size` (touch target) is\n * preserved.\n *\n * For arbitrary fixed widths or heights, set the\n * `--md-button-width`, `--md-button-height`, `--md-button-min-width`,\n * `--md-button-min-height`, or `--md-button-max-width` CSS custom\n * properties on the host instead.\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n /** @internal Set by md-button-group — left side is connected to a neighbor */\n @Prop({ reflect: true }) connectedLeft: boolean = false;\n\n /** @internal Set by md-button-group — right side is connected to a neighbor */\n @Prop({ reflect: true }) connectedRight: boolean = false;\n\n /** @internal Value for button-group association */\n @Prop() value: string = '';\n\n /**\n * @internal Roving-tabindex override set by `md-button-group`. When the\n * button is a child of a group, the group sets this to `0` on the\n * currently-active button and `-1` on the rest, so Tab enters the group\n * once instead of stepping through every button. Outside a group, this\n * stays `null` and the button uses its normal tabindex behavior.\n */\n @Prop({ mutable: true, reflect: false }) groupTabindex: number | null = null;\n\n /**\n * Override the default `role=\"button\"`. Used by composite widgets such as\n * `md-date-picker` day cells (`role=\"gridcell\"`). Leave empty for `button`.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fires every time the user activates the button (mouse click, touch,\n * or `Enter`/`Space` while focused). The event is **cancelable** and\n * the detail payload describes what *would* happen: the post-click\n * toggle state, the navigation `href`, and so on.\n *\n * Calling `event.preventDefault()` from a listener suppresses the\n * default side effects (toggle flip + `href` navigation) but lets\n * the underlying DOM click bubble. This is the hook to use for SPA\n * routing, \"are you sure?\" prompts, async confirmation, etc.\n *\n * The event bubbles and is composed, so listeners outside the\n * shadow tree (the typical case) receive it.\n *\n * ```ts\n * document.querySelector('md-button')!.addEventListener('mdClick', (e) => {\n * const { href, selected } = (e as CustomEvent).detail;\n * if (!confirm('Continue?')) e.preventDefault();\n * });\n * ```\n */\n @Event({ cancelable: true, bubbles: true, composed: true })\n mdClick!: EventEmitter<MdButtonClickDetail>;\n\n /**\n * Fires when toggle mode flips the `selected` state in response to a\n * user activation. Not cancelable — the state change has already\n * happened. Pair with `mdClick` (cancelable) when you need a veto.\n *\n * Bubbles and is composed.\n */\n @Event({ bubbles: true, composed: true })\n mdChange!: EventEmitter<MdButtonChangeDetail>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n @State() private pressed = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled || this.loading;\n }\n\n componentDidLoad() {\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const leadingSlot = shadow.querySelector('slot[name=\"leading-icon\"]') as HTMLSlotElement | null;\n const trailingSlot = shadow.querySelector('slot[name=\"trailing-icon\"]') as HTMLSlotElement | null;\n\n leadingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedLeadingIcon = leadingSlot.assignedElements().length > 0;\n });\n trailingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrailingIcon = trailingSlot.assignedElements().length > 0;\n });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n // Compute the post-click toggle state up front so the detail\n // payload describes what *would* happen — listeners can then\n // call preventDefault on the CustomEvent to veto the change.\n const nextSelected = this.toggle ? !this.selected : this.selected;\n\n const evt = this.mdClick.emit({\n value: this.value,\n toggle: this.toggle,\n selected: nextSelected,\n href: this.href,\n target: this.target,\n originalEvent: e,\n });\n\n if (evt.defaultPrevented) {\n // Suppress browser's default link navigation as well so the\n // host stays consistent. We don't flip selected and don't\n // open the href.\n e.preventDefault();\n return;\n }\n\n if (this.toggle && nextSelected !== this.selected) {\n this.selected = nextSelected;\n this.mdChange.emit({ selected: nextSelected, value: this.value });\n }\n\n /* Setting `href` makes this a link rather than a form control, so the\n branch is taken on the raw prop — an unsafe URL must not silently fall\n through to submitting the form. Only the navigation itself is refused. */\n if (this.href) {\n /* A safe href renders a REAL <a> in the shadow root, and the browser\n owns activation from there — so do nothing here. That is what makes\n middle-click, cmd/ctrl-click and \"copy link address\" work, and it is\n why cancelling mdClick above (which calls preventDefault on this very\n event) still vetoes navigation.\n\n The fallback below covers only the case where NO anchor exists: an\n href that failed sanitising renders none, so there is nothing to\n navigate and nothing to fall back to — the navigation is refused, as\n before. window.open remains for a programmatic click() on a button\n whose href is safe but whose anchor has not rendered yet. */\n const href = sanitizeHref(this.href);\n if (!href) return;\n const anchor = this.el.shadowRoot?.querySelector('.md-button__anchor');\n /* Did this click actually pass THROUGH the anchor? composedPath sees\n across the shadow boundary, so a real pointer click — on the label, an\n icon, or the anchor's stretched ::after over the padding — is\n recognised and left alone: the browser is already navigating.\n\n A PROGRAMMATIC el.click() targets the host and never reaches the\n anchor, so nothing would happen at all. A native <a>.click() does\n navigate, and this component behaved that way before it grew a real\n anchor — including keyboard activation, which routes through\n el.click() in handleKeyDown. Falling back to window.open keeps both\n working, and the composedPath check is what stops a real click from\n navigating twice. */\n if (!anchor || !e.composedPath().includes(anchor)) {\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n }\n return;\n }\n\n // Implicit form action, mirroring a native submit/reset button. Uses\n // ElementInternals so the associated <form> is found across the shadow\n // boundary. requestSubmit() (not submit()) so the form's submit event\n // fires and built-in constraint validation runs.\n if (this.type === 'submit') {\n this.internals.form?.requestSubmit();\n } else if (this.type === 'reset') {\n this.internals.form?.reset();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n this.pressed = true;\n triggerRipple(this.el);\n this.el.click();\n setTimeout(() => { this.pressed = false; }, 150);\n }\n }\n };\n\n private handlePointerDown = () => {\n if (!this.isDisabled) this.pressed = true;\n };\n\n private handlePointerUp = () => {\n this.pressed = false;\n };\n\n render() {\n const isEffectivelyDisabled = this.isDisabled;\n const hasLeadingIcon = !!this.icon;\n const hasTrailingIcon = !!this.trailingIcon;\n /* A component that accepts `href` must produce a real link. Sanitising\n here (not just at click time) means an unsafe URL renders NO anchor at\n all rather than an inert one. Disabled link-buttons also drop the\n anchor: there is no disabled state for <a>, and a focusable link that\n refuses to navigate is worse than no link. */\n const linkHref =\n this.href && !isEffectivelyDisabled ? sanitizeHref(this.href) : '';\n /* rel only where it means something: a target that opens a NEW browsing\n context. Blanket noreferrer would also strip the Referer on ordinary\n same-tab navigation, quietly breaking referrer-based analytics. */\n const opensNewContext = !!this.target && this.target !== '_self';\n\n return (\n <Host\n class={{\n 'md-button': true,\n [`md-button--${this.variant}`]: true,\n [`md-button--${this.size}`]: true,\n [`md-button--${this.shape}`]: true,\n 'md-button--with-leading-icon': hasLeadingIcon || this.hasSlottedLeadingIcon,\n 'md-button--with-trailing-icon': hasTrailingIcon || this.hasSlottedTrailingIcon,\n 'md-button--disabled': this.disabled || this.softDisabled,\n 'md-button--loading': this.loading,\n 'md-button--toggle': this.toggle,\n 'md-button--selected': this.selected,\n 'md-button--shape-morph': this.shapeMorph,\n 'md-button--pressed': this.shapeMorph && this.pressed,\n 'md-button--connected-left': this.connectedLeft,\n 'md-button--connected-right': this.connectedRight,\n 'md-button--full-width': this.fullWidth,\n }}\n role={this.roleOverride || (linkHref ? null : 'button')}\n aria-disabled={isEffectivelyDisabled ? 'true' : 'false'}\n aria-pressed={this.toggle ? String(this.selected) : undefined}\n tabindex={\n /* When a real anchor is rendered IT is the focusable element, so the\n host must not be a tab stop as well — otherwise every link button\n costs two presses of Tab and screen readers meet a button wrapping\n a link. */\n linkHref\n ? null\n : this.disabled\n ? '-1'\n : (this.groupTabindex !== null ? String(this.groupTabindex) : '0')\n }\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onPointerDown={this.handlePointerDown}\n onPointerUp={this.handlePointerUp}\n onPointerLeave={this.handlePointerUp}\n onPointerCancel={this.handlePointerUp}\n >\n {linkHref ? (\n <a\n class=\"md-button__anchor\"\n part=\"anchor\"\n role=\"link\"\n href={linkHref}\n target={this.target || undefined}\n rel={opensNewContext ? SAFE_LINK_REL : undefined}\n tabindex={this.groupTabindex !== null ? String(this.groupTabindex) : '0'}\n aria-disabled={isEffectivelyDisabled ? 'true' : null}\n >\n {this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)}\n </a>\n ) : (\n this.renderContent(isEffectivelyDisabled, hasLeadingIcon, hasTrailingIcon)\n )}\n </Host>\n );\n }\n\n /** Button innards, rendered either directly in the host or inside the\n * anchor when `href` makes this a link. */\n private renderContent(\n isEffectivelyDisabled: boolean,\n hasLeadingIcon: boolean,\n hasTrailingIcon: boolean,\n ) {\n return (\n <Fragment>\n {this.ripple && <md-ripple disabled={isEffectivelyDisabled}></md-ripple>}\n <span class=\"md-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n <slot name=\"leading-icon\">\n {hasLeadingIcon && <span class=\"md-button__icon material-symbols-outlined\" part=\"icon\">{this.icon}</span>}\n </slot>\n <span class=\"md-button__label\" part=\"label\"><slot /></span>\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && <span class=\"md-button__trailing-icon material-symbols-outlined\" part=\"trailing-icon\">{this.trailingIcon}</span>}\n </slot>\n {this.loading && (\n /* md-loading-indicator, not a hand-rolled ring: never ship a custom\n loading affordance where a library component exists. It is\n md-loading-indicator rather than md-progress-indicator because the\n latter clamps its circular variant to a 24px M3 minimum, while a\n button spinner runs 10-28px -- every tier but xl would clamp up and\n lose the density taper. Same choice md-select made for its trigger.\n\n The `loader` slot lets a consumer swap it (e.g. for a circular\n md-progress-indicator). The size hooks sit on this WRAPPER so they\n cascade to whatever ends up inside it, default or slotted. */\n <span class=\"md-button__loading\" part=\"loading\" aria-hidden=\"true\">\n <slot name=\"loader\">\n <LazyLoadingIndicator class=\"md-button__loading-default\" />\n </slot>\n </span>\n )}\n </Fragment>\n );\n }\n}\n"]}
|
|
@@ -5,6 +5,24 @@ export class MdSegmentedButtonSet {
|
|
|
5
5
|
this.multiselect = false;
|
|
6
6
|
/** Density: 0 = 40px, -1 = 36px, -2 = 32px, -3 = 28px, -4 = 24px */
|
|
7
7
|
this.density = 0;
|
|
8
|
+
/**
|
|
9
|
+
* Re-assign positions whenever the slotted segments change.
|
|
10
|
+
*
|
|
11
|
+
* `componentDidLoad` alone is not enough, and the gap is visible rather than
|
|
12
|
+
* theoretical. A segment defaults to `segmentIndex: 0` of `segmentTotal: 1`,
|
|
13
|
+
* which makes it BOTH first and last — so an unsynced segment renders fully
|
|
14
|
+
* rounded on every edge. Replace a set's children after it has loaded and
|
|
15
|
+
* every segment in it becomes a lone pill: the joined bar visibly falls apart,
|
|
16
|
+
* and nothing about it looks like a stale index.
|
|
17
|
+
*
|
|
18
|
+
* Any consumer that renders segments dynamically hits this — a set whose
|
|
19
|
+
* options come from state, a framework re-render, or `replaceChildren()`. The
|
|
20
|
+
* showcase dock rebuilds its controls that way and shows the bug on the first
|
|
21
|
+
* re-render after navigation.
|
|
22
|
+
*/
|
|
23
|
+
this.handleSlotChange = () => {
|
|
24
|
+
this.syncSegments();
|
|
25
|
+
};
|
|
8
26
|
}
|
|
9
27
|
onPropsChange() {
|
|
10
28
|
this.syncSegments();
|
|
@@ -51,10 +69,10 @@ export class MdSegmentedButtonSet {
|
|
|
51
69
|
}
|
|
52
70
|
}
|
|
53
71
|
render() {
|
|
54
|
-
return (h(Host, { key: '
|
|
72
|
+
return (h(Host, { key: '2a8bf244149352d69dfb03dd32ef0dcc24487dc4', class: {
|
|
55
73
|
'md-segmented-button-set': true,
|
|
56
74
|
[`md-segmented-button-set--density-${Math.abs(this.density)}`]: this.density !== 0,
|
|
57
|
-
}, role: this.multiselect ? 'group' : 'radiogroup' }, h("slot", { key: '
|
|
75
|
+
}, role: this.multiselect ? 'group' : 'radiogroup' }, h("slot", { key: '2d6cfc8e5a79bf9dc7d4cf92d0a087b9401bff46', onSlotchange: this.handleSlotChange })));
|
|
58
76
|
}
|
|
59
77
|
static get is() { return "md-segmented-button-set"; }
|
|
60
78
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"md-segmented-button-set.js","sourceRoot":"","sources":["../../../src/components/md-segmented-button-set/md-segmented-button-set.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAgB,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAQtG,MAAM,OAAO,oBAAoB;IALjC;QAQE,yCAAyC;QACjC,gBAAW,GAAY,KAAK,CAAC;QAErC,oEAAoE;QAC3C,YAAO,GAA0B,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"md-segmented-button-set.js","sourceRoot":"","sources":["../../../src/components/md-segmented-button-set/md-segmented-button-set.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Host, h, Prop, Element, Event, EventEmitter, Listen, Watch } from '@stencil/core';\nimport { SegmentElement } from '../../utils/types';\n\n@Component({\n tag: 'md-segmented-button-set',\n styleUrl: 'md-segmented-button-set.css',\n shadow: true,\n})\nexport class MdSegmentedButtonSet {\n @Element() el!: HTMLElement;\n\n /** Single-select or multi-select mode */\n @Prop() multiselect: boolean = false;\n\n /** Density: 0 = 40px, -1 = 36px, -2 = 32px, -3 = 28px, -4 = 24px */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fires when the set of selected segment values changes */\n @Event() mdChange: EventEmitter<string[]>;\n\n @Watch('multiselect')\n @Watch('density')\n onPropsChange() {\n this.syncSegments();\n }\n\n componentDidLoad() {\n this.syncSegments();\n }\n\n @Listen('mdSegmentClick')\n handleSegmentClick(event: CustomEvent<{ value: string; selected: boolean }>) {\n event.stopPropagation();\n const segments = this.getSegments();\n // Match by element identity, not by `.value`. The child segment\n // emits `mdSegmentClick` from its own host, and the event re-targets\n // to that <md-segmented-button> as it crosses the shadow boundary\n // into this set. Matching by value would break whenever segments\n // share the default value of '' (which is the common case when\n // consumers omit the `value` prop — every segment would toggle\n // together because every `'' === ''` is true).\n const clicked = event.target as SegmentElement | null;\n if (!clicked) return;\n\n const { selected } = event.detail;\n\n if (this.multiselect) {\n clicked.selected = selected;\n } else {\n for (const seg of segments) {\n seg.selected = seg === clicked;\n }\n }\n\n this.mdChange.emit(\n segments.filter(s => s.selected).map(s => s.value),\n );\n }\n\n private getSegments(): SegmentElement[] {\n return Array.from(this.el.querySelectorAll('md-segmented-button')) as unknown as SegmentElement[];\n }\n\n /**\n * Re-assign positions whenever the slotted segments change.\n *\n * `componentDidLoad` alone is not enough, and the gap is visible rather than\n * theoretical. A segment defaults to `segmentIndex: 0` of `segmentTotal: 1`,\n * which makes it BOTH first and last — so an unsynced segment renders fully\n * rounded on every edge. Replace a set's children after it has loaded and\n * every segment in it becomes a lone pill: the joined bar visibly falls apart,\n * and nothing about it looks like a stale index.\n *\n * Any consumer that renders segments dynamically hits this — a set whose\n * options come from state, a framework re-render, or `replaceChildren()`. The\n * showcase dock rebuilds its controls that way and shows the bug on the first\n * re-render after navigation.\n */\n private handleSlotChange = () => {\n this.syncSegments();\n };\n\n private syncSegments() {\n const segments = this.getSegments();\n const total = segments.length;\n\n for (let i = 0; i < total; i++) {\n const seg = segments[i];\n seg.segmentIndex = i;\n seg.segmentTotal = total;\n seg.segmentDensity = this.density;\n seg.segmentMultiselect = this.multiselect;\n }\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-segmented-button-set': true,\n [`md-segmented-button-set--density-${Math.abs(this.density)}`]: this.density !== 0,\n }}\n role={this.multiselect ? 'group' : 'radiogroup'}\n >\n <slot onSlotchange={this.handleSlotChange}></slot>\n </Host>\n );\n }\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{M as o,d as s}from"./p-
|
|
1
|
+
import{M as o,d as s}from"./p-BTgac9TA.js";const t=o;const a=s;export{t as MdButton,a as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=md-button.js.map
|