@awc-ui/core 1.0.0-beta.8 → 1.0.0-beta.9

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.
@@ -1,2 +1,2 @@
1
- import{p as a,H as i,c as t,h as n,d as e,t as o}from"./p-B7GMP_JD.js";import{t as s}from"./p-DYBUr7K_.js";import{s as r,a as l}from"./p-BdEoSBtL.js";import{d}from"./p-BMizw_F3.js";const c=()=>`:host{--_indicator-color:var( --md-navigation-tab-active-indicator-color, var(--md-sys-color-secondary-container, #E8DEF8) );--_indicator-w:var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));--_indicator-h:var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));--_indicator-shape:var( --md-navigation-tab-active-indicator-shape, var(--md-sys-shape-corner-full, 9999px) );--_active-icon-color:var( --md-navigation-tab-active-icon-color, var(--md-sys-color-on-secondary-container, #1E192B) );--_inactive-icon-color:var( --md-navigation-tab-inactive-icon-color, var(--md-sys-color-on-surface-variant, #49454F) );--_active-label-color:var( --md-navigation-tab-active-label-color, var(--md-sys-color-on-surface, #1C1B1F) );--_inactive-label-color:var( --md-navigation-tab-inactive-label-color, var(--md-sys-color-on-surface-variant, #49454F) );--_icon-size:var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));--_pad-top:var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_pad-bottom:var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_hover-color:var( --md-navigation-tab-hover-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_focus-color:var( --md-navigation-tab-focus-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_pressed-color:var( --md-navigation-tab-pressed-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_badge-color:var( --md-navigation-tab-badge-color, var(--md-sys-color-error, #B3261E) );--_badge-on-color:var( --md-navigation-tab-badge-on-color, var(--md-sys-color-on-error, #FFFFFF) );--_disabled-opacity:var(--md-navigation-tab-disabled-opacity, 0.38);--_label-font:var( --md-navigation-tab-label-font, var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif) );--_label-size:var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));--_label-weight-active:var(--md-navigation-tab-label-font-weight, 600);--_motion-duration:var(--md-sys-motion-duration-short4, 200ms);--_motion-easing:var( --md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1) );display:inline-flex;flex-direction:column;align-items:center;justify-content:flex-start;inline-size:100%;min-inline-size:48px;block-size:100%;padding-block:var(--_pad-top) var(--_pad-bottom);box-sizing:border-box;cursor:pointer;position:relative;outline:none;user-select:none;-webkit-tap-highlight-color:transparent;color:var(--_inactive-icon-color);transition:color var(--_motion-duration) var(--_motion-easing)}:host(.md-navigation-tab--active){color:var(--_active-icon-color)}:host(.md-navigation-tab--disabled),:host(.md-navigation-tab--soft-disabled){cursor:not-allowed;opacity:var(--_disabled-opacity)}:host(.md-navigation-tab--disabled){pointer-events:none}.md-navigation-tab__state-layer{position:absolute;inset:0;background-color:currentColor;opacity:0;border-radius:inherit;pointer-events:none;transition:opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_hover-color);opacity:var(--md-sys-state-hover-state-layer-opacity, 0.08)}:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_pressed-color);opacity:var(--md-sys-state-pressed-state-layer-opacity, 0.12)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer{background-color:var(--_focus-color);opacity:var(--md-navigation-tab-focus-state-layer-opacity, 0.1)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after{content:'';position:absolute;inset:-4px;border:3px solid var(--md-sys-color-secondary, #625B71);border-radius:var(--_indicator-shape, 9999px);box-sizing:border-box;pointer-events:none}.md-navigation-tab__container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));inline-size:100%;pointer-events:none;}.md-navigation-tab__indicator{position:absolute;inset-block-start:0;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);border-radius:var(--_indicator-shape);background-color:var(--_indicator-color);transform:scale(0, 1);transform-origin:center center;opacity:0;transition:transform var(--_motion-duration) var(--_motion-easing), opacity var(--md-sys-motion-duration-short2, 100ms) ease;pointer-events:none}.md-navigation-tab__indicator--active{transform:scale(1, 1);opacity:1}.md-navigation-tab__icon-container{position:relative;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);pointer-events:none}.md-navigation-tab__icon{position:relative;display:inline-flex;align-items:center;justify-content:center;font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size);line-height:1;color:inherit;z-index:1;transition:font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease}.md-navigation-tab__icon ::slotted(*){display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_icon-size);block-size:var(--_icon-size);font-size:var(--_icon-size);line-height:1;font-family:var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);color:inherit;object-fit:contain}.md-navigation-tab__icon--filled{font-variation-settings:'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24}.material-symbols-outlined{font-family:var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;font-weight:normal;font-style:normal;letter-spacing:normal;text-transform:none;white-space:nowrap;direction:ltr;font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-variation-settings:'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24}.md-navigation-tab__badge{position:absolute;z-index:2;background-color:var(--_badge-color);color:var(--_badge-on-color);border-radius:var(--md-sys-shape-corner-full, 9999px);box-sizing:border-box;pointer-events:none;display:inline-flex;align-items:center;justify-content:center}.md-navigation-tab__badge--small{inset-block-start:2px;inset-inline-end:14px;inline-size:6px;block-size:6px}.md-navigation-tab__badge--large{inset-block-start:0;inset-inline-end:0;transform:translate(50%, -50%);min-inline-size:16px;block-size:16px;padding-inline:4px;font:var( --md-sys-typescale-label-small-font, 500 11px/16px Roboto, sans-serif );letter-spacing:var( --md-sys-typescale-label-small-letter-spacing, 0.5px )}.md-navigation-tab__label{font:var(--_label-font);font-size:var(--_label-size);letter-spacing:var( --md-sys-typescale-label-medium-letter-spacing, 0.5px );color:var(--_inactive-label-color);max-inline-size:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center;pointer-events:none;transition:color var(--md-sys-motion-duration-short2, 100ms) ease, opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(.md-navigation-tab--active) .md-navigation-tab__label{color:var(--_active-label-color);font-weight:var(--_label-weight-active)}.md-navigation-tab__label--hidden{opacity:0;visibility:hidden}:host(.md-navigation-tab--label-hidden){--_pad-top:var(--md-sys-spacing-inset-lg, 16px);--_pad-bottom:var(--md-sys-spacing-inset-lg, 16px);justify-content:center}:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container{justify-content:center}@media (forced-colors: active){:host{--_indicator-color:Highlight;--_active-icon-color:HighlightText;--_active-label-color:HighlightText;--_inactive-icon-color:ButtonText;--_inactive-label-color:ButtonText}:host(:focus-visible:not(.md-navigation-tab--disabled)){outline:2px solid CanvasText}}@media (prefers-reduced-motion: reduce){:host,.md-navigation-tab__state-layer,.md-navigation-tab__indicator,.md-navigation-tab__icon,.md-navigation-tab__label{transition:none !important}}: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}:host([hidden]){display:none !important}`;const b=a(class a extends i{constructor(a){super();if(a!==false){this.__registerHost()}this.__attachShadow();this.mdTabClick=t(this,"mdTabClick",7);this.active=false;this.disabled=false;this.softDisabled=false;this.label="";this.icon="";this.activeIcon="";this.badge=false;this.badgeValue="";this.badgeMax=999;this.href="";this.target="";this.labelBehavior="always";this.density=0;this.focusVisible=false;this.handleClick=a=>{if(this.interactionDisabled){a.preventDefault();a.stopPropagation();return}if(a.defaultPrevented)return;this.emitActivation();this.maybeFollowHref()};this.handleKeyDown=a=>{if(this.interactionDisabled)return;if(a.key==="Enter"||a.key===" "||a.key==="Spacebar"){a.preventDefault();s(this.el);this.el.click()}};this.handleFocus=()=>{this.focusVisible=this.el.matches(":focus-visible")};this.handleBlur=()=>{this.focusVisible=false}}onActiveChange(a){this.el.setAttribute("aria-selected",String(a))}onDisabledChange(){this.syncAriaDisabled()}onSoftDisabledChange(){this.syncAriaDisabled()}get interactionDisabled(){return this.disabled||this.softDisabled}syncAriaDisabled(){this.el.setAttribute("aria-disabled",String(this.interactionDisabled))}connectedCallback(){if(!this.el.hasAttribute("role"))this.el.setAttribute("role","tab");this.el.setAttribute("aria-selected",String(this.active));if(this.interactionDisabled)this.el.setAttribute("aria-disabled","true");if(!this.el.hasAttribute("tabindex")){this.el.setAttribute("tabindex",this.active?"0":"-1")}}async focusEl(){if(this.disabled)return;this.el.focus()}resolveIndex(){const a=this.el.parentElement;if(!a)return-1;const i=[];for(const t of Array.from(a.children)){if(t.tagName==="MD-NAVIGATION-TAB"){i.push(t)}}return i.indexOf(this.el)}emitActivation(){const a=this.resolveIndex();this.mdTabClick.emit({index:a})}maybeFollowHref(){const a=r(this.href);if(!a)return;if(typeof window==="undefined")return;if(this.target==="_blank"){window.open(a,"_blank",l)}else if(this.target){window.open(a,this.target,l)}else{window.location.assign(a)}}resolveLabelVisibility(){return this.labelBehavior}formatBadgeValue(){const a=(this.badgeValue??"").trim();if(!a)return"";if(this.badgeMax>0){const i=Number(a);if(!Number.isNaN(i)&&Number.isFinite(i)&&i>this.badgeMax){return`${this.badgeMax}+`}}return a}renderIcon(){const a=this.active&&(this.activeIcon||this.icon);const i=this.active;const t=a?this.activeIcon||this.icon:this.icon;return n("span",{class:"md-navigation-tab__icon-container",part:"icon-container"},n("span",{class:{"md-navigation-tab__icon":true,"material-symbols-outlined":true,"md-navigation-tab__icon--filled":i},part:"icon","aria-hidden":"true"},this.active?n("slot",{name:"active-icon"},t):n("slot",{name:"icon"},t)),this.renderBadge())}renderBadge(){if(!this.badge&&!this.badgeValue)return null;const a=this.formatBadgeValue();const i=a.length>0;return n("span",{class:{"md-navigation-tab__badge":true,"md-navigation-tab__badge--small":!i,"md-navigation-tab__badge--large":i},part:"badge",role:"status","aria-label":i?`${a} new`:"New"},i?a:"")}renderLabel(){const a=this.resolveLabelVisibility();if(a==="none")return null;return n("span",{class:{"md-navigation-tab__label":true,"md-navigation-tab__label--hidden":a==="selected"&&!this.active},part:"label"},n("slot",null,this.label))}render(){const a=this.label||undefined;const i=this.resolveLabelVisibility();const t=i==="none"?a:undefined;return n(e,{key:"928761c7b7df565f1a3782b4342cd961e71daf0c",class:{"md-navigation-tab":true,"md-navigation-tab--active":this.active,"md-navigation-tab--disabled":this.disabled,"md-navigation-tab--soft-disabled":this.softDisabled&&!this.disabled,"md-navigation-tab--label-hidden":i==="none"},"aria-label":t,onClick:this.handleClick,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onBlur:this.handleBlur},n("md-ripple",{key:"d926ea5c82f8be601dd8572eddb37882f4716c1a",disabled:this.interactionDisabled}),n("span",{key:"9354c3ca399f568bbfea25742dc73b1123662acb",class:"md-navigation-tab__state-layer",part:"state-layer","aria-hidden":"true","data-focus-visible":this.focusVisible?"true":null}),n("span",{key:"c693e3826dbade6ab953eb2f8202762f970396bf",class:"md-navigation-tab__container",part:"container"},n("span",{key:"7ad855313a15e392b47e2a04fb52c9a465a81f35",class:{"md-navigation-tab__indicator":true,"md-navigation-tab__indicator--active":this.active},part:"indicator","aria-hidden":"true"}),this.renderIcon(),this.renderLabel()))}get el(){return this}static get watchers(){return{active:[{onActiveChange:0}],disabled:[{onDisabledChange:0}],softDisabled:[{onSoftDisabledChange:0}]}}static get style(){return c()}},[257,"md-navigation-tab",{active:[1540],disabled:[516],softDisabled:[516,"soft-disabled"],label:[1],icon:[1],activeIcon:[1,"active-icon"],badge:[516],badgeValue:[1,"badge-value"],badgeMax:[2,"badge-max"],href:[1],target:[1],labelBehavior:[1025,"label-behavior"],density:[514],focusVisible:[32],focusEl:[64]},undefined,{active:[{onActiveChange:0}],disabled:[{onDisabledChange:0}],softDisabled:[{onSoftDisabledChange:0}]}]);function v(){if(typeof customElements==="undefined"){return}const a=["md-navigation-tab","md-ripple"];a.forEach((a=>{switch(a){case"md-navigation-tab":if(!customElements.get(o(a))){customElements.define(o(a),b)}break;case"md-ripple":if(!customElements.get(o(a))){d()}break}}))}v();const m=b;const h=v;export{m as MdNavigationTab,h as defineCustomElement};
1
+ import{p as a,H as i,c as t,h as n,d as e,t as o}from"./p-B7GMP_JD.js";import{t as s}from"./p-DYBUr7K_.js";import{s as r,a as l}from"./p-BdEoSBtL.js";import{d}from"./p-BMizw_F3.js";const c=()=>`:host{--_indicator-color:var( --md-navigation-tab-active-indicator-color, var(--md-sys-color-secondary-container, #E8DEF8) );--_indicator-w:var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));--_indicator-h:var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));--_indicator-shape:var( --md-navigation-tab-active-indicator-shape, var(--md-sys-shape-corner-full, 9999px) );--_active-icon-color:var( --md-navigation-tab-active-icon-color, var(--md-sys-color-on-secondary-container, #1E192B) );--_inactive-icon-color:var( --md-navigation-tab-inactive-icon-color, var(--md-sys-color-on-surface-variant, #49454F) );--_active-label-color:var( --md-navigation-tab-active-label-color, var(--md-sys-color-on-surface, #1C1B1F) );--_inactive-label-color:var( --md-navigation-tab-inactive-label-color, var(--md-sys-color-on-surface-variant, #49454F) );--_icon-size:var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));--_pad-top:var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_pad-bottom:var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_hover-color:var( --md-navigation-tab-hover-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_focus-color:var( --md-navigation-tab-focus-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_pressed-color:var( --md-navigation-tab-pressed-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_badge-color:var( --md-navigation-tab-badge-color, var(--md-sys-color-error, #B3261E) );--_badge-on-color:var( --md-navigation-tab-badge-on-color, var(--md-sys-color-on-error, #FFFFFF) );--_disabled-opacity:var(--md-navigation-tab-disabled-opacity, 0.38);--_label-font:var( --md-navigation-tab-label-font, var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif) );--_label-size:var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));--_label-weight-active:var(--md-navigation-tab-label-font-weight, 600);--_motion-duration:var(--md-sys-motion-duration-short4, 200ms);--_motion-easing:var( --md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1) );display:inline-flex;flex-direction:column;align-items:center;justify-content:flex-start;inline-size:100%;min-inline-size:48px;block-size:100%;padding-block:var(--_pad-top) var(--_pad-bottom);box-sizing:border-box;cursor:pointer;position:relative;outline:none;user-select:none;-webkit-tap-highlight-color:transparent;color:var(--_inactive-icon-color);transition:color var(--_motion-duration) var(--_motion-easing)}:host(.md-navigation-tab--active){color:var(--_active-icon-color)}:host(.md-navigation-tab--disabled),:host(.md-navigation-tab--soft-disabled){cursor:not-allowed;opacity:var(--_disabled-opacity)}:host(.md-navigation-tab--disabled){pointer-events:none}.md-navigation-tab__state-layer{position:absolute;inset:0;background-color:currentColor;opacity:0;border-radius:inherit;pointer-events:none;transition:opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_hover-color);opacity:var(--md-sys-state-hover-state-layer-opacity, 0.08)}:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_pressed-color);opacity:var(--md-sys-state-pressed-state-layer-opacity, 0.12)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer{background-color:var(--_focus-color);opacity:var(--md-navigation-tab-focus-state-layer-opacity, 0.1)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after{content:'';position:absolute;inset:-4px;border:3px solid var(--md-sys-color-secondary, #625B71);border-radius:var(--_indicator-shape, 9999px);box-sizing:border-box;pointer-events:none}.md-navigation-tab__container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));inline-size:100%;pointer-events:none;}.md-navigation-tab__indicator{position:absolute;inset-block-start:0;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);border-radius:var(--_indicator-shape);background-color:var(--_indicator-color);transform:scale(0, 1);transform-origin:center center;opacity:0;transition:transform var(--_motion-duration) var(--_motion-easing), opacity var(--md-sys-motion-duration-short2, 100ms) ease;pointer-events:none}.md-navigation-tab__indicator--active{transform:scale(1, 1);opacity:1}.md-navigation-tab__icon-container{position:relative;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);pointer-events:none}.md-navigation-tab__icon{position:relative;display:inline-flex;align-items:center;justify-content:center;font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size);line-height:1;color:inherit;z-index:1;transition:font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease}.md-navigation-tab__icon ::slotted(*){display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_icon-size);block-size:var(--_icon-size);font-size:var(--_icon-size);line-height:1;font-family:var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);color:inherit;object-fit:contain}.md-navigation-tab__icon--filled{font-variation-settings:'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24}.material-symbols-outlined{font-family:var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;font-weight:normal;font-style:normal;letter-spacing:normal;text-transform:none;white-space:nowrap;direction:ltr;font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-variation-settings:'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24}.md-navigation-tab__badge{position:absolute;z-index:2;background-color:var(--_badge-color);color:var(--_badge-on-color);border-radius:var(--md-sys-shape-corner-full, 9999px);box-sizing:border-box;pointer-events:none;display:inline-flex;align-items:center;justify-content:center}.md-navigation-tab__badge--small{inset-block-start:2px;inset-inline-end:14px;inline-size:6px;block-size:6px}.md-navigation-tab__badge--large{inset-block-start:calc((var(--_indicator-h) - var(--_icon-size)) / 2);inset-inline-end:calc((var(--_indicator-w) - var(--_icon-size)) / 2);transform:translate(50%, -50%);min-inline-size:16px;block-size:16px;padding-inline:4px;font:var( --md-sys-typescale-label-small-font, 500 11px/16px Roboto, sans-serif );letter-spacing:var( --md-sys-typescale-label-small-letter-spacing, 0.5px )}.md-navigation-tab__label{font:var(--_label-font);font-size:var(--_label-size);letter-spacing:var( --md-sys-typescale-label-medium-letter-spacing, 0.5px );color:var(--_inactive-label-color);max-inline-size:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center;pointer-events:none;transition:color var(--md-sys-motion-duration-short2, 100ms) ease, opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(.md-navigation-tab--active) .md-navigation-tab__label{color:var(--_active-label-color);font-weight:var(--_label-weight-active)}.md-navigation-tab__label--hidden{opacity:0;visibility:hidden}:host(.md-navigation-tab--label-hidden){--_pad-top:var(--md-sys-spacing-inset-lg, 16px);--_pad-bottom:var(--md-sys-spacing-inset-lg, 16px);justify-content:center}:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container{justify-content:center}@media (forced-colors: active){:host{--_indicator-color:Highlight;--_active-icon-color:HighlightText;--_active-label-color:HighlightText;--_inactive-icon-color:ButtonText;--_inactive-label-color:ButtonText}:host(:focus-visible:not(.md-navigation-tab--disabled)){outline:2px solid CanvasText}}@media (prefers-reduced-motion: reduce){:host,.md-navigation-tab__state-layer,.md-navigation-tab__indicator,.md-navigation-tab__icon,.md-navigation-tab__label{transition:none !important}}: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}:host([hidden]){display:none !important}`;const b=a(class a extends i{constructor(a){super();if(a!==false){this.__registerHost()}this.__attachShadow();this.mdTabClick=t(this,"mdTabClick",7);this.active=false;this.disabled=false;this.softDisabled=false;this.label="";this.icon="";this.activeIcon="";this.badge=false;this.badgeValue="";this.badgeMax=999;this.href="";this.target="";this.labelBehavior="always";this.density=0;this.focusVisible=false;this.handleClick=a=>{if(this.interactionDisabled){a.preventDefault();a.stopPropagation();return}if(a.defaultPrevented)return;this.emitActivation();this.maybeFollowHref()};this.handleKeyDown=a=>{if(this.interactionDisabled)return;if(a.key==="Enter"||a.key===" "||a.key==="Spacebar"){a.preventDefault();s(this.el);this.el.click()}};this.handleFocus=()=>{this.focusVisible=this.el.matches(":focus-visible")};this.handleBlur=()=>{this.focusVisible=false}}onActiveChange(a){this.el.setAttribute("aria-selected",String(a))}onDisabledChange(){this.syncAriaDisabled()}onSoftDisabledChange(){this.syncAriaDisabled()}get interactionDisabled(){return this.disabled||this.softDisabled}syncAriaDisabled(){this.el.setAttribute("aria-disabled",String(this.interactionDisabled))}connectedCallback(){if(!this.el.hasAttribute("role"))this.el.setAttribute("role","tab");this.el.setAttribute("aria-selected",String(this.active));if(this.interactionDisabled)this.el.setAttribute("aria-disabled","true");if(!this.el.hasAttribute("tabindex")){this.el.setAttribute("tabindex",this.active?"0":"-1")}}async focusEl(){if(this.disabled)return;this.el.focus()}resolveIndex(){const a=this.el.parentElement;if(!a)return-1;const i=[];for(const t of Array.from(a.children)){if(t.tagName==="MD-NAVIGATION-TAB"){i.push(t)}}return i.indexOf(this.el)}emitActivation(){const a=this.resolveIndex();this.mdTabClick.emit({index:a})}maybeFollowHref(){const a=r(this.href);if(!a)return;if(typeof window==="undefined")return;if(this.target==="_blank"){window.open(a,"_blank",l)}else if(this.target){window.open(a,this.target,l)}else{window.location.assign(a)}}resolveLabelVisibility(){return this.labelBehavior}formatBadgeValue(){const a=(this.badgeValue??"").trim();if(!a)return"";if(this.badgeMax>0){const i=Number(a);if(!Number.isNaN(i)&&Number.isFinite(i)&&i>this.badgeMax){return`${this.badgeMax}+`}}return a}renderIcon(){const a=this.active&&(this.activeIcon||this.icon);const i=this.active;const t=a?this.activeIcon||this.icon:this.icon;return n("span",{class:"md-navigation-tab__icon-container",part:"icon-container"},n("span",{class:{"md-navigation-tab__icon":true,"material-symbols-outlined":true,"md-navigation-tab__icon--filled":i},part:"icon","aria-hidden":"true"},this.active?n("slot",{name:"active-icon"},t):n("slot",{name:"icon"},t)),this.renderBadge())}renderBadge(){if(!this.badge&&!this.badgeValue)return null;const a=this.formatBadgeValue();const i=a.length>0;return n("span",{class:{"md-navigation-tab__badge":true,"md-navigation-tab__badge--small":!i,"md-navigation-tab__badge--large":i},part:"badge",role:"status","aria-label":i?`${a} new`:"New"},i?a:"")}renderLabel(){const a=this.resolveLabelVisibility();if(a==="none")return null;return n("span",{class:{"md-navigation-tab__label":true,"md-navigation-tab__label--hidden":a==="selected"&&!this.active},part:"label"},n("slot",null,this.label))}render(){const a=this.label||undefined;const i=this.resolveLabelVisibility();const t=i==="none"?a:undefined;return n(e,{key:"928761c7b7df565f1a3782b4342cd961e71daf0c",class:{"md-navigation-tab":true,"md-navigation-tab--active":this.active,"md-navigation-tab--disabled":this.disabled,"md-navigation-tab--soft-disabled":this.softDisabled&&!this.disabled,"md-navigation-tab--label-hidden":i==="none"},"aria-label":t,onClick:this.handleClick,onKeyDown:this.handleKeyDown,onFocus:this.handleFocus,onBlur:this.handleBlur},n("md-ripple",{key:"d926ea5c82f8be601dd8572eddb37882f4716c1a",disabled:this.interactionDisabled}),n("span",{key:"9354c3ca399f568bbfea25742dc73b1123662acb",class:"md-navigation-tab__state-layer",part:"state-layer","aria-hidden":"true","data-focus-visible":this.focusVisible?"true":null}),n("span",{key:"c693e3826dbade6ab953eb2f8202762f970396bf",class:"md-navigation-tab__container",part:"container"},n("span",{key:"7ad855313a15e392b47e2a04fb52c9a465a81f35",class:{"md-navigation-tab__indicator":true,"md-navigation-tab__indicator--active":this.active},part:"indicator","aria-hidden":"true"}),this.renderIcon(),this.renderLabel()))}get el(){return this}static get watchers(){return{active:[{onActiveChange:0}],disabled:[{onDisabledChange:0}],softDisabled:[{onSoftDisabledChange:0}]}}static get style(){return c()}},[257,"md-navigation-tab",{active:[1540],disabled:[516],softDisabled:[516,"soft-disabled"],label:[1],icon:[1],activeIcon:[1,"active-icon"],badge:[516],badgeValue:[1,"badge-value"],badgeMax:[2,"badge-max"],href:[1],target:[1],labelBehavior:[1025,"label-behavior"],density:[514],focusVisible:[32],focusEl:[64]},undefined,{active:[{onActiveChange:0}],disabled:[{onDisabledChange:0}],softDisabled:[{onSoftDisabledChange:0}]}]);function v(){if(typeof customElements==="undefined"){return}const a=["md-navigation-tab","md-ripple"];a.forEach((a=>{switch(a){case"md-navigation-tab":if(!customElements.get(o(a))){customElements.define(o(a),b)}break;case"md-ripple":if(!customElements.get(o(a))){d()}break}}))}v();const m=b;const h=v;export{m as MdNavigationTab,h as defineCustomElement};
2
2
  //# sourceMappingURL=md-navigation-tab.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["mdNavigationTabCss","MdNavigationTab","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","active","disabled","softDisabled","label","icon","activeIcon","badge","badgeValue","badgeMax","href","target","labelBehavior","density","focusVisible","handleClick","e","interactionDisabled","preventDefault","stopPropagation","defaultPrevented","emitActivation","maybeFollowHref","handleKeyDown","key","triggerRipple","el","click","handleFocus","matches","handleBlur","onActiveChange","setAttribute","String","onDisabledChange","syncAriaDisabled","onSoftDisabledChange","connectedCallback","hasAttribute","focusEl","focus","resolveIndex","parent","parentElement","siblings","child","Array","from","children","tagName","push","indexOf","index","mdTabClick","emit","sanitizeHref","window","open","SAFE_WINDOW_FEATURES","location","assign","resolveLabelVisibility","formatBadgeValue","raw","trim","num","Number","isNaN","isFinite","renderIcon","useActive","filled","glyph","h","class","part","name","renderBadge","value","isLarge","length","role","renderLabel","visibility","render","accessibleLabel","undefined","ariaLabel","Host","onClick","onKeyDown","onFocus","onBlur"],"sources":["src/components/md-navigation-tab/md-navigation-tab.css?tag=md-navigation-tab&encapsulation=shadow","src/components/md-navigation-tab/md-navigation-tab.tsx"],"sourcesContent":["/* ==========================================================\n md-navigation-tab — Material Design 3 Navigation Bar Item\n Spec: https://m3.material.io/components/navigation-bar/specs\n A11y: https://m3.material.io/components/navigation-bar/accessibility\n\n Anatomy:\n - State layer (hover / focus / pressed tint)\n - Active indicator (56×32 secondary-container pill)\n - Icon (outlined inactive, filled active)\n - Label (label-medium type)\n - Badge (small dot or large numeric capsule)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-navigation-tab-active-indicator-color\n --md-navigation-tab-active-indicator-width (default 56px)\n --md-navigation-tab-active-indicator-height (default 32px)\n --md-navigation-tab-active-indicator-shape (default full-rounded)\n --md-navigation-tab-active-icon-color\n --md-navigation-tab-inactive-icon-color\n --md-navigation-tab-active-label-color\n --md-navigation-tab-inactive-label-color\n --md-navigation-tab-label-font (label-medium font shorthand)\n --md-navigation-tab-label-font-weight (active label weight; defaults 600)\n --md-navigation-tab-icon-size (default 24px)\n --md-navigation-tab-padding-block-start (default 5px — centers 54px content in 64px bar)\n --md-navigation-tab-padding-block-end (default 5px)\n --md-navigation-tab-hover-state-layer-color\n --md-navigation-tab-focus-state-layer-color\n --md-navigation-tab-pressed-state-layer-color\n --md-navigation-tab-badge-color\n --md-navigation-tab-badge-on-color\n --md-navigation-tab-disabled-opacity (default 0.38)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — base layout, sizing, focus\n ========================================================== */\n:host {\n --_indicator-color: var(\n --md-navigation-tab-active-indicator-color,\n var(--md-sys-color-secondary-container, #E8DEF8)\n );\n --_indicator-w: var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_indicator-h: var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));\n --_indicator-shape: var(\n --md-navigation-tab-active-indicator-shape,\n var(--md-sys-shape-corner-full, 9999px)\n );\n\n --_active-icon-color: var(\n --md-navigation-tab-active-icon-color,\n var(--md-sys-color-on-secondary-container, #1E192B)\n );\n --_inactive-icon-color: var(\n --md-navigation-tab-inactive-icon-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_active-label-color: var(\n --md-navigation-tab-active-label-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_inactive-label-color: var(\n --md-navigation-tab-inactive-label-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_icon-size: var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_pad-top: var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n --_pad-bottom: var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n\n --_hover-color: var(\n --md-navigation-tab-hover-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_focus-color: var(\n --md-navigation-tab-focus-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_pressed-color: var(\n --md-navigation-tab-pressed-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n\n --_badge-color: var(\n --md-navigation-tab-badge-color,\n var(--md-sys-color-error, #B3261E)\n );\n --_badge-on-color: var(\n --md-navigation-tab-badge-on-color,\n var(--md-sys-color-on-error, #FFFFFF)\n );\n\n --_disabled-opacity: var(--md-navigation-tab-disabled-opacity, 0.38);\n\n --_label-font: var(\n --md-navigation-tab-label-font,\n var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif)\n );\n --_label-size: var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));\n --_label-weight-active: var(--md-navigation-tab-label-font-weight, 600);\n\n --_motion-duration: var(--md-sys-motion-duration-short4, 200ms);\n --_motion-easing: var(\n --md-sys-motion-easing-emphasized-decelerate,\n cubic-bezier(0.05, 0.7, 0.1, 1)\n );\n\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n inline-size: 100%;\n min-inline-size: 48px; /* M3 minimum touch target */\n block-size: 100%;\n padding-block: var(--_pad-top) var(--_pad-bottom);\n box-sizing: border-box;\n cursor: pointer;\n position: relative;\n outline: none;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n color: var(--_inactive-icon-color);\n /* Color transitions are quick and additive — they don't trigger layout. */\n transition:\n color var(--_motion-duration) var(--_motion-easing);\n}\n\n:host(.md-navigation-tab--active) {\n color: var(--_active-icon-color);\n}\n\n/* ==========================================================\n 2. DISABLED STATE\n M3 nav-bar doesn't formally define disabled, but our API\n needs one — match the global disabled-content opacity.\n `--soft-disabled` shares the dim but stays keyboard-focusable\n (it keeps pointer-events + the focus ring) so screen-reader\n users can discover a temporarily-unavailable destination.\n ========================================================== */\n:host(.md-navigation-tab--disabled),\n:host(.md-navigation-tab--soft-disabled) {\n cursor: not-allowed;\n opacity: var(--_disabled-opacity);\n}\n\n:host(.md-navigation-tab--disabled) {\n pointer-events: none;\n}\n\n/* ==========================================================\n 3. STATE LAYER\n Spans the full hit-area so hover/focus/pressed feedback\n covers the whole tab — not just the active-indicator pill.\n Opacities come from the M3 state-layer tokens.\n ========================================================== */\n.md-navigation-tab__state-layer {\n position: absolute;\n inset: 0;\n background-color: currentColor;\n opacity: 0;\n border-radius: inherit;\n pointer-events: none;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_hover-color);\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_pressed-color);\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_focus-color);\n /* M3 nav-bar focus state-layer opacity is 0.10 (the global sys token is 0.12);\n keep a component override so it matches the spec regardless of the sys value. */\n opacity: var(--md-navigation-tab-focus-state-layer-opacity, 0.1);\n}\n\n/* Visible 3px focus ring per M3 accessibility guidance.\n Wraps the active-indicator pill (centered, rounded) rather than the whole\n tab: a full-tab inset outline gets clipped at the navigation bar's rounded\n corners, and `secondary` matches the focus-ring color used library-wide\n (the old full-tab ring used `primary`, which stood out from every other\n component). */\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after {\n content: '';\n position: absolute;\n inset: -4px;\n border: 3px solid var(--md-sys-color-secondary, #625B71);\n border-radius: var(--_indicator-shape, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n}\n\n/* ==========================================================\n 4. STACK CONTAINER\n The icon-container + indicator + label are stacked centered\n so the visual layout matches MD3 even when extra width is\n available.\n ========================================================== */\n.md-navigation-tab__container {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n /* M3 vertical item: active-indicator → label \"container between space\" = 6px.\n (The 24px icon centered in the 32px indicator yields the 4px icon inset.) */\n gap: max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));\n inline-size: 100%;\n pointer-events: none; /* Click goes through to host. */\n}\n\n/* ==========================================================\n 5. ACTIVE INDICATOR PILL\n Animates from a vertically-collapsed shape into the full\n 56×32px pill — per M3's emphasized-decelerate spec.\n ========================================================== */\n.md-navigation-tab__indicator {\n position: absolute;\n /* Aligned to the icon-container vertical box. */\n inset-block-start: 0;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n border-radius: var(--_indicator-shape);\n background-color: var(--_indicator-color);\n /* Start collapsed; grow on activation. */\n transform: scale(0, 1);\n transform-origin: center center;\n opacity: 0;\n transition:\n transform var(--_motion-duration) var(--_motion-easing),\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n pointer-events: none;\n}\n\n.md-navigation-tab__indicator--active {\n transform: scale(1, 1);\n opacity: 1;\n}\n\n/* ==========================================================\n 6. ICON CONTAINER & ICON\n The container is exactly the size of the active indicator\n so the indicator sits behind the icon at 100% coverage.\n ========================================================== */\n.md-navigation-tab__icon-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n pointer-events: none;\n}\n\n.md-navigation-tab__icon {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: var(--_icon-size);\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n line-height: 1;\n color: inherit;\n z-index: 1;\n transition: font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n/* Custom icons via slot=\"icon\" / \"active-icon\" (SVG, emoji, custom font):\n slotted light-DOM nodes don't inherit the shadow icon-span's sizing, so a\n bare <span>★</span> would render at the host font-size. Pin them to the 24px\n Material Symbols footprint, inherit the active/inactive icon color (so SVGs\n using currentColor tint correctly), and center within the box. */\n.md-navigation-tab__icon ::slotted(*) {\n /* Fixed 24px flex box so text glyphs (★, emoji) and SVGs share one footprint\n and center identically — a bare inline glyph otherwise gets a taller line\n box and rides off-center against an SVG's box. */\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 line-height: 1;\n /* Reset the icon span's Material Symbols font: slotted text/emoji inherit it\n through the flattened tree, but that icon font has no ★/emoji glyph and its\n line metrics drop the fallback glyph ~5px below center. A normal UI font\n centers them; authors slotting a custom icon font override this from light DOM. */\n font-family: var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);\n color: inherit;\n object-fit: contain;\n}\n\n/* Material Symbols variable-font: flip the FILL axis on active. */\n.md-navigation-tab__icon--filled {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* When Material Symbols is the icon font, the outlined font already\n gives us the inactive look. When Material Icons (legacy) is used,\n we still get the inactive look via the font family. */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;\n font-weight: normal;\n font-style: normal;\n letter-spacing: normal;\n text-transform: none;\n /* No `display` here: the element is also `.md-navigation-tab__icon`, which must\n stay an `inline-flex` centering box (this class is later in source with equal\n specificity, so an inline-block here would silently win and break centering of\n slotted custom icons — they'd sit on the text baseline ~5px low). */\n white-space: nowrap;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* ==========================================================\n 7. BADGES\n Two flavors per M3 spec:\n - small → 6px dot\n - large → numeric / textual capsule (16px min height)\n Both anchor to the top-right of the icon container.\n ========================================================== */\n.md-navigation-tab__badge {\n position: absolute;\n /* Above the icon — the icon glyph has z-index:1, so without this the SVG\n strokes paint over the badge (\"polluted\" badge). */\n z-index: 2;\n background-color: var(--_badge-color);\n color: var(--_badge-on-color);\n border-radius: var(--md-sys-shape-corner-full, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.md-navigation-tab__badge--small {\n inset-block-start: 2px;\n inset-inline-end: 14px;\n inline-size: 6px;\n block-size: 6px;\n}\n\n/* Centred on the icon corner, like md-tab and md-navigation-rail-tab. The old\n `inset-inline-start: 50%` + 4px margin anchored the badge to the middle of the\n icon box and shoved it right by a fixed amount, so a wider badge grew to the\n right instead of straddling the corner. */\n.md-navigation-tab__badge--large {\n inset-block-start: 0;\n inset-inline-end: 0;\n transform: translate(50%, -50%);\n min-inline-size: 16px;\n block-size: 16px;\n padding-inline: 4px;\n font: var(\n --md-sys-typescale-label-small-font,\n 500 11px/16px Roboto, sans-serif\n );\n letter-spacing: var(\n --md-sys-typescale-label-small-letter-spacing,\n 0.5px\n );\n}\n\n/* ==========================================================\n 8. LABEL\n label-medium typography per M3. Active label gains a\n slightly heavier weight to convey selection.\n ========================================================== */\n.md-navigation-tab__label {\n font: var(--_label-font);\n font-size: var(--_label-size);\n letter-spacing: var(\n --md-sys-typescale-label-medium-letter-spacing,\n 0.5px\n );\n color: var(--_inactive-label-color);\n max-inline-size: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-align: center;\n pointer-events: none;\n transition:\n color var(--md-sys-motion-duration-short2, 100ms) ease,\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(.md-navigation-tab--active) .md-navigation-tab__label {\n color: var(--_active-label-color);\n font-weight: var(--_label-weight-active);\n}\n\n/* When `labelBehavior=\"selected\"` keep the label slot in the layout\n but hide it visually for inactive tabs so heights stay constant. */\n.md-navigation-tab__label--hidden {\n opacity: 0;\n visibility: hidden;\n}\n\n/* When `labelBehavior=\"none\"` is applied on the host the label is\n not rendered at all — collapse the vertical padding so the icon\n sits centered in the row. */\n:host(.md-navigation-tab--label-hidden) {\n /* No label: center the 32px icon-container in the 64px bar → 16px each side. */\n --_pad-top: var(--md-sys-spacing-inset-lg, 16px);\n --_pad-bottom: var(--md-sys-spacing-inset-lg, 16px);\n justify-content: center;\n}\n\n:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container {\n justify-content: center;\n}\n\n/* ==========================================================\n 9. FORCED COLORS / REDUCED MOTION\n ========================================================== */\n@media (forced-colors: active) {\n :host {\n --_indicator-color: Highlight;\n --_active-icon-color: HighlightText;\n --_active-label-color: HighlightText;\n --_inactive-icon-color: ButtonText;\n --_inactive-label-color: ButtonText;\n }\n :host(:focus-visible:not(.md-navigation-tab--disabled)) {\n outline: 2px solid CanvasText;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n .md-navigation-tab__state-layer,\n .md-navigation-tab__indicator,\n .md-navigation-tab__icon,\n .md-navigation-tab__label {\n transition: none !important;\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\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\nexport type MdNavigationTabLabelBehavior = 'always' | 'selected' | 'none';\n\n/**\n * `md-navigation-tab` — a single destination inside `md-navigation-bar`.\n *\n * Renders an icon, an optional label, and an optional badge. Selecting\n * the tab swaps the icon to a filled variant (per M3 spec) and reveals\n * an \"active indicator\" pill behind the icon.\n *\n * References:\n * - {@link https://m3.material.io/components/navigation-bar/specs Specs}\n * - {@link https://m3.material.io/components/navigation-bar/accessibility Accessibility}\n *\n * @slot icon - Custom icon for the inactive state\n * (replaces the `icon` attribute).\n * @slot active-icon - Custom icon for the active state\n * (replaces the `active-icon` attribute).\n * @slot - Default slot for a custom label\n * (replaces the `label` attribute).\n *\n * @part container - The full tab hit-area / touch target.\n * @part indicator - The 56×32 pill that highlights the active icon.\n * @part state-layer - The hover/focus/pressed tint overlay.\n * @part icon-container - The 56×32 wrapper around the icon (badge anchor).\n * @part icon - The rendered icon glyph.\n * @part badge - The badge dot or text capsule (when present).\n * @part label - The destination label text.\n */\n@Component({\n tag: 'md-navigation-tab',\n styleUrl: 'md-navigation-tab.css',\n shadow: true,\n})\nexport class MdNavigationTab {\n @Element() el!: HTMLElement;\n\n /** Whether this destination is currently selected. */\n @Prop({ mutable: true, reflect: true }) active: boolean = false;\n\n /** Disable interaction. Disabled tabs are skipped by keyboard nav. */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /**\n * Soft-disable the destination: it cannot be activated or selected and is\n * announced as `aria-disabled`, but — unlike `disabled` — it stays\n * keyboard-reachable (the bar's arrow-key tour still lands on it) so\n * screen-reader users can discover a temporarily-unavailable destination.\n */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Destination label rendered below the icon. */\n @Prop() label: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when inactive.\n * Per M3 spec, inactive destinations use the outlined variant.\n */\n @Prop() icon: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when active.\n * Per M3 spec, active destinations use the filled variant.\n * Defaults to `icon` when empty (the same glyph in both states).\n */\n @Prop({ attribute: 'active-icon' }) activeIcon: string = '';\n\n /**\n * Show a small \"notification dot\" badge in the top-right of the icon.\n * Use when there are new items but no count is needed.\n */\n @Prop({ reflect: true }) badge: boolean = false;\n\n /**\n * Numeric / textual badge value (e.g. `\"3\"`, `\"99+\"`, `\"New\"`).\n * When set, the badge expands to a pill that accommodates the value\n * (M3 calls this the \"large badge\" variant).\n */\n @Prop({ attribute: 'badge-value' }) badgeValue: string = '';\n\n /**\n * Maximum value rendered when `badgeValue` is purely numeric. Values\n * greater than this render as `\"{max}+\"` (e.g. `99+`). Set to `0` to\n * disable the cap.\n */\n @Prop({ attribute: 'badge-max' }) badgeMax: number = 999;\n\n /**\n * When set, activating the tab also navigates to the URL — useful when\n * each destination is a full route. For SPA routing, intercept the native\n * `click` (call `preventDefault()`) or listen to the bar's `mdChange`;\n * navigation only occurs when `href` is truthy and the click isn't prevented.\n */\n @Prop() href: string = '';\n\n /** Link target (forwarded only when `href` is set). */\n @Prop() target: string = '';\n\n /**\n * Label visibility for this tab. Inherits from the parent\n * `md-navigation-bar`'s `label-behavior` when not set.\n *\n * Not reflected as an attribute — the parent bar uses\n * `getAttribute('label-behavior')` to detect *explicit* author\n * overrides, so reflecting the default would defeat that signal.\n */\n @Prop({ mutable: true, attribute: 'label-behavior' })\n labelBehavior: MdNavigationTabLabelBehavior = 'always';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fired when the tab is activated (click, Enter, or Space) and the tab is\n * not disabled. The parent `md-navigation-bar` listens for this to drive\n * selection; external code may also listen to detect per-tab activation\n * (including a re-click of the already-active tab, which does not emit\n * `mdChange` on the bar).\n */\n @Event() mdTabClick: EventEmitter<{ index: number }>;\n\n /** Internal — track focus-visible for the state layer + a11y. */\n @State() private focusVisible: boolean = false;\n\n // ─── Watchers ────────────────────────────────────────────────────\n\n @Watch('active')\n onActiveChange(active: boolean) {\n // Mirror the active state into aria-selected so the parent isn't\n // the sole writer (works in detached usage / docs without a bar).\n this.el.setAttribute('aria-selected', String(active));\n }\n\n @Watch('disabled')\n onDisabledChange() {\n this.syncAriaDisabled();\n }\n\n @Watch('softDisabled')\n onSoftDisabledChange() {\n this.syncAriaDisabled();\n }\n\n /** Activation/selection is blocked when either disabled flag is set. */\n private get interactionDisabled(): boolean {\n return this.disabled || this.softDisabled;\n }\n\n private syncAriaDisabled() {\n this.el.setAttribute('aria-disabled', String(this.interactionDisabled));\n }\n\n // ─── Lifecycle ───────────────────────────────────────────────────\n\n connectedCallback() {\n // Defaults — the bar may override these on mount.\n if (!this.el.hasAttribute('role')) this.el.setAttribute('role', 'tab');\n this.el.setAttribute('aria-selected', String(this.active));\n if (this.interactionDisabled) this.el.setAttribute('aria-disabled', 'true');\n if (!this.el.hasAttribute('tabindex')) {\n this.el.setAttribute('tabindex', this.active ? '0' : '-1');\n }\n }\n\n // ─── Public API ──────────────────────────────────────────────────\n\n /** Focus the tab programmatically (skip when disabled). */\n @Method()\n async focusEl(): Promise<void> {\n if (this.disabled) return;\n this.el.focus();\n }\n\n // ─── Internal helpers ────────────────────────────────────────────\n\n /** Locate this tab's index inside its parent navigation bar. */\n private resolveIndex(): number {\n const parent = this.el.parentElement;\n if (!parent) return -1;\n // Walk direct children rather than using `:scope > md-navigation-tab`\n // — the latter is unsupported by Stencil's mock-doc in spec tests.\n const siblings: HTMLElement[] = [];\n for (const child of Array.from(parent.children)) {\n if ((child as HTMLElement).tagName === 'MD-NAVIGATION-TAB') {\n siblings.push(child as HTMLElement);\n }\n }\n return siblings.indexOf(this.el);\n }\n\n private emitActivation() {\n const index = this.resolveIndex();\n this.mdTabClick.emit({ index });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.interactionDisabled) {\n // Block activation and stop the click from reaching the bar.\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.defaultPrevented) return; // SPA routers call preventDefault()\n this.emitActivation();\n this.maybeFollowHref();\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.interactionDisabled) return;\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') {\n e.preventDefault();\n triggerRipple(this.el);\n // Synthesize a native click so keyboard and pointer activation share one\n // path (bubbles to the bar + follows href).\n this.el.click();\n }\n };\n\n private maybeFollowHref() {\n const href = sanitizeHref(this.href);\n if (!href) return;\n if (typeof window === 'undefined') return;\n if (this.target === '_blank') {\n window.open(href, '_blank', SAFE_WINDOW_FEATURES);\n } else if (this.target) {\n /* A named target opens a new browsing context just like `_blank` does,\n so it needs the same opener severing. */\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n } else {\n window.location.assign(href);\n }\n }\n\n private handleFocus = () => {\n this.focusVisible = this.el.matches(':focus-visible');\n };\n\n private handleBlur = () => {\n this.focusVisible = false;\n };\n\n // ─── Rendering helpers ───────────────────────────────────────────\n\n private resolveLabelVisibility(): MdNavigationTabLabelBehavior {\n return this.labelBehavior;\n }\n\n private formatBadgeValue(): string {\n const raw = (this.badgeValue ?? '').trim();\n if (!raw) return '';\n if (this.badgeMax > 0) {\n const num = Number(raw);\n if (!Number.isNaN(num) && Number.isFinite(num) && num > this.badgeMax) {\n return `${this.badgeMax}+`;\n }\n }\n return raw;\n }\n\n private renderIcon() {\n const useActive = this.active && (this.activeIcon || this.icon);\n const filled = this.active;\n const glyph = useActive ? (this.activeIcon || this.icon) : this.icon;\n\n return (\n <span class=\"md-navigation-tab__icon-container\" part=\"icon-container\">\n <span\n class={{\n 'md-navigation-tab__icon': true,\n 'material-symbols-outlined': true,\n 'md-navigation-tab__icon--filled': filled,\n }}\n part=\"icon\"\n aria-hidden=\"true\"\n >\n {/* Custom-icon slots win over the icon attribute. */}\n {this.active ? <slot name=\"active-icon\">{glyph}</slot> : <slot name=\"icon\">{glyph}</slot>}\n </span>\n {this.renderBadge()}\n </span>\n );\n }\n\n private renderBadge() {\n if (!this.badge && !this.badgeValue) return null;\n const value = this.formatBadgeValue();\n const isLarge = value.length > 0;\n\n return (\n <span\n class={{\n 'md-navigation-tab__badge': true,\n 'md-navigation-tab__badge--small': !isLarge,\n 'md-navigation-tab__badge--large': isLarge,\n }}\n part=\"badge\"\n role=\"status\"\n aria-label={isLarge ? `${value} new` : 'New'}\n >\n {isLarge ? value : ''}\n </span>\n );\n }\n\n private renderLabel() {\n const visibility = this.resolveLabelVisibility();\n if (visibility === 'none') return null;\n\n // CSS handles hiding the label when visibility === 'selected' && !active,\n // so we still render it (preserves space + keeps accessible name stable).\n return (\n <span\n class={{\n 'md-navigation-tab__label': true,\n 'md-navigation-tab__label--hidden':\n visibility === 'selected' && !this.active,\n }}\n part=\"label\"\n >\n <slot>{this.label}</slot>\n </span>\n );\n }\n\n // ─── Render ──────────────────────────────────────────────────────\n\n render() {\n // Accessible name resolution: the host carries the label so the\n // `tab` role gets a stable accessible name. Icon-only mode still\n // exposes the textual `label` via aria-label.\n const accessibleLabel = this.label || undefined;\n const visibility = this.resolveLabelVisibility();\n const ariaLabel = visibility === 'none' ? accessibleLabel : undefined;\n\n return (\n <Host\n class={{\n 'md-navigation-tab': true,\n 'md-navigation-tab--active': this.active,\n 'md-navigation-tab--disabled': this.disabled,\n 'md-navigation-tab--soft-disabled': this.softDisabled && !this.disabled,\n 'md-navigation-tab--label-hidden': visibility === 'none',\n }}\n aria-label={ariaLabel}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n >\n <md-ripple disabled={this.interactionDisabled}></md-ripple>\n <span\n class=\"md-navigation-tab__state-layer\"\n part=\"state-layer\"\n aria-hidden=\"true\"\n data-focus-visible={this.focusVisible ? 'true' : null}\n ></span>\n <span\n class=\"md-navigation-tab__container\"\n part=\"container\"\n >\n <span\n class={{\n 'md-navigation-tab__indicator': true,\n 'md-navigation-tab__indicator--active': this.active,\n }}\n part=\"indicator\"\n aria-hidden=\"true\"\n ></span>\n {this.renderIcon()}\n {this.renderLabel()}\n </span>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["mdNavigationTabCss","MdNavigationTab","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","active","disabled","softDisabled","label","icon","activeIcon","badge","badgeValue","badgeMax","href","target","labelBehavior","density","focusVisible","handleClick","e","interactionDisabled","preventDefault","stopPropagation","defaultPrevented","emitActivation","maybeFollowHref","handleKeyDown","key","triggerRipple","el","click","handleFocus","matches","handleBlur","onActiveChange","setAttribute","String","onDisabledChange","syncAriaDisabled","onSoftDisabledChange","connectedCallback","hasAttribute","focusEl","focus","resolveIndex","parent","parentElement","siblings","child","Array","from","children","tagName","push","indexOf","index","mdTabClick","emit","sanitizeHref","window","open","SAFE_WINDOW_FEATURES","location","assign","resolveLabelVisibility","formatBadgeValue","raw","trim","num","Number","isNaN","isFinite","renderIcon","useActive","filled","glyph","h","class","part","name","renderBadge","value","isLarge","length","role","renderLabel","visibility","render","accessibleLabel","undefined","ariaLabel","Host","onClick","onKeyDown","onFocus","onBlur"],"sources":["src/components/md-navigation-tab/md-navigation-tab.css?tag=md-navigation-tab&encapsulation=shadow","src/components/md-navigation-tab/md-navigation-tab.tsx"],"sourcesContent":["/* ==========================================================\n md-navigation-tab — Material Design 3 Navigation Bar Item\n Spec: https://m3.material.io/components/navigation-bar/specs\n A11y: https://m3.material.io/components/navigation-bar/accessibility\n\n Anatomy:\n - State layer (hover / focus / pressed tint)\n - Active indicator (56×32 secondary-container pill)\n - Icon (outlined inactive, filled active)\n - Label (label-medium type)\n - Badge (small dot or large numeric capsule)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-navigation-tab-active-indicator-color\n --md-navigation-tab-active-indicator-width (default 56px)\n --md-navigation-tab-active-indicator-height (default 32px)\n --md-navigation-tab-active-indicator-shape (default full-rounded)\n --md-navigation-tab-active-icon-color\n --md-navigation-tab-inactive-icon-color\n --md-navigation-tab-active-label-color\n --md-navigation-tab-inactive-label-color\n --md-navigation-tab-label-font (label-medium font shorthand)\n --md-navigation-tab-label-font-weight (active label weight; defaults 600)\n --md-navigation-tab-icon-size (default 24px)\n --md-navigation-tab-padding-block-start (default 5px — centers 54px content in 64px bar)\n --md-navigation-tab-padding-block-end (default 5px)\n --md-navigation-tab-hover-state-layer-color\n --md-navigation-tab-focus-state-layer-color\n --md-navigation-tab-pressed-state-layer-color\n --md-navigation-tab-badge-color\n --md-navigation-tab-badge-on-color\n --md-navigation-tab-disabled-opacity (default 0.38)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — base layout, sizing, focus\n ========================================================== */\n:host {\n --_indicator-color: var(\n --md-navigation-tab-active-indicator-color,\n var(--md-sys-color-secondary-container, #E8DEF8)\n );\n --_indicator-w: var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_indicator-h: var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));\n --_indicator-shape: var(\n --md-navigation-tab-active-indicator-shape,\n var(--md-sys-shape-corner-full, 9999px)\n );\n\n --_active-icon-color: var(\n --md-navigation-tab-active-icon-color,\n var(--md-sys-color-on-secondary-container, #1E192B)\n );\n --_inactive-icon-color: var(\n --md-navigation-tab-inactive-icon-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_active-label-color: var(\n --md-navigation-tab-active-label-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_inactive-label-color: var(\n --md-navigation-tab-inactive-label-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_icon-size: var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_pad-top: var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n --_pad-bottom: var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n\n --_hover-color: var(\n --md-navigation-tab-hover-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_focus-color: var(\n --md-navigation-tab-focus-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_pressed-color: var(\n --md-navigation-tab-pressed-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n\n --_badge-color: var(\n --md-navigation-tab-badge-color,\n var(--md-sys-color-error, #B3261E)\n );\n --_badge-on-color: var(\n --md-navigation-tab-badge-on-color,\n var(--md-sys-color-on-error, #FFFFFF)\n );\n\n --_disabled-opacity: var(--md-navigation-tab-disabled-opacity, 0.38);\n\n --_label-font: var(\n --md-navigation-tab-label-font,\n var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif)\n );\n --_label-size: var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));\n --_label-weight-active: var(--md-navigation-tab-label-font-weight, 600);\n\n --_motion-duration: var(--md-sys-motion-duration-short4, 200ms);\n --_motion-easing: var(\n --md-sys-motion-easing-emphasized-decelerate,\n cubic-bezier(0.05, 0.7, 0.1, 1)\n );\n\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n inline-size: 100%;\n min-inline-size: 48px; /* M3 minimum touch target */\n block-size: 100%;\n padding-block: var(--_pad-top) var(--_pad-bottom);\n box-sizing: border-box;\n cursor: pointer;\n position: relative;\n outline: none;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n color: var(--_inactive-icon-color);\n /* Color transitions are quick and additive — they don't trigger layout. */\n transition:\n color var(--_motion-duration) var(--_motion-easing);\n}\n\n:host(.md-navigation-tab--active) {\n color: var(--_active-icon-color);\n}\n\n/* ==========================================================\n 2. DISABLED STATE\n M3 nav-bar doesn't formally define disabled, but our API\n needs one — match the global disabled-content opacity.\n `--soft-disabled` shares the dim but stays keyboard-focusable\n (it keeps pointer-events + the focus ring) so screen-reader\n users can discover a temporarily-unavailable destination.\n ========================================================== */\n:host(.md-navigation-tab--disabled),\n:host(.md-navigation-tab--soft-disabled) {\n cursor: not-allowed;\n opacity: var(--_disabled-opacity);\n}\n\n:host(.md-navigation-tab--disabled) {\n pointer-events: none;\n}\n\n/* ==========================================================\n 3. STATE LAYER\n Spans the full hit-area so hover/focus/pressed feedback\n covers the whole tab — not just the active-indicator pill.\n Opacities come from the M3 state-layer tokens.\n ========================================================== */\n.md-navigation-tab__state-layer {\n position: absolute;\n inset: 0;\n background-color: currentColor;\n opacity: 0;\n border-radius: inherit;\n pointer-events: none;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_hover-color);\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_pressed-color);\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_focus-color);\n /* M3 nav-bar focus state-layer opacity is 0.10 (the global sys token is 0.12);\n keep a component override so it matches the spec regardless of the sys value. */\n opacity: var(--md-navigation-tab-focus-state-layer-opacity, 0.1);\n}\n\n/* Visible 3px focus ring per M3 accessibility guidance.\n Wraps the active-indicator pill (centered, rounded) rather than the whole\n tab: a full-tab inset outline gets clipped at the navigation bar's rounded\n corners, and `secondary` matches the focus-ring color used library-wide\n (the old full-tab ring used `primary`, which stood out from every other\n component). */\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after {\n content: '';\n position: absolute;\n inset: -4px;\n border: 3px solid var(--md-sys-color-secondary, #625B71);\n border-radius: var(--_indicator-shape, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n}\n\n/* ==========================================================\n 4. STACK CONTAINER\n The icon-container + indicator + label are stacked centered\n so the visual layout matches MD3 even when extra width is\n available.\n ========================================================== */\n.md-navigation-tab__container {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n /* M3 vertical item: active-indicator → label \"container between space\" = 6px.\n (The 24px icon centered in the 32px indicator yields the 4px icon inset.) */\n gap: max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));\n inline-size: 100%;\n pointer-events: none; /* Click goes through to host. */\n}\n\n/* ==========================================================\n 5. ACTIVE INDICATOR PILL\n Animates from a vertically-collapsed shape into the full\n 56×32px pill — per M3's emphasized-decelerate spec.\n ========================================================== */\n.md-navigation-tab__indicator {\n position: absolute;\n /* Aligned to the icon-container vertical box. */\n inset-block-start: 0;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n border-radius: var(--_indicator-shape);\n background-color: var(--_indicator-color);\n /* Start collapsed; grow on activation. */\n transform: scale(0, 1);\n transform-origin: center center;\n opacity: 0;\n transition:\n transform var(--_motion-duration) var(--_motion-easing),\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n pointer-events: none;\n}\n\n.md-navigation-tab__indicator--active {\n transform: scale(1, 1);\n opacity: 1;\n}\n\n/* ==========================================================\n 6. ICON CONTAINER & ICON\n The container is exactly the size of the active indicator\n so the indicator sits behind the icon at 100% coverage.\n ========================================================== */\n.md-navigation-tab__icon-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n pointer-events: none;\n}\n\n.md-navigation-tab__icon {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: var(--_icon-size);\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n line-height: 1;\n color: inherit;\n z-index: 1;\n transition: font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n/* Custom icons via slot=\"icon\" / \"active-icon\" (SVG, emoji, custom font):\n slotted light-DOM nodes don't inherit the shadow icon-span's sizing, so a\n bare <span>★</span> would render at the host font-size. Pin them to the 24px\n Material Symbols footprint, inherit the active/inactive icon color (so SVGs\n using currentColor tint correctly), and center within the box. */\n.md-navigation-tab__icon ::slotted(*) {\n /* Fixed 24px flex box so text glyphs (★, emoji) and SVGs share one footprint\n and center identically — a bare inline glyph otherwise gets a taller line\n box and rides off-center against an SVG's box. */\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 line-height: 1;\n /* Reset the icon span's Material Symbols font: slotted text/emoji inherit it\n through the flattened tree, but that icon font has no ★/emoji glyph and its\n line metrics drop the fallback glyph ~5px below center. A normal UI font\n centers them; authors slotting a custom icon font override this from light DOM. */\n font-family: var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);\n color: inherit;\n object-fit: contain;\n}\n\n/* Material Symbols variable-font: flip the FILL axis on active. */\n.md-navigation-tab__icon--filled {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* When Material Symbols is the icon font, the outlined font already\n gives us the inactive look. When Material Icons (legacy) is used,\n we still get the inactive look via the font family. */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;\n font-weight: normal;\n font-style: normal;\n letter-spacing: normal;\n text-transform: none;\n /* No `display` here: the element is also `.md-navigation-tab__icon`, which must\n stay an `inline-flex` centering box (this class is later in source with equal\n specificity, so an inline-block here would silently win and break centering of\n slotted custom icons — they'd sit on the text baseline ~5px low). */\n white-space: nowrap;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* ==========================================================\n 7. BADGES\n Two flavors per M3 spec:\n - small → 6px dot\n - large → numeric / textual capsule (16px min height)\n Both anchor to the top-right of the icon container.\n ========================================================== */\n.md-navigation-tab__badge {\n position: absolute;\n /* Above the icon — the icon glyph has z-index:1, so without this the SVG\n strokes paint over the badge (\"polluted\" badge). */\n z-index: 2;\n background-color: var(--_badge-color);\n color: var(--_badge-on-color);\n border-radius: var(--md-sys-shape-corner-full, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.md-navigation-tab__badge--small {\n inset-block-start: 2px;\n inset-inline-end: 14px;\n inline-size: 6px;\n block-size: 6px;\n}\n\n/* Centred on the icon corner. The old `inset-inline-start: 50%` + 4px margin\n anchored the badge to the middle of the icon box and shoved it right by a\n fixed amount, so a wider badge grew to the right instead of straddling the\n corner.\n\n THE CORNER IS THE GLYPH'S, NOT THE CONTAINER'S — which is what `inset: 0`\n still got wrong. The badge's positioning parent is the icon CONTAINER, and\n that is the active-indicator pill: `--_indicator-w` is 56px against a 24px\n glyph, so a badge pinned to its right edge floats 16px clear of the icon and\n reads as a separate object beside it rather than as a mark on it. Measured\n on a real bar: icon right edge at 285px, badge starting at 290px, a visible\n gap between them.\n\n Insetting by half the difference on each axis puts the badge's anchor exactly\n on the glyph's top-right corner, which `translate(50%, -50%)` then straddles.\n Both lengths are the component's own resolved variables, so this follows the\n density scale rather than pinning a number that is only right at density 0. */\n.md-navigation-tab__badge--large {\n inset-block-start: calc((var(--_indicator-h) - var(--_icon-size)) / 2);\n inset-inline-end: calc((var(--_indicator-w) - var(--_icon-size)) / 2);\n transform: translate(50%, -50%);\n min-inline-size: 16px;\n block-size: 16px;\n padding-inline: 4px;\n font: var(\n --md-sys-typescale-label-small-font,\n 500 11px/16px Roboto, sans-serif\n );\n letter-spacing: var(\n --md-sys-typescale-label-small-letter-spacing,\n 0.5px\n );\n}\n\n/* ==========================================================\n 8. LABEL\n label-medium typography per M3. Active label gains a\n slightly heavier weight to convey selection.\n ========================================================== */\n.md-navigation-tab__label {\n font: var(--_label-font);\n font-size: var(--_label-size);\n letter-spacing: var(\n --md-sys-typescale-label-medium-letter-spacing,\n 0.5px\n );\n color: var(--_inactive-label-color);\n max-inline-size: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-align: center;\n pointer-events: none;\n transition:\n color var(--md-sys-motion-duration-short2, 100ms) ease,\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(.md-navigation-tab--active) .md-navigation-tab__label {\n color: var(--_active-label-color);\n font-weight: var(--_label-weight-active);\n}\n\n/* When `labelBehavior=\"selected\"` keep the label slot in the layout\n but hide it visually for inactive tabs so heights stay constant. */\n.md-navigation-tab__label--hidden {\n opacity: 0;\n visibility: hidden;\n}\n\n/* When `labelBehavior=\"none\"` is applied on the host the label is\n not rendered at all — collapse the vertical padding so the icon\n sits centered in the row. */\n:host(.md-navigation-tab--label-hidden) {\n /* No label: center the 32px icon-container in the 64px bar → 16px each side. */\n --_pad-top: var(--md-sys-spacing-inset-lg, 16px);\n --_pad-bottom: var(--md-sys-spacing-inset-lg, 16px);\n justify-content: center;\n}\n\n:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container {\n justify-content: center;\n}\n\n/* ==========================================================\n 9. FORCED COLORS / REDUCED MOTION\n ========================================================== */\n@media (forced-colors: active) {\n :host {\n --_indicator-color: Highlight;\n --_active-icon-color: HighlightText;\n --_active-label-color: HighlightText;\n --_inactive-icon-color: ButtonText;\n --_inactive-label-color: ButtonText;\n }\n :host(:focus-visible:not(.md-navigation-tab--disabled)) {\n outline: 2px solid CanvasText;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n .md-navigation-tab__state-layer,\n .md-navigation-tab__indicator,\n .md-navigation-tab__icon,\n .md-navigation-tab__label {\n transition: none !important;\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\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\nexport type MdNavigationTabLabelBehavior = 'always' | 'selected' | 'none';\n\n/**\n * `md-navigation-tab` — a single destination inside `md-navigation-bar`.\n *\n * Renders an icon, an optional label, and an optional badge. Selecting\n * the tab swaps the icon to a filled variant (per M3 spec) and reveals\n * an \"active indicator\" pill behind the icon.\n *\n * References:\n * - {@link https://m3.material.io/components/navigation-bar/specs Specs}\n * - {@link https://m3.material.io/components/navigation-bar/accessibility Accessibility}\n *\n * @slot icon - Custom icon for the inactive state\n * (replaces the `icon` attribute).\n * @slot active-icon - Custom icon for the active state\n * (replaces the `active-icon` attribute).\n * @slot - Default slot for a custom label\n * (replaces the `label` attribute).\n *\n * @part container - The full tab hit-area / touch target.\n * @part indicator - The 56×32 pill that highlights the active icon.\n * @part state-layer - The hover/focus/pressed tint overlay.\n * @part icon-container - The 56×32 wrapper around the icon (badge anchor).\n * @part icon - The rendered icon glyph.\n * @part badge - The badge dot or text capsule (when present).\n * @part label - The destination label text.\n */\n@Component({\n tag: 'md-navigation-tab',\n styleUrl: 'md-navigation-tab.css',\n shadow: true,\n})\nexport class MdNavigationTab {\n @Element() el!: HTMLElement;\n\n /** Whether this destination is currently selected. */\n @Prop({ mutable: true, reflect: true }) active: boolean = false;\n\n /** Disable interaction. Disabled tabs are skipped by keyboard nav. */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /**\n * Soft-disable the destination: it cannot be activated or selected and is\n * announced as `aria-disabled`, but — unlike `disabled` — it stays\n * keyboard-reachable (the bar's arrow-key tour still lands on it) so\n * screen-reader users can discover a temporarily-unavailable destination.\n */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Destination label rendered below the icon. */\n @Prop() label: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when inactive.\n * Per M3 spec, inactive destinations use the outlined variant.\n */\n @Prop() icon: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when active.\n * Per M3 spec, active destinations use the filled variant.\n * Defaults to `icon` when empty (the same glyph in both states).\n */\n @Prop({ attribute: 'active-icon' }) activeIcon: string = '';\n\n /**\n * Show a small \"notification dot\" badge in the top-right of the icon.\n * Use when there are new items but no count is needed.\n */\n @Prop({ reflect: true }) badge: boolean = false;\n\n /**\n * Numeric / textual badge value (e.g. `\"3\"`, `\"99+\"`, `\"New\"`).\n * When set, the badge expands to a pill that accommodates the value\n * (M3 calls this the \"large badge\" variant).\n */\n @Prop({ attribute: 'badge-value' }) badgeValue: string = '';\n\n /**\n * Maximum value rendered when `badgeValue` is purely numeric. Values\n * greater than this render as `\"{max}+\"` (e.g. `99+`). Set to `0` to\n * disable the cap.\n */\n @Prop({ attribute: 'badge-max' }) badgeMax: number = 999;\n\n /**\n * When set, activating the tab also navigates to the URL — useful when\n * each destination is a full route. For SPA routing, intercept the native\n * `click` (call `preventDefault()`) or listen to the bar's `mdChange`;\n * navigation only occurs when `href` is truthy and the click isn't prevented.\n */\n @Prop() href: string = '';\n\n /** Link target (forwarded only when `href` is set). */\n @Prop() target: string = '';\n\n /**\n * Label visibility for this tab. Inherits from the parent\n * `md-navigation-bar`'s `label-behavior` when not set.\n *\n * Not reflected as an attribute — the parent bar uses\n * `getAttribute('label-behavior')` to detect *explicit* author\n * overrides, so reflecting the default would defeat that signal.\n */\n @Prop({ mutable: true, attribute: 'label-behavior' })\n labelBehavior: MdNavigationTabLabelBehavior = 'always';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fired when the tab is activated (click, Enter, or Space) and the tab is\n * not disabled. The parent `md-navigation-bar` listens for this to drive\n * selection; external code may also listen to detect per-tab activation\n * (including a re-click of the already-active tab, which does not emit\n * `mdChange` on the bar).\n */\n @Event() mdTabClick: EventEmitter<{ index: number }>;\n\n /** Internal — track focus-visible for the state layer + a11y. */\n @State() private focusVisible: boolean = false;\n\n // ─── Watchers ────────────────────────────────────────────────────\n\n @Watch('active')\n onActiveChange(active: boolean) {\n // Mirror the active state into aria-selected so the parent isn't\n // the sole writer (works in detached usage / docs without a bar).\n this.el.setAttribute('aria-selected', String(active));\n }\n\n @Watch('disabled')\n onDisabledChange() {\n this.syncAriaDisabled();\n }\n\n @Watch('softDisabled')\n onSoftDisabledChange() {\n this.syncAriaDisabled();\n }\n\n /** Activation/selection is blocked when either disabled flag is set. */\n private get interactionDisabled(): boolean {\n return this.disabled || this.softDisabled;\n }\n\n private syncAriaDisabled() {\n this.el.setAttribute('aria-disabled', String(this.interactionDisabled));\n }\n\n // ─── Lifecycle ───────────────────────────────────────────────────\n\n connectedCallback() {\n // Defaults — the bar may override these on mount.\n if (!this.el.hasAttribute('role')) this.el.setAttribute('role', 'tab');\n this.el.setAttribute('aria-selected', String(this.active));\n if (this.interactionDisabled) this.el.setAttribute('aria-disabled', 'true');\n if (!this.el.hasAttribute('tabindex')) {\n this.el.setAttribute('tabindex', this.active ? '0' : '-1');\n }\n }\n\n // ─── Public API ──────────────────────────────────────────────────\n\n /** Focus the tab programmatically (skip when disabled). */\n @Method()\n async focusEl(): Promise<void> {\n if (this.disabled) return;\n this.el.focus();\n }\n\n // ─── Internal helpers ────────────────────────────────────────────\n\n /** Locate this tab's index inside its parent navigation bar. */\n private resolveIndex(): number {\n const parent = this.el.parentElement;\n if (!parent) return -1;\n // Walk direct children rather than using `:scope > md-navigation-tab`\n // — the latter is unsupported by Stencil's mock-doc in spec tests.\n const siblings: HTMLElement[] = [];\n for (const child of Array.from(parent.children)) {\n if ((child as HTMLElement).tagName === 'MD-NAVIGATION-TAB') {\n siblings.push(child as HTMLElement);\n }\n }\n return siblings.indexOf(this.el);\n }\n\n private emitActivation() {\n const index = this.resolveIndex();\n this.mdTabClick.emit({ index });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.interactionDisabled) {\n // Block activation and stop the click from reaching the bar.\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.defaultPrevented) return; // SPA routers call preventDefault()\n this.emitActivation();\n this.maybeFollowHref();\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.interactionDisabled) return;\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') {\n e.preventDefault();\n triggerRipple(this.el);\n // Synthesize a native click so keyboard and pointer activation share one\n // path (bubbles to the bar + follows href).\n this.el.click();\n }\n };\n\n private maybeFollowHref() {\n const href = sanitizeHref(this.href);\n if (!href) return;\n if (typeof window === 'undefined') return;\n if (this.target === '_blank') {\n window.open(href, '_blank', SAFE_WINDOW_FEATURES);\n } else if (this.target) {\n /* A named target opens a new browsing context just like `_blank` does,\n so it needs the same opener severing. */\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n } else {\n window.location.assign(href);\n }\n }\n\n private handleFocus = () => {\n this.focusVisible = this.el.matches(':focus-visible');\n };\n\n private handleBlur = () => {\n this.focusVisible = false;\n };\n\n // ─── Rendering helpers ───────────────────────────────────────────\n\n private resolveLabelVisibility(): MdNavigationTabLabelBehavior {\n return this.labelBehavior;\n }\n\n private formatBadgeValue(): string {\n const raw = (this.badgeValue ?? '').trim();\n if (!raw) return '';\n if (this.badgeMax > 0) {\n const num = Number(raw);\n if (!Number.isNaN(num) && Number.isFinite(num) && num > this.badgeMax) {\n return `${this.badgeMax}+`;\n }\n }\n return raw;\n }\n\n private renderIcon() {\n const useActive = this.active && (this.activeIcon || this.icon);\n const filled = this.active;\n const glyph = useActive ? (this.activeIcon || this.icon) : this.icon;\n\n return (\n <span class=\"md-navigation-tab__icon-container\" part=\"icon-container\">\n <span\n class={{\n 'md-navigation-tab__icon': true,\n 'material-symbols-outlined': true,\n 'md-navigation-tab__icon--filled': filled,\n }}\n part=\"icon\"\n aria-hidden=\"true\"\n >\n {/* Custom-icon slots win over the icon attribute. */}\n {this.active ? <slot name=\"active-icon\">{glyph}</slot> : <slot name=\"icon\">{glyph}</slot>}\n </span>\n {this.renderBadge()}\n </span>\n );\n }\n\n private renderBadge() {\n if (!this.badge && !this.badgeValue) return null;\n const value = this.formatBadgeValue();\n const isLarge = value.length > 0;\n\n return (\n <span\n class={{\n 'md-navigation-tab__badge': true,\n 'md-navigation-tab__badge--small': !isLarge,\n 'md-navigation-tab__badge--large': isLarge,\n }}\n part=\"badge\"\n role=\"status\"\n aria-label={isLarge ? `${value} new` : 'New'}\n >\n {isLarge ? value : ''}\n </span>\n );\n }\n\n private renderLabel() {\n const visibility = this.resolveLabelVisibility();\n if (visibility === 'none') return null;\n\n // CSS handles hiding the label when visibility === 'selected' && !active,\n // so we still render it (preserves space + keeps accessible name stable).\n return (\n <span\n class={{\n 'md-navigation-tab__label': true,\n 'md-navigation-tab__label--hidden':\n visibility === 'selected' && !this.active,\n }}\n part=\"label\"\n >\n <slot>{this.label}</slot>\n </span>\n );\n }\n\n // ─── Render ──────────────────────────────────────────────────────\n\n render() {\n // Accessible name resolution: the host carries the label so the\n // `tab` role gets a stable accessible name. Icon-only mode still\n // exposes the textual `label` via aria-label.\n const accessibleLabel = this.label || undefined;\n const visibility = this.resolveLabelVisibility();\n const ariaLabel = visibility === 'none' ? accessibleLabel : undefined;\n\n return (\n <Host\n class={{\n 'md-navigation-tab': true,\n 'md-navigation-tab--active': this.active,\n 'md-navigation-tab--disabled': this.disabled,\n 'md-navigation-tab--soft-disabled': this.softDisabled && !this.disabled,\n 'md-navigation-tab--label-hidden': visibility === 'none',\n }}\n aria-label={ariaLabel}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n >\n <md-ripple disabled={this.interactionDisabled}></md-ripple>\n <span\n class=\"md-navigation-tab__state-layer\"\n part=\"state-layer\"\n aria-hidden=\"true\"\n data-focus-visible={this.focusVisible ? 'true' : null}\n ></span>\n <span\n class=\"md-navigation-tab__container\"\n part=\"container\"\n >\n <span\n class={{\n 'md-navigation-tab__indicator': true,\n 'md-navigation-tab__indicator--active': this.active,\n }}\n part=\"indicator\"\n aria-hidden=\"true\"\n ></span>\n {this.renderIcon()}\n {this.renderLabel()}\n </span>\n </Host>\n );\n }\n}\n"],"mappings":"qLAAA,MAAMA,EAAqB,IAAM,4/Q,MCgDpBC,EAAeC,EAAA,MAAAD,UAAAE,EAL5B,WAAAC,CAAAC,G,yGAS0CC,KAAAC,OAAkB,MAGjCD,KAAAE,SAAoB,MAQQF,KAAAG,aAAwB,MAGrEH,KAAAI,MAAgB,GAMhBJ,KAAAK,KAAe,GAOaL,KAAAM,WAAqB,GAMhCN,KAAAO,MAAiB,MAONP,KAAAQ,WAAqB,GAOvBR,KAAAS,SAAmB,IAQ7CT,KAAAU,KAAe,GAGfV,KAAAW,OAAiB,GAWzBX,KAAAY,cAA8C,SAOrBZ,KAAAa,QAAiC,EAYzCb,KAAAc,aAAwB,MAyEjCd,KAAAe,YAAeC,IACrB,GAAIhB,KAAKiB,oBAAqB,CAE5BD,EAAEE,iBACFF,EAAEG,kBACF,M,CAEF,GAAIH,EAAEI,iBAAkB,OACxBpB,KAAKqB,iBACLrB,KAAKsB,iBAAiB,EAGhBtB,KAAAuB,cAAiBP,IACvB,GAAIhB,KAAKiB,oBAAqB,OAC9B,GAAID,EAAEQ,MAAQ,SAAWR,EAAEQ,MAAQ,KAAOR,EAAEQ,MAAQ,WAAY,CAC9DR,EAAEE,iBACFO,EAAczB,KAAK0B,IAGnB1B,KAAK0B,GAAGC,O,GAmBJ3B,KAAA4B,YAAc,KACpB5B,KAAKc,aAAed,KAAK0B,GAAGG,QAAQ,iBAAiB,EAG/C7B,KAAA8B,WAAa,KACnB9B,KAAKc,aAAe,KAAK,CAwI5B,CAvPC,cAAAiB,CAAe9B,GAGbD,KAAK0B,GAAGM,aAAa,gBAAiBC,OAAOhC,G,CAI/C,gBAAAiC,GACElC,KAAKmC,kB,CAIP,oBAAAC,GACEpC,KAAKmC,kB,CAIP,uBAAYlB,GACV,OAAOjB,KAAKE,UAAYF,KAAKG,Y,CAGvB,gBAAAgC,GACNnC,KAAK0B,GAAGM,aAAa,gBAAiBC,OAAOjC,KAAKiB,qB,CAKpD,iBAAAoB,GAEE,IAAKrC,KAAK0B,GAAGY,aAAa,QAAStC,KAAK0B,GAAGM,aAAa,OAAQ,OAChEhC,KAAK0B,GAAGM,aAAa,gBAAiBC,OAAOjC,KAAKC,SAClD,GAAID,KAAKiB,oBAAqBjB,KAAK0B,GAAGM,aAAa,gBAAiB,QACpE,IAAKhC,KAAK0B,GAAGY,aAAa,YAAa,CACrCtC,KAAK0B,GAAGM,aAAa,WAAYhC,KAAKC,OAAS,IAAM,K,EAQzD,aAAMsC,GACJ,GAAIvC,KAAKE,SAAU,OACnBF,KAAK0B,GAAGc,O,CAMF,YAAAC,GACN,MAAMC,EAAS1C,KAAK0B,GAAGiB,cACvB,IAAKD,EAAQ,OAAO,EAGpB,MAAME,EAA0B,GAChC,IAAK,MAAMC,KAASC,MAAMC,KAAKL,EAAOM,UAAW,CAC/C,GAAKH,EAAsBI,UAAY,oBAAqB,CAC1DL,EAASM,KAAKL,E,EAGlB,OAAOD,EAASO,QAAQnD,KAAK0B,G,CAGvB,cAAAL,GACN,MAAM+B,EAAQpD,KAAKyC,eACnBzC,KAAKqD,WAAWC,KAAK,CAAEF,S,CA0BjB,eAAA9B,GACN,MAAMZ,EAAO6C,EAAavD,KAAKU,MAC/B,IAAKA,EAAM,OACX,UAAW8C,SAAW,YAAa,OACnC,GAAIxD,KAAKW,SAAW,SAAU,CAC5B6C,OAAOC,KAAK/C,EAAM,SAAUgD,E,MACvB,GAAI1D,KAAKW,OAAQ,CAGtB6C,OAAOC,KAAK/C,EAAMV,KAAKW,OAAQ+C,E,KAC1B,CACLF,OAAOG,SAASC,OAAOlD,E,EAcnB,sBAAAmD,GACN,OAAO7D,KAAKY,a,CAGN,gBAAAkD,GACN,MAAMC,GAAO/D,KAAKQ,YAAc,IAAIwD,OACpC,IAAKD,EAAK,MAAO,GACjB,GAAI/D,KAAKS,SAAW,EAAG,CACrB,MAAMwD,EAAMC,OAAOH,GACnB,IAAKG,OAAOC,MAAMF,IAAQC,OAAOE,SAASH,IAAQA,EAAMjE,KAAKS,SAAU,CACrE,MAAO,GAAGT,KAAKS,W,EAGnB,OAAOsD,C,CAGD,UAAAM,GACN,MAAMC,EAAYtE,KAAKC,SAAWD,KAAKM,YAAcN,KAAKK,MAC1D,MAAMkE,EAASvE,KAAKC,OACpB,MAAMuE,EAAQF,EAAatE,KAAKM,YAAcN,KAAKK,KAAQL,KAAKK,KAEhE,OACEoE,EAAA,QAAMC,MAAM,oCAAoCC,KAAK,kBACnDF,EAAA,QACEC,MAAO,CACL,0BAA2B,KAC3B,4BAA6B,KAC7B,kCAAmCH,GAErCI,KAAK,OAAM,cACC,QAGX3E,KAAKC,OAASwE,EAAA,QAAMG,KAAK,eAAeJ,GAAgBC,EAAA,QAAMG,KAAK,QAAQJ,IAE7ExE,KAAK6E,c,CAKJ,WAAAA,GACN,IAAK7E,KAAKO,QAAUP,KAAKQ,WAAY,OAAO,KAC5C,MAAMsE,EAAQ9E,KAAK8D,mBACnB,MAAMiB,EAAUD,EAAME,OAAS,EAE/B,OACEP,EAAA,QACEC,MAAO,CACL,2BAA4B,KAC5B,mCAAoCK,EACpC,kCAAmCA,GAErCJ,KAAK,QACLM,KAAK,SAAQ,aACDF,EAAU,GAAGD,QAAc,OAEtCC,EAAUD,EAAQ,G,CAKjB,WAAAI,GACN,MAAMC,EAAanF,KAAK6D,yBACxB,GAAIsB,IAAe,OAAQ,OAAO,KAIlC,OACEV,EAAA,QACEC,MAAO,CACL,2BAA4B,KAC5B,mCACES,IAAe,aAAenF,KAAKC,QAEvC0E,KAAK,SAELF,EAAA,YAAOzE,KAAKI,O,CAOlB,MAAAgF,GAIE,MAAMC,EAAkBrF,KAAKI,OAASkF,UACtC,MAAMH,EAAanF,KAAK6D,yBACxB,MAAM0B,EAAYJ,IAAe,OAASE,EAAkBC,UAE5D,OACEb,EAACe,EAAI,CAAAhE,IAAA,2CACHkD,MAAO,CACL,oBAAqB,KACrB,4BAA6B1E,KAAKC,OAClC,8BAA+BD,KAAKE,SACpC,mCAAoCF,KAAKG,eAAiBH,KAAKE,SAC/D,kCAAmCiF,IAAe,QACnD,aACWI,EACZE,QAASzF,KAAKe,YACd2E,UAAW1F,KAAKuB,cAChBoE,QAAS3F,KAAK4B,YACdgE,OAAQ5F,KAAK8B,YAEb2C,EAAA,aAAAjD,IAAA,2CAAWtB,SAAUF,KAAKiB,sBAC1BwD,EAAA,QAAAjD,IAAA,2CACEkD,MAAM,iCACNC,KAAK,cAAa,cACN,OAAM,qBACE3E,KAAKc,aAAe,OAAS,OAEnD2D,EAAA,QAAAjD,IAAA,2CACEkD,MAAM,+BACNC,KAAK,aAELF,EAAA,QAAAjD,IAAA,2CACEkD,MAAO,CACL,+BAAgC,KAChC,uCAAwC1E,KAAKC,QAE/C0E,KAAK,YAAW,cACJ,SAEb3E,KAAKqE,aACLrE,KAAKkF,e","ignoreList":[]}
