@awc-ui/core 1.0.0-beta → 1.0.0-beta.1
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/components/p-6wZSqm_2.js +2 -0
- package/dist/components/{p-Bx5sxRqa.js.map → p-6wZSqm_2.js.map} +1 -1
- package/dist/components/p-7fN_yCXW.js +2 -0
- package/dist/components/{p-CJdqKSuf.js.map → p-7fN_yCXW.js.map} +1 -1
- package/dist/components/{p-G5m2pHZ2.js → p-B0Opn6dK.js} +2 -2
- package/dist/components/{p-pDrTJmeT.js → p-B3MWYEEJ.js} +2 -2
- package/dist/components/{p-DGGkdSZk.js → p-BwXpiUsu.js} +2 -2
- package/dist/{md3/p-B0NLeNWu.js → components/p-Bx6--dQF.js} +2 -2
- package/dist/components/{p-BIIp3Qod.js → p-C8EP4S21.js} +2 -2
- package/dist/components/{p-CWM3KSti.js → p-C_ogF68H.js} +2 -2
- package/dist/components/{p-BlwGYUkt.js → p-Ch2-tttM.js} +2 -2
- package/dist/components/p-DXXUoRSH.js +2 -0
- package/dist/components/{p-DWUCvzfU.js.map → p-DXXUoRSH.js.map} +1 -1
- package/dist/components/p-Dp-w93ot.js +2 -0
- package/dist/components/{p-BUYYCrGa.js.map → p-Dp-w93ot.js.map} +1 -1
- package/dist/{md3/p-CGStn3Iq.js → components/p-DvOKnoqK.js} +2 -2
- package/dist/components/{p-B7yMxWo-.js → p-DzPKu-Ma.js} +2 -2
- package/dist/components/{p-CXpXrhQH.js → p-RLxbNqRv.js} +2 -2
- package/dist/components/p-UdGDg2oJ.js +2 -0
- package/dist/components/{p-BujtL9xW.js.map → p-UdGDg2oJ.js.map} +1 -1
- package/dist/components/p-e2HRV63Y.js +2 -0
- package/dist/components/{p-CrlkPxeB.js.map → p-e2HRV63Y.js.map} +1 -1
- package/dist/components/p-stybaFzj.js +2 -0
- package/dist/components/{p-JbwZ84YK.js.map → p-stybaFzj.js.map} +1 -1
- package/dist/components/p-uTEkf0sE.js +2 -0
- package/dist/components/{p-BXwh1zjF.js.map → p-uTEkf0sE.js.map} +1 -1
- package/dist/esm/{a11y-C9_cZAF_.js → a11y-C6CRqodW.js} +3 -3
- package/dist/esm/{a11y-C9_cZAF_.js.map → a11y-C6CRqodW.js.map} +1 -1
- package/dist/esm/{bar-chart-IvBgAmmF.js → bar-chart-ZZrajEkM.js} +4 -4
- package/dist/esm/{bar-chart-IvBgAmmF.js.map → bar-chart-ZZrajEkM.js.map} +1 -1
- package/dist/esm/{chart-D1kP9gfW.js → chart-32olae06.js} +4 -4
- package/dist/esm/{chart-D1kP9gfW.js.map → chart-32olae06.js.map} +1 -1
- package/dist/esm/{hit-test-DFfwlMb9.js → hit-test-DHldf5Lm.js} +3 -3
- package/dist/esm/{hit-test-DFfwlMb9.js.map → hit-test-DHldf5Lm.js.map} +1 -1
- package/dist/esm/{rtl-CGStn3Iq.js → rtl-DvOKnoqK.js} +3 -3
- package/dist/esm/{rtl-CGStn3Iq.js.map → rtl-DvOKnoqK.js.map} +1 -1
- package/dist/md3/p-04e97f5d.entry.js +2 -0
- package/dist/md3/{p-ec14eaca.entry.js.map → p-04e97f5d.entry.js.map} +1 -1
- package/dist/md3/p-3cce1de3.entry.js +2 -0
- package/dist/md3/{p-2121c939.entry.js.map → p-3cce1de3.entry.js.map} +1 -1
- package/dist/md3/p-4d82132d.entry.js +2 -0
- package/dist/md3/{p-fe78659d.entry.js.map → p-4d82132d.entry.js.map} +1 -1
- package/dist/{components/p-Bu-m4Gm2.js → md3/p-Bx6--dQF.js} +2 -2
- package/dist/md3/{p-B0NLeNWu.js.map → p-Bx6--dQF.js.map} +1 -1
- package/dist/md3/{p-CWM3KSti.js → p-C_ogF68H.js} +2 -2
- package/dist/md3/{p-CWM3KSti.js.map → p-C_ogF68H.js.map} +1 -1
- package/dist/{components/p-CGStn3Iq.js → md3/p-DvOKnoqK.js} +2 -2
- package/dist/md3/{p-CGStn3Iq.js.map → p-DvOKnoqK.js.map} +1 -1
- package/dist/md3/{p-B7yMxWo-.js → p-DzPKu-Ma.js} +2 -2
- package/dist/md3/{p-B7yMxWo-.js.map → p-DzPKu-Ma.js.map} +1 -1
- package/dist/md3/{p-CXpXrhQH.js → p-RLxbNqRv.js} +2 -2
- package/dist/md3/{p-CXpXrhQH.js.map → p-RLxbNqRv.js.map} +1 -1
- package/dist/md3/{p-f6373c6c.entry.js → p-aaec2698.entry.js} +2 -2
- package/dist/md3/{p-9ff2d5d1.entry.js → p-c063c823.entry.js} +2 -2
- package/main-llm.md +2 -2
- package/package.json +24 -3
- package/dist/components/p-BUYYCrGa.js +0 -2
- package/dist/components/p-BXwh1zjF.js +0 -2
- package/dist/components/p-BujtL9xW.js +0 -2
- package/dist/components/p-Bx5sxRqa.js +0 -2
- package/dist/components/p-CJdqKSuf.js +0 -2
- package/dist/components/p-CrlkPxeB.js +0 -2
- package/dist/components/p-DWUCvzfU.js +0 -2
- package/dist/components/p-JbwZ84YK.js +0 -2
- package/dist/md3/p-2121c939.entry.js +0 -2
- package/dist/md3/p-ec14eaca.entry.js +0 -2
- package/dist/md3/p-fe78659d.entry.js +0 -2
- /package/dist/components/{p-G5m2pHZ2.js.map → p-B0Opn6dK.js.map} +0 -0
- /package/dist/components/{p-pDrTJmeT.js.map → p-B3MWYEEJ.js.map} +0 -0
- /package/dist/components/{p-DGGkdSZk.js.map → p-BwXpiUsu.js.map} +0 -0
- /package/dist/components/{p-Bu-m4Gm2.js.map → p-Bx6--dQF.js.map} +0 -0
- /package/dist/components/{p-BIIp3Qod.js.map → p-C8EP4S21.js.map} +0 -0
- /package/dist/components/{p-CWM3KSti.js.map → p-C_ogF68H.js.map} +0 -0
- /package/dist/components/{p-BlwGYUkt.js.map → p-Ch2-tttM.js.map} +0 -0
- /package/dist/components/{p-CGStn3Iq.js.map → p-DvOKnoqK.js.map} +0 -0
- /package/dist/components/{p-B7yMxWo-.js.map → p-DzPKu-Ma.js.map} +0 -0
- /package/dist/components/{p-CXpXrhQH.js.map → p-RLxbNqRv.js.map} +0 -0
- /package/dist/md3/{p-f6373c6c.entry.js.map → p-aaec2698.entry.js.map} +0 -0
- /package/dist/md3/{p-9ff2d5d1.entry.js.map → p-c063c823.entry.js.map} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as t,H as s,h as e,d as i,t as n}from"./p-MWBNn6Lj.js";const r=()=>`:host{display:contents;border-radius:inherit;--_color:var(--md-ripple-color, currentColor)}.md-ripple{position:absolute;inset:0;border-radius:inherit;overflow:hidden;pointer-events:none}.md-ripple__wave{position:absolute;border-radius:50%;pointer-events:none;background:var(--_color);opacity:0;transform:scale(0);will-change:transform, opacity}.md-ripple{opacity:var(--md-sys-ripple-enabled, 1)}`;const o=450;const h=150;const c=.12;const a="cubic-bezier(0.2, 0, 0, 1)";const l="--md-ripple-grow-duration";const p="--md-ripple-grow-easing";const d=t(class t extends s{constructor(t){super();if(t!==false){this.__registerHost()}this.__attachShadow();this.disabled=false;this.hostEl=null;this.activeWave=null;this.growAnimation=null;this.activeOpacity=c;this.bound=false;this.settlePromise=null;this.settleResolve=null;this.onPointerDown=t=>{if(this.disabled||this.rippleSuppressed())return;const s=this.el.shadowRoot?.querySelector(".md-ripple");if(!s||!this.hostEl)return;this.endWave();const e=this.hostEl.getBoundingClientRect();const i=this.resolveExtent("--md-ripple-extend-inline");const n=this.resolveExtent("--md-ripple-extend-block");const r=e.left-i;const o=e.right+i;const h=e.top-n;const c=e.bottom+n;const a=Math.max(Math.abs(t.clientX-r),Math.abs(t.clientX-o));const l=Math.max(Math.abs(t.clientY-h),Math.abs(t.clientY-c));const p=Math.sqrt(a*a+l*l);const d=p*2;const u=t.clientX-e.left-p;const f=t.clientY-e.top-p;const m=document.createElement("span");m.classList.add("md-ripple__wave");m.style.width=m.style.height=`${d}px`;m.style.left=`${u}px`;m.style.top=`${f}px`;s.appendChild(m);this.activeWave=m;this.activeOpacity=this.resolveOpacity();this.beginSettle();this.growAnimation=m.animate([{transform:"scale(0)",opacity:this.activeOpacity},{transform:"scale(1)",opacity:this.activeOpacity}],{duration:this.resolveGrowDuration(),easing:this.resolveGrowEasing(),fill:"forwards"});window.addEventListener("pointerup",this.onRelease,{once:true});window.addEventListener("pointercancel",this.onRelease,{once:true})};this.onRelease=()=>{this.endWave()}}rippleSuppressed(){if(typeof getComputedStyle!=="function")return false;try{return getComputedStyle(this.el).getPropertyValue("--md-sys-ripple-enabled").trim()==="0"}catch{return false}}resolveOpacity(){if(!this.hostEl)return c;const t=getComputedStyle(this.hostEl).getPropertyValue("--md-ripple-opacity").trim();if(!t)return c;const s=parseFloat(t);return Number.isFinite(s)?s:c}resolveExtent(t){const s=getComputedStyle(this.el).getPropertyValue(t).trim();if(!s)return 0;const e=parseFloat(s);return Number.isFinite(e)&&e>0?e:0}resolveGrowDuration(){const t=getComputedStyle(this.el).getPropertyValue(l).trim();if(!t)return o;const s=parseFloat(t);return Number.isFinite(s)&&s>0?s:o}resolveGrowEasing(){const t=getComputedStyle(this.el).getPropertyValue(p).trim();return t||a}beginSettle(){this.finishSettle();this.settlePromise=new Promise((t=>{this.settleResolve=t}))}finishSettle(){this.settleResolve?.();this.settleResolve=null;this.settlePromise=null}async whenSettled(){if(!this.settlePromise)return;const t=new Promise((t=>{setTimeout(t,h+50)}));await Promise.race([this.settlePromise,t]);this.finishSettle()}resolveHost(){const t=this.el.getRootNode();return this.el.parentElement??(t instanceof ShadowRoot?t.host:null)}bind(){if(this.bound)return;this.hostEl=this.resolveHost();if(!this.hostEl)return;this.bound=true;this.hostEl.addEventListener("pointerdown",this.onPointerDown)}connectedCallback(){this.bind();if(!this.bound){queueMicrotask((()=>this.bind()))}}disconnectedCallback(){this.hostEl?.removeEventListener("pointerdown",this.onPointerDown);this.hostEl=null;this.bound=false}async endWave(){const t=this.activeWave;const s=this.growAnimation;if(!t||!s)return;this.activeWave=null;this.growAnimation=null;if(s.playState!=="finished"){await s.finished}const e=t.animate([{opacity:this.activeOpacity},{opacity:0}],{duration:h,easing:a,fill:"forwards"});try{if(typeof e.finished?.then==="function"){await e.finished}else{await new Promise((t=>setTimeout(t,h)))}}catch{}t.remove();this.finishSettle()}async trigger(){if(this.disabled||this.rippleSuppressed())return;if(!this.hostEl)this.hostEl=this.resolveHost();const t=this.el.shadowRoot?.querySelector(".md-ripple");if(!t||!this.hostEl)return;this.endWave();const s=this.hostEl.getBoundingClientRect();const e=this.resolveExtent("--md-ripple-extend-inline");const i=this.resolveExtent("--md-ripple-extend-block");const n=s.width/2;const r=s.height/2;const o=n+e;const h=r+i;const c=Math.sqrt(o*o+h*h);const a=c*2;const l=document.createElement("span");l.classList.add("md-ripple__wave");l.style.width=l.style.height=`${a}px`;l.style.left=`${n-c}px`;l.style.top=`${r-c}px`;t.appendChild(l);this.activeWave=l;this.activeOpacity=this.resolveOpacity();this.beginSettle();this.growAnimation=l.animate([{transform:"scale(0)",opacity:this.activeOpacity},{transform:"scale(1)",opacity:this.activeOpacity}],{duration:this.resolveGrowDuration(),easing:this.resolveGrowEasing(),fill:"forwards"});this.growAnimation.addEventListener("finish",(()=>this.endWave()),{once:true})}render(){return e(i,{key:"db104269176da1fe8c379500716b44c7d6575407","aria-hidden":"true"},e("div",{key:"94d23e0d1697a050e49ae66e8e8c022b20f108bd",class:"md-ripple"}))}get el(){return this}static get style(){return r()}},[1,"md-ripple",{disabled:[4],whenSettled:[64],trigger:[64]}]);function u(){if(typeof customElements==="undefined"){return}const t=["md-ripple"];t.forEach((t=>{switch(t){case"md-ripple":if(!customElements.get(n(t))){customElements.define(n(t),d)}break}}))}u();export{d as M,u as d};
|
|
2
|
+
//# sourceMappingURL=p-stybaFzj.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["mdRippleCss","PRESS_GROW_MS","RELEASE_FADE_MS","DEFAULT_PRESS_OPACITY","EASING_STANDARD","GROW_DURATION_PROP","GROW_EASING_PROP","MdRipple","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","disabled","hostEl","activeWave","growAnimation","activeOpacity","bound","settlePromise","settleResolve","onPointerDown","e","rippleSuppressed","container","el","shadowRoot","querySelector","endWave","rect","getBoundingClientRect","extendInline","resolveExtent","extendBlock","left","right","top","bottom","dx","Math","max","abs","clientX","dy","clientY","radius","sqrt","size","x","y","wave","document","createElement","classList","add","style","width","height","appendChild","resolveOpacity","beginSettle","animate","transform","opacity","duration","resolveGrowDuration","easing","resolveGrowEasing","fill","window","addEventListener","onRelease","once","getComputedStyle","getPropertyValue","trim","raw","parsed","parseFloat","Number","isFinite","prop","finishSettle","Promise","resolve","whenSettled","maxWait","setTimeout","race","resolveHost","root","getRootNode","parentElement","ShadowRoot","host","bind","connectedCallback","queueMicrotask","disconnectedCallback","removeEventListener","grow","playState","finished","fade","then","remove","trigger","cx","cy","halfX","halfY","render","h","Host","key","class"],"sources":["src/components/md-ripple/md-ripple.css?tag=md-ripple&encapsulation=shadow","src/components/md-ripple/md-ripple.tsx"],"sourcesContent":["/* ==========================================================\n md-ripple — Material Design 3 ripple effect\n Spec: https://m3.material.io/foundations/interaction/states\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-ripple-color Ripple tint color (default: currentColor)\n --md-ripple-opacity Ripple peak opacity (default: 0.12)\n --md-ripple-extend-inline Extra pixels to add on each inline edge\n of the host's rect when computing the\n wave's farthest-corner radius. Use on\n surfaces that GROW horizontally during\n the ripple's lifetime (e.g. md-search\n springing out on focus) so the wave is\n sized for the settled rect instead of\n the resting one. Wave position is\n unaffected — the wave still originates\n at the click point. Must be a CONCRETE\n PIXEL VALUE (e.g. `120px`). Computed\n expressions involving %, calc() or\n clamp() are NOT resolved by this hook —\n read the literal token via\n getComputedStyle and parseFloat returns\n NaN on those forms. Consumers needing\n such expressions should compute the\n value in JS and write it back as fixed\n pixels via inline style. (default: 0)\n --md-ripple-extend-block Same as --md-ripple-extend-inline but\n for the block axis. (default: 0)\n --md-ripple-grow-duration Override the wave's scale 0 → 1 grow\n duration. Use on surfaces that animate\n their own size during the ripple's\n lifetime (e.g. md-search) so the wave\n reaches full size at the same instant\n the surface settles — otherwise the\n wave is still ramping up while the\n surface is already at its final width.\n var() references and any value that\n resolves to a CSS time work (e.g.\n `250ms`). (default: 450ms)\n --md-ripple-grow-easing Companion to --md-ripple-grow-duration\n — usually set to the surface's own\n easing so the wave feels like part of\n the same motion.\n (default: cubic-bezier(0.2, 0, 0, 1))\n\n CSS PARTS:\n (none)\n\n SLOTS:\n (none)\n ========================================================== */\n\n:host {\n display: contents;\n\n /* `.md-ripple` clips the wave with `border-radius: inherit`, which inherits\n from THIS host — not from the component embedding us. Left at the initial\n 0, that clip is a square, and the wave only looked round because the\n embedding host happened to clip it with its own `overflow: hidden`. Any\n host that must let something escape (an icon button with a badge) then got\n a square ripple. Inheriting the radius here makes the clip follow the\n container's shape on its own. */\n border-radius: inherit;\n\n --_color: var(--md-ripple-color, currentColor);\n}\n\n.md-ripple {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n overflow: hidden;\n pointer-events: none;\n}\n\n.md-ripple__wave {\n position: absolute;\n border-radius: 50%;\n pointer-events: none;\n background: var(--_color);\n opacity: 0;\n transform: scale(0);\n will-change: transform, opacity;\n}\n\n/* ==========================================================\n SUPPRESSION (global data-ripple=\"off\" / per-component ripple=\"off\")\n The real gate is in TS — onPointerDown and trigger() bail before a wave is\n ever created, so nothing is allocated or animated. This rule is the safety\n net for the one case TS cannot cover: a wave already mid-flight when the\n toggle flips. Without it that wave would finish its 450ms grow after ripples\n were switched off.\n\n The signal is 0/1, which is already a valid opacity, so it drops straight in\n — no keyword mapping, and the default of 1 makes this a no-op when the\n feature is on. opacity (not display) so nothing about layout or the\n containing block changes.\n ========================================================== */\n.md-ripple {\n opacity: var(--md-sys-ripple-enabled, 1);\n}\n","import { Component, Element, h, Host, Method, Prop } from '@stencil/core';\n\nconst PRESS_GROW_MS = 450;\nconst RELEASE_FADE_MS = 150;\nconst DEFAULT_PRESS_OPACITY = 0.12;\nconst EASING_STANDARD = 'cubic-bezier(0.2, 0, 0, 1)';\n\nconst GROW_DURATION_PROP = '--md-ripple-grow-duration';\nconst GROW_EASING_PROP = '--md-ripple-grow-easing';\n\n@Component({ tag: 'md-ripple', styleUrl: 'md-ripple.css', shadow: true })\nexport class MdRipple {\n @Element() el!: HTMLElement;\n\n @Prop() disabled: boolean = false;\n\n /**\n * True when ripples are switched off for this element, either globally\n * (`data-ripple=\"off\"` on any ancestor) or on the owning component\n * (`ripple=\"off\"`). Both spellings resolve to `--md-sys-ripple-enabled` in\n * tokens.css, so only the resolved value is read here.\n *\n * Read at interaction time rather than cached. The signal is a plain\n * inherited custom property, so it can change at any moment — a theme\n * switch, a settings toggle, a parent re-render — with no attribute mutation\n * on THIS element to observe. One getComputedStyle per press is cheap next to\n * the wave animation that follows, and it cannot go stale.\n *\n * The check is deliberately `=== '0'`: an unset property returns '' and must\n * mean ENABLED, so testing for falsiness would disable ripples everywhere the\n * token sheet has not loaded.\n */\n private rippleSuppressed(): boolean {\n if (typeof getComputedStyle !== 'function') return false;\n try {\n return (\n getComputedStyle(this.el).getPropertyValue('--md-sys-ripple-enabled').trim() === '0'\n );\n } catch {\n return false;\n }\n }\n\n private hostEl: HTMLElement | null = null;\n private activeWave: HTMLElement | null = null;\n private growAnimation: Animation | null = null;\n private activeOpacity: number = DEFAULT_PRESS_OPACITY;\n private bound = false;\n private settlePromise: Promise<void> | null = null;\n private settleResolve: (() => void) | null = null;\n\n private resolveOpacity(): number {\n if (!this.hostEl) return DEFAULT_PRESS_OPACITY;\n const raw = getComputedStyle(this.hostEl)\n .getPropertyValue('--md-ripple-opacity')\n .trim();\n if (!raw) return DEFAULT_PRESS_OPACITY;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : DEFAULT_PRESS_OPACITY;\n }\n\n /**\n * Resolve the inline / block extents that surfaces growing during the\n * ripple's lifetime (e.g. md-search springing out on focus) declare via\n * `--md-ripple-extend-inline` / `--md-ripple-extend-block`. The values\n * inflate the host's rect ONLY for the wave's farthest-corner radius\n * calculation, so the wave is sized for the SETTLED rect even though\n * the actual host is still at its resting size at pointerdown. Wave\n * POSITION still uses the unmodified rect so the wave originates\n * exactly where the user clicked.\n *\n * Consumers MUST pass concrete pixel values here (e.g.\n * `style.setProperty('--md-ripple-extend-inline', '120px')`).\n * `getComputedStyle().getPropertyValue()` on a custom property returns\n * the LITERAL TOKEN — for `calc()` / `clamp()` / `%` expressions the\n * string is unparsed (`\"calc(clamp(0px, 8%, 64px) * 2)\"`) and\n * `parseFloat()` returns `NaN`. Resolving such expressions reliably\n * requires knowing the consumer's intended containing-block reference,\n * which md-ripple cannot infer; consumers therefore compute the value\n * themselves (typically with a hidden probe element scoped to the\n * correct containing block) and write it back as fixed pixels.\n */\n private resolveExtent(prop: string): number {\n const raw = getComputedStyle(this.el).getPropertyValue(prop).trim();\n if (!raw) return 0;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;\n }\n\n /**\n * Wave grow duration (ms). Surfaces that animate their size during the\n * ripple's lifetime (e.g. md-search springing from a narrower resting\n * width to its full width) should sync the wave's growth with their\n * own settle so the wave reaches scale = 1 at the same moment the\n * surface stops moving — otherwise the wave is still ramping up while\n * the surface is already at its final width and the user sees a\n * visible gap on the side that grew. Default is the spec-canonical\n * 450ms.\n */\n private resolveGrowDuration(): number {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_DURATION_PROP).trim();\n if (!raw) return PRESS_GROW_MS;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : PRESS_GROW_MS;\n }\n\n /**\n * Wave grow easing function. Companion to {@link resolveGrowDuration}\n * — when a surface drives the timing it should usually pass its own\n * easing (typically a back-out spring) so the wave's growth feels\n * like part of the same motion.\n */\n private resolveGrowEasing(): string {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_EASING_PROP).trim();\n return raw || EASING_STANDARD;\n }\n\n private beginSettle() {\n this.finishSettle();\n this.settlePromise = new Promise<void>((resolve) => {\n this.settleResolve = resolve;\n });\n }\n\n private finishSettle() {\n this.settleResolve?.();\n this.settleResolve = null;\n this.settlePromise = null;\n }\n\n /** Resolves when the active press ripple has fully faded out. */\n @Method()\n async whenSettled(): Promise<void> {\n if (!this.settlePromise) return;\n const maxWait = new Promise<void>((resolve) => {\n setTimeout(resolve, RELEASE_FADE_MS + 50);\n });\n await Promise.race([this.settlePromise, maxWait]);\n this.finishSettle();\n }\n\n private resolveHost(): HTMLElement | null {\n const root = this.el.getRootNode();\n return this.el.parentElement ??\n (root instanceof ShadowRoot ? (root.host as HTMLElement) : null);\n }\n\n private bind() {\n if (this.bound) return;\n this.hostEl = this.resolveHost();\n if (!this.hostEl) return;\n this.bound = true;\n this.hostEl.addEventListener('pointerdown', this.onPointerDown);\n }\n\n connectedCallback() {\n this.bind();\n if (!this.bound) {\n queueMicrotask(() => this.bind());\n }\n }\n\n disconnectedCallback() {\n this.hostEl?.removeEventListener('pointerdown', this.onPointerDown);\n this.hostEl = null;\n this.bound = false;\n }\n\n private onPointerDown = (e: PointerEvent) => {\n if (this.disabled || this.rippleSuppressed()) return;\n\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n // Treat the surface as if it spans an extended rect when the host has\n // declared `--md-ripple-extend-inline` / `--md-ripple-extend-block`.\n // Wave POSITION still uses the actual (current) rect so the wave\n // visually originates at the click point — only the RADIUS uses the\n // inflated bounds so the wave grows large enough to cover the surface\n // once it settles.\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const left = rect.left - extendInline;\n const right = rect.right + extendInline;\n const top = rect.top - extendBlock;\n const bottom = rect.bottom + extendBlock;\n const dx = Math.max(Math.abs(e.clientX - left), Math.abs(e.clientX - right));\n const dy = Math.max(Math.abs(e.clientY - top), Math.abs(e.clientY - bottom));\n const radius = Math.sqrt(dx * dx + dy * dy);\n const size = radius * 2;\n const x = e.clientX - rect.left - radius;\n const y = e.clientY - rect.top - radius;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${x}px`;\n wave.style.top = `${y}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n window.addEventListener('pointerup', this.onRelease, { once: true });\n window.addEventListener('pointercancel', this.onRelease, { once: true });\n };\n\n private onRelease = () => {\n this.endWave();\n };\n\n private async endWave() {\n const wave = this.activeWave;\n const grow = this.growAnimation;\n if (!wave || !grow) return;\n\n this.activeWave = null;\n this.growAnimation = null;\n\n if (grow.playState !== 'finished') {\n await grow.finished;\n }\n\n const fade = wave.animate(\n [{ opacity: this.activeOpacity }, { opacity: 0 }],\n { duration: RELEASE_FADE_MS, easing: EASING_STANDARD, fill: 'forwards' },\n );\n try {\n if (typeof fade.finished?.then === 'function') {\n await fade.finished;\n } else {\n await new Promise<void>((resolve) => setTimeout(resolve, RELEASE_FADE_MS));\n }\n } catch {\n /* animation cancelled */\n }\n wave.remove();\n this.finishSettle();\n }\n\n /** Programmatically trigger a centered ripple (for keyboard activations). */\n @Method()\n async trigger() {\n if (this.disabled || this.rippleSuppressed()) return;\n\n if (!this.hostEl) this.hostEl = this.resolveHost();\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n // Centered ripples use the rect's centre as both anchor and farthest\n // reference, so the inflated half-extents become the radius\n // contribution directly.\n const halfX = cx + extendInline;\n const halfY = cy + extendBlock;\n const radius = Math.sqrt(halfX * halfX + halfY * halfY);\n const size = radius * 2;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${cx - radius}px`;\n wave.style.top = `${cy - radius}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n this.growAnimation.addEventListener('finish', () => this.endWave(), { once: true });\n }\n\n render() {\n return (\n <Host aria-hidden=\"true\">\n <div class=\"md-ripple\"></div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["mdRippleCss","PRESS_GROW_MS","RELEASE_FADE_MS","DEFAULT_PRESS_OPACITY","EASING_STANDARD","GROW_DURATION_PROP","GROW_EASING_PROP","MdRipple","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","disabled","hostEl","activeWave","growAnimation","activeOpacity","bound","settlePromise","settleResolve","onPointerDown","e","rippleSuppressed","container","el","shadowRoot","querySelector","endWave","rect","getBoundingClientRect","extendInline","resolveExtent","extendBlock","left","right","top","bottom","dx","Math","max","abs","clientX","dy","clientY","radius","sqrt","size","x","y","wave","document","createElement","classList","add","style","width","height","appendChild","resolveOpacity","beginSettle","animate","transform","opacity","duration","resolveGrowDuration","easing","resolveGrowEasing","fill","window","addEventListener","onRelease","once","getComputedStyle","getPropertyValue","trim","raw","parsed","parseFloat","Number","isFinite","prop","finishSettle","Promise","resolve","whenSettled","maxWait","setTimeout","race","resolveHost","root","getRootNode","parentElement","ShadowRoot","host","bind","connectedCallback","queueMicrotask","disconnectedCallback","removeEventListener","grow","playState","finished","fade","then","remove","trigger","cx","cy","halfX","halfY","render","h","Host","key","class"],"sources":["src/components/md-ripple/md-ripple.css?tag=md-ripple&encapsulation=shadow","src/components/md-ripple/md-ripple.tsx"],"sourcesContent":["/* ==========================================================\n md-ripple — Material Design 3 ripple effect\n Spec: https://m3.material.io/foundations/interaction/states\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-ripple-color Ripple tint color (default: currentColor)\n --md-ripple-opacity Ripple peak opacity (default: 0.12)\n --md-ripple-extend-inline Extra pixels to add on each inline edge\n of the host's rect when computing the\n wave's farthest-corner radius. Use on\n surfaces that GROW horizontally during\n the ripple's lifetime (e.g. md-search\n springing out on focus) so the wave is\n sized for the settled rect instead of\n the resting one. Wave position is\n unaffected — the wave still originates\n at the click point. Must be a CONCRETE\n PIXEL VALUE (e.g. `120px`). Computed\n expressions involving %, calc() or\n clamp() are NOT resolved by this hook —\n read the literal token via\n getComputedStyle and parseFloat returns\n NaN on those forms. Consumers needing\n such expressions should compute the\n value in JS and write it back as fixed\n pixels via inline style. (default: 0)\n --md-ripple-extend-block Same as --md-ripple-extend-inline but\n for the block axis. (default: 0)\n --md-ripple-grow-duration Override the wave's scale 0 → 1 grow\n duration. Use on surfaces that animate\n their own size during the ripple's\n lifetime (e.g. md-search) so the wave\n reaches full size at the same instant\n the surface settles — otherwise the\n wave is still ramping up while the\n surface is already at its final width.\n var() references and any value that\n resolves to a CSS time work (e.g.\n `250ms`). (default: 450ms)\n --md-ripple-grow-easing Companion to --md-ripple-grow-duration\n — usually set to the surface's own\n easing so the wave feels like part of\n the same motion.\n (default: cubic-bezier(0.2, 0, 0, 1))\n\n CSS PARTS:\n (none)\n\n SLOTS:\n (none)\n ========================================================== */\n\n:host {\n display: contents;\n\n /* `.md-ripple` clips the wave with `border-radius: inherit`, which inherits\n from THIS host — not from the component embedding us. Left at the initial\n 0, that clip is a square, and the wave only looked round because the\n embedding host happened to clip it with its own `overflow: hidden`. Any\n host that must let something escape (an icon button with a badge) then got\n a square ripple. Inheriting the radius here makes the clip follow the\n container's shape on its own. */\n border-radius: inherit;\n\n --_color: var(--md-ripple-color, currentColor);\n}\n\n.md-ripple {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n overflow: hidden;\n pointer-events: none;\n}\n\n.md-ripple__wave {\n position: absolute;\n border-radius: 50%;\n pointer-events: none;\n background: var(--_color);\n opacity: 0;\n transform: scale(0);\n will-change: transform, opacity;\n}\n\n/* ==========================================================\n SUPPRESSION (global data-ripple=\"off\" / per-component ripple=\"off\")\n The real gate is in TS — onPointerDown and trigger() bail before a wave is\n ever created, so nothing is allocated or animated. This rule is the safety\n net for the one case TS cannot cover: a wave already mid-flight when the\n toggle flips. Without it that wave would finish its 450ms grow after ripples\n were switched off.\n\n The signal is 0/1, which is already a valid opacity, so it drops straight in\n — no keyword mapping, and the default of 1 makes this a no-op when the\n feature is on. opacity (not display) so nothing about layout or the\n containing block changes.\n ========================================================== */\n.md-ripple {\n opacity: var(--md-sys-ripple-enabled, 1);\n}\n","import { Component, Element, h, Host, Method, Prop } from '@stencil/core';\n\nconst PRESS_GROW_MS = 450;\nconst RELEASE_FADE_MS = 150;\nconst DEFAULT_PRESS_OPACITY = 0.12;\nconst EASING_STANDARD = 'cubic-bezier(0.2, 0, 0, 1)';\n\nconst GROW_DURATION_PROP = '--md-ripple-grow-duration';\nconst GROW_EASING_PROP = '--md-ripple-grow-easing';\n\n@Component({ tag: 'md-ripple', styleUrl: 'md-ripple.css', shadow: true })\nexport class MdRipple {\n @Element() el!: HTMLElement;\n\n @Prop() disabled: boolean = false;\n\n /**\n * True when ripples are switched off for this element, either globally\n * (`data-ripple=\"off\"` on any ancestor) or on the owning component\n * (`ripple=\"off\"`). Both spellings resolve to `--md-sys-ripple-enabled` in\n * tokens.css, so only the resolved value is read here.\n *\n * Read at interaction time rather than cached. The signal is a plain\n * inherited custom property, so it can change at any moment — a theme\n * switch, a settings toggle, a parent re-render — with no attribute mutation\n * on THIS element to observe. One getComputedStyle per press is cheap next to\n * the wave animation that follows, and it cannot go stale.\n *\n * The check is deliberately `=== '0'`: an unset property returns '' and must\n * mean ENABLED, so testing for falsiness would disable ripples everywhere the\n * token sheet has not loaded.\n */\n private rippleSuppressed(): boolean {\n if (typeof getComputedStyle !== 'function') return false;\n try {\n return (\n getComputedStyle(this.el).getPropertyValue('--md-sys-ripple-enabled').trim() === '0'\n );\n } catch {\n return false;\n }\n }\n\n private hostEl: HTMLElement | null = null;\n private activeWave: HTMLElement | null = null;\n private growAnimation: Animation | null = null;\n private activeOpacity: number = DEFAULT_PRESS_OPACITY;\n private bound = false;\n private settlePromise: Promise<void> | null = null;\n private settleResolve: (() => void) | null = null;\n\n private resolveOpacity(): number {\n if (!this.hostEl) return DEFAULT_PRESS_OPACITY;\n const raw = getComputedStyle(this.hostEl)\n .getPropertyValue('--md-ripple-opacity')\n .trim();\n if (!raw) return DEFAULT_PRESS_OPACITY;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : DEFAULT_PRESS_OPACITY;\n }\n\n /**\n * Resolve the inline / block extents that surfaces growing during the\n * ripple's lifetime (e.g. md-search springing out on focus) declare via\n * `--md-ripple-extend-inline` / `--md-ripple-extend-block`. The values\n * inflate the host's rect ONLY for the wave's farthest-corner radius\n * calculation, so the wave is sized for the SETTLED rect even though\n * the actual host is still at its resting size at pointerdown. Wave\n * POSITION still uses the unmodified rect so the wave originates\n * exactly where the user clicked.\n *\n * Consumers MUST pass concrete pixel values here (e.g.\n * `style.setProperty('--md-ripple-extend-inline', '120px')`).\n * `getComputedStyle().getPropertyValue()` on a custom property returns\n * the LITERAL TOKEN — for `calc()` / `clamp()` / `%` expressions the\n * string is unparsed (`\"calc(clamp(0px, 8%, 64px) * 2)\"`) and\n * `parseFloat()` returns `NaN`. Resolving such expressions reliably\n * requires knowing the consumer's intended containing-block reference,\n * which md-ripple cannot infer; consumers therefore compute the value\n * themselves (typically with a hidden probe element scoped to the\n * correct containing block) and write it back as fixed pixels.\n */\n private resolveExtent(prop: string): number {\n const raw = getComputedStyle(this.el).getPropertyValue(prop).trim();\n if (!raw) return 0;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;\n }\n\n /**\n * Wave grow duration (ms). Surfaces that animate their size during the\n * ripple's lifetime (e.g. md-search springing from a narrower resting\n * width to its full width) should sync the wave's growth with their\n * own settle so the wave reaches scale = 1 at the same moment the\n * surface stops moving — otherwise the wave is still ramping up while\n * the surface is already at its final width and the user sees a\n * visible gap on the side that grew. Default is the spec-canonical\n * 450ms.\n */\n private resolveGrowDuration(): number {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_DURATION_PROP).trim();\n if (!raw) return PRESS_GROW_MS;\n const parsed = parseFloat(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : PRESS_GROW_MS;\n }\n\n /**\n * Wave grow easing function. Companion to {@link resolveGrowDuration}\n * — when a surface drives the timing it should usually pass its own\n * easing (typically a back-out spring) so the wave's growth feels\n * like part of the same motion.\n */\n private resolveGrowEasing(): string {\n const raw = getComputedStyle(this.el).getPropertyValue(GROW_EASING_PROP).trim();\n return raw || EASING_STANDARD;\n }\n\n private beginSettle() {\n this.finishSettle();\n this.settlePromise = new Promise<void>((resolve) => {\n this.settleResolve = resolve;\n });\n }\n\n private finishSettle() {\n this.settleResolve?.();\n this.settleResolve = null;\n this.settlePromise = null;\n }\n\n /** Resolves when the active press ripple has fully faded out. */\n @Method()\n async whenSettled(): Promise<void> {\n if (!this.settlePromise) return;\n const maxWait = new Promise<void>((resolve) => {\n setTimeout(resolve, RELEASE_FADE_MS + 50);\n });\n await Promise.race([this.settlePromise, maxWait]);\n this.finishSettle();\n }\n\n private resolveHost(): HTMLElement | null {\n const root = this.el.getRootNode();\n return this.el.parentElement ??\n (root instanceof ShadowRoot ? (root.host as HTMLElement) : null);\n }\n\n private bind() {\n if (this.bound) return;\n this.hostEl = this.resolveHost();\n if (!this.hostEl) return;\n this.bound = true;\n this.hostEl.addEventListener('pointerdown', this.onPointerDown);\n }\n\n connectedCallback() {\n this.bind();\n if (!this.bound) {\n queueMicrotask(() => this.bind());\n }\n }\n\n disconnectedCallback() {\n this.hostEl?.removeEventListener('pointerdown', this.onPointerDown);\n this.hostEl = null;\n this.bound = false;\n }\n\n private onPointerDown = (e: PointerEvent) => {\n if (this.disabled || this.rippleSuppressed()) return;\n\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n // Treat the surface as if it spans an extended rect when the host has\n // declared `--md-ripple-extend-inline` / `--md-ripple-extend-block`.\n // Wave POSITION still uses the actual (current) rect so the wave\n // visually originates at the click point — only the RADIUS uses the\n // inflated bounds so the wave grows large enough to cover the surface\n // once it settles.\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const left = rect.left - extendInline;\n const right = rect.right + extendInline;\n const top = rect.top - extendBlock;\n const bottom = rect.bottom + extendBlock;\n const dx = Math.max(Math.abs(e.clientX - left), Math.abs(e.clientX - right));\n const dy = Math.max(Math.abs(e.clientY - top), Math.abs(e.clientY - bottom));\n const radius = Math.sqrt(dx * dx + dy * dy);\n const size = radius * 2;\n const x = e.clientX - rect.left - radius;\n const y = e.clientY - rect.top - radius;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${x}px`;\n wave.style.top = `${y}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n window.addEventListener('pointerup', this.onRelease, { once: true });\n window.addEventListener('pointercancel', this.onRelease, { once: true });\n };\n\n private onRelease = () => {\n this.endWave();\n };\n\n private async endWave() {\n const wave = this.activeWave;\n const grow = this.growAnimation;\n if (!wave || !grow) return;\n\n this.activeWave = null;\n this.growAnimation = null;\n\n if (grow.playState !== 'finished') {\n await grow.finished;\n }\n\n const fade = wave.animate(\n [{ opacity: this.activeOpacity }, { opacity: 0 }],\n { duration: RELEASE_FADE_MS, easing: EASING_STANDARD, fill: 'forwards' },\n );\n try {\n if (typeof fade.finished?.then === 'function') {\n await fade.finished;\n } else {\n await new Promise<void>((resolve) => setTimeout(resolve, RELEASE_FADE_MS));\n }\n } catch {\n /* animation cancelled */\n }\n wave.remove();\n this.finishSettle();\n }\n\n /** Programmatically trigger a centered ripple (for keyboard activations). */\n @Method()\n async trigger() {\n if (this.disabled || this.rippleSuppressed()) return;\n\n if (!this.hostEl) this.hostEl = this.resolveHost();\n const container = this.el.shadowRoot?.querySelector('.md-ripple') as HTMLElement;\n if (!container || !this.hostEl) return;\n\n this.endWave();\n\n const rect = this.hostEl.getBoundingClientRect();\n const extendInline = this.resolveExtent('--md-ripple-extend-inline');\n const extendBlock = this.resolveExtent('--md-ripple-extend-block');\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n // Centered ripples use the rect's centre as both anchor and farthest\n // reference, so the inflated half-extents become the radius\n // contribution directly.\n const halfX = cx + extendInline;\n const halfY = cy + extendBlock;\n const radius = Math.sqrt(halfX * halfX + halfY * halfY);\n const size = radius * 2;\n\n const wave = document.createElement('span');\n wave.classList.add('md-ripple__wave');\n wave.style.width = wave.style.height = `${size}px`;\n wave.style.left = `${cx - radius}px`;\n wave.style.top = `${cy - radius}px`;\n container.appendChild(wave);\n this.activeWave = wave;\n this.activeOpacity = this.resolveOpacity();\n this.beginSettle();\n\n this.growAnimation = wave.animate(\n [\n { transform: 'scale(0)', opacity: this.activeOpacity },\n { transform: 'scale(1)', opacity: this.activeOpacity },\n ],\n {\n duration: this.resolveGrowDuration(),\n easing: this.resolveGrowEasing(),\n fill: 'forwards',\n },\n );\n\n this.growAnimation.addEventListener('finish', () => this.endWave(), { once: true });\n }\n\n render() {\n return (\n <Host aria-hidden=\"true\">\n <div class=\"md-ripple\"></div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as e,H as o,c as i,h as a,d as r,t}from"./p-MWBNn6Lj.js";import{t as s}from"./p-DYBUr7K_.js";import{d as n}from"./p-stybaFzj.js";const c=()=>`:host{--_container-color:var(--md-chip-container-color, transparent);--_container-color-selected:var(--md-chip-container-color-selected, var(--md-sys-color-secondary-container));--_label-color:var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));--_label-color-selected:var(--md-chip-label-color-selected, var(--md-sys-color-on-secondary-container));--_icon-color:var(--md-chip-icon-color, var(--md-sys-color-primary));--_icon-size:var(--md-chip-icon-size, max(14px, calc(18px + var(--md-sys-density-scale, 0) * 1px)));--_container-shape:var(--md-chip-container-shape, var(--md-sys-shape-corner-small, 8px));--_container-height:var(--md-chip-container-height, 32px);--_outline-color:var(--md-chip-outline-color, var(--md-sys-color-outline));--_outline-width:var(--md-chip-outline-width, 1px);--_state-layer-color:var(--md-chip-state-layer-color, var(--md-sys-color-on-surface));--_elevation:var(--md-chip-elevation, var(--md-sys-elevation-0, none));--_c-main:var(--md-sys-color-primary);--_c-on-main:var(--md-sys-color-on-primary);--_c-container:var(--md-sys-color-secondary-container);--_c-on-container:var(--md-sys-color-on-secondary-container);--_padding-inline:var(--md-sys-spacing-inset-lg, 16px);--_gap:var(--md-sys-spacing-gap-sm, 8px);display:inline-flex;align-items:center;justify-content:center;position:relative;box-sizing:border-box;block-size:max(24px, calc(var(--_container-height) + var(--md-sys-density-scale, 0) * 4px));padding-inline:var(--_padding-inline);gap:var(--_gap);background-color:var(--_container-color);border-radius:var(--_container-shape);box-shadow:var(--_elevation);cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;overflow:hidden;font-family:var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);font-size:max(11px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));font-weight:var(--md-sys-typescale-label-large-font-weight, 500);line-height:max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));letter-spacing:var(--md-sys-typescale-label-large-letter-spacing, 0.1px);color:var(--_label-color);transition:background-color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)), box-shadow var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)), color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1))}:host(.md-chip--with-leading-icon){padding-inline-start:var(--md-sys-spacing-inset-sm, 8px)}:host(.md-chip--with-trailing-icon){padding-inline-end:var(--md-sys-spacing-inset-sm, 8px)}:host(.md-chip--assist){--_icon-color:var(--md-chip-icon-color, var(--md-sys-color-primary));--_label-color:var(--md-chip-label-color, var(--md-sys-color-on-surface))}:host(.md-chip--filter){--_icon-color:var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));--_label-color:var(--md-chip-label-color, var(--md-sys-color-on-surface-variant))}:host(.md-chip--input){--_outline-color:var(--md-chip-outline-color, var(--md-sys-color-outline-variant));--_icon-color:var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));--_label-color:var(--md-chip-label-color, var(--md-sys-color-on-surface-variant))}:host(.md-chip--suggestion){--_icon-color:var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));--_label-color:var(--md-chip-label-color, var(--md-sys-color-on-surface-variant))}:host(.md-chip--selected){--_container-color:var(--_container-color-selected);color:var(--_label-color-selected);--_icon-color:var(--md-chip-icon-color, var(--md-sys-color-on-secondary-container));--_state-layer-color:var(--md-sys-color-on-secondary-container)}:host(.md-chip--selected) .md-chip__outline{border-color:transparent}:host(.md-chip--elevated){--_elevation:var(--md-chip-elevation, var(--md-sys-elevation-1))}:host(.md-chip--elevated) .md-chip__outline{border-color:transparent}:host(.md-chip--elevated.md-chip--selected){--_elevation:var(--md-chip-elevation, var(--md-sys-elevation-1))}:host(.md-chip--appearance-outlined[color]){--_outline-color:var(--md-chip-outline-color, var(--_c-main));--_label-color:var(--md-chip-label-color, var(--_c-main));--_icon-color:var(--md-chip-icon-color, var(--_c-main));--_state-layer-color:var(--md-chip-state-layer-color, var(--_c-main))}:host(.md-chip--appearance-filled),:host(.md-chip--appearance-elevated){--_container-color:var(--md-chip-container-color, var(--md-sys-color-surface-container-high));--_label-color:var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));--_icon-color:var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant))}:host(.md-chip--appearance-filled[color]),:host(.md-chip--appearance-elevated[color]){--_container-color:var(--md-chip-container-color, var(--_c-container));--_label-color:var(--md-chip-label-color, var(--_c-on-container));--_icon-color:var(--md-chip-icon-color, var(--_c-on-container));--_state-layer-color:var(--md-chip-state-layer-color, var(--_c-on-container))}:host(.md-chip--appearance-filled) .md-chip__outline,:host(.md-chip--appearance-elevated) .md-chip__outline{border-color:transparent}:host(.md-chip--selected[color]){--_container-color:var(--_c-container);color:var(--_c-on-container);--_label-color-selected:var(--_c-on-container);--_icon-color:var(--md-chip-icon-color, var(--_c-on-container));--_state-layer-color:var(--_c-on-container)}.md-chip__outline{position:absolute;inset:0;border-radius:inherit;border:var(--_outline-width) solid var(--_outline-color);pointer-events:none}.md-chip__state-layer{position:absolute;inset:0;border-radius:inherit;background-color:var(--_state-layer-color);opacity:0;transition:opacity var(--md-sys-motion-duration-short1, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));pointer-events:none;z-index:1}:host(:hover) .md-chip__state-layer{opacity:var(--md-sys-state-hover-state-layer-opacity, 0.08)}:host(:focus-visible) .md-chip__state-layer{opacity:var(--md-sys-state-focus-state-layer-opacity, 0.12)}:host(:active) .md-chip__state-layer{opacity:var(--md-sys-state-pressed-state-layer-opacity, 0.12)}:host(:focus-visible){outline:3px solid var(--md-sys-color-secondary);outline-offset:2px}.md-chip__primary{position:absolute;inset:0;z-index:2;margin:0;padding:0;border:none;background:none;border-radius:inherit;cursor:inherit;-webkit-tap-highlight-color:transparent}.md-chip__primary:focus-visible{outline:3px solid var(--md-sys-color-secondary);outline-offset:-3px}.md-chip__label{position:relative;z-index:2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start}.md-chip__icon,.md-chip__trailing-icon{position:relative;z-index:2;font-family:var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size);color:var(--_icon-color);line-height:1;font-weight:normal;font-style:normal;letter-spacing:normal;text-transform:none;white-space:nowrap;overflow-wrap:normal;direction:ltr;-webkit-font-smoothing:antialiased;pointer-events:none;flex-shrink:0}slot[name="leading-icon"],slot[name="trailing-icon"]{display:contents}::slotted([slot="leading-icon"]),::slotted([slot="trailing-icon"]){display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_icon-size);block-size:var(--_icon-size);font-size:var(--_icon-size);color:var(--_icon-color);fill:currentColor;pointer-events:none;flex-shrink:0;position:relative;z-index:2}.md-chip__checkmark{position:relative;z-index:2;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_icon-size);block-size:var(--_icon-size);color:var(--_icon-color);flex-shrink:0}.md-chip__checkmark svg{inline-size:var(--_icon-size);block-size:var(--_icon-size)}.md-chip__remove{position:relative;z-index:2;display:inline-flex;align-items:center;justify-content:center;min-inline-size:18px;min-block-size:18px;padding:0;border:none;background:none;color:var(--_icon-color);cursor:pointer;border-radius:50%;flex-shrink:0;-webkit-tap-highlight-color:transparent}.md-chip__remove:focus-visible{outline:2px solid var(--md-sys-color-secondary);outline-offset:1px}.md-chip__remove svg{inline-size:var(--_icon-size);block-size:var(--_icon-size);pointer-events:none}.md-chip__remove:disabled{cursor:default;pointer-events:none}:host(.md-chip--disabled){cursor:default;pointer-events:none;color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);--_icon-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);--_elevation:var(--md-sys-elevation-0, none) !important}:host(.md-chip--disabled:not(.md-chip--selected):not(.md-chip--elevated)) .md-chip__outline{border-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent)}:host(.md-chip--disabled.md-chip--selected){--_container-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent)}:host(.md-chip--disabled.md-chip--elevated:not(.md-chip--selected)){--_container-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent)}:host(.md-chip--disabled:hover) .md-chip__state-layer,:host(.md-chip--disabled:active) .md-chip__state-layer,:host(.md-chip--disabled:focus-visible) .md-chip__state-layer{opacity:0}:host([soft-disabled]){cursor:default;pointer-events:auto;color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);--_icon-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);--_elevation:var(--md-sys-elevation-0, none) !important}:host([soft-disabled]) .md-chip__state-layer{display:none}@media (prefers-reduced-motion: reduce){:host{transition:none}.md-chip__state-layer{transition:none}}@media (forced-colors: active){:host{border:1px solid ButtonText;background-color:ButtonFace;color:ButtonText;forced-color-adjust:none}.md-chip__outline{border-color:ButtonText}:host(:focus-visible){outline-color:Highlight}.md-chip__primary:focus-visible{outline-color:Highlight}:host(.md-chip--selected){background-color:Highlight;color:HighlightText}:host(.md-chip--disabled){border-color:GrayText;color:GrayText;opacity:1}.md-chip__state-layer{display:none}}:host([density='-1']){--md-sys-density-scale:-1}:host([density='-2']){--md-sys-density-scale:-2}:host([density='-3']){--md-sys-density-scale:-3}:host([density='-4']){--md-sys-density-scale:-4}`;const l=e(class e extends o{constructor(e){super();if(e!==false){this.__registerHost()}this.__attachShadow();this.mdClick=i(this,"mdClick",7);this.mdSelect=i(this,"mdSelect",7);this.mdRemove=i(this,"mdRemove",7);this.variant="assist";this.icon="";this.trailingIcon="";this.selected=false;this.appearance="outlined";this.elevated=false;this.disabled=false;this.softDisabled=false;this.label="";this.density=0;this.hasSlottedLeadingIcon=false;this.hasSlottedTrailingIcon=false;this.handleClick=e=>{if(this.isDisabled){e.preventDefault();return}if(this.isSelectable){this.selected=!this.selected;this.mdSelect.emit({selected:this.selected})}this.mdClick.emit()};this.handleKeyDown=e=>{if(this.isDisabled)return;if(e.key==="Enter"||e.key===" "){e.preventDefault();s(this.el);this.el.click();return}if(this.isRemovable&&(e.key==="Delete"||e.key==="Backspace")){e.preventDefault();this.dispatchRemove()}};this.handleRemoveClick=e=>{e.stopPropagation();if(this.isDisabled)return;this.dispatchRemove()};this.handleRemoveKeyDown=e=>{if(this.isDisabled)return;if(e.key==="Enter"||e.key===" "){e.stopPropagation();e.preventDefault();this.dispatchRemove()}}}get isDisabled(){return this.disabled||this.softDisabled}get colorVars(){const e=this.color;if(!e||!/^[a-z][a-z0-9-]*$/i.test(e))return undefined;return{"--_c-main":`var(--md-sys-color-${e}, var(--md-sys-color-primary))`,"--_c-on-main":`var(--md-sys-color-on-${e}, var(--md-sys-color-on-primary))`,"--_c-container":`var(--md-sys-color-${e}-container, var(--md-sys-color-secondary-container))`,"--_c-on-container":`var(--md-sys-color-on-${e}-container, var(--md-sys-color-on-secondary-container))`}}get effectiveAppearance(){return this.elevated?"elevated":this.appearance}get isSelectable(){if(this.selectable!==undefined)return this.selectable;return this.variant==="filter"||this.variant==="input"}get isInteractiveHost(){return!(this.selectable===false&&this.isRemovable)}get isRemovable(){if(this.removable===true)return true;if(this.removable===false)return false;return this.variant==="input"}get accessibleLabel(){return this.label||this.el.textContent?.trim()||""}componentDidLoad(){const e=this.el.shadowRoot;if(!e)return;const o=e.querySelector('slot[name="leading-icon"]');const i=e.querySelector('slot[name="trailing-icon"]');o?.addEventListener("slotchange",(()=>{this.hasSlottedLeadingIcon=o.assignedElements().length>0}));i?.addEventListener("slotchange",(()=>{this.hasSlottedTrailingIcon=i.assignedElements().length>0}))}dispatchRemove(){const e=this.mdRemove.emit();if(!e.defaultPrevented){this.el.remove()}}render(){const e=!!this.icon||this.hasSlottedLeadingIcon;const o=!!this.trailingIcon||this.hasSlottedTrailingIcon;const i=this.variant==="filter"&&this.selected&&!e;const t=this.isRemovable;const s=this.isDisabled;const n=this.accessibleLabel;const c=this.isInteractiveHost&&!t;const l=this.isInteractiveHost&&t;return a(r,{key:"ac377a67d3c9c5e464f9cc30cada24b9c9f2e848",style:this.colorVars,class:{"md-chip":true,[`md-chip--${this.variant}`]:true,"md-chip--selected":this.selected&&this.isSelectable,[`md-chip--appearance-${this.effectiveAppearance}`]:true,"md-chip--elevated":this.effectiveAppearance==="elevated",[`md-chip--color-${this.color}`]:!!this.color,"md-chip--disabled":s,"md-chip--with-leading-icon":e||i,"md-chip--with-trailing-icon":o||t},role:c?"button":"group","aria-roledescription":"chip","aria-pressed":c&&this.isSelectable?String(this.selected):undefined,"aria-label":c?undefined:n||undefined,"aria-disabled":s?"true":undefined,tabindex:c?this.disabled?"-1":"0":undefined,onClick:this.handleClick,onKeyDown:this.handleKeyDown},a("md-ripple",{key:"71ddc00b4e7f72a93b9356f647b3630aa50380a3",disabled:s}),a("span",{key:"6eab2a000c1543bb6957c175cfb33cbb06d3f345",class:"md-chip__state-layer",part:"state-layer","aria-hidden":"true"}),!this.elevated&&a("span",{key:"ee96614931899684057f77b1bed36c315964fdca",class:"md-chip__outline",part:"outline","aria-hidden":"true"}),l&&a("span",{key:"f0743bfa4bc9b7c6cf7d357c000426f1e5f3b108",class:"md-chip__primary",part:"primary",role:"button",tabindex:this.disabled?"-1":"0","aria-labelledby":"md-chip-label-text","aria-pressed":this.isSelectable?String(this.selected):undefined,"aria-disabled":s?"true":undefined}),i&&a("span",{key:"c15afa18cc1fa1e956c1dcf3c0806d7b065620b0",class:"md-chip__checkmark",part:"checkmark","aria-hidden":"true"},a("svg",{key:"1e7a5eb1ec44df6efd803543e943889bff65e1e8",viewBox:"0 0 18 18",fill:"none"},a("path",{key:"3d36f6406d5bce2e0b7fb71f25b9a6142cc88b3b",d:"M6.75 12.127L3.623 9l-1.06 1.057L6.75 14.25l9-9-1.057-1.057L6.75 12.127z",fill:"currentColor"}))),a("slot",{key:"9dd3792251fc0f43baa3e3b0787fbbf7967cfc2b",name:"leading-icon"},e&&!i&&a("span",{key:"0078163a6741535eef3c413559d8cc9a4b7dbbc2",class:"md-chip__icon material-symbols-outlined",part:"icon","aria-hidden":"true"},this.icon)),a("span",{key:"bae9ed93b4ba0e8dda2e9d0fbae102405fbdaeae",class:"md-chip__label",part:"label",id:"md-chip-label-text"},a("slot",{key:"9f36d159a093aaa93e3c4867e7bbf7a5543fcebd"},this.label)),t?a("button",{class:"md-chip__remove",part:"remove",type:"button",tabindex:this.disabled?"-1":"0","aria-label":n?`Remove ${n}`:"Remove",disabled:s,onClick:this.handleRemoveClick,onKeyDown:this.handleRemoveKeyDown},a("slot",{name:"trailing-icon"},a("svg",{viewBox:"0 0 18 18",fill:"none","aria-hidden":"true"},a("path",{d:"M14.25 4.808l-1.058-1.058L9 7.942 4.808 3.75 3.75 4.808 7.942 9 3.75 13.192l1.058 1.058L9 10.058l4.192 4.192 1.058-1.058L10.058 9l4.192-4.192z",fill:"currentColor"})))):a("slot",{name:"trailing-icon"},o&&a("span",{class:"md-chip__trailing-icon material-symbols-outlined",part:"trailing-icon","aria-hidden":"true"},this.trailingIcon)))}get el(){return this}static get style(){return c()}},[257,"md-chip",{variant:[513],icon:[1],trailingIcon:[1,"trailing-icon"],selected:[1540],selectable:[4],appearance:[513],color:[513],elevated:[516],disabled:[516],softDisabled:[516,"soft-disabled"],removable:[516],label:[1],density:[514],hasSlottedLeadingIcon:[32],hasSlottedTrailingIcon:[32]}]);function d(){if(typeof customElements==="undefined"){return}const e=["md-chip","md-ripple"];e.forEach((e=>{switch(e){case"md-chip":if(!customElements.get(t(e))){customElements.define(t(e),l)}break;case"md-ripple":if(!customElements.get(t(e))){n()}break}}))}d();export{l as M,d};
|
|
2
|
+
//# sourceMappingURL=p-uTEkf0sE.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["mdChipCss","MdChip","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","variant","icon","trailingIcon","selected","appearance","elevated","disabled","softDisabled","label","density","hasSlottedLeadingIcon","hasSlottedTrailingIcon","handleClick","e","isDisabled","preventDefault","isSelectable","mdSelect","emit","mdClick","handleKeyDown","key","triggerRipple","el","click","isRemovable","dispatchRemove","handleRemoveClick","stopPropagation","handleRemoveKeyDown","colorVars","c","color","test","undefined","effectiveAppearance","selectable","isInteractiveHost","removable","accessibleLabel","textContent","trim","componentDidLoad","shadow","shadowRoot","leadingSlot","querySelector","trailingSlot","addEventListener","assignedElements","length","ev","mdRemove","defaultPrevented","remove","render","hasLeadingIcon","hasTrailingIcon","showCheckmark","showRemove","isEffectivelyDisabled","chipLabel","hostIsButton","renderPrimary","h","Host","style","class","role","String","tabindex","onClick","onKeyDown","part","viewBox","fill","d","name","id","type"],"sources":["src/components/md-chip/md-chip.css?tag=md-chip&encapsulation=shadow","src/components/md-chip/md-chip.tsx"],"sourcesContent":["/* ==========================================================\n md-chip — Material Design 3 Chip\n Spec: https://m3.material.io/components/chips/specs\n\n Four variants:\n assist — surface-container-low, on-surface, outline\n filter — surface-container-low, on-surface-variant, outline (selectable)\n input — surface-container-low, on-surface-variant, outline-variant (selectable + removable)\n suggestion — surface-container-low, on-surface-variant, outline\n\n Measurements (MD3 spec):\n Height: 32px\n Shape: 8px corner radius (shape-corner-small)\n Icon size: 18px\n Left/right padding: 16px (no icon), 8px (with icon)\n Padding between: 8px\n Label text: label-large\n\n APPEARANCE x COLOUR:\n `appearance` picks the surface style (outlined | filled | elevated) and is\n independent of `variant`, which picks the M3 chip TYPE. `color` picks a\n role — primary / secondary / tertiary / error (baseline M3) or\n success / warning / info (semantic status roles, defined in\n packages/tokens/src/tokens.css on the same tonal recipe).\n\n outlined + color -> tints outline, label and icon; container transparent\n filled/elevated -> tonal container (<color>-container) with\n on-<color>-container label; outline dropped\n no color -> neutral: outlined is unchanged from before, and\n filled/elevated take a surface tone rather than the\n secondary container, so an unselected filled chip is\n never mistaken for a selected one\n\n Every per-instance property below still wins over all of it.\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-chip-container-color Container background\n --md-chip-container-color-selected Selected container background\n --md-chip-label-color Label text color\n --md-chip-label-color-selected Selected label text color\n --md-chip-icon-color Leading/trailing icon color\n --md-chip-icon-size Icon dimensions\n --md-chip-container-shape Border-radius override\n --md-chip-container-height Height override\n --md-chip-outline-color Outline color\n --md-chip-outline-width Outline width\n --md-chip-state-layer-color State layer color override\n --md-chip-elevation Box-shadow override\n\n CSS PARTS:\n state-layer Hover/press overlay\n outline Border element\n label Label text wrapper\n icon Leading icon\n trailing-icon Trailing icon\n checkmark Filter chip checkmark\n remove Input chip remove button\n\n SLOTS:\n (default) Label text\n leading-icon Custom leading icon\n trailing-icon Custom trailing icon\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — BASE\n ========================================================== */\n\n:host {\n --_container-color: var(--md-chip-container-color, transparent);\n --_container-color-selected: var(--md-chip-container-color-selected, var(--md-sys-color-secondary-container));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n --_label-color-selected: var(--md-chip-label-color-selected, var(--md-sys-color-on-secondary-container));\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-primary));\n --_icon-size: var(--md-chip-icon-size, max(14px, calc(18px + var(--md-sys-density-scale, 0) * 1px)));\n --_container-shape: var(--md-chip-container-shape, var(--md-sys-shape-corner-small, 8px));\n --_container-height: var(--md-chip-container-height, 32px);\n --_outline-color: var(--md-chip-outline-color, var(--md-sys-color-outline));\n --_outline-width: var(--md-chip-outline-width, 1px);\n --_state-layer-color: var(--md-chip-state-layer-color, var(--md-sys-color-on-surface));\n --_elevation: var(--md-chip-elevation, var(--md-sys-elevation-0, none));\n /* Colour-role slots. These four are the ONLY thing the `color` prop swaps;\n every appearance below is written against them, so adding a role is a\n 4-line block and never touches the appearance rules.\n The neutral defaults reproduce the pre-existing look exactly: an uncoloured\n chip's selected state has always been secondary-container. */\n --_c-main: var(--md-sys-color-primary);\n --_c-on-main: var(--md-sys-color-on-primary);\n --_c-container: var(--md-sys-color-secondary-container);\n --_c-on-container: var(--md-sys-color-on-secondary-container);\n --_padding-inline: var(--md-sys-spacing-inset-lg, 16px);\n --_gap: var(--md-sys-spacing-gap-sm, 8px);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n box-sizing: border-box;\n /* Global density: each `data-density` rung (0…-4) trims 4px off the chip\n height, floored at 24px (label-large line-height is 20px). Applied at the\n consumption point so every size/variant is covered by one edit. Unchanged\n at density 0. */\n block-size: max(24px, calc(var(--_container-height) + var(--md-sys-density-scale, 0) * 4px));\n padding-inline: var(--_padding-inline);\n gap: var(--_gap);\n\n background-color: var(--_container-color);\n border-radius: var(--_container-shape);\n box-shadow: var(--_elevation);\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n overflow: hidden;\n\n font-family: var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);\n font-size: max(11px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-large-font-weight, 500);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n letter-spacing: var(--md-sys-typescale-label-large-letter-spacing, 0.1px);\n color: var(--_label-color);\n\n transition:\n background-color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n box-shadow var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* Shrink padding when leading/trailing icon present */\n:host(.md-chip--with-leading-icon) {\n padding-inline-start: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n:host(.md-chip--with-trailing-icon) {\n padding-inline-end: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n/* ==========================================================\n 2. VARIANT-SPECIFIC COLORS\n ========================================================== */\n\n/* Assist — primary icon color */\n:host(.md-chip--assist) {\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-primary));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface));\n}\n\n/* Filter */\n:host(.md-chip--filter) {\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n}\n\n/* Input */\n:host(.md-chip--input) {\n --_outline-color: var(--md-chip-outline-color, var(--md-sys-color-outline-variant));\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n}\n\n/* Suggestion */\n:host(.md-chip--suggestion) {\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n}\n\n/* ==========================================================\n 3. SELECTED STATE\n ========================================================== */\n\n:host(.md-chip--selected) {\n --_container-color: var(--_container-color-selected);\n color: var(--_label-color-selected);\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-secondary-container));\n --_state-layer-color: var(--md-sys-color-on-secondary-container);\n}\n\n:host(.md-chip--selected) .md-chip__outline {\n border-color: transparent;\n}\n\n/* ==========================================================\n 4. ELEVATED\n ========================================================== */\n\n:host(.md-chip--elevated) {\n --_elevation: var(--md-chip-elevation, var(--md-sys-elevation-1));\n}\n\n:host(.md-chip--elevated) .md-chip__outline {\n border-color: transparent;\n}\n\n:host(.md-chip--elevated.md-chip--selected) {\n --_elevation: var(--md-chip-elevation, var(--md-sys-elevation-1));\n}\n\n/* ==========================================================\n 4b. COLOUR ROLES\n Resolved in the component, not here: md-chip.tsx maps `color` onto the four\n --_c-* slots below as inline custom properties. That way ANY role the theme\n defines works — `color=\"brand\"` picks up --md-sys-color-brand the moment a\n theme ships it — instead of only the names we happened to enumerate in CSS.\n Each slot falls back to the neutral default, so an unknown role renders as an\n uncoloured chip rather than losing its container colour entirely.\n ========================================================== */\n\n/* ==========================================================\n 4c. APPEARANCE (outlined | filled | elevated)\n ========================================================== */\n\n/* `outlined` is the default and is deliberately a no-op when no `color` is set,\n so untouched chips render exactly as before. With a colour, the role tints\n the outline, label and icon while the container stays transparent. */\n:host(.md-chip--appearance-outlined[color]) {\n --_outline-color: var(--md-chip-outline-color, var(--_c-main));\n --_label-color: var(--md-chip-label-color, var(--_c-main));\n --_icon-color: var(--md-chip-icon-color, var(--_c-main));\n --_state-layer-color: var(--md-chip-state-layer-color, var(--_c-main));\n}\n\n/* `filled` and `elevated` share one tonal container — they differ only in\n elevation, which section 4 already owns. Without a colour they take a neutral\n surface rather than the secondary container, so an unselected filled chip is\n never mistaken for a selected one. */\n:host(.md-chip--appearance-filled),\n:host(.md-chip--appearance-elevated) {\n --_container-color: var(--md-chip-container-color, var(--md-sys-color-surface-container-high));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n}\n\n:host(.md-chip--appearance-filled[color]),\n:host(.md-chip--appearance-elevated[color]) {\n --_container-color: var(--md-chip-container-color, var(--_c-container));\n --_label-color: var(--md-chip-label-color, var(--_c-on-container));\n --_icon-color: var(--md-chip-icon-color, var(--_c-on-container));\n --_state-layer-color: var(--md-chip-state-layer-color, var(--_c-on-container));\n}\n\n/* Both drop the outline: the container itself is now the shape. */\n:host(.md-chip--appearance-filled) .md-chip__outline,\n:host(.md-chip--appearance-elevated) .md-chip__outline {\n border-color: transparent;\n}\n\n/* Selection tints with the chosen role instead of the fixed secondary\n container, for every appearance. Section 3 still supplies the neutral case. */\n:host(.md-chip--selected[color]) {\n --_container-color: var(--_c-container);\n color: var(--_c-on-container);\n --_label-color-selected: var(--_c-on-container);\n --_icon-color: var(--md-chip-icon-color, var(--_c-on-container));\n --_state-layer-color: var(--_c-on-container);\n}\n\n/* ==========================================================\n 5. OUTLINE\n ========================================================== */\n\n.md-chip__outline {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n border: var(--_outline-width) solid var(--_outline-color);\n pointer-events: none;\n}\n\n/* ==========================================================\n 6. STATE LAYER\n ========================================================== */\n\n.md-chip__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short1, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n z-index: 1;\n}\n\n:host(:hover) .md-chip__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(:focus-visible) .md-chip__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n:host(:active) .md-chip__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 7. FOCUS RING\n ========================================================== */\n\n:host(:focus-visible) {\n outline: 3px solid var(--md-sys-color-secondary);\n outline-offset: 2px;\n}\n\n/* ==========================================================\n 7b. PRIMARY ACTION (removable chips)\n When a chip is both interactive AND removable, its body action is a\n SEPARATE focusable control that is a sibling of the remove ✕ button\n (so the two interactive controls don't nest — see md-chip.tsx). It is a\n transparent layer over the chip; the label/icons paint above it (higher in\n DOM at the same z-index) and pointer/keyboard activation bubbles to the\n host handlers. The focus ring uses a NEGATIVE outline-offset so it renders\n INSIDE the chip edge and is not clipped by the host's `overflow: hidden`.\n ========================================================== */\n\n.md-chip__primary {\n position: absolute;\n inset: 0;\n z-index: 2;\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n border-radius: inherit;\n cursor: inherit;\n -webkit-tap-highlight-color: transparent;\n}\n\n.md-chip__primary:focus-visible {\n outline: 3px solid var(--md-sys-color-secondary);\n outline-offset: -3px;\n}\n\n/* ==========================================================\n 8. LABEL\n ========================================================== */\n\n.md-chip__label {\n position: relative;\n z-index: 2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-align: start;\n}\n\n/* ==========================================================\n 9. ICONS\n ========================================================== */\n\n.md-chip__icon,\n.md-chip__trailing-icon {\n position: relative;\n z-index: 2;\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-size: var(--_icon-size);\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n color: var(--_icon-color);\n line-height: 1;\n font-weight: normal;\n font-style: normal;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n -webkit-font-smoothing: antialiased;\n pointer-events: none;\n flex-shrink: 0;\n}\n\nslot[name=\"leading-icon\"],\nslot[name=\"trailing-icon\"] {\n display: contents;\n}\n\n::slotted([slot=\"leading-icon\"]),\n::slotted([slot=\"trailing-icon\"]) {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n font-size: var(--_icon-size);\n color: var(--_icon-color);\n fill: currentColor;\n pointer-events: none;\n flex-shrink: 0;\n position: relative;\n z-index: 2;\n}\n\n/* ==========================================================\n 10. CHECKMARK (filter chip selected)\n ========================================================== */\n\n.md-chip__checkmark {\n position: relative;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n color: var(--_icon-color);\n flex-shrink: 0;\n}\n\n.md-chip__checkmark svg {\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n}\n\n/* ==========================================================\n 11. REMOVE BUTTON (input chip)\n ========================================================== */\n\n.md-chip__remove {\n position: relative;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-inline-size: 18px;\n min-block-size: 18px;\n padding: 0;\n border: none;\n background: none;\n color: var(--_icon-color);\n cursor: pointer;\n border-radius: 50%;\n flex-shrink: 0;\n -webkit-tap-highlight-color: transparent;\n}\n\n.md-chip__remove:focus-visible {\n outline: 2px solid var(--md-sys-color-secondary);\n outline-offset: 1px;\n}\n\n.md-chip__remove svg {\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n pointer-events: none;\n}\n\n.md-chip__remove:disabled {\n cursor: default;\n pointer-events: none;\n}\n\n/* ==========================================================\n 12. DISABLED\n ========================================================== */\n\n:host(.md-chip--disabled) {\n cursor: default;\n pointer-events: none;\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_elevation: var(--md-sys-elevation-0, none) !important;\n}\n\n:host(.md-chip--disabled:not(.md-chip--selected):not(.md-chip--elevated)) .md-chip__outline {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-chip--disabled.md-chip--selected) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-chip--disabled.md-chip--elevated:not(.md-chip--selected)) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-chip--disabled:hover) .md-chip__state-layer,\n:host(.md-chip--disabled:active) .md-chip__state-layer,\n:host(.md-chip--disabled:focus-visible) .md-chip__state-layer {\n opacity: 0;\n}\n\n/* Soft-disabled: disabled visuals but remains focusable */\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_elevation: var(--md-sys-elevation-0, none) !important;\n}\n\n:host([soft-disabled]) .md-chip__state-layer {\n display: none;\n}\n\n/* ==========================================================\n 13. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-chip__state-layer {\n transition: none;\n }\n}\n\n/* ==========================================================\n 14. FORCED COLORS — Windows High Contrast\n ========================================================== */\n\n@media (forced-colors: active) {\n :host {\n border: 1px solid ButtonText;\n background-color: ButtonFace;\n color: ButtonText;\n forced-color-adjust: none;\n }\n\n .md-chip__outline {\n border-color: ButtonText;\n }\n\n :host(:focus-visible) {\n outline-color: Highlight;\n }\n\n .md-chip__primary:focus-visible {\n outline-color: Highlight;\n }\n\n :host(.md-chip--selected) {\n background-color: Highlight;\n color: HighlightText;\n }\n\n :host(.md-chip--disabled) {\n border-color: GrayText;\n color: GrayText;\n opacity: 1;\n }\n\n .md-chip__state-layer {\n display: none;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\n\n@Component({ tag: 'md-chip', styleUrl: 'md-chip.css', shadow: true })\nexport class MdChip {\n @Element() el!: HTMLElement;\n\n /** Chip variant */\n @Prop({ reflect: true }) variant: 'assist' | 'filter' | 'input' | 'suggestion' = 'assist';\n\n /** Material Symbols icon name for the leading icon */\n @Prop() icon: string = '';\n\n /** Material Symbols icon name for the trailing icon (filter/input only) */\n @Prop({ attribute: 'trailing-icon' }) trailingIcon: string = '';\n\n /** Whether the chip is selected (filter/input variants) */\n @Prop({ mutable: true, reflect: true }) selected: boolean = false;\n\n /**\n * Whether clicking the chip body toggles `selected`. Defaults to true for\n * `filter`/`input` variants. Set `selectable=\"false\"` for a token that is only\n * a display of a value (e.g. a multi-select's removable chips) — clicking the\n * body then does nothing and the ✕ remove button is the only action, so the\n * chip doesn't flash a misleading \"active\" state.\n */\n @Prop() selectable?: boolean;\n\n /**\n * Surface style of the chip. Distinct from `variant`, which selects the M3\n * chip TYPE (assist / filter / input / suggestion); a chip has both.\n *\n * - `outlined` (default) — transparent container with a 1dp outline.\n * - `filled` — tonal container, no outline.\n * - `elevated` — tonal container with elevation and no outline.\n */\n @Prop({ reflect: true }) appearance: 'outlined' | 'filled' | 'elevated' = 'outlined';\n\n /**\n * Colour role applied to the chip's outline / label / container, depending on\n * `appearance`. Omit for the neutral surface treatment.\n *\n * Any role name the THEME defines is accepted, not just a fixed list — the\n * chip resolves `<name>` to the `--md-sys-color-<name>` /\n * `-<name>-container` / `-on-<name>-container` family at runtime. So\n * `color=\"brand\"` works as soon as a theme ships those tokens, and a name the\n * theme does not define degrades to the neutral treatment rather than\n * rendering broken.\n *\n * `primary` | `secondary` | `tertiary` | `error` are the baseline M3 roles;\n * `success` | `warning` | `info` ship in packages/tokens on the same tonal\n * recipe. The union below is a hint for editor autocomplete only — the `string`\n * arm is what makes custom roles work.\n */\n @Prop({ reflect: true }) color?:\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'error'\n | 'success'\n | 'warning'\n | 'info'\n | (string & {});\n\n /**\n * Whether the chip is elevated (adds shadow instead of outline).\n *\n * @deprecated Use `appearance=\"elevated\"`. Kept as an alias so existing\n * markup keeps working: when true it forces the elevated appearance and wins\n * over `appearance`, since a consumer setting it is being explicit.\n */\n @Prop({ reflect: true }) elevated: boolean = false;\n\n /** Disables the chip */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Soft-disabled: disabled visuals but remains focusable */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /**\n * When `true`, the chip renders a trailing remove (\"✕\") button and responds\n * to Delete / Backspace from the chip itself. Works on every variant.\n *\n * `variant=\"input\"` is removable by default (per MD3 spec) — setting\n * `removable=\"false\"` explicitly opts out of that behavior.\n */\n @Prop({ reflect: true }) removable?: boolean;\n\n /** Label text — alternative to default slot */\n @Prop() label: 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 /** Emits when the chip is clicked or activated via keyboard */\n @Event() mdClick: EventEmitter<void>;\n\n /** Emits when the selected state changes (filter/input) */\n @Event() mdSelect: EventEmitter<{ selected: boolean }>;\n\n /**\n * Fires when the trailing remove (\"✕\") button is activated on a removable\n * chip (by click, Enter, Space, Delete, or Backspace).\n *\n * The event is **cancelable**: by default, after `mdRemove` is dispatched\n * the chip removes itself from the DOM. Call `event.preventDefault()` in a\n * handler to keep the chip mounted (e.g. when your state layer owns the\n * list and will re-render with the chip gone).\n */\n @Event({ cancelable: true }) mdRemove: EventEmitter<void>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n /**\n * Maps `color` onto the four slots every appearance rule is written against.\n * Done here rather than as one CSS block per role so ANY theme-defined role\n * works, not just a list we happen to have enumerated.\n *\n * Each var carries a fallback to the neutral default, so a role the theme has\n * not defined renders as an uncoloured chip instead of collapsing to\n * guaranteed-invalid and losing its container colour entirely.\n */\n private get colorVars(): Record<string, string> | undefined {\n const c = this.color;\n // Guard the interpolation: this value becomes part of a custom-property\n // NAME, so anything outside a plain CSS ident is rejected outright.\n if (!c || !/^[a-z][a-z0-9-]*$/i.test(c)) return undefined;\n return {\n '--_c-main': `var(--md-sys-color-${c}, var(--md-sys-color-primary))`,\n '--_c-on-main': `var(--md-sys-color-on-${c}, var(--md-sys-color-on-primary))`,\n '--_c-container': `var(--md-sys-color-${c}-container, var(--md-sys-color-secondary-container))`,\n '--_c-on-container': `var(--md-sys-color-on-${c}-container, var(--md-sys-color-on-secondary-container))`,\n };\n }\n\n /**\n * Resolves the deprecated `elevated` boolean against `appearance`. Setting\n * `elevated` is an explicit act, so it wins; `appearance` covers everything\n * else. One accessor means the class map and any future logic can't disagree\n * about which surface style is in effect.\n */\n private get effectiveAppearance(): 'outlined' | 'filled' | 'elevated' {\n return this.elevated ? 'elevated' : this.appearance;\n }\n\n private get isSelectable() {\n if (this.selectable !== undefined) return this.selectable;\n return this.variant === 'filter' || this.variant === 'input';\n }\n\n /**\n * Whether the chip BODY is an interactive control. An EXPLICITLY non-selectable\n * (`selectable=\"false\"`) REMOVABLE token — e.g. md-multi-select's display chips —\n * does nothing on body-click and only its ✕ is interactive, so exposing the host\n * as a focusable `button` both misleads AT and nests an interactive control inside\n * another (axe nested-interactive). Such tokens are a labelled `group` whose only\n * tab stop is the remove ✕. Every other chip keeps its default button semantics.\n */\n private get isInteractiveHost() {\n return !(this.selectable === false && this.isRemovable);\n }\n\n /**\n * A chip is removable when `removable` is explicitly true, or when the chip\n * is an `input` variant and the consumer hasn't explicitly opted out\n * (`removable=\"false\"`). This keeps backward compatibility: pre-existing\n * `<md-chip variant=\"input\">` markup continues to show the ✕ button.\n */\n private get isRemovable() {\n if (this.removable === true) return true;\n if (this.removable === false) return false;\n return this.variant === 'input';\n }\n\n /** Resolves the chip's accessible label from the label prop or light-DOM text content. */\n private get accessibleLabel(): string {\n return this.label || this.el.textContent?.trim() || '';\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 /**\n * Dispatches the cancelable `mdRemove` event. When the consumer hasn't\n * called `preventDefault()`, removes the chip from its parent DOM as the\n * default action. Centralises the policy so click/key handlers stay\n * single-purpose and we never forget the default action on one path.\n */\n private dispatchRemove() {\n const ev = this.mdRemove.emit();\n if (!ev.defaultPrevented) {\n this.el.remove();\n }\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n if (this.isSelectable) {\n this.selected = !this.selected;\n this.mdSelect.emit({ selected: this.selected });\n }\n\n this.mdClick.emit();\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.isDisabled) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n triggerRipple(this.el);\n this.el.click();\n return;\n }\n\n if (this.isRemovable && (e.key === 'Delete' || e.key === 'Backspace')) {\n e.preventDefault();\n this.dispatchRemove();\n }\n };\n\n private handleRemoveClick = (e: MouseEvent) => {\n e.stopPropagation();\n if (this.isDisabled) return;\n this.dispatchRemove();\n };\n\n private handleRemoveKeyDown = (e: KeyboardEvent) => {\n if (this.isDisabled) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.stopPropagation();\n e.preventDefault();\n this.dispatchRemove();\n }\n };\n\n render() {\n const hasLeadingIcon = !!this.icon || this.hasSlottedLeadingIcon;\n const hasTrailingIcon = !!this.trailingIcon || this.hasSlottedTrailingIcon;\n const showCheckmark = this.variant === 'filter' && this.selected && !hasLeadingIcon;\n const showRemove = this.isRemovable;\n const isEffectivelyDisabled = this.isDisabled;\n const chipLabel = this.accessibleLabel;\n\n // A removable chip renders a trailing remove ✕ <button> — itself a\n // focusable control. If the HOST were also a focusable widget\n // (role=\"button\" + tabindex) the two would nest (axe \"nested-interactive\").\n // So when the body is interactive AND a remove button is present, the host\n // steps down to a labelled `group` container and the primary (body) action\n // becomes its OWN focusable element — a sibling of the remove button, not\n // its ancestor. The host stays a single `button` only when there is no\n // remove button to nest.\n const hostIsButton = this.isInteractiveHost && !showRemove;\n const renderPrimary = this.isInteractiveHost && showRemove;\n\n return (\n <Host\n style={this.colorVars}\n class={{\n 'md-chip': true,\n [`md-chip--${this.variant}`]: true,\n 'md-chip--selected': this.selected && this.isSelectable,\n // The deprecated `elevated` boolean resolves into `appearance`, and\n // the legacy `md-chip--elevated` class is still emitted for that case\n // so every existing rule keyed on it (disabled states, selected\n // combinations) keeps applying untouched.\n [`md-chip--appearance-${this.effectiveAppearance}`]: true,\n 'md-chip--elevated': this.effectiveAppearance === 'elevated',\n [`md-chip--color-${this.color}`]: !!this.color,\n 'md-chip--disabled': isEffectivelyDisabled,\n 'md-chip--with-leading-icon': hasLeadingIcon || showCheckmark,\n 'md-chip--with-trailing-icon': hasTrailingIcon || showRemove,\n }}\n role={hostIsButton ? 'button' : 'group'}\n aria-roledescription=\"chip\"\n aria-pressed={hostIsButton && this.isSelectable ? String(this.selected) : undefined}\n aria-label={hostIsButton ? undefined : chipLabel || undefined}\n aria-disabled={isEffectivelyDisabled ? 'true' : undefined}\n tabindex={hostIsButton ? (this.disabled ? '-1' : '0') : undefined}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n >\n <md-ripple disabled={isEffectivelyDisabled}></md-ripple>\n <span class=\"md-chip__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n {!this.elevated && <span class=\"md-chip__outline\" part=\"outline\" aria-hidden=\"true\"></span>}\n\n {renderPrimary && (\n <span\n class=\"md-chip__primary\"\n part=\"primary\"\n role=\"button\"\n tabindex={this.disabled ? '-1' : '0'}\n aria-labelledby=\"md-chip-label-text\"\n aria-pressed={this.isSelectable ? String(this.selected) : undefined}\n aria-disabled={isEffectivelyDisabled ? 'true' : undefined}\n ></span>\n )}\n\n {showCheckmark && (\n <span class=\"md-chip__checkmark\" part=\"checkmark\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M6.75 12.127L3.623 9l-1.06 1.057L6.75 14.25l9-9-1.057-1.057L6.75 12.127z\" fill=\"currentColor\" />\n </svg>\n </span>\n )}\n\n <slot name=\"leading-icon\">\n {hasLeadingIcon && !showCheckmark && (\n <span class=\"md-chip__icon material-symbols-outlined\" part=\"icon\" aria-hidden=\"true\">\n {this.icon}\n </span>\n )}\n </slot>\n\n <span class=\"md-chip__label\" part=\"label\" id=\"md-chip-label-text\">\n <slot>{this.label}</slot>\n </span>\n\n {showRemove ? (\n <button\n class=\"md-chip__remove\"\n part=\"remove\"\n type=\"button\"\n tabindex={this.disabled ? '-1' : '0'}\n aria-label={chipLabel ? `Remove ${chipLabel}` : 'Remove'}\n disabled={isEffectivelyDisabled}\n onClick={this.handleRemoveClick}\n onKeyDown={this.handleRemoveKeyDown}\n >\n <slot name=\"trailing-icon\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M14.25 4.808l-1.058-1.058L9 7.942 4.808 3.75 3.75 4.808 7.942 9 3.75 13.192l1.058 1.058L9 10.058l4.192 4.192 1.058-1.058L10.058 9l4.192-4.192z\" fill=\"currentColor\" />\n </svg>\n </slot>\n </button>\n ) : (\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && (\n <span class=\"md-chip__trailing-icon material-symbols-outlined\" part=\"trailing-icon\" aria-hidden=\"true\">\n {this.trailingIcon}\n </span>\n )}\n </slot>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"+IAAA,MAAMA,EAAY,IAAM,2iV,MCIXC,EAAMC,EAAA,MAAAD,UAAAE,EADnB,WAAAC,CAAAC,G,yKAK2BC,KAAAC,QAAwD,SAGzED,KAAAE,KAAe,GAGeF,KAAAG,aAAuB,GAGrBH,KAAAI,SAAoB,MAmBnCJ,KAAAK,WAAiD,WAmCjDL,KAAAM,SAAoB,MAGpBN,KAAAO,SAAoB,MAGQP,KAAAQ,aAAwB,MAYrER,KAAAS,MAAgB,GAOCT,KAAAU,QAAiC,EAmBzCV,KAAAW,sBAAwB,MACxBX,KAAAY,uBAAyB,MAoGlCZ,KAAAa,YAAeC,IACrB,GAAId,KAAKe,WAAY,CAAED,EAAEE,iBAAkB,M,CAE3C,GAAIhB,KAAKiB,aAAc,CACrBjB,KAAKI,UAAYJ,KAAKI,SACtBJ,KAAKkB,SAASC,KAAK,CAAEf,SAAUJ,KAAKI,U,CAGtCJ,KAAKoB,QAAQD,MAAM,EAGbnB,KAAAqB,cAAiBP,IACvB,GAAId,KAAKe,WAAY,OAErB,GAAID,EAAEQ,MAAQ,SAAWR,EAAEQ,MAAQ,IAAK,CACtCR,EAAEE,iBACFO,EAAcvB,KAAKwB,IACnBxB,KAAKwB,GAAGC,QACR,M,CAGF,GAAIzB,KAAK0B,cAAgBZ,EAAEQ,MAAQ,UAAYR,EAAEQ,MAAQ,aAAc,CACrER,EAAEE,iBACFhB,KAAK2B,gB,GAID3B,KAAA4B,kBAAqBd,IAC3BA,EAAEe,kBACF,GAAI7B,KAAKe,WAAY,OACrBf,KAAK2B,gBAAgB,EAGf3B,KAAA8B,oBAAuBhB,IAC7B,GAAId,KAAKe,WAAY,OACrB,GAAID,EAAEQ,MAAQ,SAAWR,EAAEQ,MAAQ,IAAK,CACtCR,EAAEe,kBACFf,EAAEE,iBACFhB,KAAK2B,gB,EAoHV,CA5PC,cAAYZ,GACV,OAAOf,KAAKO,UAAYP,KAAKQ,Y,CAY/B,aAAYuB,GACV,MAAMC,EAAIhC,KAAKiC,MAGf,IAAKD,IAAM,qBAAqBE,KAAKF,GAAI,OAAOG,UAChD,MAAO,CACL,YAAa,sBAAsBH,kCACnC,eAAgB,yBAAyBA,qCACzC,iBAAkB,sBAAsBA,wDACxC,oBAAqB,yBAAyBA,2D,CAUlD,uBAAYI,GACV,OAAOpC,KAAKM,SAAW,WAAaN,KAAKK,U,CAG3C,gBAAYY,GACV,GAAIjB,KAAKqC,aAAeF,UAAW,OAAOnC,KAAKqC,WAC/C,OAAOrC,KAAKC,UAAY,UAAYD,KAAKC,UAAY,O,CAWvD,qBAAYqC,GACV,QAAStC,KAAKqC,aAAe,OAASrC,KAAK0B,Y,CAS7C,eAAYA,GACV,GAAI1B,KAAKuC,YAAc,KAAM,OAAO,KACpC,GAAIvC,KAAKuC,YAAc,MAAO,OAAO,MACrC,OAAOvC,KAAKC,UAAY,O,CAI1B,mBAAYuC,GACV,OAAOxC,KAAKS,OAAST,KAAKwB,GAAGiB,aAAaC,QAAU,E,CAGtD,gBAAAC,GACE,MAAMC,EAAS5C,KAAKwB,GAAGqB,WACvB,IAAKD,EAAQ,OAEb,MAAME,EAAcF,EAAOG,cAAc,6BACzC,MAAMC,EAAeJ,EAAOG,cAAc,8BAE1CD,GAAaG,iBAAiB,cAAc,KAC1CjD,KAAKW,sBAAwBmC,EAAYI,mBAAmBC,OAAS,CAAC,IAExEH,GAAcC,iBAAiB,cAAc,KAC3CjD,KAAKY,uBAAyBoC,EAAaE,mBAAmBC,OAAS,CAAC,G,CAUpE,cAAAxB,GACN,MAAMyB,EAAKpD,KAAKqD,SAASlC,OACzB,IAAKiC,EAAGE,iBAAkB,CACxBtD,KAAKwB,GAAG+B,Q,EA8CZ,MAAAC,GACE,MAAMC,IAAmBzD,KAAKE,MAAQF,KAAKW,sBAC3C,MAAM+C,IAAoB1D,KAAKG,cAAgBH,KAAKY,uBACpD,MAAM+C,EAAgB3D,KAAKC,UAAY,UAAYD,KAAKI,WAAaqD,EACrE,MAAMG,EAAa5D,KAAK0B,YACxB,MAAMmC,EAAwB7D,KAAKe,WACnC,MAAM+C,EAAY9D,KAAKwC,gBAUvB,MAAMuB,EAAe/D,KAAKsC,oBAAsBsB,EAChD,MAAMI,EAAgBhE,KAAKsC,mBAAqBsB,EAEhD,OACEK,EAACC,EAAI,CAAA5C,IAAA,2CACH6C,MAAOnE,KAAK+B,UACZqC,MAAO,CACL,UAAW,KACX,CAAC,YAAYpE,KAAKC,WAAY,KAC9B,oBAAqBD,KAAKI,UAAYJ,KAAKiB,aAK3C,CAAC,uBAAuBjB,KAAKoC,uBAAwB,KACrD,oBAAqBpC,KAAKoC,sBAAwB,WAClD,CAAC,kBAAkBpC,KAAKiC,WAAYjC,KAAKiC,MACzC,oBAAqB4B,EACrB,6BAA8BJ,GAAkBE,EAChD,8BAA+BD,GAAmBE,GAEpDS,KAAMN,EAAe,SAAW,QAAO,uBAClB,OAAM,eACbA,GAAgB/D,KAAKiB,aAAeqD,OAAOtE,KAAKI,UAAY+B,UAAS,aACvE4B,EAAe5B,UAAY2B,GAAa3B,UAAS,gBAC9C0B,EAAwB,OAAS1B,UAChDoC,SAAUR,EAAgB/D,KAAKO,SAAW,KAAO,IAAO4B,UACxDqC,QAASxE,KAAKa,YACd4D,UAAWzE,KAAKqB,eAEhB4C,EAAA,aAAA3C,IAAA,2CAAWf,SAAUsD,IACrBI,EAAA,QAAA3C,IAAA,2CAAM8C,MAAM,uBAAuBM,KAAK,cAAa,cAAa,UAEhE1E,KAAKM,UAAY2D,EAAA,QAAA3C,IAAA,2CAAM8C,MAAM,mBAAmBM,KAAK,UAAS,cAAa,SAE5EV,GACCC,EAAA,QAAA3C,IAAA,2CACE8C,MAAM,mBACNM,KAAK,UACLL,KAAK,SACLE,SAAUvE,KAAKO,SAAW,KAAO,IAAG,kBACpB,qBAAoB,eACtBP,KAAKiB,aAAeqD,OAAOtE,KAAKI,UAAY+B,UAAS,gBACpD0B,EAAwB,OAAS1B,YAInDwB,GACCM,EAAA,QAAA3C,IAAA,2CAAM8C,MAAM,qBAAqBM,KAAK,YAAW,cAAa,QAC5DT,EAAA,OAAA3C,IAAA,2CAAKqD,QAAQ,YAAYC,KAAK,QAC5BX,EAAA,QAAA3C,IAAA,2CAAMuD,EAAE,2EAA2ED,KAAK,mBAK9FX,EAAA,QAAA3C,IAAA,2CAAMwD,KAAK,gBACRrB,IAAmBE,GAClBM,EAAA,QAAA3C,IAAA,2CAAM8C,MAAM,0CAA0CM,KAAK,OAAM,cAAa,QAC3E1E,KAAKE,OAKZ+D,EAAA,QAAA3C,IAAA,2CAAM8C,MAAM,iBAAiBM,KAAK,QAAQK,GAAG,sBAC3Cd,EAAA,QAAA3C,IAAA,4CAAOtB,KAAKS,QAGbmD,EACCK,EAAA,UACEG,MAAM,kBACNM,KAAK,SACLM,KAAK,SACLT,SAAUvE,KAAKO,SAAW,KAAO,IAAG,aACxBuD,EAAY,UAAUA,IAAc,SAChDvD,SAAUsD,EACVW,QAASxE,KAAK4B,kBACd6C,UAAWzE,KAAK8B,qBAEhBmC,EAAA,QAAMa,KAAK,iBACTb,EAAA,OAAKU,QAAQ,YAAYC,KAAK,OAAM,cAAa,QAC/CX,EAAA,QAAMY,EAAE,iJAAiJD,KAAK,oBAKpKX,EAAA,QAAMa,KAAK,iBACRpB,GACCO,EAAA,QAAMG,MAAM,mDAAmDM,KAAK,gBAAe,cAAa,QAC7F1E,KAAKG,e","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["mdChipCss","MdChip","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","variant","icon","trailingIcon","selected","appearance","elevated","disabled","softDisabled","label","density","hasSlottedLeadingIcon","hasSlottedTrailingIcon","handleClick","e","isDisabled","preventDefault","isSelectable","mdSelect","emit","mdClick","handleKeyDown","key","triggerRipple","el","click","isRemovable","dispatchRemove","handleRemoveClick","stopPropagation","handleRemoveKeyDown","colorVars","c","color","test","undefined","effectiveAppearance","selectable","isInteractiveHost","removable","accessibleLabel","textContent","trim","componentDidLoad","shadow","shadowRoot","leadingSlot","querySelector","trailingSlot","addEventListener","assignedElements","length","ev","mdRemove","defaultPrevented","remove","render","hasLeadingIcon","hasTrailingIcon","showCheckmark","showRemove","isEffectivelyDisabled","chipLabel","hostIsButton","renderPrimary","h","Host","style","class","role","String","tabindex","onClick","onKeyDown","part","viewBox","fill","d","name","id","type"],"sources":["src/components/md-chip/md-chip.css?tag=md-chip&encapsulation=shadow","src/components/md-chip/md-chip.tsx"],"sourcesContent":["/* ==========================================================\n md-chip — Material Design 3 Chip\n Spec: https://m3.material.io/components/chips/specs\n\n Four variants:\n assist — surface-container-low, on-surface, outline\n filter — surface-container-low, on-surface-variant, outline (selectable)\n input — surface-container-low, on-surface-variant, outline-variant (selectable + removable)\n suggestion — surface-container-low, on-surface-variant, outline\n\n Measurements (MD3 spec):\n Height: 32px\n Shape: 8px corner radius (shape-corner-small)\n Icon size: 18px\n Left/right padding: 16px (no icon), 8px (with icon)\n Padding between: 8px\n Label text: label-large\n\n APPEARANCE x COLOUR:\n `appearance` picks the surface style (outlined | filled | elevated) and is\n independent of `variant`, which picks the M3 chip TYPE. `color` picks a\n role — primary / secondary / tertiary / error (baseline M3) or\n success / warning / info (semantic status roles, defined in\n packages/tokens/src/tokens.css on the same tonal recipe).\n\n outlined + color -> tints outline, label and icon; container transparent\n filled/elevated -> tonal container (<color>-container) with\n on-<color>-container label; outline dropped\n no color -> neutral: outlined is unchanged from before, and\n filled/elevated take a surface tone rather than the\n secondary container, so an unselected filled chip is\n never mistaken for a selected one\n\n Every per-instance property below still wins over all of it.\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-chip-container-color Container background\n --md-chip-container-color-selected Selected container background\n --md-chip-label-color Label text color\n --md-chip-label-color-selected Selected label text color\n --md-chip-icon-color Leading/trailing icon color\n --md-chip-icon-size Icon dimensions\n --md-chip-container-shape Border-radius override\n --md-chip-container-height Height override\n --md-chip-outline-color Outline color\n --md-chip-outline-width Outline width\n --md-chip-state-layer-color State layer color override\n --md-chip-elevation Box-shadow override\n\n CSS PARTS:\n state-layer Hover/press overlay\n outline Border element\n label Label text wrapper\n icon Leading icon\n trailing-icon Trailing icon\n checkmark Filter chip checkmark\n remove Input chip remove button\n\n SLOTS:\n (default) Label text\n leading-icon Custom leading icon\n trailing-icon Custom trailing icon\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — BASE\n ========================================================== */\n\n:host {\n --_container-color: var(--md-chip-container-color, transparent);\n --_container-color-selected: var(--md-chip-container-color-selected, var(--md-sys-color-secondary-container));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n --_label-color-selected: var(--md-chip-label-color-selected, var(--md-sys-color-on-secondary-container));\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-primary));\n --_icon-size: var(--md-chip-icon-size, max(14px, calc(18px + var(--md-sys-density-scale, 0) * 1px)));\n --_container-shape: var(--md-chip-container-shape, var(--md-sys-shape-corner-small, 8px));\n --_container-height: var(--md-chip-container-height, 32px);\n --_outline-color: var(--md-chip-outline-color, var(--md-sys-color-outline));\n --_outline-width: var(--md-chip-outline-width, 1px);\n --_state-layer-color: var(--md-chip-state-layer-color, var(--md-sys-color-on-surface));\n --_elevation: var(--md-chip-elevation, var(--md-sys-elevation-0, none));\n /* Colour-role slots. These four are the ONLY thing the `color` prop swaps;\n every appearance below is written against them, so adding a role is a\n 4-line block and never touches the appearance rules.\n The neutral defaults reproduce the pre-existing look exactly: an uncoloured\n chip's selected state has always been secondary-container. */\n --_c-main: var(--md-sys-color-primary);\n --_c-on-main: var(--md-sys-color-on-primary);\n --_c-container: var(--md-sys-color-secondary-container);\n --_c-on-container: var(--md-sys-color-on-secondary-container);\n --_padding-inline: var(--md-sys-spacing-inset-lg, 16px);\n --_gap: var(--md-sys-spacing-gap-sm, 8px);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n box-sizing: border-box;\n /* Global density: each `data-density` rung (0…-4) trims 4px off the chip\n height, floored at 24px (label-large line-height is 20px). Applied at the\n consumption point so every size/variant is covered by one edit. Unchanged\n at density 0. */\n block-size: max(24px, calc(var(--_container-height) + var(--md-sys-density-scale, 0) * 4px));\n padding-inline: var(--_padding-inline);\n gap: var(--_gap);\n\n background-color: var(--_container-color);\n border-radius: var(--_container-shape);\n box-shadow: var(--_elevation);\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n overflow: hidden;\n\n font-family: var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);\n font-size: max(11px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-large-font-weight, 500);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n letter-spacing: var(--md-sys-typescale-label-large-letter-spacing, 0.1px);\n color: var(--_label-color);\n\n transition:\n background-color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n box-shadow var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n color var(--md-sys-motion-duration-short2, 200ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* Shrink padding when leading/trailing icon present */\n:host(.md-chip--with-leading-icon) {\n padding-inline-start: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n:host(.md-chip--with-trailing-icon) {\n padding-inline-end: var(--md-sys-spacing-inset-sm, 8px);\n}\n\n/* ==========================================================\n 2. VARIANT-SPECIFIC COLORS\n ========================================================== */\n\n/* Assist — primary icon color */\n:host(.md-chip--assist) {\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-primary));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface));\n}\n\n/* Filter */\n:host(.md-chip--filter) {\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n}\n\n/* Input */\n:host(.md-chip--input) {\n --_outline-color: var(--md-chip-outline-color, var(--md-sys-color-outline-variant));\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n}\n\n/* Suggestion */\n:host(.md-chip--suggestion) {\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n}\n\n/* ==========================================================\n 3. SELECTED STATE\n ========================================================== */\n\n:host(.md-chip--selected) {\n --_container-color: var(--_container-color-selected);\n color: var(--_label-color-selected);\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-secondary-container));\n --_state-layer-color: var(--md-sys-color-on-secondary-container);\n}\n\n:host(.md-chip--selected) .md-chip__outline {\n border-color: transparent;\n}\n\n/* ==========================================================\n 4. ELEVATED\n ========================================================== */\n\n:host(.md-chip--elevated) {\n --_elevation: var(--md-chip-elevation, var(--md-sys-elevation-1));\n}\n\n:host(.md-chip--elevated) .md-chip__outline {\n border-color: transparent;\n}\n\n:host(.md-chip--elevated.md-chip--selected) {\n --_elevation: var(--md-chip-elevation, var(--md-sys-elevation-1));\n}\n\n/* ==========================================================\n 4b. COLOUR ROLES\n Resolved in the component, not here: md-chip.tsx maps `color` onto the four\n --_c-* slots below as inline custom properties. That way ANY role the theme\n defines works — `color=\"brand\"` picks up --md-sys-color-brand the moment a\n theme ships it — instead of only the names we happened to enumerate in CSS.\n Each slot falls back to the neutral default, so an unknown role renders as an\n uncoloured chip rather than losing its container colour entirely.\n ========================================================== */\n\n/* ==========================================================\n 4c. APPEARANCE (outlined | filled | elevated)\n ========================================================== */\n\n/* `outlined` is the default and is deliberately a no-op when no `color` is set,\n so untouched chips render exactly as before. With a colour, the role tints\n the outline, label and icon while the container stays transparent. */\n:host(.md-chip--appearance-outlined[color]) {\n --_outline-color: var(--md-chip-outline-color, var(--_c-main));\n --_label-color: var(--md-chip-label-color, var(--_c-main));\n --_icon-color: var(--md-chip-icon-color, var(--_c-main));\n --_state-layer-color: var(--md-chip-state-layer-color, var(--_c-main));\n}\n\n/* `filled` and `elevated` share one tonal container — they differ only in\n elevation, which section 4 already owns. Without a colour they take a neutral\n surface rather than the secondary container, so an unselected filled chip is\n never mistaken for a selected one. */\n:host(.md-chip--appearance-filled),\n:host(.md-chip--appearance-elevated) {\n --_container-color: var(--md-chip-container-color, var(--md-sys-color-surface-container-high));\n --_label-color: var(--md-chip-label-color, var(--md-sys-color-on-surface-variant));\n --_icon-color: var(--md-chip-icon-color, var(--md-sys-color-on-surface-variant));\n}\n\n:host(.md-chip--appearance-filled[color]),\n:host(.md-chip--appearance-elevated[color]) {\n --_container-color: var(--md-chip-container-color, var(--_c-container));\n --_label-color: var(--md-chip-label-color, var(--_c-on-container));\n --_icon-color: var(--md-chip-icon-color, var(--_c-on-container));\n --_state-layer-color: var(--md-chip-state-layer-color, var(--_c-on-container));\n}\n\n/* Both drop the outline: the container itself is now the shape. */\n:host(.md-chip--appearance-filled) .md-chip__outline,\n:host(.md-chip--appearance-elevated) .md-chip__outline {\n border-color: transparent;\n}\n\n/* Selection tints with the chosen role instead of the fixed secondary\n container, for every appearance. Section 3 still supplies the neutral case. */\n:host(.md-chip--selected[color]) {\n --_container-color: var(--_c-container);\n color: var(--_c-on-container);\n --_label-color-selected: var(--_c-on-container);\n --_icon-color: var(--md-chip-icon-color, var(--_c-on-container));\n --_state-layer-color: var(--_c-on-container);\n}\n\n/* ==========================================================\n 5. OUTLINE\n ========================================================== */\n\n.md-chip__outline {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n border: var(--_outline-width) solid var(--_outline-color);\n pointer-events: none;\n}\n\n/* ==========================================================\n 6. STATE LAYER\n ========================================================== */\n\n.md-chip__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity var(--md-sys-motion-duration-short1, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n z-index: 1;\n}\n\n:host(:hover) .md-chip__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(:focus-visible) .md-chip__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.12);\n}\n\n:host(:active) .md-chip__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n/* ==========================================================\n 7. FOCUS RING\n ========================================================== */\n\n:host(:focus-visible) {\n outline: 3px solid var(--md-sys-color-secondary);\n outline-offset: 2px;\n}\n\n/* ==========================================================\n 7b. PRIMARY ACTION (removable chips)\n When a chip is both interactive AND removable, its body action is a\n SEPARATE focusable control that is a sibling of the remove ✕ button\n (so the two interactive controls don't nest — see md-chip.tsx). It is a\n transparent layer over the chip; the label/icons paint above it (higher in\n DOM at the same z-index) and pointer/keyboard activation bubbles to the\n host handlers. The focus ring uses a NEGATIVE outline-offset so it renders\n INSIDE the chip edge and is not clipped by the host's `overflow: hidden`.\n ========================================================== */\n\n.md-chip__primary {\n position: absolute;\n inset: 0;\n z-index: 2;\n margin: 0;\n padding: 0;\n border: none;\n background: none;\n border-radius: inherit;\n cursor: inherit;\n -webkit-tap-highlight-color: transparent;\n}\n\n.md-chip__primary:focus-visible {\n outline: 3px solid var(--md-sys-color-secondary);\n outline-offset: -3px;\n}\n\n/* ==========================================================\n 8. LABEL\n ========================================================== */\n\n.md-chip__label {\n position: relative;\n z-index: 2;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-align: start;\n}\n\n/* ==========================================================\n 9. ICONS\n ========================================================== */\n\n.md-chip__icon,\n.md-chip__trailing-icon {\n position: relative;\n z-index: 2;\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-size: var(--_icon-size);\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n color: var(--_icon-color);\n line-height: 1;\n font-weight: normal;\n font-style: normal;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n -webkit-font-smoothing: antialiased;\n pointer-events: none;\n flex-shrink: 0;\n}\n\nslot[name=\"leading-icon\"],\nslot[name=\"trailing-icon\"] {\n display: contents;\n}\n\n::slotted([slot=\"leading-icon\"]),\n::slotted([slot=\"trailing-icon\"]) {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n font-size: var(--_icon-size);\n color: var(--_icon-color);\n fill: currentColor;\n pointer-events: none;\n flex-shrink: 0;\n position: relative;\n z-index: 2;\n}\n\n/* ==========================================================\n 10. CHECKMARK (filter chip selected)\n ========================================================== */\n\n.md-chip__checkmark {\n position: relative;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n color: var(--_icon-color);\n flex-shrink: 0;\n}\n\n.md-chip__checkmark svg {\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n}\n\n/* ==========================================================\n 11. REMOVE BUTTON (input chip)\n ========================================================== */\n\n.md-chip__remove {\n position: relative;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-inline-size: 18px;\n min-block-size: 18px;\n padding: 0;\n border: none;\n background: none;\n color: var(--_icon-color);\n cursor: pointer;\n border-radius: 50%;\n flex-shrink: 0;\n -webkit-tap-highlight-color: transparent;\n}\n\n.md-chip__remove:focus-visible {\n outline: 2px solid var(--md-sys-color-secondary);\n outline-offset: 1px;\n}\n\n.md-chip__remove svg {\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n pointer-events: none;\n}\n\n.md-chip__remove:disabled {\n cursor: default;\n pointer-events: none;\n}\n\n/* ==========================================================\n 12. DISABLED\n ========================================================== */\n\n:host(.md-chip--disabled) {\n cursor: default;\n pointer-events: none;\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_elevation: var(--md-sys-elevation-0, none) !important;\n}\n\n:host(.md-chip--disabled:not(.md-chip--selected):not(.md-chip--elevated)) .md-chip__outline {\n border-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-chip--disabled.md-chip--selected) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-chip--disabled.md-chip--elevated:not(.md-chip--selected)) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-chip--disabled:hover) .md-chip__state-layer,\n:host(.md-chip--disabled:active) .md-chip__state-layer,\n:host(.md-chip--disabled:focus-visible) .md-chip__state-layer {\n opacity: 0;\n}\n\n/* Soft-disabled: disabled visuals but remains focusable */\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_icon-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_elevation: var(--md-sys-elevation-0, none) !important;\n}\n\n:host([soft-disabled]) .md-chip__state-layer {\n display: none;\n}\n\n/* ==========================================================\n 13. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-chip__state-layer {\n transition: none;\n }\n}\n\n/* ==========================================================\n 14. FORCED COLORS — Windows High Contrast\n ========================================================== */\n\n@media (forced-colors: active) {\n :host {\n border: 1px solid ButtonText;\n background-color: ButtonFace;\n color: ButtonText;\n forced-color-adjust: none;\n }\n\n .md-chip__outline {\n border-color: ButtonText;\n }\n\n :host(:focus-visible) {\n outline-color: Highlight;\n }\n\n .md-chip__primary:focus-visible {\n outline-color: Highlight;\n }\n\n :host(.md-chip--selected) {\n background-color: Highlight;\n color: HighlightText;\n }\n\n :host(.md-chip--disabled) {\n border-color: GrayText;\n color: GrayText;\n opacity: 1;\n }\n\n .md-chip__state-layer {\n display: none;\n }\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element } from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\n\n@Component({ tag: 'md-chip', styleUrl: 'md-chip.css', shadow: true })\nexport class MdChip {\n @Element() el!: HTMLElement;\n\n /** Chip variant */\n @Prop({ reflect: true }) variant: 'assist' | 'filter' | 'input' | 'suggestion' = 'assist';\n\n /** Material Symbols icon name for the leading icon */\n @Prop() icon: string = '';\n\n /** Material Symbols icon name for the trailing icon (filter/input only) */\n @Prop({ attribute: 'trailing-icon' }) trailingIcon: string = '';\n\n /** Whether the chip is selected (filter/input variants) */\n @Prop({ mutable: true, reflect: true }) selected: boolean = false;\n\n /**\n * Whether clicking the chip body toggles `selected`. Defaults to true for\n * `filter`/`input` variants. Set `selectable=\"false\"` for a token that is only\n * a display of a value (e.g. a multi-select's removable chips) — clicking the\n * body then does nothing and the ✕ remove button is the only action, so the\n * chip doesn't flash a misleading \"active\" state.\n */\n @Prop() selectable?: boolean;\n\n /**\n * Surface style of the chip. Distinct from `variant`, which selects the M3\n * chip TYPE (assist / filter / input / suggestion); a chip has both.\n *\n * - `outlined` (default) — transparent container with a 1dp outline.\n * - `filled` — tonal container, no outline.\n * - `elevated` — tonal container with elevation and no outline.\n */\n @Prop({ reflect: true }) appearance: 'outlined' | 'filled' | 'elevated' = 'outlined';\n\n /**\n * Colour role applied to the chip's outline / label / container, depending on\n * `appearance`. Omit for the neutral surface treatment.\n *\n * Any role name the THEME defines is accepted, not just a fixed list — the\n * chip resolves `<name>` to the `--md-sys-color-<name>` /\n * `-<name>-container` / `-on-<name>-container` family at runtime. So\n * `color=\"brand\"` works as soon as a theme ships those tokens, and a name the\n * theme does not define degrades to the neutral treatment rather than\n * rendering broken.\n *\n * `primary` | `secondary` | `tertiary` | `error` are the baseline M3 roles;\n * `success` | `warning` | `info` ship in packages/tokens on the same tonal\n * recipe. The union below is a hint for editor autocomplete only — the `string`\n * arm is what makes custom roles work.\n */\n @Prop({ reflect: true }) color?:\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'error'\n | 'success'\n | 'warning'\n | 'info'\n | (string & {});\n\n /**\n * Whether the chip is elevated (adds shadow instead of outline).\n *\n * @deprecated Use `appearance=\"elevated\"`. Kept as an alias so existing\n * markup keeps working: when true it forces the elevated appearance and wins\n * over `appearance`, since a consumer setting it is being explicit.\n */\n @Prop({ reflect: true }) elevated: boolean = false;\n\n /** Disables the chip */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Soft-disabled: disabled visuals but remains focusable */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /**\n * When `true`, the chip renders a trailing remove (\"✕\") button and responds\n * to Delete / Backspace from the chip itself. Works on every variant.\n *\n * `variant=\"input\"` is removable by default (per MD3 spec) — setting\n * `removable=\"false\"` explicitly opts out of that behavior.\n */\n @Prop({ reflect: true }) removable?: boolean;\n\n /** Label text — alternative to default slot */\n @Prop() label: 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 /** Emits when the chip is clicked or activated via keyboard */\n @Event() mdClick: EventEmitter<void>;\n\n /** Emits when the selected state changes (filter/input) */\n @Event() mdSelect: EventEmitter<{ selected: boolean }>;\n\n /**\n * Fires when the trailing remove (\"✕\") button is activated on a removable\n * chip (by click, Enter, Space, Delete, or Backspace).\n *\n * The event is **cancelable**: by default, after `mdRemove` is dispatched\n * the chip removes itself from the DOM. Call `event.preventDefault()` in a\n * handler to keep the chip mounted (e.g. when your state layer owns the\n * list and will re-render with the chip gone).\n */\n @Event({ cancelable: true }) mdRemove: EventEmitter<void>;\n\n @State() private hasSlottedLeadingIcon = false;\n @State() private hasSlottedTrailingIcon = false;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n /**\n * Maps `color` onto the four slots every appearance rule is written against.\n * Done here rather than as one CSS block per role so ANY theme-defined role\n * works, not just a list we happen to have enumerated.\n *\n * Each var carries a fallback to the neutral default, so a role the theme has\n * not defined renders as an uncoloured chip instead of collapsing to\n * guaranteed-invalid and losing its container colour entirely.\n */\n private get colorVars(): Record<string, string> | undefined {\n const c = this.color;\n // Guard the interpolation: this value becomes part of a custom-property\n // NAME, so anything outside a plain CSS ident is rejected outright.\n if (!c || !/^[a-z][a-z0-9-]*$/i.test(c)) return undefined;\n return {\n '--_c-main': `var(--md-sys-color-${c}, var(--md-sys-color-primary))`,\n '--_c-on-main': `var(--md-sys-color-on-${c}, var(--md-sys-color-on-primary))`,\n '--_c-container': `var(--md-sys-color-${c}-container, var(--md-sys-color-secondary-container))`,\n '--_c-on-container': `var(--md-sys-color-on-${c}-container, var(--md-sys-color-on-secondary-container))`,\n };\n }\n\n /**\n * Resolves the deprecated `elevated` boolean against `appearance`. Setting\n * `elevated` is an explicit act, so it wins; `appearance` covers everything\n * else. One accessor means the class map and any future logic can't disagree\n * about which surface style is in effect.\n */\n private get effectiveAppearance(): 'outlined' | 'filled' | 'elevated' {\n return this.elevated ? 'elevated' : this.appearance;\n }\n\n private get isSelectable() {\n if (this.selectable !== undefined) return this.selectable;\n return this.variant === 'filter' || this.variant === 'input';\n }\n\n /**\n * Whether the chip BODY is an interactive control. An EXPLICITLY non-selectable\n * (`selectable=\"false\"`) REMOVABLE token — e.g. md-multi-select's display chips —\n * does nothing on body-click and only its ✕ is interactive, so exposing the host\n * as a focusable `button` both misleads AT and nests an interactive control inside\n * another (axe nested-interactive). Such tokens are a labelled `group` whose only\n * tab stop is the remove ✕. Every other chip keeps its default button semantics.\n */\n private get isInteractiveHost() {\n return !(this.selectable === false && this.isRemovable);\n }\n\n /**\n * A chip is removable when `removable` is explicitly true, or when the chip\n * is an `input` variant and the consumer hasn't explicitly opted out\n * (`removable=\"false\"`). This keeps backward compatibility: pre-existing\n * `<md-chip variant=\"input\">` markup continues to show the ✕ button.\n */\n private get isRemovable() {\n if (this.removable === true) return true;\n if (this.removable === false) return false;\n return this.variant === 'input';\n }\n\n /** Resolves the chip's accessible label from the label prop or light-DOM text content. */\n private get accessibleLabel(): string {\n return this.label || this.el.textContent?.trim() || '';\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 /**\n * Dispatches the cancelable `mdRemove` event. When the consumer hasn't\n * called `preventDefault()`, removes the chip from its parent DOM as the\n * default action. Centralises the policy so click/key handlers stay\n * single-purpose and we never forget the default action on one path.\n */\n private dispatchRemove() {\n const ev = this.mdRemove.emit();\n if (!ev.defaultPrevented) {\n this.el.remove();\n }\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) { e.preventDefault(); return; }\n\n if (this.isSelectable) {\n this.selected = !this.selected;\n this.mdSelect.emit({ selected: this.selected });\n }\n\n this.mdClick.emit();\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.isDisabled) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n triggerRipple(this.el);\n this.el.click();\n return;\n }\n\n if (this.isRemovable && (e.key === 'Delete' || e.key === 'Backspace')) {\n e.preventDefault();\n this.dispatchRemove();\n }\n };\n\n private handleRemoveClick = (e: MouseEvent) => {\n e.stopPropagation();\n if (this.isDisabled) return;\n this.dispatchRemove();\n };\n\n private handleRemoveKeyDown = (e: KeyboardEvent) => {\n if (this.isDisabled) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.stopPropagation();\n e.preventDefault();\n this.dispatchRemove();\n }\n };\n\n render() {\n const hasLeadingIcon = !!this.icon || this.hasSlottedLeadingIcon;\n const hasTrailingIcon = !!this.trailingIcon || this.hasSlottedTrailingIcon;\n const showCheckmark = this.variant === 'filter' && this.selected && !hasLeadingIcon;\n const showRemove = this.isRemovable;\n const isEffectivelyDisabled = this.isDisabled;\n const chipLabel = this.accessibleLabel;\n\n // A removable chip renders a trailing remove ✕ <button> — itself a\n // focusable control. If the HOST were also a focusable widget\n // (role=\"button\" + tabindex) the two would nest (axe \"nested-interactive\").\n // So when the body is interactive AND a remove button is present, the host\n // steps down to a labelled `group` container and the primary (body) action\n // becomes its OWN focusable element — a sibling of the remove button, not\n // its ancestor. The host stays a single `button` only when there is no\n // remove button to nest.\n const hostIsButton = this.isInteractiveHost && !showRemove;\n const renderPrimary = this.isInteractiveHost && showRemove;\n\n return (\n <Host\n style={this.colorVars}\n class={{\n 'md-chip': true,\n [`md-chip--${this.variant}`]: true,\n 'md-chip--selected': this.selected && this.isSelectable,\n // The deprecated `elevated` boolean resolves into `appearance`, and\n // the legacy `md-chip--elevated` class is still emitted for that case\n // so every existing rule keyed on it (disabled states, selected\n // combinations) keeps applying untouched.\n [`md-chip--appearance-${this.effectiveAppearance}`]: true,\n 'md-chip--elevated': this.effectiveAppearance === 'elevated',\n [`md-chip--color-${this.color}`]: !!this.color,\n 'md-chip--disabled': isEffectivelyDisabled,\n 'md-chip--with-leading-icon': hasLeadingIcon || showCheckmark,\n 'md-chip--with-trailing-icon': hasTrailingIcon || showRemove,\n }}\n role={hostIsButton ? 'button' : 'group'}\n aria-roledescription=\"chip\"\n aria-pressed={hostIsButton && this.isSelectable ? String(this.selected) : undefined}\n aria-label={hostIsButton ? undefined : chipLabel || undefined}\n aria-disabled={isEffectivelyDisabled ? 'true' : undefined}\n tabindex={hostIsButton ? (this.disabled ? '-1' : '0') : undefined}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n >\n <md-ripple disabled={isEffectivelyDisabled}></md-ripple>\n <span class=\"md-chip__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n {!this.elevated && <span class=\"md-chip__outline\" part=\"outline\" aria-hidden=\"true\"></span>}\n\n {renderPrimary && (\n <span\n class=\"md-chip__primary\"\n part=\"primary\"\n role=\"button\"\n tabindex={this.disabled ? '-1' : '0'}\n aria-labelledby=\"md-chip-label-text\"\n aria-pressed={this.isSelectable ? String(this.selected) : undefined}\n aria-disabled={isEffectivelyDisabled ? 'true' : undefined}\n ></span>\n )}\n\n {showCheckmark && (\n <span class=\"md-chip__checkmark\" part=\"checkmark\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M6.75 12.127L3.623 9l-1.06 1.057L6.75 14.25l9-9-1.057-1.057L6.75 12.127z\" fill=\"currentColor\" />\n </svg>\n </span>\n )}\n\n <slot name=\"leading-icon\">\n {hasLeadingIcon && !showCheckmark && (\n <span class=\"md-chip__icon material-symbols-outlined\" part=\"icon\" aria-hidden=\"true\">\n {this.icon}\n </span>\n )}\n </slot>\n\n <span class=\"md-chip__label\" part=\"label\" id=\"md-chip-label-text\">\n <slot>{this.label}</slot>\n </span>\n\n {showRemove ? (\n <button\n class=\"md-chip__remove\"\n part=\"remove\"\n type=\"button\"\n tabindex={this.disabled ? '-1' : '0'}\n aria-label={chipLabel ? `Remove ${chipLabel}` : 'Remove'}\n disabled={isEffectivelyDisabled}\n onClick={this.handleRemoveClick}\n onKeyDown={this.handleRemoveKeyDown}\n >\n <slot name=\"trailing-icon\">\n <svg viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M14.25 4.808l-1.058-1.058L9 7.942 4.808 3.75 3.75 4.808 7.942 9 3.75 13.192l1.058 1.058L9 10.058l4.192 4.192 1.058-1.058L10.058 9l4.192-4.192z\" fill=\"currentColor\" />\n </svg>\n </slot>\n </button>\n ) : (\n <slot name=\"trailing-icon\">\n {hasTrailingIcon && (\n <span class=\"md-chip__trailing-icon material-symbols-outlined\" part=\"trailing-icon\" aria-hidden=\"true\">\n {this.trailingIcon}\n </span>\n )}\n </slot>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as toNumeric, d as defaultValueFormatter } from './rtl-
|
|
1
|
+
import { t as toNumeric, d as defaultValueFormatter } from './rtl-DvOKnoqK.js';
|
|
2
2
|
|
|
3
3
|
/*
|
|
4
4
|
* Per-point x values — irregular / independent series data
|
|
@@ -314,6 +314,6 @@ function escapeHtml(s) {
|
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
export { buildChartSummary as a, buildDataTableHtml as b, normalizeSeriesX as c, datumY as d, normalizeRange as n, remapIndexRecord as r };
|
|
317
|
-
//# sourceMappingURL=a11y-
|
|
317
|
+
//# sourceMappingURL=a11y-C6CRqodW.js.map
|
|
318
318
|
|
|
319
|
-
//# sourceMappingURL=a11y-
|
|
319
|
+
//# sourceMappingURL=a11y-C6CRqodW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"a11y-C9_cZAF_.js","sources":["src/utils/charts/xy.ts","src/utils/charts/a11y.ts"],"sourcesContent":["/*\n * Per-point x values — irregular / independent series data\n * ===========================================================\n * A series is normally a bare list of y values positioned by INDEX against\n * `xAxis.data`. Real time series rarely line up like that: two sensors sample\n * at different moments, three winters are measured on entirely different dates.\n * Those series carry their own x per point (`{ x, y }` or `[x, y]`).\n *\n * The engine draws every series against ONE shared x array, so this module\n * merges all the x values into a single sorted axis and re-aligns each series\n * onto it. A slot a series has no sample for becomes a HOLE (`undefined`),\n * which is deliberately distinct from an authored `null`:\n *\n * • hole (`undefined`) — \"this series wasn't measured here\". The line is\n * drawn straight through it to the series' next real sample.\n * • gap (`null`) — \"measured, no value\". Breaks the line (unless\n * `connectNulls`), exactly as it always has.\n *\n * Everything downstream stays index-aligned to the merged axis, so tooltips,\n * the zoom window, markers and the screen-reader table keep working unchanged.\n * ===========================================================\n */\n\nimport { toNumeric } from './engine/scale';\nimport type {\n MdChartAxisValue,\n MdChartDataPoint,\n MdChartDatum,\n MdChartRangeDatum,\n MdChartScaleType,\n MdChartXYPoint,\n MdChartXYTuple,\n} from './types';\n\n/** A value aligned to the merged axis: a number, a `null` gap, or a hole. */\nexport type MdChartAlignedValue = MdChartDataPoint | undefined;\n\nexport interface NormalizedSeriesX {\n /** The merged x axis every series' data is aligned to. */\n xValues: MdChartAxisValue[];\n /** Per series, values aligned to `xValues` (`undefined` = no sample here). */\n data: MdChartAlignedValue[][];\n /**\n * Per series, that series' own datum index → merged index. `null` when the\n * series was already index-aligned (own index *is* the merged index).\n */\n toMerged: (number[] | null)[];\n /** Per series, merged index → own datum index (`-1` where it has no sample). */\n toOwn: (number[] | null)[];\n /** True when at least one series carried its own x values. */\n hasPointX: boolean;\n}\n\n/** Does this datum carry its own x? */\nexport function isPointDatum(d: MdChartDatum | undefined): d is MdChartXYPoint | MdChartXYTuple {\n return d != null && typeof d === 'object' && !(d instanceof Date);\n}\n\n/** The y value of any datum shape. */\nexport function datumY(d: MdChartDatum | undefined): MdChartDataPoint {\n if (d == null) return null;\n if (typeof d === 'number') return d;\n if (!isPointDatum(d)) return null;\n // `in` rather than Array.isArray: the tuple form is readonly, which\n // Array.isArray does not narrow.\n return ('y' in d ? d.y : d[1]) ?? null;\n}\n\n/** The x value of a point datum, or `undefined` for a bare value. */\nexport function datumX(d: MdChartDatum | undefined): MdChartAxisValue | undefined {\n if (!isPointDatum(d)) return undefined;\n return 'x' in d ? d.x : d[0];\n}\n\n/** Does this series carry its own x values? Reads the first non-empty datum —\n * a series is all points or all bare values, never a mix. */\nfunction seriesHasPointX(data: readonly MdChartDatum[] | undefined): boolean {\n return isPointDatum(data?.find((d) => d != null));\n}\n\n/**\n * Merge every series onto one x axis.\n *\n * With no point-carrying series this is a pass-through: the original arrays are\n * handed straight back, so the common (and possibly very large) index-aligned\n * case allocates nothing.\n *\n * @param series the series to align (only `data` is read)\n * @param axisData the consumer's `xAxis.data`, if any\n * @param scale the x scale — decides the merge order (numeric/chronological\n * for value/time/log, first-seen for category)\n */\nexport function normalizeSeriesX(\n series: readonly { data?: readonly MdChartDatum[] }[],\n axisData: readonly MdChartAxisValue[] | undefined,\n scale: MdChartScaleType,\n): NormalizedSeriesX {\n const hasPointX = series.some((s) => seriesHasPointX(s.data));\n if (!hasPointX) {\n return {\n xValues: (axisData as MdChartAxisValue[] | undefined) ?? [],\n // Safe: no datum in any series is a point, so the array already IS\n // (number | null)[] — no copy, which keeps 100k-point feeds cheap.\n data: series.map((s) => (s.data ?? []) as MdChartAlignedValue[]),\n toMerged: series.map(() => null),\n toOwn: series.map(() => null),\n hasPointX: false,\n };\n }\n\n // ── build the merged axis ──\n // Category x values have no numeric order, so they merge in first-seen order\n // (axis data first, then whatever the series introduce). Everything else\n // sorts by its numeric / epoch value, which is what makes uneven gaps render\n // proportionally rather than evenly.\n const category = scale === 'category';\n const keyOf = (v: MdChartAxisValue) => (category ? `c${String(v)}` : `n${toNumeric(v, scale)}`);\n const slots = new Map<string, { sort: number; value: MdChartAxisValue }>();\n const add = (v: MdChartAxisValue) => {\n const k = keyOf(v);\n if (!slots.has(k)) slots.set(k, { sort: category ? slots.size : toNumeric(v, scale), value: v });\n };\n axisData?.forEach(add);\n for (const s of series) {\n if (!seriesHasPointX(s.data)) continue;\n for (const d of s.data ?? []) {\n const x = datumX(d);\n if (x !== undefined) add(x);\n }\n }\n const xValues = [...slots.values()].sort((a, b) => a.sort - b.sort).map((s) => s.value);\n const indexOf = new Map<string, number>(xValues.map((v, i) => [keyOf(v), i]));\n const n = xValues.length;\n\n // ── align each series onto it ──\n const data: MdChartAlignedValue[][] = [];\n const toMerged: (number[] | null)[] = [];\n const toOwn: (number[] | null)[] = [];\n\n series.forEach((s) => {\n const own = s.data ?? [];\n if (!seriesHasPointX(own)) {\n // Index-aligned series: it borrows x from `xAxis.data`, so it lands on\n // whatever merged slots those values took. Without an axis to borrow\n // from, its index is its position.\n if (!axisData?.length) {\n const row: MdChartAlignedValue[] = new Array(n).fill(undefined);\n for (let j = 0; j < own.length && j < n; j++) row[j] = datumY(own[j]);\n data.push(row);\n toMerged.push(null);\n toOwn.push(null);\n return;\n }\n const row: MdChartAlignedValue[] = new Array(n).fill(undefined);\n const fwd: number[] = new Array(own.length).fill(-1);\n const back: number[] = new Array(n).fill(-1);\n for (let j = 0; j < own.length; j++) {\n const at = j < axisData.length ? indexOf.get(keyOf(axisData[j])) : undefined;\n if (at === undefined) continue;\n row[at] = datumY(own[j]);\n fwd[j] = at;\n back[at] = j;\n }\n data.push(row);\n toMerged.push(fwd);\n toOwn.push(back);\n return;\n }\n\n const row: MdChartAlignedValue[] = new Array(n).fill(undefined);\n const fwd: number[] = new Array(own.length).fill(-1);\n const back: number[] = new Array(n).fill(-1);\n for (let j = 0; j < own.length; j++) {\n const x = datumX(own[j]);\n // A bare value inside a point series has no x to sit at — drop it rather\n // than inventing a position for it.\n if (x === undefined) continue;\n const at = indexOf.get(keyOf(x));\n if (at === undefined) continue;\n // Duplicate x within one series: the last one wins.\n row[at] = datumY(own[j]);\n fwd[j] = at;\n back[at] = j;\n }\n data.push(row);\n toMerged.push(fwd);\n toOwn.push(back);\n });\n\n return { xValues, data, toMerged, toOwn, hasPointX: true };\n}\n\n/** Remap an index-keyed record (e.g. `pointSymbols`) from a series' own indices\n * onto the merged axis. Entries with no merged slot are dropped. */\nexport function remapIndexRecord<T>(\n rec: Record<number, T> | undefined,\n toMerged: number[] | null,\n): Record<number, T> | undefined {\n if (!rec || !toMerged) return rec;\n const out: Record<number, T> = {};\n for (const [k, v] of Object.entries(rec)) {\n const at = toMerged[Number(k)];\n if (at != null && at >= 0) out[at] = v;\n }\n return out;\n}\n\n/**\n * Flatten a {@link MdChartRangeDatum} to a `[low, high]` pair, or `null` for a\n * gap. Both the tuple and the `{ low, high }` object forms are accepted, and\n * the edges are ordered — a caller who writes `[max, min]` still gets a band\n * rather than an inverted one that draws backwards.\n */\nexport function normalizeRange(d: MdChartRangeDatum | undefined): [number, number] | null {\n if (d == null) return null;\n const lo = Array.isArray(d) ? d[0] : (d as { low: number | null }).low;\n const hi = Array.isArray(d) ? d[1] : (d as { high: number | null }).high;\n if (lo == null || hi == null || !Number.isFinite(lo) || !Number.isFinite(hi)) return null;\n return [Math.min(lo, hi), Math.max(lo, hi)];\n}\n","/*\n * Chart accessibility helpers\n * ===========================================================\n * Charts are a tricky a11y surface because:\n * • SVG nodes carry no inherent semantics to screen readers;\n * a bare `<svg>` of a line chart announces as \"graphic\"\n * with no values.\n * • Sighted users get visual tooltips on hover; SR users\n * need text equivalents triggered by keyboard focus.\n * • Data tables are the WCAG-required fallback for visual\n * charts (SC 1.3.1, 1.1.1); even with rich SVG semantics,\n * a screen-reader-only table is the most-reliable backstop.\n *\n * Our pattern (matches BBC, GOV.UK, and Highcharts' a11y\n * module):\n * • Host element gets `role=\"img\"` + an aria-label summary.\n * • A visually-hidden `<table>` mirrors the chart data,\n * announced when the user tabs into it.\n * • An aria-live region narrates hover / focus events so\n * keyboard + SR users get the same tooltip text as\n * pointer users.\n * ===========================================================\n */\n\nimport type { MdChartAxisValue, MdChartRangeDatum, MdChartSeries } from './types';\nimport { defaultValueFormatter } from './options';\nimport { normalizeRange } from './xy';\n\n/**\n * Compose the chart's `aria-label` summary. Keep it under\n * ~120 chars — screen readers truncate long labels and the\n * full data lives in the SR-only table anyway.\n */\n/**\n * Translatable strings for the generated chart summary. Each is a plain string\n * a consumer hands over from their own dictionary — the components stay\n * i18n-engine-agnostic. `%count%` / `%min%` / `%max%` are substituted.\n */\nexport interface MdChartSummaryLabels {\n line?: string;\n area?: string;\n bar?: string;\n pie?: string;\n sparkline?: string;\n /** e.g. `'with %count% series'`. */\n series?: string;\n /** A pie's parts are slices, not series — e.g. `'with %count% slices'`. Used\n * in place of `series` for `chartType: 'pie'`. */\n slices?: string;\n /** e.g. `'from %min% to %max%'`. */\n range?: string;\n}\n\nexport function buildChartSummary(opts: {\n title?: string;\n chartType: 'line' | 'area' | 'bar' | 'pie' | 'sparkline';\n seriesCount: number;\n xMin?: MdChartAxisValue;\n xMax?: MdChartAxisValue;\n /** BCP-47 locale for the formatted range. */\n locale?: string;\n labels?: MdChartSummaryLabels;\n}): string {\n const l = opts.labels ?? {};\n const verb =\n opts.chartType === 'pie'\n ? l.pie ?? 'Pie chart'\n : opts.chartType === 'bar'\n ? l.bar ?? 'Bar chart'\n : opts.chartType === 'area'\n ? l.area ?? 'Area chart'\n : opts.chartType === 'sparkline'\n ? l.sparkline ?? 'Sparkline'\n : l.line ?? 'Line chart';\n const parts: string[] = [];\n if (opts.title) parts.push(opts.title);\n parts.push(verb);\n if (opts.chartType === 'pie') {\n // A pie has slices, and its count is worth saying even at one — \"Pie chart.\"\n // alone tells a screen-reader user nothing about how much is in it.\n if (opts.seriesCount > 0) {\n const tpl = l.slices ?? (opts.seriesCount === 1 ? 'with %count% slice' : 'with %count% slices');\n parts.push(tpl.replace('%count%', String(opts.seriesCount)));\n }\n } else if (opts.seriesCount > 1) {\n parts.push((l.series ?? 'with %count% series').replace('%count%', String(opts.seriesCount)));\n }\n if (opts.xMin != null && opts.xMax != null && opts.chartType !== 'pie') {\n parts.push(\n (l.range ?? 'from %min% to %max%')\n .replace('%min%', defaultValueFormatter(opts.xMin, opts.locale))\n .replace('%max%', defaultValueFormatter(opts.xMax, opts.locale)),\n );\n }\n return parts.join(', ') + '.';\n}\n\n/**\n * Build the screen-reader-only HTML data table for the chart.\n * Returns an HTML string so the host can inject it with\n * `innerHTML` on a hidden node; no per-cell DOM manipulation\n * needed.\n *\n * Caveats:\n * • Series with > 200 rows are truncated to 200 (an SR user\n * reading row-by-row past 200 is rare enough that we trade\n * completeness for performance). The full data is still\n * accessible programmatically via the component instance.\n * • Categorical / time / numeric x-axes all flatten to\n * strings via the user formatter (or the default).\n */\nexport function buildDataTableHtml(opts: {\n title?: string;\n xAxisLabel?: string;\n xAxisData?: readonly MdChartAxisValue[];\n xValueFormatter?: (v: MdChartAxisValue) => string;\n /** `undefined` in `data` is a slot this series has no sample for (see\n * `utils/charts/xy.ts`) and prints the same as a `null` gap. A series with\n * `range` is a band: its cells print `low–high`, since `data` holds no\n * reading for it. */\n series: readonly {\n label?: string;\n data: readonly (number | null | undefined)[];\n range?: readonly MdChartRangeDatum[];\n }[];\n valueFormatter?: (v: number | null) => string;\n /** BCP-47 locale for the default number / date formatting. */\n locale?: string;\n /** Translatable table chrome. `%shown%` / `%total%` are substituted. */\n labels?: {\n /** Header over the x column when the chart has an x axis. Default `X`. */\n x?: string;\n /** Header over the row-number column when it doesn't. Default `#`. */\n index?: string;\n /** Fallback header for a series with no label. Default `Series`. */\n series?: string;\n /** Default `Showing first %shown% of %total% rows.` */\n truncated?: string;\n };\n}): string {\n const MAX = 200;\n const lb = opts.labels ?? {};\n const fmtX = opts.xValueFormatter ?? ((v: MdChartAxisValue) => defaultValueFormatter(v, opts.locale));\n const fmtY =\n opts.valueFormatter ??\n ((v: number | null) => (v == null ? '—' : v.toLocaleString(opts.locale || undefined)));\n // Charts render fine without an explicit x-axis (points/bars plot by data\n // index), so the SR table must too: fall back to the series' own length and\n // number the rows, otherwise a visually-populated chart has an empty table.\n const hasX = (opts.xAxisData?.length ?? 0) > 0;\n const total = hasX\n ? opts.xAxisData!.length\n : Math.max(0, ...opts.series.map(s => (s.range ? s.range.length : s.data.length)));\n const n = Math.min(total, MAX);\n const rowsArr: string[] = [];\n for (let i = 0; i < n; i++) {\n const cells = opts.series\n .map(s => {\n if (s.range) {\n const b = normalizeRange(s.range[i]);\n // En dash, not a hyphen: a screen reader reads \"3 to 9\" for a range\n // and \"3 minus 9\" for a hyphen between two numbers.\n return `<td>${escapeHtml(b ? `${fmtY(b[0])}–${fmtY(b[1])}` : fmtY(null))}</td>`;\n }\n return `<td>${escapeHtml(fmtY(s.data[i] ?? null))}</td>`;\n })\n .join('');\n const rowHeader = hasX ? fmtX(opts.xAxisData![i]) : String(i + 1);\n rowsArr.push(`<tr><th scope=\"row\">${escapeHtml(rowHeader)}</th>${cells}</tr>`);\n }\n const rows = rowsArr.join('');\n const head = opts.series\n .map(s => `<th scope=\"col\">${escapeHtml(s.label ?? lb.series ?? 'Series')}</th>`)\n .join('');\n const caption = opts.title ? `<caption>${escapeHtml(opts.title)}</caption>` : '';\n const truncatedNote =\n total > MAX\n ? `<tfoot><tr><td colspan=\"${1 + opts.series.length}\">${escapeHtml(\n (lb.truncated ?? 'Showing first %shown% of %total% rows.')\n .replace('%shown%', String(MAX))\n .replace('%total%', String(total)),\n )}</td></tr></tfoot>`\n : '';\n return `<table>\n ${caption}\n <thead><tr><th scope=\"col\">${escapeHtml(\n opts.xAxisLabel ?? (hasX ? lb.x ?? 'X' : lb.index ?? '#'),\n )}</th>${head}</tr></thead>\n <tbody>${rows}</tbody>\n ${truncatedNote}\n </table>`;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"a11y-C6CRqodW.js","sources":["src/utils/charts/xy.ts","src/utils/charts/a11y.ts"],"sourcesContent":["/*\n * Per-point x values — irregular / independent series data\n * ===========================================================\n * A series is normally a bare list of y values positioned by INDEX against\n * `xAxis.data`. Real time series rarely line up like that: two sensors sample\n * at different moments, three winters are measured on entirely different dates.\n * Those series carry their own x per point (`{ x, y }` or `[x, y]`).\n *\n * The engine draws every series against ONE shared x array, so this module\n * merges all the x values into a single sorted axis and re-aligns each series\n * onto it. A slot a series has no sample for becomes a HOLE (`undefined`),\n * which is deliberately distinct from an authored `null`:\n *\n * • hole (`undefined`) — \"this series wasn't measured here\". The line is\n * drawn straight through it to the series' next real sample.\n * • gap (`null`) — \"measured, no value\". Breaks the line (unless\n * `connectNulls`), exactly as it always has.\n *\n * Everything downstream stays index-aligned to the merged axis, so tooltips,\n * the zoom window, markers and the screen-reader table keep working unchanged.\n * ===========================================================\n */\n\nimport { toNumeric } from './engine/scale';\nimport type {\n MdChartAxisValue,\n MdChartDataPoint,\n MdChartDatum,\n MdChartRangeDatum,\n MdChartScaleType,\n MdChartXYPoint,\n MdChartXYTuple,\n} from './types';\n\n/** A value aligned to the merged axis: a number, a `null` gap, or a hole. */\nexport type MdChartAlignedValue = MdChartDataPoint | undefined;\n\nexport interface NormalizedSeriesX {\n /** The merged x axis every series' data is aligned to. */\n xValues: MdChartAxisValue[];\n /** Per series, values aligned to `xValues` (`undefined` = no sample here). */\n data: MdChartAlignedValue[][];\n /**\n * Per series, that series' own datum index → merged index. `null` when the\n * series was already index-aligned (own index *is* the merged index).\n */\n toMerged: (number[] | null)[];\n /** Per series, merged index → own datum index (`-1` where it has no sample). */\n toOwn: (number[] | null)[];\n /** True when at least one series carried its own x values. */\n hasPointX: boolean;\n}\n\n/** Does this datum carry its own x? */\nexport function isPointDatum(d: MdChartDatum | undefined): d is MdChartXYPoint | MdChartXYTuple {\n return d != null && typeof d === 'object' && !(d instanceof Date);\n}\n\n/** The y value of any datum shape. */\nexport function datumY(d: MdChartDatum | undefined): MdChartDataPoint {\n if (d == null) return null;\n if (typeof d === 'number') return d;\n if (!isPointDatum(d)) return null;\n // `in` rather than Array.isArray: the tuple form is readonly, which\n // Array.isArray does not narrow.\n return ('y' in d ? d.y : d[1]) ?? null;\n}\n\n/** The x value of a point datum, or `undefined` for a bare value. */\nexport function datumX(d: MdChartDatum | undefined): MdChartAxisValue | undefined {\n if (!isPointDatum(d)) return undefined;\n return 'x' in d ? d.x : d[0];\n}\n\n/** Does this series carry its own x values? Reads the first non-empty datum —\n * a series is all points or all bare values, never a mix. */\nfunction seriesHasPointX(data: readonly MdChartDatum[] | undefined): boolean {\n return isPointDatum(data?.find((d) => d != null));\n}\n\n/**\n * Merge every series onto one x axis.\n *\n * With no point-carrying series this is a pass-through: the original arrays are\n * handed straight back, so the common (and possibly very large) index-aligned\n * case allocates nothing.\n *\n * @param series the series to align (only `data` is read)\n * @param axisData the consumer's `xAxis.data`, if any\n * @param scale the x scale — decides the merge order (numeric/chronological\n * for value/time/log, first-seen for category)\n */\nexport function normalizeSeriesX(\n series: readonly { data?: readonly MdChartDatum[] }[],\n axisData: readonly MdChartAxisValue[] | undefined,\n scale: MdChartScaleType,\n): NormalizedSeriesX {\n const hasPointX = series.some((s) => seriesHasPointX(s.data));\n if (!hasPointX) {\n return {\n xValues: (axisData as MdChartAxisValue[] | undefined) ?? [],\n // Safe: no datum in any series is a point, so the array already IS\n // (number | null)[] — no copy, which keeps 100k-point feeds cheap.\n data: series.map((s) => (s.data ?? []) as MdChartAlignedValue[]),\n toMerged: series.map(() => null),\n toOwn: series.map(() => null),\n hasPointX: false,\n };\n }\n\n // ── build the merged axis ──\n // Category x values have no numeric order, so they merge in first-seen order\n // (axis data first, then whatever the series introduce). Everything else\n // sorts by its numeric / epoch value, which is what makes uneven gaps render\n // proportionally rather than evenly.\n const category = scale === 'category';\n const keyOf = (v: MdChartAxisValue) => (category ? `c${String(v)}` : `n${toNumeric(v, scale)}`);\n const slots = new Map<string, { sort: number; value: MdChartAxisValue }>();\n const add = (v: MdChartAxisValue) => {\n const k = keyOf(v);\n if (!slots.has(k)) slots.set(k, { sort: category ? slots.size : toNumeric(v, scale), value: v });\n };\n axisData?.forEach(add);\n for (const s of series) {\n if (!seriesHasPointX(s.data)) continue;\n for (const d of s.data ?? []) {\n const x = datumX(d);\n if (x !== undefined) add(x);\n }\n }\n const xValues = [...slots.values()].sort((a, b) => a.sort - b.sort).map((s) => s.value);\n const indexOf = new Map<string, number>(xValues.map((v, i) => [keyOf(v), i]));\n const n = xValues.length;\n\n // ── align each series onto it ──\n const data: MdChartAlignedValue[][] = [];\n const toMerged: (number[] | null)[] = [];\n const toOwn: (number[] | null)[] = [];\n\n series.forEach((s) => {\n const own = s.data ?? [];\n if (!seriesHasPointX(own)) {\n // Index-aligned series: it borrows x from `xAxis.data`, so it lands on\n // whatever merged slots those values took. Without an axis to borrow\n // from, its index is its position.\n if (!axisData?.length) {\n const row: MdChartAlignedValue[] = new Array(n).fill(undefined);\n for (let j = 0; j < own.length && j < n; j++) row[j] = datumY(own[j]);\n data.push(row);\n toMerged.push(null);\n toOwn.push(null);\n return;\n }\n const row: MdChartAlignedValue[] = new Array(n).fill(undefined);\n const fwd: number[] = new Array(own.length).fill(-1);\n const back: number[] = new Array(n).fill(-1);\n for (let j = 0; j < own.length; j++) {\n const at = j < axisData.length ? indexOf.get(keyOf(axisData[j])) : undefined;\n if (at === undefined) continue;\n row[at] = datumY(own[j]);\n fwd[j] = at;\n back[at] = j;\n }\n data.push(row);\n toMerged.push(fwd);\n toOwn.push(back);\n return;\n }\n\n const row: MdChartAlignedValue[] = new Array(n).fill(undefined);\n const fwd: number[] = new Array(own.length).fill(-1);\n const back: number[] = new Array(n).fill(-1);\n for (let j = 0; j < own.length; j++) {\n const x = datumX(own[j]);\n // A bare value inside a point series has no x to sit at — drop it rather\n // than inventing a position for it.\n if (x === undefined) continue;\n const at = indexOf.get(keyOf(x));\n if (at === undefined) continue;\n // Duplicate x within one series: the last one wins.\n row[at] = datumY(own[j]);\n fwd[j] = at;\n back[at] = j;\n }\n data.push(row);\n toMerged.push(fwd);\n toOwn.push(back);\n });\n\n return { xValues, data, toMerged, toOwn, hasPointX: true };\n}\n\n/** Remap an index-keyed record (e.g. `pointSymbols`) from a series' own indices\n * onto the merged axis. Entries with no merged slot are dropped. */\nexport function remapIndexRecord<T>(\n rec: Record<number, T> | undefined,\n toMerged: number[] | null,\n): Record<number, T> | undefined {\n if (!rec || !toMerged) return rec;\n const out: Record<number, T> = {};\n for (const [k, v] of Object.entries(rec)) {\n const at = toMerged[Number(k)];\n if (at != null && at >= 0) out[at] = v;\n }\n return out;\n}\n\n/**\n * Flatten a {@link MdChartRangeDatum} to a `[low, high]` pair, or `null` for a\n * gap. Both the tuple and the `{ low, high }` object forms are accepted, and\n * the edges are ordered — a caller who writes `[max, min]` still gets a band\n * rather than an inverted one that draws backwards.\n */\nexport function normalizeRange(d: MdChartRangeDatum | undefined): [number, number] | null {\n if (d == null) return null;\n const lo = Array.isArray(d) ? d[0] : (d as { low: number | null }).low;\n const hi = Array.isArray(d) ? d[1] : (d as { high: number | null }).high;\n if (lo == null || hi == null || !Number.isFinite(lo) || !Number.isFinite(hi)) return null;\n return [Math.min(lo, hi), Math.max(lo, hi)];\n}\n","/*\n * Chart accessibility helpers\n * ===========================================================\n * Charts are a tricky a11y surface because:\n * • SVG nodes carry no inherent semantics to screen readers;\n * a bare `<svg>` of a line chart announces as \"graphic\"\n * with no values.\n * • Sighted users get visual tooltips on hover; SR users\n * need text equivalents triggered by keyboard focus.\n * • Data tables are the WCAG-required fallback for visual\n * charts (SC 1.3.1, 1.1.1); even with rich SVG semantics,\n * a screen-reader-only table is the most-reliable backstop.\n *\n * Our pattern (matches BBC, GOV.UK, and Highcharts' a11y\n * module):\n * • Host element gets `role=\"img\"` + an aria-label summary.\n * • A visually-hidden `<table>` mirrors the chart data,\n * announced when the user tabs into it.\n * • An aria-live region narrates hover / focus events so\n * keyboard + SR users get the same tooltip text as\n * pointer users.\n * ===========================================================\n */\n\nimport type { MdChartAxisValue, MdChartRangeDatum, MdChartSeries } from './types';\nimport { defaultValueFormatter } from './options';\nimport { normalizeRange } from './xy';\n\n/**\n * Compose the chart's `aria-label` summary. Keep it under\n * ~120 chars — screen readers truncate long labels and the\n * full data lives in the SR-only table anyway.\n */\n/**\n * Translatable strings for the generated chart summary. Each is a plain string\n * a consumer hands over from their own dictionary — the components stay\n * i18n-engine-agnostic. `%count%` / `%min%` / `%max%` are substituted.\n */\nexport interface MdChartSummaryLabels {\n line?: string;\n area?: string;\n bar?: string;\n pie?: string;\n sparkline?: string;\n /** e.g. `'with %count% series'`. */\n series?: string;\n /** A pie's parts are slices, not series — e.g. `'with %count% slices'`. Used\n * in place of `series` for `chartType: 'pie'`. */\n slices?: string;\n /** e.g. `'from %min% to %max%'`. */\n range?: string;\n}\n\nexport function buildChartSummary(opts: {\n title?: string;\n chartType: 'line' | 'area' | 'bar' | 'pie' | 'sparkline';\n seriesCount: number;\n xMin?: MdChartAxisValue;\n xMax?: MdChartAxisValue;\n /** BCP-47 locale for the formatted range. */\n locale?: string;\n labels?: MdChartSummaryLabels;\n}): string {\n const l = opts.labels ?? {};\n const verb =\n opts.chartType === 'pie'\n ? l.pie ?? 'Pie chart'\n : opts.chartType === 'bar'\n ? l.bar ?? 'Bar chart'\n : opts.chartType === 'area'\n ? l.area ?? 'Area chart'\n : opts.chartType === 'sparkline'\n ? l.sparkline ?? 'Sparkline'\n : l.line ?? 'Line chart';\n const parts: string[] = [];\n if (opts.title) parts.push(opts.title);\n parts.push(verb);\n if (opts.chartType === 'pie') {\n // A pie has slices, and its count is worth saying even at one — \"Pie chart.\"\n // alone tells a screen-reader user nothing about how much is in it.\n if (opts.seriesCount > 0) {\n const tpl = l.slices ?? (opts.seriesCount === 1 ? 'with %count% slice' : 'with %count% slices');\n parts.push(tpl.replace('%count%', String(opts.seriesCount)));\n }\n } else if (opts.seriesCount > 1) {\n parts.push((l.series ?? 'with %count% series').replace('%count%', String(opts.seriesCount)));\n }\n if (opts.xMin != null && opts.xMax != null && opts.chartType !== 'pie') {\n parts.push(\n (l.range ?? 'from %min% to %max%')\n .replace('%min%', defaultValueFormatter(opts.xMin, opts.locale))\n .replace('%max%', defaultValueFormatter(opts.xMax, opts.locale)),\n );\n }\n return parts.join(', ') + '.';\n}\n\n/**\n * Build the screen-reader-only HTML data table for the chart.\n * Returns an HTML string so the host can inject it with\n * `innerHTML` on a hidden node; no per-cell DOM manipulation\n * needed.\n *\n * Caveats:\n * • Series with > 200 rows are truncated to 200 (an SR user\n * reading row-by-row past 200 is rare enough that we trade\n * completeness for performance). The full data is still\n * accessible programmatically via the component instance.\n * • Categorical / time / numeric x-axes all flatten to\n * strings via the user formatter (or the default).\n */\nexport function buildDataTableHtml(opts: {\n title?: string;\n xAxisLabel?: string;\n xAxisData?: readonly MdChartAxisValue[];\n xValueFormatter?: (v: MdChartAxisValue) => string;\n /** `undefined` in `data` is a slot this series has no sample for (see\n * `utils/charts/xy.ts`) and prints the same as a `null` gap. A series with\n * `range` is a band: its cells print `low–high`, since `data` holds no\n * reading for it. */\n series: readonly {\n label?: string;\n data: readonly (number | null | undefined)[];\n range?: readonly MdChartRangeDatum[];\n }[];\n valueFormatter?: (v: number | null) => string;\n /** BCP-47 locale for the default number / date formatting. */\n locale?: string;\n /** Translatable table chrome. `%shown%` / `%total%` are substituted. */\n labels?: {\n /** Header over the x column when the chart has an x axis. Default `X`. */\n x?: string;\n /** Header over the row-number column when it doesn't. Default `#`. */\n index?: string;\n /** Fallback header for a series with no label. Default `Series`. */\n series?: string;\n /** Default `Showing first %shown% of %total% rows.` */\n truncated?: string;\n };\n}): string {\n const MAX = 200;\n const lb = opts.labels ?? {};\n const fmtX = opts.xValueFormatter ?? ((v: MdChartAxisValue) => defaultValueFormatter(v, opts.locale));\n const fmtY =\n opts.valueFormatter ??\n ((v: number | null) => (v == null ? '—' : v.toLocaleString(opts.locale || undefined)));\n // Charts render fine without an explicit x-axis (points/bars plot by data\n // index), so the SR table must too: fall back to the series' own length and\n // number the rows, otherwise a visually-populated chart has an empty table.\n const hasX = (opts.xAxisData?.length ?? 0) > 0;\n const total = hasX\n ? opts.xAxisData!.length\n : Math.max(0, ...opts.series.map(s => (s.range ? s.range.length : s.data.length)));\n const n = Math.min(total, MAX);\n const rowsArr: string[] = [];\n for (let i = 0; i < n; i++) {\n const cells = opts.series\n .map(s => {\n if (s.range) {\n const b = normalizeRange(s.range[i]);\n // En dash, not a hyphen: a screen reader reads \"3 to 9\" for a range\n // and \"3 minus 9\" for a hyphen between two numbers.\n return `<td>${escapeHtml(b ? `${fmtY(b[0])}–${fmtY(b[1])}` : fmtY(null))}</td>`;\n }\n return `<td>${escapeHtml(fmtY(s.data[i] ?? null))}</td>`;\n })\n .join('');\n const rowHeader = hasX ? fmtX(opts.xAxisData![i]) : String(i + 1);\n rowsArr.push(`<tr><th scope=\"row\">${escapeHtml(rowHeader)}</th>${cells}</tr>`);\n }\n const rows = rowsArr.join('');\n const head = opts.series\n .map(s => `<th scope=\"col\">${escapeHtml(s.label ?? lb.series ?? 'Series')}</th>`)\n .join('');\n const caption = opts.title ? `<caption>${escapeHtml(opts.title)}</caption>` : '';\n const truncatedNote =\n total > MAX\n ? `<tfoot><tr><td colspan=\"${1 + opts.series.length}\">${escapeHtml(\n (lb.truncated ?? 'Showing first %shown% of %total% rows.')\n .replace('%shown%', String(MAX))\n .replace('%total%', String(total)),\n )}</td></tr></tfoot>`\n : '';\n return `<table>\n ${caption}\n <thead><tr><th scope=\"col\">${escapeHtml(\n opts.xAxisLabel ?? (hasX ? lb.x ?? 'X' : lb.index ?? '#'),\n )}</th>${head}</tr></thead>\n <tbody>${rows}</tbody>\n ${truncatedNote}\n </table>`;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { v as makeBrokenScale, x as onColorFor, y as dashPattern, z as axisLineWithBreaks, A as breakBandSegments, B as titlePlacement, C as stackSeries, D as
|
|
2
|
-
import { n as nearestIndex } from './hit-test-
|
|
1
|
+
import { v as makeBrokenScale, x as onColorFor, y as dashPattern, z as axisLineWithBreaks, A as breakBandSegments, B as titlePlacement, C as stackSeries, D as resolveAxisBreaks, E as openTopSection, F as normalizeBreaks, G as computeDomain, H as sectionedTicks, I as inBreak, J as estimateLegendRows, K as chevronTipDepth, w as watchDevicePixelRatio, c as watchDirection, e as renderHover, f as clearHover, i as isRtl, s as syncOverlay, g as prefersReducedMotion, h as resolveIntro, L as drillScene, l as drawSceneCanvas, M as renderBarLabels, n as stepAnimation, m as mirrorScene, N as mixColor } from './rtl-DvOKnoqK.js';
|
|
2
|
+
import { n as nearestIndex } from './hit-test-DHldf5Lm.js';
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
5
|
* Chart engine — bar layout (spec → RenderScene)
|
|
@@ -1749,6 +1749,6 @@ class BarChartEngine {
|
|
|
1749
1749
|
}
|
|
1750
1750
|
|
|
1751
1751
|
export { BarChartEngine as B };
|
|
1752
|
-
//# sourceMappingURL=bar-chart-
|
|
1752
|
+
//# sourceMappingURL=bar-chart-ZZrajEkM.js.map
|
|
1753
1753
|
|
|
1754
|
-
//# sourceMappingURL=bar-chart-
|
|
1754
|
+
//# sourceMappingURL=bar-chart-ZZrajEkM.js.map
|