{"version":3,"file":"tab-item.cjs","names":[],"sources":["../src/disclosure/tab-item/tab-item.ts"],"sourcesContent":["import { bind, define, getHost, html, inject, onMounted, prop, ref, watchEffect } from '@vielzeug/ore';\nimport { computed } from '@vielzeug/ripple';\nimport { setAriaReflection } from '../../core';\nimport { disablableBundle } from '../../shared';\nimport { coarsePointerMixin, colorThemeMixin, forcedColorsFocusMixin } from '../../styles';\nimport type { ComponentSize, SurfaceVariant, ThemeColor } from '../../types';\nimport { TABS_CTX } from '../tabs/tabs';\nimport styles from './tab-item.css?inline';\n\nexport type OreTabItemProps = {\n  /** Whether this tab is currently selected (set by ore-tabs) */\n  active?: boolean;\n  /** Theme color (inherited from ore-tabs) */\n  color?: ThemeColor;\n  /** Disable this tab */\n  disabled?: boolean;\n  /** Size (inherited from ore-tabs) */\n  size?: ComponentSize;\n  /** Unique value identifier — must match a ore-tab-panel value */\n  value: string;\n  /** Visual variant (inherited from ore-tabs) */\n  variant?: SurfaceVariant;\n};\n\n/**\n * Individual tab trigger. Must be placed in the `tabs` slot of `ore-tabs`.\n *\n * @element ore-tab-item\n *\n * @attr {string} value - Unique identifier, matches the corresponding ore-tab-panel value\n * @attr {boolean} active - Set by the parent ore-tabs when this tab is selected\n * @attr {boolean} disabled - Prevents selection\n * @attr {string} size - 'sm' | 'md' | 'lg'\n * @attr {string} variant - Inherited from ore-tabs: 'solid' | 'flat' | 'bordered' | 'ghost' | 'glass' | 'frost'\n * @attr {string} color - Inherited from ore-tabs: 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'error'\n *\n * @slot prefix - Icon or content before the label\n * @slot - Tab label\n * @slot suffix - Badge or count after the label\n *\n * @cssprop --tab-item-radius - Button border radius\n * @cssprop --tab-item-transition - Transition duration/easing\n * @cssprop --tab-item-padding - Button padding\n * @cssprop --tab-item-font-size - Button font size\n * @cssprop --tab-item-color - Default text color\n * @cssprop --tab-item-hover-bg - Background on hover\n * @cssprop --tab-item-active-bg - Background when active/selected\n * @cssprop --tab-item-active-color - Text color when active/selected\n * @cssprop --tab-item-active-shadow - Box shadow when active/selected\n * @part tab - Tab trigger element.\n * @example\n * ```html\n * <ore-tab-item slot=\"tabs\" value=\"overview\">Overview</ore-tab-item>\n * <ore-tab-item slot=\"tabs\" value=\"settings\" disabled>Settings</ore-tab-item>\n * ```\n */\nexport const TAB_ITEM_TAG = 'ore-tab-item' as const;\ndefine<OreTabItemProps>(TAB_ITEM_TAG, {\n  props: {\n    ...disablableBundle,\n    active: prop.bool(false),\n    color: prop.string<ThemeColor>(),\n    size: prop.string<ComponentSize>(),\n    value: prop.string(''),\n    variant: prop.string<SurfaceVariant>(),\n  },\n  setup(props) {\n    const el = getHost();\n    const watch = watchEffect;\n\n    const tabsCtx = inject(TABS_CTX);\n\n    if (tabsCtx) {\n      watch(() => {\n        const color = tabsCtx.color.value;\n        const size = tabsCtx.size.value;\n        const variant = tabsCtx.variant.value;\n\n        if (color !== undefined) el.setAttribute('color', color);\n\n        if (size !== undefined) el.setAttribute('size', size);\n\n        if (variant !== undefined) el.setAttribute('variant', variant);\n      });\n    }\n\n    const isActive = computed(() =>\n      tabsCtx ? !!tabsCtx.value.value && tabsCtx.value.value === props.value.value : props.active.value,\n    );\n    const isDisabled = () => Boolean(props.disabled.value);\n\n    bind({\n      attr: {\n        active: () => (isActive.value ? true : undefined),\n      },\n    });\n\n    const handleClick = (event: MouseEvent) => {\n      event.stopPropagation();\n\n      if (isDisabled()) {\n        event.preventDefault();\n\n        return;\n      }\n\n      el.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: { value: props.value.value } }));\n    };\n\n    const tabId = () => `tab-${props.value.value}`;\n    const buttonRef = ref<HTMLButtonElement>();\n\n    // `aria-controls` as a plain IDREF attribute cannot resolve across shadow-tree boundaries\n    // (the matching `id` lives inside <ore-tab-panel>'s own shadow root) — see\n    // `setAriaReflection()`'s doc comment. Deferred to `onMounted()`: sibling custom elements\n    // (including the peer `<ore-tab-panel>`) connect in tree order within the same synchronous\n    // insertion, so a sibling's shadow content may not exist yet during this element's own\n    // `setup()` — `onMounted()`'s microtask runs after the whole subtree has connected.\n    onMounted(() => {\n      watchEffect(() => {\n        const button = buttonRef.value;\n        const value = props.value.value;\n\n        if (!button) return;\n\n        const tabsEl = value ? el.closest('ore-tabs') : null;\n        const panelEl = tabsEl?.querySelector<HTMLElement>(`:scope > ore-tab-panel[value=\"${value}\"]`);\n        const panel = panelEl?.shadowRoot?.querySelector<HTMLElement>('.panel') ?? null;\n\n        setAriaReflection(button, 'ariaControlsElements', panel ? [panel] : []);\n      });\n    });\n\n    return html`\n      <button\n        role=\"tab\"\n        type=\"button\"\n        part=\"tab\"\n        ref=\"${buttonRef}\"\n        id=\"${tabId}\"\n        aria-selected=\"${isActive}\"\n        tabindex=\"${() => (isActive.value ? '0' : '-1')}\"\n        aria-disabled=\"${isDisabled}\"\n        @click=\"${handleClick}\">\n        <slot name=\"prefix\"></slot>\n        <slot></slot>\n        <slot name=\"suffix\"></slot>\n      </button>\n    `;\n  },\n  styles: [colorThemeMixin, forcedColorsFocusMixin('button'), coarsePointerMixin, styles],\n});\n"],"mappings":"+XAwDA,IAAa,EAAe,gBAC5B,EAAA,EAAA,OAAA,CAAwB,EAAc,CACpC,MAAO,CACL,GAAG,EAAA,iBACH,OAAQ,EAAA,KAAK,KAAK,EAAK,EACvB,MAAO,EAAA,KAAK,OAAmB,EAC/B,KAAM,EAAA,KAAK,OAAsB,EACjC,MAAO,EAAA,KAAK,OAAO,EAAE,EACrB,QAAS,EAAA,KAAK,OAAuB,CACvC,EACA,MAAM,EAAO,CACX,IAAM,GAAA,EAAK,EAAA,QAAA,CAAQ,EACb,EAAQ,EAAA,YAER,GAAA,EAAU,EAAA,OAAA,CAAO,EAAA,QAAQ,EAE3B,GACF,MAAY,CACV,IAAM,EAAQ,EAAQ,MAAM,MACtB,EAAO,EAAQ,KAAK,MACpB,EAAU,EAAQ,QAAQ,MAE5B,IAAU,IAAA,IAAW,EAAG,aAAa,QAAS,CAAK,EAEnD,IAAS,IAAA,IAAW,EAAG,aAAa,OAAQ,CAAI,EAEhD,IAAY,IAAA,IAAW,EAAG,aAAa,UAAW,CAAO,CAC/D,CAAC,EAGH,IAAM,GAAA,EAAW,EAAA,SAAA,KACf,EAAU,CAAC,CAAC,EAAQ,MAAM,OAAS,EAAQ,MAAM,QAAU,EAAM,MAAM,MAAQ,EAAM,OAAO,KAC9F,EACM,MAAmB,EAAQ,EAAM,SAAS,OAEhD,EAAA,EAAA,KAAA,CAAK,CACH,KAAM,CACJ,WAAe,EAAS,MAAQ,GAAO,IAAA,EACzC,CACF,CAAC,EAED,IAAM,EAAe,GAAsB,CAGzC,GAFA,EAAM,gBAAgB,EAElB,EAAW,EAAG,CAChB,EAAM,eAAe,EAErB,MACF,CAEA,EAAG,cAAc,IAAI,YAAY,QAAS,CAAE,QAAS,GAAM,OAAQ,CAAE,MAAO,EAAM,MAAM,KAAM,CAAE,CAAC,CAAC,CACpG,EAEM,MAAc,OAAO,EAAM,MAAM,QACjC,GAAA,EAAY,EAAA,IAAA,CAAuB,EAuBzC,OAfA,EAAA,EAAA,UAAA,KAAgB,EACd,EAAA,EAAA,YAAA,KAAkB,CAChB,IAAM,EAAS,EAAU,MACnB,EAAQ,EAAM,MAAM,MAE1B,GAAI,CAAC,EAAQ,OAIb,IAAM,IAFS,EAAQ,EAAG,QAAQ,UAAU,EAAI,KAAA,EACxB,cAA2B,iCAAiC,EAAM,GAAG,EAAA,EACtE,YAAY,cAA2B,QAAQ,GAAK,KAE3E,EAAA,kBAAkB,EAAQ,uBAAwB,EAAQ,CAAC,CAAK,EAAI,CAAC,CAAC,CACxE,CAAC,CACH,CAAC,EAEM,EAAA,IAAI;;;;;eAKA,EAAU;cACX,EAAM;yBACK,EAAS;wBACP,EAAS,MAAQ,IAAM,KAAM;yBAC/B,EAAW;kBAClB,EAAY;;;;;KAM5B,EACA,OAAQ,CAAC,EAAA,gBAAiB,EAAA,uBAAuB,QAAQ,EAAG,EAAA,mBAAoB,EAAA,OAAM,CACxF,CAAC"}