@@ -2,7 +2,7 @@ import { r as registerInstance, c as createEvent, h, H as Host, g as getElement
2
2
  import { t as triggerRipple } from './ripple-DYBUr7K_.js';
3
3
  import { s as sanitizeHref, a as SAFE_WINDOW_FEATURES } from './url-BdEoSBtL.js';
4
4
 
5
- const mdNavigationTabCss = () => `:host{--_indicator-color:var( --md-navigation-tab-active-indicator-color, var(--md-sys-color-secondary-container, #E8DEF8) );--_indicator-w:var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));--_indicator-h:var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));--_indicator-shape:var( --md-navigation-tab-active-indicator-shape, var(--md-sys-shape-corner-full, 9999px) );--_active-icon-color:var( --md-navigation-tab-active-icon-color, var(--md-sys-color-on-secondary-container, #1E192B) );--_inactive-icon-color:var( --md-navigation-tab-inactive-icon-color, var(--md-sys-color-on-surface-variant, #49454F) );--_active-label-color:var( --md-navigation-tab-active-label-color, var(--md-sys-color-on-surface, #1C1B1F) );--_inactive-label-color:var( --md-navigation-tab-inactive-label-color, var(--md-sys-color-on-surface-variant, #49454F) );--_icon-size:var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));--_pad-top:var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_pad-bottom:var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_hover-color:var( --md-navigation-tab-hover-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_focus-color:var( --md-navigation-tab-focus-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_pressed-color:var( --md-navigation-tab-pressed-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_badge-color:var( --md-navigation-tab-badge-color, var(--md-sys-color-error, #B3261E) );--_badge-on-color:var( --md-navigation-tab-badge-on-color, var(--md-sys-color-on-error, #FFFFFF) );--_disabled-opacity:var(--md-navigation-tab-disabled-opacity, 0.38);--_label-font:var( --md-navigation-tab-label-font, var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif) );--_label-size:var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));--_label-weight-active:var(--md-navigation-tab-label-font-weight, 600);--_motion-duration:var(--md-sys-motion-duration-short4, 200ms);--_motion-easing:var( --md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1) );display:inline-flex;flex-direction:column;align-items:center;justify-content:flex-start;inline-size:100%;min-inline-size:48px;block-size:100%;padding-block:var(--_pad-top) var(--_pad-bottom);box-sizing:border-box;cursor:pointer;position:relative;outline:none;user-select:none;-webkit-tap-highlight-color:transparent;color:var(--_inactive-icon-color);transition:color var(--_motion-duration) var(--_motion-easing)}:host(.md-navigation-tab--active){color:var(--_active-icon-color)}:host(.md-navigation-tab--disabled),:host(.md-navigation-tab--soft-disabled){cursor:not-allowed;opacity:var(--_disabled-opacity)}:host(.md-navigation-tab--disabled){pointer-events:none}.md-navigation-tab__state-layer{position:absolute;inset:0;background-color:currentColor;opacity:0;border-radius:inherit;pointer-events:none;transition:opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_hover-color);opacity:var(--md-sys-state-hover-state-layer-opacity, 0.08)}:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_pressed-color);opacity:var(--md-sys-state-pressed-state-layer-opacity, 0.12)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer{background-color:var(--_focus-color);opacity:var(--md-navigation-tab-focus-state-layer-opacity, 0.1)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after{content:'';position:absolute;inset:-4px;border:3px solid var(--md-sys-color-secondary, #625B71);border-radius:var(--_indicator-shape, 9999px);box-sizing:border-box;pointer-events:none}.md-navigation-tab__container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));inline-size:100%;pointer-events:none;}.md-navigation-tab__indicator{position:absolute;inset-block-start:0;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);border-radius:var(--_indicator-shape);background-color:var(--_indicator-color);transform:scale(0, 1);transform-origin:center center;opacity:0;transition:transform var(--_motion-duration) var(--_motion-easing), opacity var(--md-sys-motion-duration-short2, 100ms) ease;pointer-events:none}.md-navigation-tab__indicator--active{transform:scale(1, 1);opacity:1}.md-navigation-tab__icon-container{position:relative;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);pointer-events:none}.md-navigation-tab__icon{position:relative;display:inline-flex;align-items:center;justify-content:center;font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size);line-height:1;color:inherit;z-index:1;transition:font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease}.md-navigation-tab__icon ::slotted(*){display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_icon-size);block-size:var(--_icon-size);font-size:var(--_icon-size);line-height:1;font-family:var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);color:inherit;object-fit:contain}.md-navigation-tab__icon--filled{font-variation-settings:'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24}.material-symbols-outlined{font-family:var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;font-weight:normal;font-style:normal;letter-spacing:normal;text-transform:none;white-space:nowrap;direction:ltr;font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-variation-settings:'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24}.md-navigation-tab__badge{position:absolute;z-index:2;background-color:var(--_badge-color);color:var(--_badge-on-color);border-radius:var(--md-sys-shape-corner-full, 9999px);box-sizing:border-box;pointer-events:none;display:inline-flex;align-items:center;justify-content:center}.md-navigation-tab__badge--small{inset-block-start:2px;inset-inline-end:14px;inline-size:6px;block-size:6px}.md-navigation-tab__badge--large{inset-block-start:0;inset-inline-end:0;transform:translate(50%, -50%);min-inline-size:16px;block-size:16px;padding-inline:4px;font:var( --md-sys-typescale-label-small-font, 500 11px/16px Roboto, sans-serif );letter-spacing:var( --md-sys-typescale-label-small-letter-spacing, 0.5px )}.md-navigation-tab__label{font:var(--_label-font);font-size:var(--_label-size);letter-spacing:var( --md-sys-typescale-label-medium-letter-spacing, 0.5px );color:var(--_inactive-label-color);max-inline-size:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center;pointer-events:none;transition:color var(--md-sys-motion-duration-short2, 100ms) ease, opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(.md-navigation-tab--active) .md-navigation-tab__label{color:var(--_active-label-color);font-weight:var(--_label-weight-active)}.md-navigation-tab__label--hidden{opacity:0;visibility:hidden}:host(.md-navigation-tab--label-hidden){--_pad-top:var(--md-sys-spacing-inset-lg, 16px);--_pad-bottom:var(--md-sys-spacing-inset-lg, 16px);justify-content:center}:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container{justify-content:center}@media (forced-colors: active){:host{--_indicator-color:Highlight;--_active-icon-color:HighlightText;--_active-label-color:HighlightText;--_inactive-icon-color:ButtonText;--_inactive-label-color:ButtonText}:host(:focus-visible:not(.md-navigation-tab--disabled)){outline:2px solid CanvasText}}@media (prefers-reduced-motion: reduce){:host,.md-navigation-tab__state-layer,.md-navigation-tab__indicator,.md-navigation-tab__icon,.md-navigation-tab__label{transition:none !important}}: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}:host([hidden]){display:none !important}`;
5
+ const mdNavigationTabCss = () => `:host{--_indicator-color:var( --md-navigation-tab-active-indicator-color, var(--md-sys-color-secondary-container, #E8DEF8) );--_indicator-w:var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));--_indicator-h:var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));--_indicator-shape:var( --md-navigation-tab-active-indicator-shape, var(--md-sys-shape-corner-full, 9999px) );--_active-icon-color:var( --md-navigation-tab-active-icon-color, var(--md-sys-color-on-secondary-container, #1E192B) );--_inactive-icon-color:var( --md-navigation-tab-inactive-icon-color, var(--md-sys-color-on-surface-variant, #49454F) );--_active-label-color:var( --md-navigation-tab-active-label-color, var(--md-sys-color-on-surface, #1C1B1F) );--_inactive-label-color:var( --md-navigation-tab-inactive-label-color, var(--md-sys-color-on-surface-variant, #49454F) );--_icon-size:var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));--_pad-top:var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_pad-bottom:var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));--_hover-color:var( --md-navigation-tab-hover-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_focus-color:var( --md-navigation-tab-focus-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_pressed-color:var( --md-navigation-tab-pressed-state-layer-color, var(--md-sys-color-on-surface, #1C1B1F) );--_badge-color:var( --md-navigation-tab-badge-color, var(--md-sys-color-error, #B3261E) );--_badge-on-color:var( --md-navigation-tab-badge-on-color, var(--md-sys-color-on-error, #FFFFFF) );--_disabled-opacity:var(--md-navigation-tab-disabled-opacity, 0.38);--_label-font:var( --md-navigation-tab-label-font, var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif) );--_label-size:var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));--_label-weight-active:var(--md-navigation-tab-label-font-weight, 600);--_motion-duration:var(--md-sys-motion-duration-short4, 200ms);--_motion-easing:var( --md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1) );display:inline-flex;flex-direction:column;align-items:center;justify-content:flex-start;inline-size:100%;min-inline-size:48px;block-size:100%;padding-block:var(--_pad-top) var(--_pad-bottom);box-sizing:border-box;cursor:pointer;position:relative;outline:none;user-select:none;-webkit-tap-highlight-color:transparent;color:var(--_inactive-icon-color);transition:color var(--_motion-duration) var(--_motion-easing)}:host(.md-navigation-tab--active){color:var(--_active-icon-color)}:host(.md-navigation-tab--disabled),:host(.md-navigation-tab--soft-disabled){cursor:not-allowed;opacity:var(--_disabled-opacity)}:host(.md-navigation-tab--disabled){pointer-events:none}.md-navigation-tab__state-layer{position:absolute;inset:0;background-color:currentColor;opacity:0;border-radius:inherit;pointer-events:none;transition:opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_hover-color);opacity:var(--md-sys-state-hover-state-layer-opacity, 0.08)}:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer{background-color:var(--_pressed-color);opacity:var(--md-sys-state-pressed-state-layer-opacity, 0.12)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer{background-color:var(--_focus-color);opacity:var(--md-navigation-tab-focus-state-layer-opacity, 0.1)}:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after{content:'';position:absolute;inset:-4px;border:3px solid var(--md-sys-color-secondary, #625B71);border-radius:var(--_indicator-shape, 9999px);box-sizing:border-box;pointer-events:none}.md-navigation-tab__container{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));inline-size:100%;pointer-events:none;}.md-navigation-tab__indicator{position:absolute;inset-block-start:0;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);border-radius:var(--_indicator-shape);background-color:var(--_indicator-color);transform:scale(0, 1);transform-origin:center center;opacity:0;transition:transform var(--_motion-duration) var(--_motion-easing), opacity var(--md-sys-motion-duration-short2, 100ms) ease;pointer-events:none}.md-navigation-tab__indicator--active{transform:scale(1, 1);opacity:1}.md-navigation-tab__icon-container{position:relative;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_indicator-w);block-size:var(--_indicator-h);pointer-events:none}.md-navigation-tab__icon{position:relative;display:inline-flex;align-items:center;justify-content:center;font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size);line-height:1;color:inherit;z-index:1;transition:font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease}.md-navigation-tab__icon ::slotted(*){display:inline-flex;align-items:center;justify-content:center;inline-size:var(--_icon-size);block-size:var(--_icon-size);font-size:var(--_icon-size);line-height:1;font-family:var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);color:inherit;object-fit:contain}.md-navigation-tab__icon--filled{font-variation-settings:'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24}.material-symbols-outlined{font-family:var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;font-weight:normal;font-style:normal;letter-spacing:normal;text-transform:none;white-space:nowrap;direction:ltr;font-feature-settings:'liga';-webkit-font-smoothing:antialiased;font-variation-settings:'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24}.md-navigation-tab__badge{position:absolute;z-index:2;background-color:var(--_badge-color);color:var(--_badge-on-color);border-radius:var(--md-sys-shape-corner-full, 9999px);box-sizing:border-box;pointer-events:none;display:inline-flex;align-items:center;justify-content:center}.md-navigation-tab__badge--small{inset-block-start:2px;inset-inline-end:14px;inline-size:6px;block-size:6px}.md-navigation-tab__badge--large{inset-block-start:calc((var(--_indicator-h) - var(--_icon-size)) / 2);inset-inline-end:calc((var(--_indicator-w) - var(--_icon-size)) / 2);transform:translate(50%, -50%);min-inline-size:16px;block-size:16px;padding-inline:4px;font:var( --md-sys-typescale-label-small-font, 500 11px/16px Roboto, sans-serif );letter-spacing:var( --md-sys-typescale-label-small-letter-spacing, 0.5px )}.md-navigation-tab__label{font:var(--_label-font);font-size:var(--_label-size);letter-spacing:var( --md-sys-typescale-label-medium-letter-spacing, 0.5px );color:var(--_inactive-label-color);max-inline-size:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center;pointer-events:none;transition:color var(--md-sys-motion-duration-short2, 100ms) ease, opacity var(--md-sys-motion-duration-short2, 100ms) ease}:host(.md-navigation-tab--active) .md-navigation-tab__label{color:var(--_active-label-color);font-weight:var(--_label-weight-active)}.md-navigation-tab__label--hidden{opacity:0;visibility:hidden}:host(.md-navigation-tab--label-hidden){--_pad-top:var(--md-sys-spacing-inset-lg, 16px);--_pad-bottom:var(--md-sys-spacing-inset-lg, 16px);justify-content:center}:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container{justify-content:center}@media (forced-colors: active){:host{--_indicator-color:Highlight;--_active-icon-color:HighlightText;--_active-label-color:HighlightText;--_inactive-icon-color:ButtonText;--_inactive-label-color:ButtonText}:host(:focus-visible:not(.md-navigation-tab--disabled)){outline:2px solid CanvasText}}@media (prefers-reduced-motion: reduce){:host,.md-navigation-tab__state-layer,.md-navigation-tab__indicator,.md-navigation-tab__icon,.md-navigation-tab__label{transition:none !important}}: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}:host([hidden]){display:none !important}`;
6
6
 
7
7
  const MdNavigationTab = class {
8
8
  constructor(hostRef) {
@@ -1 +1 @@
1
- {"version":3,"file":"md-navigation-tab.entry.js","sources":["src/components/md-navigation-tab/md-navigation-tab.css?tag=md-navigation-tab&encapsulation=shadow","src/components/md-navigation-tab/md-navigation-tab.tsx"],"sourcesContent":["/* ==========================================================\n md-navigation-tab — Material Design 3 Navigation Bar Item\n Spec: https://m3.material.io/components/navigation-bar/specs\n A11y: https://m3.material.io/components/navigation-bar/accessibility\n\n Anatomy:\n - State layer (hover / focus / pressed tint)\n - Active indicator (56×32 secondary-container pill)\n - Icon (outlined inactive, filled active)\n - Label (label-medium type)\n - Badge (small dot or large numeric capsule)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-navigation-tab-active-indicator-color\n --md-navigation-tab-active-indicator-width (default 56px)\n --md-navigation-tab-active-indicator-height (default 32px)\n --md-navigation-tab-active-indicator-shape (default full-rounded)\n --md-navigation-tab-active-icon-color\n --md-navigation-tab-inactive-icon-color\n --md-navigation-tab-active-label-color\n --md-navigation-tab-inactive-label-color\n --md-navigation-tab-label-font (label-medium font shorthand)\n --md-navigation-tab-label-font-weight (active label weight; defaults 600)\n --md-navigation-tab-icon-size (default 24px)\n --md-navigation-tab-padding-block-start (default 5px — centers 54px content in 64px bar)\n --md-navigation-tab-padding-block-end (default 5px)\n --md-navigation-tab-hover-state-layer-color\n --md-navigation-tab-focus-state-layer-color\n --md-navigation-tab-pressed-state-layer-color\n --md-navigation-tab-badge-color\n --md-navigation-tab-badge-on-color\n --md-navigation-tab-disabled-opacity (default 0.38)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — base layout, sizing, focus\n ========================================================== */\n:host {\n --_indicator-color: var(\n --md-navigation-tab-active-indicator-color,\n var(--md-sys-color-secondary-container, #E8DEF8)\n );\n --_indicator-w: var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_indicator-h: var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));\n --_indicator-shape: var(\n --md-navigation-tab-active-indicator-shape,\n var(--md-sys-shape-corner-full, 9999px)\n );\n\n --_active-icon-color: var(\n --md-navigation-tab-active-icon-color,\n var(--md-sys-color-on-secondary-container, #1E192B)\n );\n --_inactive-icon-color: var(\n --md-navigation-tab-inactive-icon-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_active-label-color: var(\n --md-navigation-tab-active-label-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_inactive-label-color: var(\n --md-navigation-tab-inactive-label-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_icon-size: var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_pad-top: var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n --_pad-bottom: var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n\n --_hover-color: var(\n --md-navigation-tab-hover-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_focus-color: var(\n --md-navigation-tab-focus-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_pressed-color: var(\n --md-navigation-tab-pressed-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n\n --_badge-color: var(\n --md-navigation-tab-badge-color,\n var(--md-sys-color-error, #B3261E)\n );\n --_badge-on-color: var(\n --md-navigation-tab-badge-on-color,\n var(--md-sys-color-on-error, #FFFFFF)\n );\n\n --_disabled-opacity: var(--md-navigation-tab-disabled-opacity, 0.38);\n\n --_label-font: var(\n --md-navigation-tab-label-font,\n var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif)\n );\n --_label-size: var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));\n --_label-weight-active: var(--md-navigation-tab-label-font-weight, 600);\n\n --_motion-duration: var(--md-sys-motion-duration-short4, 200ms);\n --_motion-easing: var(\n --md-sys-motion-easing-emphasized-decelerate,\n cubic-bezier(0.05, 0.7, 0.1, 1)\n );\n\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n inline-size: 100%;\n min-inline-size: 48px; /* M3 minimum touch target */\n block-size: 100%;\n padding-block: var(--_pad-top) var(--_pad-bottom);\n box-sizing: border-box;\n cursor: pointer;\n position: relative;\n outline: none;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n color: var(--_inactive-icon-color);\n /* Color transitions are quick and additive — they don't trigger layout. */\n transition:\n color var(--_motion-duration) var(--_motion-easing);\n}\n\n:host(.md-navigation-tab--active) {\n color: var(--_active-icon-color);\n}\n\n/* ==========================================================\n 2. DISABLED STATE\n M3 nav-bar doesn't formally define disabled, but our API\n needs one — match the global disabled-content opacity.\n `--soft-disabled` shares the dim but stays keyboard-focusable\n (it keeps pointer-events + the focus ring) so screen-reader\n users can discover a temporarily-unavailable destination.\n ========================================================== */\n:host(.md-navigation-tab--disabled),\n:host(.md-navigation-tab--soft-disabled) {\n cursor: not-allowed;\n opacity: var(--_disabled-opacity);\n}\n\n:host(.md-navigation-tab--disabled) {\n pointer-events: none;\n}\n\n/* ==========================================================\n 3. STATE LAYER\n Spans the full hit-area so hover/focus/pressed feedback\n covers the whole tab — not just the active-indicator pill.\n Opacities come from the M3 state-layer tokens.\n ========================================================== */\n.md-navigation-tab__state-layer {\n position: absolute;\n inset: 0;\n background-color: currentColor;\n opacity: 0;\n border-radius: inherit;\n pointer-events: none;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_hover-color);\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_pressed-color);\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_focus-color);\n /* M3 nav-bar focus state-layer opacity is 0.10 (the global sys token is 0.12);\n keep a component override so it matches the spec regardless of the sys value. */\n opacity: var(--md-navigation-tab-focus-state-layer-opacity, 0.1);\n}\n\n/* Visible 3px focus ring per M3 accessibility guidance.\n Wraps the active-indicator pill (centered, rounded) rather than the whole\n tab: a full-tab inset outline gets clipped at the navigation bar's rounded\n corners, and `secondary` matches the focus-ring color used library-wide\n (the old full-tab ring used `primary`, which stood out from every other\n component). */\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after {\n content: '';\n position: absolute;\n inset: -4px;\n border: 3px solid var(--md-sys-color-secondary, #625B71);\n border-radius: var(--_indicator-shape, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n}\n\n/* ==========================================================\n 4. STACK CONTAINER\n The icon-container + indicator + label are stacked centered\n so the visual layout matches MD3 even when extra width is\n available.\n ========================================================== */\n.md-navigation-tab__container {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n /* M3 vertical item: active-indicator → label \"container between space\" = 6px.\n (The 24px icon centered in the 32px indicator yields the 4px icon inset.) */\n gap: max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));\n inline-size: 100%;\n pointer-events: none; /* Click goes through to host. */\n}\n\n/* ==========================================================\n 5. ACTIVE INDICATOR PILL\n Animates from a vertically-collapsed shape into the full\n 56×32px pill — per M3's emphasized-decelerate spec.\n ========================================================== */\n.md-navigation-tab__indicator {\n position: absolute;\n /* Aligned to the icon-container vertical box. */\n inset-block-start: 0;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n border-radius: var(--_indicator-shape);\n background-color: var(--_indicator-color);\n /* Start collapsed; grow on activation. */\n transform: scale(0, 1);\n transform-origin: center center;\n opacity: 0;\n transition:\n transform var(--_motion-duration) var(--_motion-easing),\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n pointer-events: none;\n}\n\n.md-navigation-tab__indicator--active {\n transform: scale(1, 1);\n opacity: 1;\n}\n\n/* ==========================================================\n 6. ICON CONTAINER & ICON\n The container is exactly the size of the active indicator\n so the indicator sits behind the icon at 100% coverage.\n ========================================================== */\n.md-navigation-tab__icon-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n pointer-events: none;\n}\n\n.md-navigation-tab__icon {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: var(--_icon-size);\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n line-height: 1;\n color: inherit;\n z-index: 1;\n transition: font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n/* Custom icons via slot=\"icon\" / \"active-icon\" (SVG, emoji, custom font):\n slotted light-DOM nodes don't inherit the shadow icon-span's sizing, so a\n bare <span>★</span> would render at the host font-size. Pin them to the 24px\n Material Symbols footprint, inherit the active/inactive icon color (so SVGs\n using currentColor tint correctly), and center within the box. */\n.md-navigation-tab__icon ::slotted(*) {\n /* Fixed 24px flex box so text glyphs (★, emoji) and SVGs share one footprint\n and center identically — a bare inline glyph otherwise gets a taller line\n box and rides off-center against an SVG's box. */\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 line-height: 1;\n /* Reset the icon span's Material Symbols font: slotted text/emoji inherit it\n through the flattened tree, but that icon font has no ★/emoji glyph and its\n line metrics drop the fallback glyph ~5px below center. A normal UI font\n centers them; authors slotting a custom icon font override this from light DOM. */\n font-family: var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);\n color: inherit;\n object-fit: contain;\n}\n\n/* Material Symbols variable-font: flip the FILL axis on active. */\n.md-navigation-tab__icon--filled {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* When Material Symbols is the icon font, the outlined font already\n gives us the inactive look. When Material Icons (legacy) is used,\n we still get the inactive look via the font family. */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;\n font-weight: normal;\n font-style: normal;\n letter-spacing: normal;\n text-transform: none;\n /* No `display` here: the element is also `.md-navigation-tab__icon`, which must\n stay an `inline-flex` centering box (this class is later in source with equal\n specificity, so an inline-block here would silently win and break centering of\n slotted custom icons — they'd sit on the text baseline ~5px low). */\n white-space: nowrap;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* ==========================================================\n 7. BADGES\n Two flavors per M3 spec:\n - small → 6px dot\n - large → numeric / textual capsule (16px min height)\n Both anchor to the top-right of the icon container.\n ========================================================== */\n.md-navigation-tab__badge {\n position: absolute;\n /* Above the icon — the icon glyph has z-index:1, so without this the SVG\n strokes paint over the badge (\"polluted\" badge). */\n z-index: 2;\n background-color: var(--_badge-color);\n color: var(--_badge-on-color);\n border-radius: var(--md-sys-shape-corner-full, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.md-navigation-tab__badge--small {\n inset-block-start: 2px;\n inset-inline-end: 14px;\n inline-size: 6px;\n block-size: 6px;\n}\n\n/* Centred on the icon corner, like md-tab and md-navigation-rail-tab. The old\n `inset-inline-start: 50%` + 4px margin anchored the badge to the middle of the\n icon box and shoved it right by a fixed amount, so a wider badge grew to the\n right instead of straddling the corner. */\n.md-navigation-tab__badge--large {\n inset-block-start: 0;\n inset-inline-end: 0;\n transform: translate(50%, -50%);\n min-inline-size: 16px;\n block-size: 16px;\n padding-inline: 4px;\n font: var(\n --md-sys-typescale-label-small-font,\n 500 11px/16px Roboto, sans-serif\n );\n letter-spacing: var(\n --md-sys-typescale-label-small-letter-spacing,\n 0.5px\n );\n}\n\n/* ==========================================================\n 8. LABEL\n label-medium typography per M3. Active label gains a\n slightly heavier weight to convey selection.\n ========================================================== */\n.md-navigation-tab__label {\n font: var(--_label-font);\n font-size: var(--_label-size);\n letter-spacing: var(\n --md-sys-typescale-label-medium-letter-spacing,\n 0.5px\n );\n color: var(--_inactive-label-color);\n max-inline-size: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-align: center;\n pointer-events: none;\n transition:\n color var(--md-sys-motion-duration-short2, 100ms) ease,\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(.md-navigation-tab--active) .md-navigation-tab__label {\n color: var(--_active-label-color);\n font-weight: var(--_label-weight-active);\n}\n\n/* When `labelBehavior=\"selected\"` keep the label slot in the layout\n but hide it visually for inactive tabs so heights stay constant. */\n.md-navigation-tab__label--hidden {\n opacity: 0;\n visibility: hidden;\n}\n\n/* When `labelBehavior=\"none\"` is applied on the host the label is\n not rendered at all — collapse the vertical padding so the icon\n sits centered in the row. */\n:host(.md-navigation-tab--label-hidden) {\n /* No label: center the 32px icon-container in the 64px bar → 16px each side. */\n --_pad-top: var(--md-sys-spacing-inset-lg, 16px);\n --_pad-bottom: var(--md-sys-spacing-inset-lg, 16px);\n justify-content: center;\n}\n\n:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container {\n justify-content: center;\n}\n\n/* ==========================================================\n 9. FORCED COLORS / REDUCED MOTION\n ========================================================== */\n@media (forced-colors: active) {\n :host {\n --_indicator-color: Highlight;\n --_active-icon-color: HighlightText;\n --_active-label-color: HighlightText;\n --_inactive-icon-color: ButtonText;\n --_inactive-label-color: ButtonText;\n }\n :host(:focus-visible:not(.md-navigation-tab--disabled)) {\n outline: 2px solid CanvasText;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n .md-navigation-tab__state-layer,\n .md-navigation-tab__indicator,\n .md-navigation-tab__icon,\n .md-navigation-tab__label {\n transition: none !important;\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\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\nexport type MdNavigationTabLabelBehavior = 'always' | 'selected' | 'none';\n\n/**\n * `md-navigation-tab` — a single destination inside `md-navigation-bar`.\n *\n * Renders an icon, an optional label, and an optional badge. Selecting\n * the tab swaps the icon to a filled variant (per M3 spec) and reveals\n * an \"active indicator\" pill behind the icon.\n *\n * References:\n * - {@link https://m3.material.io/components/navigation-bar/specs Specs}\n * - {@link https://m3.material.io/components/navigation-bar/accessibility Accessibility}\n *\n * @slot icon - Custom icon for the inactive state\n * (replaces the `icon` attribute).\n * @slot active-icon - Custom icon for the active state\n * (replaces the `active-icon` attribute).\n * @slot - Default slot for a custom label\n * (replaces the `label` attribute).\n *\n * @part container - The full tab hit-area / touch target.\n * @part indicator - The 56×32 pill that highlights the active icon.\n * @part state-layer - The hover/focus/pressed tint overlay.\n * @part icon-container - The 56×32 wrapper around the icon (badge anchor).\n * @part icon - The rendered icon glyph.\n * @part badge - The badge dot or text capsule (when present).\n * @part label - The destination label text.\n */\n@Component({\n tag: 'md-navigation-tab',\n styleUrl: 'md-navigation-tab.css',\n shadow: true,\n})\nexport class MdNavigationTab {\n @Element() el!: HTMLElement;\n\n /** Whether this destination is currently selected. */\n @Prop({ mutable: true, reflect: true }) active: boolean = false;\n\n /** Disable interaction. Disabled tabs are skipped by keyboard nav. */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /**\n * Soft-disable the destination: it cannot be activated or selected and is\n * announced as `aria-disabled`, but — unlike `disabled` — it stays\n * keyboard-reachable (the bar's arrow-key tour still lands on it) so\n * screen-reader users can discover a temporarily-unavailable destination.\n */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Destination label rendered below the icon. */\n @Prop() label: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when inactive.\n * Per M3 spec, inactive destinations use the outlined variant.\n */\n @Prop() icon: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when active.\n * Per M3 spec, active destinations use the filled variant.\n * Defaults to `icon` when empty (the same glyph in both states).\n */\n @Prop({ attribute: 'active-icon' }) activeIcon: string = '';\n\n /**\n * Show a small \"notification dot\" badge in the top-right of the icon.\n * Use when there are new items but no count is needed.\n */\n @Prop({ reflect: true }) badge: boolean = false;\n\n /**\n * Numeric / textual badge value (e.g. `\"3\"`, `\"99+\"`, `\"New\"`).\n * When set, the badge expands to a pill that accommodates the value\n * (M3 calls this the \"large badge\" variant).\n */\n @Prop({ attribute: 'badge-value' }) badgeValue: string = '';\n\n /**\n * Maximum value rendered when `badgeValue` is purely numeric. Values\n * greater than this render as `\"{max}+\"` (e.g. `99+`). Set to `0` to\n * disable the cap.\n */\n @Prop({ attribute: 'badge-max' }) badgeMax: number = 999;\n\n /**\n * When set, activating the tab also navigates to the URL — useful when\n * each destination is a full route. For SPA routing, intercept the native\n * `click` (call `preventDefault()`) or listen to the bar's `mdChange`;\n * navigation only occurs when `href` is truthy and the click isn't prevented.\n */\n @Prop() href: string = '';\n\n /** Link target (forwarded only when `href` is set). */\n @Prop() target: string = '';\n\n /**\n * Label visibility for this tab. Inherits from the parent\n * `md-navigation-bar`'s `label-behavior` when not set.\n *\n * Not reflected as an attribute — the parent bar uses\n * `getAttribute('label-behavior')` to detect *explicit* author\n * overrides, so reflecting the default would defeat that signal.\n */\n @Prop({ mutable: true, attribute: 'label-behavior' })\n labelBehavior: MdNavigationTabLabelBehavior = 'always';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fired when the tab is activated (click, Enter, or Space) and the tab is\n * not disabled. The parent `md-navigation-bar` listens for this to drive\n * selection; external code may also listen to detect per-tab activation\n * (including a re-click of the already-active tab, which does not emit\n * `mdChange` on the bar).\n */\n @Event() mdTabClick: EventEmitter<{ index: number }>;\n\n /** Internal — track focus-visible for the state layer + a11y. */\n @State() private focusVisible: boolean = false;\n\n // ─── Watchers ────────────────────────────────────────────────────\n\n @Watch('active')\n onActiveChange(active: boolean) {\n // Mirror the active state into aria-selected so the parent isn't\n // the sole writer (works in detached usage / docs without a bar).\n this.el.setAttribute('aria-selected', String(active));\n }\n\n @Watch('disabled')\n onDisabledChange() {\n this.syncAriaDisabled();\n }\n\n @Watch('softDisabled')\n onSoftDisabledChange() {\n this.syncAriaDisabled();\n }\n\n /** Activation/selection is blocked when either disabled flag is set. */\n private get interactionDisabled(): boolean {\n return this.disabled || this.softDisabled;\n }\n\n private syncAriaDisabled() {\n this.el.setAttribute('aria-disabled', String(this.interactionDisabled));\n }\n\n // ─── Lifecycle ───────────────────────────────────────────────────\n\n connectedCallback() {\n // Defaults — the bar may override these on mount.\n if (!this.el.hasAttribute('role')) this.el.setAttribute('role', 'tab');\n this.el.setAttribute('aria-selected', String(this.active));\n if (this.interactionDisabled) this.el.setAttribute('aria-disabled', 'true');\n if (!this.el.hasAttribute('tabindex')) {\n this.el.setAttribute('tabindex', this.active ? '0' : '-1');\n }\n }\n\n // ─── Public API ──────────────────────────────────────────────────\n\n /** Focus the tab programmatically (skip when disabled). */\n @Method()\n async focusEl(): Promise<void> {\n if (this.disabled) return;\n this.el.focus();\n }\n\n // ─── Internal helpers ────────────────────────────────────────────\n\n /** Locate this tab's index inside its parent navigation bar. */\n private resolveIndex(): number {\n const parent = this.el.parentElement;\n if (!parent) return -1;\n // Walk direct children rather than using `:scope > md-navigation-tab`\n // — the latter is unsupported by Stencil's mock-doc in spec tests.\n const siblings: HTMLElement[] = [];\n for (const child of Array.from(parent.children)) {\n if ((child as HTMLElement).tagName === 'MD-NAVIGATION-TAB') {\n siblings.push(child as HTMLElement);\n }\n }\n return siblings.indexOf(this.el);\n }\n\n private emitActivation() {\n const index = this.resolveIndex();\n this.mdTabClick.emit({ index });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.interactionDisabled) {\n // Block activation and stop the click from reaching the bar.\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.defaultPrevented) return; // SPA routers call preventDefault()\n this.emitActivation();\n this.maybeFollowHref();\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.interactionDisabled) return;\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') {\n e.preventDefault();\n triggerRipple(this.el);\n // Synthesize a native click so keyboard and pointer activation share one\n // path (bubbles to the bar + follows href).\n this.el.click();\n }\n };\n\n private maybeFollowHref() {\n const href = sanitizeHref(this.href);\n if (!href) return;\n if (typeof window === 'undefined') return;\n if (this.target === '_blank') {\n window.open(href, '_blank', SAFE_WINDOW_FEATURES);\n } else if (this.target) {\n /* A named target opens a new browsing context just like `_blank` does,\n so it needs the same opener severing. */\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n } else {\n window.location.assign(href);\n }\n }\n\n private handleFocus = () => {\n this.focusVisible = this.el.matches(':focus-visible');\n };\n\n private handleBlur = () => {\n this.focusVisible = false;\n };\n\n // ─── Rendering helpers ───────────────────────────────────────────\n\n private resolveLabelVisibility(): MdNavigationTabLabelBehavior {\n return this.labelBehavior;\n }\n\n private formatBadgeValue(): string {\n const raw = (this.badgeValue ?? '').trim();\n if (!raw) return '';\n if (this.badgeMax > 0) {\n const num = Number(raw);\n if (!Number.isNaN(num) && Number.isFinite(num) && num > this.badgeMax) {\n return `${this.badgeMax}+`;\n }\n }\n return raw;\n }\n\n private renderIcon() {\n const useActive = this.active && (this.activeIcon || this.icon);\n const filled = this.active;\n const glyph = useActive ? (this.activeIcon || this.icon) : this.icon;\n\n return (\n <span class=\"md-navigation-tab__icon-container\" part=\"icon-container\">\n <span\n class={{\n 'md-navigation-tab__icon': true,\n 'material-symbols-outlined': true,\n 'md-navigation-tab__icon--filled': filled,\n }}\n part=\"icon\"\n aria-hidden=\"true\"\n >\n {/* Custom-icon slots win over the icon attribute. */}\n {this.active ? <slot name=\"active-icon\">{glyph}</slot> : <slot name=\"icon\">{glyph}</slot>}\n </span>\n {this.renderBadge()}\n </span>\n );\n }\n\n private renderBadge() {\n if (!this.badge && !this.badgeValue) return null;\n const value = this.formatBadgeValue();\n const isLarge = value.length > 0;\n\n return (\n <span\n class={{\n 'md-navigation-tab__badge': true,\n 'md-navigation-tab__badge--small': !isLarge,\n 'md-navigation-tab__badge--large': isLarge,\n }}\n part=\"badge\"\n role=\"status\"\n aria-label={isLarge ? `${value} new` : 'New'}\n >\n {isLarge ? value : ''}\n </span>\n );\n }\n\n private renderLabel() {\n const visibility = this.resolveLabelVisibility();\n if (visibility === 'none') return null;\n\n // CSS handles hiding the label when visibility === 'selected' && !active,\n // so we still render it (preserves space + keeps accessible name stable).\n return (\n <span\n class={{\n 'md-navigation-tab__label': true,\n 'md-navigation-tab__label--hidden':\n visibility === 'selected' && !this.active,\n }}\n part=\"label\"\n >\n <slot>{this.label}</slot>\n </span>\n );\n }\n\n // ─── Render ──────────────────────────────────────────────────────\n\n render() {\n // Accessible name resolution: the host carries the label so the\n // `tab` role gets a stable accessible name. Icon-only mode still\n // exposes the textual `label` via aria-label.\n const accessibleLabel = this.label || undefined;\n const visibility = this.resolveLabelVisibility();\n const ariaLabel = visibility === 'none' ? accessibleLabel : undefined;\n\n return (\n <Host\n class={{\n 'md-navigation-tab': true,\n 'md-navigation-tab--active': this.active,\n 'md-navigation-tab--disabled': this.disabled,\n 'md-navigation-tab--soft-disabled': this.softDisabled && !this.disabled,\n 'md-navigation-tab--label-hidden': visibility === 'none',\n }}\n aria-label={ariaLabel}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n >\n <md-ripple disabled={this.interactionDisabled}></md-ripple>\n <span\n class=\"md-navigation-tab__state-layer\"\n part=\"state-layer\"\n aria-hidden=\"true\"\n data-focus-visible={this.focusVisible ? 'true' : null}\n ></span>\n <span\n class=\"md-navigation-tab__container\"\n part=\"container\"\n >\n <span\n class={{\n 'md-navigation-tab__indicator': true,\n 'md-navigation-tab__indicator--active': this.active,\n }}\n part=\"indicator\"\n aria-hidden=\"true\"\n ></span>\n {this.renderIcon()}\n {this.renderLabel()}\n </span>\n </Host>\n );\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"md-navigation-tab.entry.js","sources":["src/components/md-navigation-tab/md-navigation-tab.css?tag=md-navigation-tab&encapsulation=shadow","src/components/md-navigation-tab/md-navigation-tab.tsx"],"sourcesContent":["/* ==========================================================\n md-navigation-tab — Material Design 3 Navigation Bar Item\n Spec: https://m3.material.io/components/navigation-bar/specs\n A11y: https://m3.material.io/components/navigation-bar/accessibility\n\n Anatomy:\n - State layer (hover / focus / pressed tint)\n - Active indicator (56×32 secondary-container pill)\n - Icon (outlined inactive, filled active)\n - Label (label-medium type)\n - Badge (small dot or large numeric capsule)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-navigation-tab-active-indicator-color\n --md-navigation-tab-active-indicator-width (default 56px)\n --md-navigation-tab-active-indicator-height (default 32px)\n --md-navigation-tab-active-indicator-shape (default full-rounded)\n --md-navigation-tab-active-icon-color\n --md-navigation-tab-inactive-icon-color\n --md-navigation-tab-active-label-color\n --md-navigation-tab-inactive-label-color\n --md-navigation-tab-label-font (label-medium font shorthand)\n --md-navigation-tab-label-font-weight (active label weight; defaults 600)\n --md-navigation-tab-icon-size (default 24px)\n --md-navigation-tab-padding-block-start (default 5px — centers 54px content in 64px bar)\n --md-navigation-tab-padding-block-end (default 5px)\n --md-navigation-tab-hover-state-layer-color\n --md-navigation-tab-focus-state-layer-color\n --md-navigation-tab-pressed-state-layer-color\n --md-navigation-tab-badge-color\n --md-navigation-tab-badge-on-color\n --md-navigation-tab-disabled-opacity (default 0.38)\n ========================================================== */\n\n/* ==========================================================\n 1. HOST — base layout, sizing, focus\n ========================================================== */\n:host {\n --_indicator-color: var(\n --md-navigation-tab-active-indicator-color,\n var(--md-sys-color-secondary-container, #E8DEF8)\n );\n --_indicator-w: var(--md-navigation-tab-active-indicator-width, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n --_indicator-h: var(--md-navigation-tab-active-indicator-height, max(24px, calc(32px + var(--md-sys-density-scale, 0) * 2px)));\n --_indicator-shape: var(\n --md-navigation-tab-active-indicator-shape,\n var(--md-sys-shape-corner-full, 9999px)\n );\n\n --_active-icon-color: var(\n --md-navigation-tab-active-icon-color,\n var(--md-sys-color-on-secondary-container, #1E192B)\n );\n --_inactive-icon-color: var(\n --md-navigation-tab-inactive-icon-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_active-label-color: var(\n --md-navigation-tab-active-label-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_inactive-label-color: var(\n --md-navigation-tab-inactive-label-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n\n --_icon-size: var(--md-navigation-tab-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_pad-top: var(--md-navigation-tab-padding-block-start, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n --_pad-bottom: var(--md-navigation-tab-padding-block-end, calc(5px + var(--md-sys-density-scale, 0) * 1px));\n\n --_hover-color: var(\n --md-navigation-tab-hover-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_focus-color: var(\n --md-navigation-tab-focus-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n --_pressed-color: var(\n --md-navigation-tab-pressed-state-layer-color,\n var(--md-sys-color-on-surface, #1C1B1F)\n );\n\n --_badge-color: var(\n --md-navigation-tab-badge-color,\n var(--md-sys-color-error, #B3261E)\n );\n --_badge-on-color: var(\n --md-navigation-tab-badge-on-color,\n var(--md-sys-color-on-error, #FFFFFF)\n );\n\n --_disabled-opacity: var(--md-navigation-tab-disabled-opacity, 0.38);\n\n --_label-font: var(\n --md-navigation-tab-label-font,\n var(--md-sys-typescale-label-medium-font, 500 12px/16px Roboto, sans-serif)\n );\n --_label-size: var(--md-navigation-tab-label-font-size, max(10px, calc(12px + var(--md-sys-density-scale, 0) * 0.5px)));\n --_label-weight-active: var(--md-navigation-tab-label-font-weight, 600);\n\n --_motion-duration: var(--md-sys-motion-duration-short4, 200ms);\n --_motion-easing: var(\n --md-sys-motion-easing-emphasized-decelerate,\n cubic-bezier(0.05, 0.7, 0.1, 1)\n );\n\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n inline-size: 100%;\n min-inline-size: 48px; /* M3 minimum touch target */\n block-size: 100%;\n padding-block: var(--_pad-top) var(--_pad-bottom);\n box-sizing: border-box;\n cursor: pointer;\n position: relative;\n outline: none;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n color: var(--_inactive-icon-color);\n /* Color transitions are quick and additive — they don't trigger layout. */\n transition:\n color var(--_motion-duration) var(--_motion-easing);\n}\n\n:host(.md-navigation-tab--active) {\n color: var(--_active-icon-color);\n}\n\n/* ==========================================================\n 2. DISABLED STATE\n M3 nav-bar doesn't formally define disabled, but our API\n needs one — match the global disabled-content opacity.\n `--soft-disabled` shares the dim but stays keyboard-focusable\n (it keeps pointer-events + the focus ring) so screen-reader\n users can discover a temporarily-unavailable destination.\n ========================================================== */\n:host(.md-navigation-tab--disabled),\n:host(.md-navigation-tab--soft-disabled) {\n cursor: not-allowed;\n opacity: var(--_disabled-opacity);\n}\n\n:host(.md-navigation-tab--disabled) {\n pointer-events: none;\n}\n\n/* ==========================================================\n 3. STATE LAYER\n Spans the full hit-area so hover/focus/pressed feedback\n covers the whole tab — not just the active-indicator pill.\n Opacities come from the M3 state-layer tokens.\n ========================================================== */\n.md-navigation-tab__state-layer {\n position: absolute;\n inset: 0;\n background-color: currentColor;\n opacity: 0;\n border-radius: inherit;\n pointer-events: none;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(:hover:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_hover-color);\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(:active:not(.md-navigation-tab--disabled):not(.md-navigation-tab--soft-disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_pressed-color);\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__state-layer {\n background-color: var(--_focus-color);\n /* M3 nav-bar focus state-layer opacity is 0.10 (the global sys token is 0.12);\n keep a component override so it matches the spec regardless of the sys value. */\n opacity: var(--md-navigation-tab-focus-state-layer-opacity, 0.1);\n}\n\n/* Visible 3px focus ring per M3 accessibility guidance.\n Wraps the active-indicator pill (centered, rounded) rather than the whole\n tab: a full-tab inset outline gets clipped at the navigation bar's rounded\n corners, and `secondary` matches the focus-ring color used library-wide\n (the old full-tab ring used `primary`, which stood out from every other\n component). */\n:host(:focus-visible:not(.md-navigation-tab--disabled)) .md-navigation-tab__icon-container::after {\n content: '';\n position: absolute;\n inset: -4px;\n border: 3px solid var(--md-sys-color-secondary, #625B71);\n border-radius: var(--_indicator-shape, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n}\n\n/* ==========================================================\n 4. STACK CONTAINER\n The icon-container + indicator + label are stacked centered\n so the visual layout matches MD3 even when extra width is\n available.\n ========================================================== */\n.md-navigation-tab__container {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: flex-start;\n /* M3 vertical item: active-indicator → label \"container between space\" = 6px.\n (The 24px icon centered in the 32px indicator yields the 4px icon inset.) */\n gap: max(2px, calc(6px + var(--md-sys-density-scale, 0) * 1px));\n inline-size: 100%;\n pointer-events: none; /* Click goes through to host. */\n}\n\n/* ==========================================================\n 5. ACTIVE INDICATOR PILL\n Animates from a vertically-collapsed shape into the full\n 56×32px pill — per M3's emphasized-decelerate spec.\n ========================================================== */\n.md-navigation-tab__indicator {\n position: absolute;\n /* Aligned to the icon-container vertical box. */\n inset-block-start: 0;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n border-radius: var(--_indicator-shape);\n background-color: var(--_indicator-color);\n /* Start collapsed; grow on activation. */\n transform: scale(0, 1);\n transform-origin: center center;\n opacity: 0;\n transition:\n transform var(--_motion-duration) var(--_motion-easing),\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n pointer-events: none;\n}\n\n.md-navigation-tab__indicator--active {\n transform: scale(1, 1);\n opacity: 1;\n}\n\n/* ==========================================================\n 6. ICON CONTAINER & ICON\n The container is exactly the size of the active indicator\n so the indicator sits behind the icon at 100% coverage.\n ========================================================== */\n.md-navigation-tab__icon-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_indicator-w);\n block-size: var(--_indicator-h);\n pointer-events: none;\n}\n\n.md-navigation-tab__icon {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: var(--_icon-size);\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n line-height: 1;\n color: inherit;\n z-index: 1;\n transition: font-variation-settings var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n/* Custom icons via slot=\"icon\" / \"active-icon\" (SVG, emoji, custom font):\n slotted light-DOM nodes don't inherit the shadow icon-span's sizing, so a\n bare <span>★</span> would render at the host font-size. Pin them to the 24px\n Material Symbols footprint, inherit the active/inactive icon color (so SVGs\n using currentColor tint correctly), and center within the box. */\n.md-navigation-tab__icon ::slotted(*) {\n /* Fixed 24px flex box so text glyphs (★, emoji) and SVGs share one footprint\n and center identically — a bare inline glyph otherwise gets a taller line\n box and rides off-center against an SVG's box. */\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 line-height: 1;\n /* Reset the icon span's Material Symbols font: slotted text/emoji inherit it\n through the flattened tree, but that icon font has no ★/emoji glyph and its\n line metrics drop the fallback glyph ~5px below center. A normal UI font\n centers them; authors slotting a custom icon font override this from light DOM. */\n font-family: var(--md-navigation-tab-slotted-icon-font, system-ui, sans-serif);\n color: inherit;\n object-fit: contain;\n}\n\n/* Material Symbols variable-font: flip the FILL axis on active. */\n.md-navigation-tab__icon--filled {\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* When Material Symbols is the icon font, the outlined font already\n gives us the inactive look. When Material Icons (legacy) is used,\n we still get the inactive look via the font family. */\n.material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons'), sans-serif;\n font-weight: normal;\n font-style: normal;\n letter-spacing: normal;\n text-transform: none;\n /* No `display` here: the element is also `.md-navigation-tab__icon`, which must\n stay an `inline-flex` centering box (this class is later in source with equal\n specificity, so an inline-block here would silently win and break centering of\n slotted custom icons — they'd sit on the text baseline ~5px low). */\n white-space: nowrap;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;\n}\n\n/* ==========================================================\n 7. BADGES\n Two flavors per M3 spec:\n - small → 6px dot\n - large → numeric / textual capsule (16px min height)\n Both anchor to the top-right of the icon container.\n ========================================================== */\n.md-navigation-tab__badge {\n position: absolute;\n /* Above the icon — the icon glyph has z-index:1, so without this the SVG\n strokes paint over the badge (\"polluted\" badge). */\n z-index: 2;\n background-color: var(--_badge-color);\n color: var(--_badge-on-color);\n border-radius: var(--md-sys-shape-corner-full, 9999px);\n box-sizing: border-box;\n pointer-events: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.md-navigation-tab__badge--small {\n inset-block-start: 2px;\n inset-inline-end: 14px;\n inline-size: 6px;\n block-size: 6px;\n}\n\n/* Centred on the icon corner. The old `inset-inline-start: 50%` + 4px margin\n anchored the badge to the middle of the icon box and shoved it right by a\n fixed amount, so a wider badge grew to the right instead of straddling the\n corner.\n\n THE CORNER IS THE GLYPH'S, NOT THE CONTAINER'S — which is what `inset: 0`\n still got wrong. The badge's positioning parent is the icon CONTAINER, and\n that is the active-indicator pill: `--_indicator-w` is 56px against a 24px\n glyph, so a badge pinned to its right edge floats 16px clear of the icon and\n reads as a separate object beside it rather than as a mark on it. Measured\n on a real bar: icon right edge at 285px, badge starting at 290px, a visible\n gap between them.\n\n Insetting by half the difference on each axis puts the badge's anchor exactly\n on the glyph's top-right corner, which `translate(50%, -50%)` then straddles.\n Both lengths are the component's own resolved variables, so this follows the\n density scale rather than pinning a number that is only right at density 0. */\n.md-navigation-tab__badge--large {\n inset-block-start: calc((var(--_indicator-h) - var(--_icon-size)) / 2);\n inset-inline-end: calc((var(--_indicator-w) - var(--_icon-size)) / 2);\n transform: translate(50%, -50%);\n min-inline-size: 16px;\n block-size: 16px;\n padding-inline: 4px;\n font: var(\n --md-sys-typescale-label-small-font,\n 500 11px/16px Roboto, sans-serif\n );\n letter-spacing: var(\n --md-sys-typescale-label-small-letter-spacing,\n 0.5px\n );\n}\n\n/* ==========================================================\n 8. LABEL\n label-medium typography per M3. Active label gains a\n slightly heavier weight to convey selection.\n ========================================================== */\n.md-navigation-tab__label {\n font: var(--_label-font);\n font-size: var(--_label-size);\n letter-spacing: var(\n --md-sys-typescale-label-medium-letter-spacing,\n 0.5px\n );\n color: var(--_inactive-label-color);\n max-inline-size: 100%;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n text-align: center;\n pointer-events: none;\n transition:\n color var(--md-sys-motion-duration-short2, 100ms) ease,\n opacity var(--md-sys-motion-duration-short2, 100ms) ease;\n}\n\n:host(.md-navigation-tab--active) .md-navigation-tab__label {\n color: var(--_active-label-color);\n font-weight: var(--_label-weight-active);\n}\n\n/* When `labelBehavior=\"selected\"` keep the label slot in the layout\n but hide it visually for inactive tabs so heights stay constant. */\n.md-navigation-tab__label--hidden {\n opacity: 0;\n visibility: hidden;\n}\n\n/* When `labelBehavior=\"none\"` is applied on the host the label is\n not rendered at all — collapse the vertical padding so the icon\n sits centered in the row. */\n:host(.md-navigation-tab--label-hidden) {\n /* No label: center the 32px icon-container in the 64px bar → 16px each side. */\n --_pad-top: var(--md-sys-spacing-inset-lg, 16px);\n --_pad-bottom: var(--md-sys-spacing-inset-lg, 16px);\n justify-content: center;\n}\n\n:host(.md-navigation-tab--label-hidden) .md-navigation-tab__container {\n justify-content: center;\n}\n\n/* ==========================================================\n 9. FORCED COLORS / REDUCED MOTION\n ========================================================== */\n@media (forced-colors: active) {\n :host {\n --_indicator-color: Highlight;\n --_active-icon-color: HighlightText;\n --_active-label-color: HighlightText;\n --_inactive-icon-color: ButtonText;\n --_inactive-label-color: ButtonText;\n }\n :host(:focus-visible:not(.md-navigation-tab--disabled)) {\n outline: 2px solid CanvasText;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host,\n .md-navigation-tab__state-layer,\n .md-navigation-tab__indicator,\n .md-navigation-tab__icon,\n .md-navigation-tab__label {\n transition: none !important;\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\n/* ==========================================================\n HIDDEN\n `[hidden]` is a UA-stylesheet rule, and every `:host` display\n declaration above is an AUTHOR rule — author origin beats UA, so without\n this guard `el.hidden = true` left the component fully laid out.\n `!important` because state rules in this file set `display` at equal or\n higher specificity than `:host([hidden])`.\n ========================================================== */\n:host([hidden]) {\n display: none !important;\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { triggerRipple } from '../../utils/ripple';\nimport { sanitizeHref, SAFE_WINDOW_FEATURES } from '../../utils/url';\n\nexport type MdNavigationTabLabelBehavior = 'always' | 'selected' | 'none';\n\n/**\n * `md-navigation-tab` — a single destination inside `md-navigation-bar`.\n *\n * Renders an icon, an optional label, and an optional badge. Selecting\n * the tab swaps the icon to a filled variant (per M3 spec) and reveals\n * an \"active indicator\" pill behind the icon.\n *\n * References:\n * - {@link https://m3.material.io/components/navigation-bar/specs Specs}\n * - {@link https://m3.material.io/components/navigation-bar/accessibility Accessibility}\n *\n * @slot icon - Custom icon for the inactive state\n * (replaces the `icon` attribute).\n * @slot active-icon - Custom icon for the active state\n * (replaces the `active-icon` attribute).\n * @slot - Default slot for a custom label\n * (replaces the `label` attribute).\n *\n * @part container - The full tab hit-area / touch target.\n * @part indicator - The 56×32 pill that highlights the active icon.\n * @part state-layer - The hover/focus/pressed tint overlay.\n * @part icon-container - The 56×32 wrapper around the icon (badge anchor).\n * @part icon - The rendered icon glyph.\n * @part badge - The badge dot or text capsule (when present).\n * @part label - The destination label text.\n */\n@Component({\n tag: 'md-navigation-tab',\n styleUrl: 'md-navigation-tab.css',\n shadow: true,\n})\nexport class MdNavigationTab {\n @Element() el!: HTMLElement;\n\n /** Whether this destination is currently selected. */\n @Prop({ mutable: true, reflect: true }) active: boolean = false;\n\n /** Disable interaction. Disabled tabs are skipped by keyboard nav. */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /**\n * Soft-disable the destination: it cannot be activated or selected and is\n * announced as `aria-disabled`, but — unlike `disabled` — it stays\n * keyboard-reachable (the bar's arrow-key tour still lands on it) so\n * screen-reader users can discover a temporarily-unavailable destination.\n */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Destination label rendered below the icon. */\n @Prop() label: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when inactive.\n * Per M3 spec, inactive destinations use the outlined variant.\n */\n @Prop() icon: string = '';\n\n /**\n * Material Symbols / Material Icons name shown when active.\n * Per M3 spec, active destinations use the filled variant.\n * Defaults to `icon` when empty (the same glyph in both states).\n */\n @Prop({ attribute: 'active-icon' }) activeIcon: string = '';\n\n /**\n * Show a small \"notification dot\" badge in the top-right of the icon.\n * Use when there are new items but no count is needed.\n */\n @Prop({ reflect: true }) badge: boolean = false;\n\n /**\n * Numeric / textual badge value (e.g. `\"3\"`, `\"99+\"`, `\"New\"`).\n * When set, the badge expands to a pill that accommodates the value\n * (M3 calls this the \"large badge\" variant).\n */\n @Prop({ attribute: 'badge-value' }) badgeValue: string = '';\n\n /**\n * Maximum value rendered when `badgeValue` is purely numeric. Values\n * greater than this render as `\"{max}+\"` (e.g. `99+`). Set to `0` to\n * disable the cap.\n */\n @Prop({ attribute: 'badge-max' }) badgeMax: number = 999;\n\n /**\n * When set, activating the tab also navigates to the URL — useful when\n * each destination is a full route. For SPA routing, intercept the native\n * `click` (call `preventDefault()`) or listen to the bar's `mdChange`;\n * navigation only occurs when `href` is truthy and the click isn't prevented.\n */\n @Prop() href: string = '';\n\n /** Link target (forwarded only when `href` is set). */\n @Prop() target: string = '';\n\n /**\n * Label visibility for this tab. Inherits from the parent\n * `md-navigation-bar`'s `label-behavior` when not set.\n *\n * Not reflected as an attribute — the parent bar uses\n * `getAttribute('label-behavior')` to detect *explicit* author\n * overrides, so reflecting the default would defeat that signal.\n */\n @Prop({ mutable: true, attribute: 'label-behavior' })\n labelBehavior: MdNavigationTabLabelBehavior = 'always';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /**\n * Fired when the tab is activated (click, Enter, or Space) and the tab is\n * not disabled. The parent `md-navigation-bar` listens for this to drive\n * selection; external code may also listen to detect per-tab activation\n * (including a re-click of the already-active tab, which does not emit\n * `mdChange` on the bar).\n */\n @Event() mdTabClick: EventEmitter<{ index: number }>;\n\n /** Internal — track focus-visible for the state layer + a11y. */\n @State() private focusVisible: boolean = false;\n\n // ─── Watchers ────────────────────────────────────────────────────\n\n @Watch('active')\n onActiveChange(active: boolean) {\n // Mirror the active state into aria-selected so the parent isn't\n // the sole writer (works in detached usage / docs without a bar).\n this.el.setAttribute('aria-selected', String(active));\n }\n\n @Watch('disabled')\n onDisabledChange() {\n this.syncAriaDisabled();\n }\n\n @Watch('softDisabled')\n onSoftDisabledChange() {\n this.syncAriaDisabled();\n }\n\n /** Activation/selection is blocked when either disabled flag is set. */\n private get interactionDisabled(): boolean {\n return this.disabled || this.softDisabled;\n }\n\n private syncAriaDisabled() {\n this.el.setAttribute('aria-disabled', String(this.interactionDisabled));\n }\n\n // ─── Lifecycle ───────────────────────────────────────────────────\n\n connectedCallback() {\n // Defaults — the bar may override these on mount.\n if (!this.el.hasAttribute('role')) this.el.setAttribute('role', 'tab');\n this.el.setAttribute('aria-selected', String(this.active));\n if (this.interactionDisabled) this.el.setAttribute('aria-disabled', 'true');\n if (!this.el.hasAttribute('tabindex')) {\n this.el.setAttribute('tabindex', this.active ? '0' : '-1');\n }\n }\n\n // ─── Public API ──────────────────────────────────────────────────\n\n /** Focus the tab programmatically (skip when disabled). */\n @Method()\n async focusEl(): Promise<void> {\n if (this.disabled) return;\n this.el.focus();\n }\n\n // ─── Internal helpers ────────────────────────────────────────────\n\n /** Locate this tab's index inside its parent navigation bar. */\n private resolveIndex(): number {\n const parent = this.el.parentElement;\n if (!parent) return -1;\n // Walk direct children rather than using `:scope > md-navigation-tab`\n // — the latter is unsupported by Stencil's mock-doc in spec tests.\n const siblings: HTMLElement[] = [];\n for (const child of Array.from(parent.children)) {\n if ((child as HTMLElement).tagName === 'MD-NAVIGATION-TAB') {\n siblings.push(child as HTMLElement);\n }\n }\n return siblings.indexOf(this.el);\n }\n\n private emitActivation() {\n const index = this.resolveIndex();\n this.mdTabClick.emit({ index });\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.interactionDisabled) {\n // Block activation and stop the click from reaching the bar.\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n if (e.defaultPrevented) return; // SPA routers call preventDefault()\n this.emitActivation();\n this.maybeFollowHref();\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.interactionDisabled) return;\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') {\n e.preventDefault();\n triggerRipple(this.el);\n // Synthesize a native click so keyboard and pointer activation share one\n // path (bubbles to the bar + follows href).\n this.el.click();\n }\n };\n\n private maybeFollowHref() {\n const href = sanitizeHref(this.href);\n if (!href) return;\n if (typeof window === 'undefined') return;\n if (this.target === '_blank') {\n window.open(href, '_blank', SAFE_WINDOW_FEATURES);\n } else if (this.target) {\n /* A named target opens a new browsing context just like `_blank` does,\n so it needs the same opener severing. */\n window.open(href, this.target, SAFE_WINDOW_FEATURES);\n } else {\n window.location.assign(href);\n }\n }\n\n private handleFocus = () => {\n this.focusVisible = this.el.matches(':focus-visible');\n };\n\n private handleBlur = () => {\n this.focusVisible = false;\n };\n\n // ─── Rendering helpers ───────────────────────────────────────────\n\n private resolveLabelVisibility(): MdNavigationTabLabelBehavior {\n return this.labelBehavior;\n }\n\n private formatBadgeValue(): string {\n const raw = (this.badgeValue ?? '').trim();\n if (!raw) return '';\n if (this.badgeMax > 0) {\n const num = Number(raw);\n if (!Number.isNaN(num) && Number.isFinite(num) && num > this.badgeMax) {\n return `${this.badgeMax}+`;\n }\n }\n return raw;\n }\n\n private renderIcon() {\n const useActive = this.active && (this.activeIcon || this.icon);\n const filled = this.active;\n const glyph = useActive ? (this.activeIcon || this.icon) : this.icon;\n\n return (\n <span class=\"md-navigation-tab__icon-container\" part=\"icon-container\">\n <span\n class={{\n 'md-navigation-tab__icon': true,\n 'material-symbols-outlined': true,\n 'md-navigation-tab__icon--filled': filled,\n }}\n part=\"icon\"\n aria-hidden=\"true\"\n >\n {/* Custom-icon slots win over the icon attribute. */}\n {this.active ? <slot name=\"active-icon\">{glyph}</slot> : <slot name=\"icon\">{glyph}</slot>}\n </span>\n {this.renderBadge()}\n </span>\n );\n }\n\n private renderBadge() {\n if (!this.badge && !this.badgeValue) return null;\n const value = this.formatBadgeValue();\n const isLarge = value.length > 0;\n\n return (\n <span\n class={{\n 'md-navigation-tab__badge': true,\n 'md-navigation-tab__badge--small': !isLarge,\n 'md-navigation-tab__badge--large': isLarge,\n }}\n part=\"badge\"\n role=\"status\"\n aria-label={isLarge ? `${value} new` : 'New'}\n >\n {isLarge ? value : ''}\n </span>\n );\n }\n\n private renderLabel() {\n const visibility = this.resolveLabelVisibility();\n if (visibility === 'none') return null;\n\n // CSS handles hiding the label when visibility === 'selected' && !active,\n // so we still render it (preserves space + keeps accessible name stable).\n return (\n <span\n class={{\n 'md-navigation-tab__label': true,\n 'md-navigation-tab__label--hidden':\n visibility === 'selected' && !this.active,\n }}\n part=\"label\"\n >\n <slot>{this.label}</slot>\n </span>\n );\n }\n\n // ─── Render ──────────────────────────────────────────────────────\n\n render() {\n // Accessible name resolution: the host carries the label so the\n // `tab` role gets a stable accessible name. Icon-only mode still\n // exposes the textual `label` via aria-label.\n const accessibleLabel = this.label || undefined;\n const visibility = this.resolveLabelVisibility();\n const ariaLabel = visibility === 'none' ? accessibleLabel : undefined;\n\n return (\n <Host\n class={{\n 'md-navigation-tab': true,\n 'md-navigation-tab--active': this.active,\n 'md-navigation-tab--disabled': this.disabled,\n 'md-navigation-tab--soft-disabled': this.softDisabled && !this.disabled,\n 'md-navigation-tab--label-hidden': visibility === 'none',\n }}\n aria-label={ariaLabel}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n >\n <md-ripple disabled={this.interactionDisabled}></md-ripple>\n <span\n class=\"md-navigation-tab__state-layer\"\n part=\"state-layer\"\n aria-hidden=\"true\"\n data-focus-visible={this.focusVisible ? 'true' : null}\n ></span>\n <span\n class=\"md-navigation-tab__container\"\n part=\"container\"\n >\n <span\n class={{\n 'md-navigation-tab__indicator': true,\n 'md-navigation-tab__indicator--active': this.active,\n }}\n part=\"indicator\"\n aria-hidden=\"true\"\n ></span>\n {this.renderIcon()}\n {this.renderLabel()}\n </span>\n </Host>\n );\n }\n}\n"],"names":[],"mappings":"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"}