@cdevhub/ngx-tw 0.6.2 → 0.8.0

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 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-radio.mjs","sources":["../../../projects/ngx-tw/radio/radio.ts","../../../projects/ngx-tw/radio/cdevhub-ngx-tw-radio.ts"],"sourcesContent":["import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n DestroyRef,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n type OnInit,\n output,\n signal,\n type Signal,\n} from '@angular/core';\nimport { type ControlValueAccessor, NgControl } from '@angular/forms';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n type TwColor,\n type TwSize,\n wireErrorState,\n} from '@cdevhub/ngx-tw/core';\n\n/** Visual style of the selected radio indicator. */\nexport type RadioVariant = 'solid' | 'outline';\n\n/** Layout direction of a radio group. */\nexport type RadioOrientation = 'horizontal' | 'vertical';\n\n/** Position of the label relative to the radio control. */\nexport type RadioLabelPosition = 'before' | 'after';\n\n// ── Radio tv() config ────────────────────────────────────────────\n\nconst radioVariants = tv(\n {\n slots: {\n // `items-start` aligns circleWrap with the top of the label container; combined with\n // a `min-h-N` matching the label's first-line line-height on circleWrap, the circle\n // stays centered on the first line whether the label spans one line or many.\n //\n // ── Row-height scale (selection cohort) ──────────────────────────────\n // The rendered row is `max(circleWrap, label first line)`, and the host itself is the\n // click target (`role=\"radio\"` + `tabindex` + `(click)` all sit on the root), so the\n // row IS the interactive target. It runs 16 / 20 / 24 / 28 / 32 px — five distinct\n // steps, every one on the 4px baseline of docs/vertical-rhythm.md, and identical to\n // `checkbox` and `switch`. Selection controls are glyph-scale and deliberately do NOT\n // take the pinned 24/32/36/44/48 form-row scale (vertical-rhythm.md section 4).\n //\n // The row is driven by `circleWrap` min-h, NOT by the circle glyph, which keeps its own\n // 14 / 16 / 20 / 24 / 28 scale. Driving it from circleWrap is what makes the five steps\n // survive when no label is projected.\n //\n // Because centering demands `circleWrap height == label first-line leading`, the label\n // leading carries the same 4 / 5 / 6 / 7 / 8 progression. That is forced, not chosen:\n // the label font scale has only three steps (text-xs, text-sm, text-base), so leading\n // is the only lever that can break the sm/md and lg/xl ties. Before this, sm and md\n // both rendered a 20px row — a dead step. Accepted cost: `text-base leading-8` at xl is\n // a 2.0 line ratio, looser than typographic ideal on a wrapped multi-line label.\n root: 'inline-flex items-start gap-3 cursor-pointer select-none rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n circleWrap: 'relative inline-flex items-center justify-center shrink-0',\n circle:\n 'inline-flex items-center justify-center rounded-full border bg-surface transition-colors duration-normal motion-reduce:transition-none',\n dotWrap:\n 'inline-flex items-center justify-center pointer-events-none',\n dot: 'inline-block rounded-full',\n labelWrap: 'flex flex-col min-w-0 empty:hidden',\n label: 'font-medium text-fg empty:hidden',\n description: 'text-fg-muted empty:hidden',\n },\n variants: {\n size: {\n xs: {\n // `size-3.5` half-step: aligns with text-xs/leading-4 row metric.\n circle: 'size-3.5',\n // The dot runs 6 / 8 / 10 / 12 / 14px — it is NOT on the status-dot sub-scale of\n // CLAUDE.md (that one is for standalone presence pips). It is a proportional inner\n // selection mark, held at ~50% of the enclosing circle at every size, so its value\n // is derived from `circle` rather than picked off a table. At xs, 50% of a 14px\n // circle is 7px, which no utility expresses; `size-1.5` (6px) is the nearest step\n // down — rounding up to 8px would leave under 3px of ring on each side.\n dot: 'size-1.5',\n circleWrap: 'min-h-4',\n label: 'text-xs leading-4',\n description: 'text-2xs leading-4',\n },\n sm: {\n circle: 'size-4',\n dot: 'size-2',\n circleWrap: 'min-h-5',\n label: 'text-sm leading-5',\n description: 'text-xs leading-4',\n },\n md: {\n circle: 'size-5',\n dot: 'size-2.5',\n // 24px row. `text-sm` is shared with sm by the documented font scale, so the\n // leading breaks the tie: leading-6 lifts the row off sm's 20px.\n circleWrap: 'min-h-6',\n label: 'text-sm leading-6',\n description: 'text-xs leading-4',\n },\n lg: {\n circle: 'size-6',\n dot: 'size-3',\n // 28px row — leading-7 keeps the first label line the same height as circleWrap.\n circleWrap: 'min-h-7',\n label: 'text-base leading-7',\n description: 'text-sm leading-5',\n },\n xl: {\n circle: 'size-7',\n // xl density: dot uses `size-3.5` (14px) as the proportionally-sized\n // selection mark inside the size-7 (28px) circle — exactly 50%.\n dot: 'size-3.5',\n // 32px row. `text-base` is shared with lg, so leading-8 breaks that tie the same\n // way leading-6 breaks sm/md. A 2.0 ratio on a wrapped label is the accepted cost.\n circleWrap: 'min-h-8',\n label: 'text-base leading-8',\n description: 'text-sm leading-5',\n },\n },\n labelPosition: {\n before: { root: 'flex-row-reverse' },\n after: { root: 'flex-row' },\n },\n checked: {\n true: { circle: '' },\n false: { circle: 'border-border hover:border-border-strong' },\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: { root: '' },\n },\n errorState: {\n true: { circle: '', label: 'text-error-700', description: 'text-error-600' },\n false: { circle: '', label: '', description: '' },\n },\n },\n compoundVariants: [\n // Error state on an unchecked radio repaints the ring with the error color.\n { errorState: true, checked: false, class: { circle: 'border-error-500 hover:border-error-600' } },\n ],\n defaultVariants: {\n size: 'md',\n labelPosition: 'after',\n checked: false,\n disabled: false,\n errorState: false,\n },\n },\n { twMerge: true },\n);\n\n// ── Static selected-state color lookups (all classes written statically for Tailwind v4 scanning) ──\n\nconst SOLID_RING: Record<TwColor, string> = {\n primary: 'border-primary-600',\n secondary: 'border-secondary-600',\n accent: 'border-accent-600',\n neutral: 'border-fg',\n info: 'border-info-600',\n success: 'border-success-600',\n warning: 'border-warning-500',\n error: 'border-error-600',\n};\n\nconst SOLID_DOT: Record<TwColor, string> = {\n primary: 'bg-primary-600',\n secondary: 'bg-secondary-600',\n accent: 'bg-accent-600',\n neutral: 'bg-fg',\n info: 'bg-info-600',\n success: 'bg-success-600',\n warning: 'bg-warning-500',\n error: 'bg-error-600',\n};\n\nconst OUTLINE_RING: Record<TwColor, string> = {\n primary: 'border-primary-600',\n secondary: 'border-secondary-600',\n accent: 'border-accent-600',\n neutral: 'border-fg',\n info: 'border-info-600',\n success: 'border-success-600',\n warning: 'border-warning-500',\n error: 'border-error-600',\n};\n\nconst OUTLINE_DOT: Record<TwColor, string> = {\n primary: 'bg-primary-600',\n secondary: 'bg-secondary-600',\n accent: 'bg-accent-600',\n neutral: 'bg-fg',\n info: 'bg-info-600',\n success: 'bg-success-600',\n warning: 'bg-warning-500',\n error: 'bg-error-600',\n};\n\nlet nextRadioId = 0;\n\n// ── RadioComponent ───────────────────────────────────────────────\n\n@Component({\n selector: 'tw-radio',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <span [class]=\"circleWrapClasses()\">\n <span [class]=\"circleClasses()\">\n @if (isSelected()) {\n <span [class]=\"dotWrapClasses()\" animate.enter=\"check-in\">\n <ng-content select=\"[slot='dot']\">\n <span [class]=\"dotClasses()\"></span>\n </ng-content>\n </span>\n }\n </span>\n </span>\n\n <span [class]=\"labelWrapClasses()\">\n <span [id]=\"labelId\" [class]=\"labelClasses()\">\n <ng-content />\n @if (label()) {\n {{ label() }}\n }\n </span>\n <span [id]=\"descriptionId\" [class]=\"descriptionClasses()\">\n <ng-content select=\"[slot='description']\" />\n @if (description()) {\n {{ description() }}\n }\n </span>\n </span>\n `,\n host: {\n 'role': 'radio',\n '[id]': 'hostId',\n '[class]': 'rootClasses()',\n '[attr.data-checked]': 'isSelected()',\n '[attr.aria-checked]': 'isSelected() ? \"true\" : \"false\"',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'effectiveAriaLabelledby() || null',\n '[attr.aria-describedby]': 'effectiveAriaDescribedby() || null',\n '[attr.tabindex]': 'isFocusable() ? 0 : -1',\n '[attr.name]': 'effectiveName() || null',\n '(click)': 'onActivate()',\n '(keydown)': 'onKeydown($event)',\n '(blur)': 'onBlur()',\n },\n})\nexport class RadioComponent implements ControlValueAccessor, OnInit {\n /** The value this radio contributes when selected inside a `tw-radio-group`. Required when nested in a group; ignored when used standalone. Defaults to `undefined`. */\n readonly value = input<unknown>(undefined);\n\n /** Overrides the parent group's color for this radio. When undefined, inherits from the group (or defaults to `'primary'` standalone). */\n readonly color = input<TwColor | undefined>(undefined);\n\n /** Overrides the parent group's size for this radio. When undefined, inherits from the group (or defaults to `'md'` standalone). */\n readonly size = input<TwSize | undefined>(undefined);\n\n /** Overrides the parent group's variant for this radio. When undefined, inherits from the group (or defaults to `'solid'` standalone). */\n readonly variant = input<RadioVariant | undefined>(undefined);\n\n /** When true, disables this radio regardless of the group's state. Group-disabled always wins as an OR. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** Optional inline label rendered next to the radio. Use default content projection for rich label content instead. */\n readonly label = input<string | undefined>(undefined);\n\n /** Optional secondary description rendered under the label. Use `[slot=\"description\"]` content projection for rich content instead. */\n readonly description = input<string | undefined>(undefined);\n\n /** Position of the label/description relative to the radio. Defaults to `'after'`. */\n readonly labelPosition = input<RadioLabelPosition>('after');\n\n /** Optional name attribute for standalone use. Ignored when the parent group provides a name. */\n readonly name = input<string | undefined>(undefined);\n\n /** Accessible name when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the radio. Mirrored to `aria-labelledby`. Defaults to `undefined`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the radio. Mirrored to `aria-describedby`. Defaults to `undefined`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /**\n * Two-way bound checked state. Authoritative only in standalone mode.\n * Defaults to `false`.\n *\n * Standalone, the minted `checkedChange` output is the *any-change* channel:\n * it fires both when the user selects this radio and when a bound form writes\n * into it (`FormControl.setValue`, `ngModel`, `writeValue`). `(change)` is the\n * *user-gesture-only* channel — bind that one for analytics or a confirmation\n * prompt, where a programmatic write must not count as a click.\n *\n * Inside a `tw-radio-group` this model is inert: the group owns selection,\n * the rendered state comes from the group's `value`, and the component never\n * writes `checked` — so `(checkedChange)` never fires on a grouped radio.\n * `(change)` still fires when this radio becomes the selected one. Bind the\n * group's `[(value)]` / `(change)` instead.\n */\n readonly checked = model(false);\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the radio uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /**\n * Fires after the checked state changes from a user interaction on this\n * radio. In grouped mode only fires when this radio becomes the selected one.\n * Does **not** fire when selection is updated programmatically via\n * `writeValue` / `FormControl.setValue` / `ngModel` — standalone, bind the\n * two-way binding's `(checkedChange)` for that, which fires on any change.\n * (Grouped, `(checkedChange)` never fires at all; use the group's\n * `[(value)]`.)\n */\n readonly change = output<boolean>();\n\n private readonly focusMonitor = inject(FocusMonitor);\n readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly parent = inject(forwardRef(() => RadioGroupComponent), { optional: true });\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n /** @internal Shared `errorState` derivation — see `wireErrorState`. */\n private readonly errorWiring = wireErrorState({\n ngControl: () => this.ngControl,\n matcher: () => this.errorStateMatcher(),\n // A radio inside a group inherits the group's error state verbatim,\n // including `false`; standalone it falls through to the matcher.\n errorStateOverride: () => (this.parent ? this.parent.errorState() : undefined),\n });\n\n private readonly uid = nextRadioId++;\n readonly hostId = `tw-radio-${this.uid}`;\n readonly labelId = `${this.hostId}-label`;\n readonly descriptionId = `${this.hostId}-description`;\n\n private readonly internalChecked = linkedSignal(() => this.checked());\n\n /** Resolved color — radio's own color wins, then group's, then `'primary'`. */\n readonly effectiveColor = computed<TwColor>(\n () => this.color() ?? this.parent?.color() ?? 'primary',\n );\n\n /** Resolved size — radio's own size wins, then group's, then `'md'`. */\n readonly effectiveSize = computed<TwSize>(\n () => this.size() ?? this.parent?.size() ?? 'md',\n );\n\n /** Resolved variant — radio's own variant wins, then group's, then `'solid'`. */\n readonly effectiveVariant = computed<RadioVariant>(\n () => this.variant() ?? this.parent?.variant() ?? 'solid',\n );\n\n /** Resolved name attribute — parent group's name wins for HTML form semantics. */\n readonly effectiveName = computed(() => this.parent?.name() ?? this.name());\n\n /** Whether this radio is currently selected (grouped: parent.value === this.value; standalone: internal checked). */\n readonly isSelected = computed(() => {\n if (this.parent) return this.parent.value() === this.value();\n return this.internalChecked();\n });\n\n /** Whether this radio is disabled (own disabled OR parent's disabled OR CVA-disabled). */\n readonly isDisabled = computed(\n () => this.disabled() || this.cvaDisabled() || (this.parent?.isDisabled() ?? false),\n );\n\n /** Whether the radio is in an error state per the configured `ErrorStateMatcher`. Inherits from the parent group when wrapped; falls back to its own NgControl when standalone. */\n readonly errorState: Signal<boolean> = this.errorWiring.errorState;\n\n /** Roving tabindex: in a group, only the selected (or first enabled if none selected) radio is focusable. Standalone radios are always focusable unless disabled. */\n readonly isFocusable = computed(() => {\n if (this.isDisabled()) return false;\n if (!this.parent) return true;\n if (this.isSelected()) return true;\n const parentValue = this.parent.value();\n if (parentValue === null || parentValue === undefined) {\n const firstEnabled = this.parent\n .radios()\n .find((r: RadioComponent) => !r.isDisabled());\n return firstEnabled === this;\n }\n return false;\n });\n\n readonly effectiveAriaLabelledby = computed(() => {\n const external = this.ariaLabelledby();\n if (external) return external;\n if (this.ariaLabel()) return undefined;\n return this.labelId;\n });\n\n readonly effectiveAriaDescribedby = computed(() => {\n const external = this.ariaDescribedby();\n if (external) return external;\n return this.descriptionId;\n });\n\n private readonly variantResult = computed(() =>\n radioVariants({\n size: this.effectiveSize(),\n labelPosition: this.labelPosition(),\n checked: this.isSelected(),\n disabled: this.isDisabled(),\n errorState: this.errorState(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly circleWrapClasses = computed(() => this.variantResult().circleWrap());\n readonly labelWrapClasses = computed(() => this.variantResult().labelWrap());\n readonly labelClasses = computed(() => this.variantResult().label());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly dotWrapClasses = computed(() => this.variantResult().dotWrap());\n\n readonly circleClasses = computed(() => {\n const base = this.variantResult().circle();\n if (!this.isSelected()) return base;\n const ringLookup = this.effectiveVariant() === 'solid' ? SOLID_RING : OUTLINE_RING;\n return `${base} ${ringLookup[this.effectiveColor()]}`;\n });\n\n readonly dotClasses = computed(() => {\n const base = this.variantResult().dot();\n const dotLookup = this.effectiveVariant() === 'solid' ? SOLID_DOT : OUTLINE_DOT;\n return `${base} ${dotLookup[this.effectiveColor()]}`;\n });\n\n constructor() {\n // Material-style CVA wiring for standalone `<tw-radio>` use. Mirrors\n // `checkbox.ts` / `slider.ts` — avoids the circular-DI a static\n // `NG_VALUE_ACCESSOR` provider would create when `NgControl` is injected\n // with `self: true` on the same element. When this radio is wrapped in a\n // `tw-radio-group`, the group owns CVA and child `NgControl` bindings are\n // not expected (no `[(ngModel)]` on children).\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-radio] The radio has no accessible name. Provide a `label` input, project label content, or set `aria-label` / `aria-labelledby`.',\n );\n }\n });\n }\n\n /** Called by user click or group keyboard handler. Selects this radio. */\n onActivate(): void {\n if (this.isDisabled()) return;\n if (this.parent) {\n const wasSelected = this.isSelected();\n this.parent.selectValue(this.value());\n if (!wasSelected) {\n this.change.emit(true);\n }\n return;\n }\n // Standalone — match native <input type=\"radio\">: clicking does not toggle back off\n if (!this.internalChecked()) {\n this.internalChecked.set(true);\n this.checked.set(true);\n this.onChange(true);\n // Deliberately NOT `onTouched()` — that is the blur notification, and\n // `onBlur()` owns it. See the note on `RadioGroupComponent.selectValue`.\n this.change.emit(true);\n }\n }\n\n /** Handles keyboard activation. Space selects; Enter does NOT — matches native `<input type=\"radio\">` semantics. */\n onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) return;\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n this.onActivate();\n }\n }\n\n /** @internal Host blur. In a group, notifies the group's CVA touched callback; standalone, notifies the local CVA. */\n onBlur(): void {\n if (this.parent) {\n this.parent.notifyTouched();\n } else {\n this.onTouched();\n // Blur flips `touched` on `NgControl`; bump the revision so `errorState` recomputes.\n this.errorWiring.bump();\n }\n }\n\n /** Focuses the host element. Required for keyboard navigation from the group. */\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n\n // ── ControlValueAccessor (standalone use) ──\n\n writeValue(value: boolean | null | undefined): void {\n const next = !!value;\n this.internalChecked.set(next);\n this.checked.set(next);\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n // Track validator status/value changes on a bound NgControl so `errorState`\n // re-evaluates when status flips. Mirrors `input.ts`'s pattern.\n this.errorWiring.connect();\n }\n\n private hasAccessibleNameHint(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n const host = this.elementRef.nativeElement;\n return host.textContent !== null && host.textContent.trim().length > 0;\n }\n}\n\n// ── RadioGroup tv() config ───────────────────────────────────────\n\nconst radioGroupVariants = tv(\n {\n base: 'flex',\n variants: {\n orientation: {\n vertical: 'flex-col gap-2',\n horizontal: 'flex-row flex-wrap gap-3',\n },\n disabled: {\n true: 'opacity-50 pointer-events-none cursor-not-allowed',\n false: '',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\nlet nextGroupId = 0;\n\n// ── RadioGroupComponent ──────────────────────────────────────────\n\n@Component({\n selector: 'tw-radio-group',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<ng-content />`,\n host: {\n 'role': 'radiogroup',\n '[id]': 'hostId',\n '[class]': 'rootClasses()',\n '[attr.aria-orientation]': 'orientation()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-required]': 'required() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'ariaLabelledby() || null',\n '[attr.aria-describedby]': 'ariaDescribedby() || null',\n '(keydown)': 'onKeydown($event)',\n },\n})\n/**\n * A keyboard-navigable group of `<tw-radio>` children with shared color, size,\n * variant, and an owned selected `value`. The `T` type parameter is the type\n * of each radio's `value` input — typically a string-literal union, but any\n * value that compares with `===` works. Inferred when consumers bind via\n * `[(value)]`; explicit on `[formControl]` of `FormControl<T | null>`.\n */\nexport class RadioGroupComponent<T = unknown> implements ControlValueAccessor, OnInit {\n /** Sets the semantic color applied to the selected radio's dot/ring. Propagated to children unless a child overrides it. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls the overall scale of radios inside the group. Propagated to children unless a child overrides it. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Visual style of the selected indicator. `'solid'` fills the dot with the color against a colored ring; `'outline'` keeps a transparent fill with a colored ring and colored dot. Propagated to children unless a child overrides it. Defaults to `'solid'`. */\n readonly variant = input<RadioVariant>('solid');\n\n /** Layout direction of the group. Sets `aria-orientation` and the visual axis; both arrow-key pairs navigate in either orientation, per WAI-ARIA APG. Defaults to `'vertical'`. */\n readonly orientation = input<RadioOrientation>('vertical');\n\n /** When true, disables every radio in the group and blocks keyboard interaction. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** When true, sets `aria-required=\"true\"` on the group for assistive tech. Also inferred from `Validators.required` on a bound control, so a reactive/template-driven form does not have to state it twice. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /**\n * @internal Shared `errorState` / `required` / `errors` derivation — see\n * `wireErrorState`. Declared here, above `required`, because class field\n * initializers run in declaration order.\n */\n private readonly errorWiring = wireErrorState({\n ngControl: () => this.ngControl,\n matcher: () => this.errorStateMatcher(),\n required: () => this.requiredInput(),\n });\n\n /**\n * @internal Resolved required state: the `required` input OR'd with\n * `Validators.required` on a bound `NgControl`.\n */\n readonly required: Signal<boolean> = this.errorWiring.required;\n\n /** Optional form-association name. Propagated to each child radio's host `name` attribute so standard HTML form semantics still apply. */\n readonly name = input<string | undefined>(undefined);\n\n /** Accessible name for the group when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the group. Mirrored to `aria-labelledby`. Defaults to `undefined`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the group. Mirrored to `aria-describedby`. Defaults to `undefined`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /**\n * Two-way bound selected value. `null` means no selection. Defaults to\n * `null`.\n *\n * The two-way binding mints a `valueChange` output. That output is the\n * *any-change* channel: it fires when the user picks a radio **and** when a\n * bound form writes into the group (`FormControl.setValue`, `ngModel`,\n * `writeValue`). `(change)` is the *user-gesture-only* channel — bind that\n * one for analytics or a confirmation prompt, where a programmatic write must\n * not count as a click. Writing back into the same form from a\n * `(valueChange)` handler will echo.\n */\n readonly value = model<T | null>(null);\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the group uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /**\n * Fires after the selected value changes from a user interaction. Does\n * **not** fire when the value is updated programmatically via `writeValue` /\n * `FormControl.setValue` / `ngModel` — for those, bind the two-way binding's\n * `(valueChange)` instead, which fires on any change.\n */\n readonly change = output<T | null>();\n\n /** @internal Child radios discovered via content projection. */\n readonly radios = contentChildren(RadioComponent, { descendants: true });\n\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n\n readonly hostId = `tw-radio-group-${nextGroupId++}`;\n\n private onChange: (value: T | null) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n /** Effective disabled state — input OR CVA disabled. */\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n /** Group-level error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher; child radios inherit from this when wrapped in the group. */\n readonly errorState: Signal<boolean> = this.errorWiring.errorState;\n\n readonly activeValue = linkedSignal(() => this.value());\n\n private readonly variantResult = computed(() =>\n radioGroupVariants({\n orientation: this.orientation(),\n disabled: this.isDisabled(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult());\n\n constructor() {\n // Material-style CVA wiring: declare ourselves as the value accessor on any\n // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids\n // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create\n // because `NgControl` is injected with `self: true` on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.ariaLabel() && !this.ariaLabelledby()) {\n console.warn(\n '[tw-radio-group] The radiogroup has no accessible name. Set `aria-label` or `aria-labelledby`.',\n );\n }\n });\n }\n\n /** Selects the given value from a user interaction. Updates the model and notifies forms. */\n selectValue(next: unknown): void {\n if (this.isDisabled()) return;\n const typed = next as T | null;\n if (typed === this.activeValue()) {\n return;\n }\n this.activeValue.set(typed);\n this.value.set(typed);\n this.onChange(typed);\n // Deliberately NOT `onTouched()`. Angular's CVA contract registers\n // `onTouched` as the BLUR notification; calling it on selection flipped\n // `touched` with no blur, so a consumer staging error display on `touched`\n // got different behaviour from `tw-radio-group` than from `tw-slider` /\n // `tw-input`. `notifyTouched()` — reached from a child radio's real blur —\n // is the only place that fires it.\n this.change.emit(typed);\n }\n\n /** @internal Called by child radios on blur — propagates to CVA onTouched and bumps the errorState revision so a blur on a child radio refreshes the group's `aria-invalid`. */\n notifyTouched(): void {\n this.onTouched();\n this.errorWiring.bump();\n }\n\n /** @internal Handles roving-focus keyboard navigation (Arrow keys, Space) across the radios in the group. */\n onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) return;\n const radios = this.radios();\n if (radios.length === 0) return;\n\n const enabledCount = radios.reduce(\n (count, r) => (r.isDisabled() ? count : count + 1),\n 0,\n );\n if (enabledCount === 0) return;\n\n const currentIdx = radios.findIndex(\n (r: RadioComponent) => r.value() === this.activeValue(),\n );\n const startIdx = currentIdx >= 0 ? currentIdx : this.firstEnabledIndex(radios);\n\n let targetIndex = -1;\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n targetIndex = this.findNextEnabledIndex(radios, startIdx, 1);\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n targetIndex = this.findNextEnabledIndex(radios, startIdx, -1);\n break;\n case 'Home':\n targetIndex = this.firstEnabledIndex(radios);\n break;\n case 'End':\n targetIndex = this.lastEnabledIndex(radios);\n break;\n default:\n return;\n }\n\n if (targetIndex >= 0) {\n event.preventDefault();\n const target = radios[targetIndex];\n this.selectValue(target.value());\n target.focus();\n }\n }\n\n private findNextEnabledIndex(\n radios: readonly RadioComponent[],\n from: number,\n direction: 1 | -1,\n ): number {\n const len = radios.length;\n let idx = from;\n for (let i = 0; i < len; i++) {\n idx = (idx + direction + len) % len;\n if (!radios[idx].isDisabled()) return idx;\n }\n return -1;\n }\n\n private firstEnabledIndex(radios: readonly RadioComponent[]): number {\n for (let i = 0; i < radios.length; i++) {\n if (!radios[i].isDisabled()) return i;\n }\n return -1;\n }\n\n private lastEnabledIndex(radios: readonly RadioComponent[]): number {\n for (let i = radios.length - 1; i >= 0; i--) {\n if (!radios[i].isDisabled()) return i;\n }\n return -1;\n }\n\n // ── ControlValueAccessor ──\n\n writeValue(value: T | null): void {\n this.activeValue.set(value);\n this.value.set(value ?? null);\n }\n\n registerOnChange(fn: (value: T | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n // NgControl's `control` is set by the parent FormControl* directive before\n // children's `ngOnInit`. Subscribe here so errorState reacts to status/value\n // changes on the bound control.\n this.errorWiring.connect();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-radio.mjs","sources":["../../../projects/ngx-tw/radio/radio.ts","../../../projects/ngx-tw/radio/cdevhub-ngx-tw-radio.ts"],"sourcesContent":["import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n DestroyRef,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n type OnInit,\n output,\n signal,\n type Signal,\n} from '@angular/core';\nimport { type ControlValueAccessor, NgControl } from '@angular/forms';\nimport { FocusMonitor } from '@angular/cdk/a11y';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n type TwColor,\n type TwSize,\n wireErrorState,\n} from '@cdevhub/ngx-tw/core';\n\n/** Visual style of the selected radio indicator. */\nexport type RadioVariant = 'solid' | 'outline';\n\n/** Layout direction of a radio group. */\nexport type RadioOrientation = 'horizontal' | 'vertical';\n\n/** Position of the label relative to the radio control. */\nexport type RadioLabelPosition = 'before' | 'after';\n\n// ── Radio tv() config ────────────────────────────────────────────\n\nconst radioVariants = tv(\n {\n slots: {\n // `items-start` aligns circleWrap with the top of the label container; combined with\n // a `min-h-N` matching the label's first-line line-height on circleWrap, the circle\n // stays centered on the first line whether the label spans one line or many.\n //\n // ── Row-height scale (selection cohort) ──────────────────────────────\n // The rendered row is `max(circleWrap, label first line)`, and the host itself is the\n // click target (`role=\"radio\"` + `tabindex` + `(click)` all sit on the root), so the\n // row IS the interactive target. It runs 16 / 20 / 24 / 28 / 32 px — five distinct\n // steps, every one on the 4px baseline of docs/vertical-rhythm.md, and identical to\n // `checkbox` and `switch`. Selection controls are glyph-scale and deliberately do NOT\n // take the pinned 24/32/36/44/48 form-row scale (vertical-rhythm.md section 4).\n //\n // The row is driven by `circleWrap` min-h, NOT by the circle glyph, which keeps its own\n // 14 / 16 / 20 / 24 / 28 scale. Driving it from circleWrap is what makes the five steps\n // survive when no label is projected.\n //\n // Because centering demands `circleWrap height == label first-line leading`, the label\n // leading carries the same 4 / 5 / 6 / 7 / 8 progression. That is forced, not chosen:\n // the label font scale has only three steps (text-xs, text-sm, text-base), so leading\n // is the only lever that can break the sm/md and lg/xl ties. Before this, sm and md\n // both rendered a 20px row — a dead step. Accepted cost: `text-base leading-8` at xl is\n // a 2.0 line ratio, looser than typographic ideal on a wrapped multi-line label.\n root: 'inline-flex items-start gap-3 cursor-pointer select-none rounded-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n circleWrap: 'relative inline-flex items-center justify-center shrink-0',\n circle:\n 'inline-flex items-center justify-center rounded-full border bg-surface transition-colors duration-normal motion-reduce:transition-none',\n dotWrap:\n 'inline-flex items-center justify-center pointer-events-none',\n dot: 'inline-block rounded-full',\n labelWrap: 'flex flex-col min-w-0 empty:hidden',\n label: 'font-medium text-fg empty:hidden',\n description: 'text-fg-muted empty:hidden',\n },\n variants: {\n size: {\n xs: {\n // `size-3.5` half-step: aligns with text-xs/leading-4 row metric.\n circle: 'size-3.5',\n // The dot runs 6 / 8 / 10 / 12 / 14px — it is NOT on the status-dot sub-scale of\n // CLAUDE.md (that one is for standalone presence pips). It is a proportional inner\n // selection mark, held at ~50% of the enclosing circle at every size, so its value\n // is derived from `circle` rather than picked off a table. At xs, 50% of a 14px\n // circle is 7px, which no utility expresses; `size-1.5` (6px) is the nearest step\n // down — rounding up to 8px would leave under 3px of ring on each side.\n dot: 'size-1.5',\n circleWrap: 'min-h-4',\n label: 'text-xs leading-4',\n description: 'text-2xs leading-4',\n },\n sm: {\n circle: 'size-4',\n dot: 'size-2',\n circleWrap: 'min-h-5',\n label: 'text-sm leading-5',\n description: 'text-xs leading-4',\n },\n md: {\n circle: 'size-5',\n dot: 'size-2.5',\n // 24px row. `text-sm` is shared with sm by the documented font scale, so the\n // leading breaks the tie: leading-6 lifts the row off sm's 20px.\n circleWrap: 'min-h-6',\n label: 'text-sm leading-6',\n description: 'text-xs leading-4',\n },\n lg: {\n circle: 'size-6',\n dot: 'size-3',\n // 28px row — leading-7 keeps the first label line the same height as circleWrap.\n circleWrap: 'min-h-7',\n label: 'text-base leading-7',\n description: 'text-sm leading-5',\n },\n xl: {\n circle: 'size-7',\n // xl density: dot uses `size-3.5` (14px) as the proportionally-sized\n // selection mark inside the size-7 (28px) circle — exactly 50%.\n dot: 'size-3.5',\n // 32px row. `text-base` is shared with lg, so leading-8 breaks that tie the same\n // way leading-6 breaks sm/md. A 2.0 ratio on a wrapped label is the accepted cost.\n circleWrap: 'min-h-8',\n label: 'text-base leading-8',\n description: 'text-sm leading-5',\n },\n },\n labelPosition: {\n before: { root: 'flex-row-reverse' },\n after: { root: 'flex-row' },\n },\n checked: {\n true: { circle: '' },\n false: { circle: 'border-border hover:border-border-strong' },\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: { root: '' },\n },\n errorState: {\n true: { circle: '', label: 'text-error-700', description: 'text-error-600' },\n false: { circle: '', label: '', description: '' },\n },\n },\n compoundVariants: [\n // Error state on an unchecked radio repaints the ring with the error color.\n { errorState: true, checked: false, class: { circle: 'border-error-500 hover:border-error-600' } },\n ],\n defaultVariants: {\n size: 'md',\n labelPosition: 'after',\n checked: false,\n disabled: false,\n errorState: false,\n },\n },\n { twMerge: true },\n);\n\n// ── Static selected-state color lookups (all classes written statically for Tailwind v4 scanning) ──\n\nconst SOLID_RING: Record<TwColor, string> = {\n primary: 'border-primary-600',\n secondary: 'border-secondary-600',\n accent: 'border-accent-600',\n neutral: 'border-fg',\n info: 'border-info-600',\n success: 'border-success-600',\n warning: 'border-warning-border-strong',\n error: 'border-error-600',\n};\n\nconst SOLID_DOT: Record<TwColor, string> = {\n primary: 'bg-primary-600',\n secondary: 'bg-secondary-600',\n accent: 'bg-accent-600',\n neutral: 'bg-fg',\n info: 'bg-info-600',\n success: 'bg-success-600',\n warning: 'bg-warning-500',\n error: 'bg-error-600',\n};\n\nconst OUTLINE_RING: Record<TwColor, string> = {\n primary: 'border-primary-600',\n secondary: 'border-secondary-600',\n accent: 'border-accent-600',\n neutral: 'border-fg',\n info: 'border-info-600',\n success: 'border-success-600',\n warning: 'border-warning-border-strong',\n error: 'border-error-600',\n};\n\nconst OUTLINE_DOT: Record<TwColor, string> = {\n primary: 'bg-primary-600',\n secondary: 'bg-secondary-600',\n accent: 'bg-accent-600',\n neutral: 'bg-fg',\n info: 'bg-info-600',\n success: 'bg-success-600',\n warning: 'bg-warning-500',\n error: 'bg-error-600',\n};\n\nlet nextRadioId = 0;\n\n// ── RadioComponent ───────────────────────────────────────────────\n\n@Component({\n selector: 'tw-radio',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <span [class]=\"circleWrapClasses()\">\n <span [class]=\"circleClasses()\">\n @if (isSelected()) {\n <span [class]=\"dotWrapClasses()\" animate.enter=\"check-in\">\n <ng-content select=\"[slot='dot']\">\n <span [class]=\"dotClasses()\"></span>\n </ng-content>\n </span>\n }\n </span>\n </span>\n\n <span [class]=\"labelWrapClasses()\">\n <span [id]=\"labelId\" [class]=\"labelClasses()\">\n <ng-content />\n @if (label()) {\n {{ label() }}\n }\n </span>\n <span [id]=\"descriptionId\" [class]=\"descriptionClasses()\">\n <ng-content select=\"[slot='description']\" />\n @if (description()) {\n {{ description() }}\n }\n </span>\n </span>\n `,\n host: {\n 'role': 'radio',\n '[id]': 'hostId',\n '[class]': 'rootClasses()',\n '[attr.data-checked]': 'isSelected()',\n '[attr.aria-checked]': 'isSelected() ? \"true\" : \"false\"',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'effectiveAriaLabelledby() || null',\n '[attr.aria-describedby]': 'effectiveAriaDescribedby() || null',\n '[attr.tabindex]': 'isFocusable() ? 0 : -1',\n '[attr.name]': 'effectiveName() || null',\n '(click)': 'onActivate()',\n '(keydown)': 'onKeydown($event)',\n '(blur)': 'onBlur()',\n },\n})\nexport class RadioComponent implements ControlValueAccessor, OnInit {\n /** The value this radio contributes when selected inside a `tw-radio-group`. Required when nested in a group; ignored when used standalone. Defaults to `undefined`. */\n readonly value = input<unknown>(undefined);\n\n /** Overrides the parent group's color for this radio. When undefined, inherits from the group (or defaults to `'primary'` standalone). */\n readonly color = input<TwColor | undefined>(undefined);\n\n /** Overrides the parent group's size for this radio. When undefined, inherits from the group (or defaults to `'md'` standalone). */\n readonly size = input<TwSize | undefined>(undefined);\n\n /** Overrides the parent group's variant for this radio. When undefined, inherits from the group (or defaults to `'solid'` standalone). */\n readonly variant = input<RadioVariant | undefined>(undefined);\n\n /** When true, disables this radio regardless of the group's state. Group-disabled always wins as an OR. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** Optional inline label rendered next to the radio. Use default content projection for rich label content instead. */\n readonly label = input<string | undefined>(undefined);\n\n /** Optional secondary description rendered under the label. Use `[slot=\"description\"]` content projection for rich content instead. */\n readonly description = input<string | undefined>(undefined);\n\n /** Position of the label/description relative to the radio. Defaults to `'after'`. */\n readonly labelPosition = input<RadioLabelPosition>('after');\n\n /** Optional name attribute for standalone use. Ignored when the parent group provides a name. */\n readonly name = input<string | undefined>(undefined);\n\n /** Accessible name when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the radio. Mirrored to `aria-labelledby`. Defaults to `undefined`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the radio. Mirrored to `aria-describedby`. Defaults to `undefined`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /**\n * Two-way bound checked state. Authoritative only in standalone mode.\n * Defaults to `false`.\n *\n * Standalone, the minted `checkedChange` output is the *any-change* channel:\n * it fires both when the user selects this radio and when a bound form writes\n * into it (`FormControl.setValue`, `ngModel`, `writeValue`). `(change)` is the\n * *user-gesture-only* channel — bind that one for analytics or a confirmation\n * prompt, where a programmatic write must not count as a click.\n *\n * Inside a `tw-radio-group` this model is inert: the group owns selection,\n * the rendered state comes from the group's `value`, and the component never\n * writes `checked` — so `(checkedChange)` never fires on a grouped radio.\n * `(change)` still fires when this radio becomes the selected one. Bind the\n * group's `[(value)]` / `(change)` instead.\n */\n readonly checked = model(false);\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the radio uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /**\n * Fires after the checked state changes from a user interaction on this\n * radio. In grouped mode only fires when this radio becomes the selected one.\n * Does **not** fire when selection is updated programmatically via\n * `writeValue` / `FormControl.setValue` / `ngModel` — standalone, bind the\n * two-way binding's `(checkedChange)` for that, which fires on any change.\n * (Grouped, `(checkedChange)` never fires at all; use the group's\n * `[(value)]`.)\n */\n readonly change = output<boolean>();\n\n private readonly focusMonitor = inject(FocusMonitor);\n readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly parent = inject(forwardRef(() => RadioGroupComponent), { optional: true });\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n\n private onChange: (value: boolean) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n /** @internal Shared `errorState` derivation — see `wireErrorState`. */\n private readonly errorWiring = wireErrorState({\n ngControl: () => this.ngControl,\n matcher: () => this.errorStateMatcher(),\n // A radio inside a group inherits the group's error state verbatim,\n // including `false`; standalone it falls through to the matcher.\n errorStateOverride: () => (this.parent ? this.parent.errorState() : undefined),\n });\n\n private readonly uid = nextRadioId++;\n readonly hostId = `tw-radio-${this.uid}`;\n readonly labelId = `${this.hostId}-label`;\n readonly descriptionId = `${this.hostId}-description`;\n\n private readonly internalChecked = linkedSignal(() => this.checked());\n\n /** Resolved color — radio's own color wins, then group's, then `'primary'`. */\n readonly effectiveColor = computed<TwColor>(\n () => this.color() ?? this.parent?.color() ?? 'primary',\n );\n\n /** Resolved size — radio's own size wins, then group's, then `'md'`. */\n readonly effectiveSize = computed<TwSize>(\n () => this.size() ?? this.parent?.size() ?? 'md',\n );\n\n /** Resolved variant — radio's own variant wins, then group's, then `'solid'`. */\n readonly effectiveVariant = computed<RadioVariant>(\n () => this.variant() ?? this.parent?.variant() ?? 'solid',\n );\n\n /** Resolved name attribute — parent group's name wins for HTML form semantics. */\n readonly effectiveName = computed(() => this.parent?.name() ?? this.name());\n\n /** Whether this radio is currently selected (grouped: parent.value === this.value; standalone: internal checked). */\n readonly isSelected = computed(() => {\n if (this.parent) return this.parent.value() === this.value();\n return this.internalChecked();\n });\n\n /** Whether this radio is disabled (own disabled OR parent's disabled OR CVA-disabled). */\n readonly isDisabled = computed(\n () => this.disabled() || this.cvaDisabled() || (this.parent?.isDisabled() ?? false),\n );\n\n /** Whether the radio is in an error state per the configured `ErrorStateMatcher`. Inherits from the parent group when wrapped; falls back to its own NgControl when standalone. */\n readonly errorState: Signal<boolean> = this.errorWiring.errorState;\n\n /** Roving tabindex: in a group, only the selected (or first enabled if none selected) radio is focusable. Standalone radios are always focusable unless disabled. */\n readonly isFocusable = computed(() => {\n if (this.isDisabled()) return false;\n if (!this.parent) return true;\n if (this.isSelected()) return true;\n const parentValue = this.parent.value();\n if (parentValue === null || parentValue === undefined) {\n const firstEnabled = this.parent\n .radios()\n .find((r: RadioComponent) => !r.isDisabled());\n return firstEnabled === this;\n }\n return false;\n });\n\n readonly effectiveAriaLabelledby = computed(() => {\n const external = this.ariaLabelledby();\n if (external) return external;\n if (this.ariaLabel()) return undefined;\n return this.labelId;\n });\n\n readonly effectiveAriaDescribedby = computed(() => {\n const external = this.ariaDescribedby();\n if (external) return external;\n return this.descriptionId;\n });\n\n private readonly variantResult = computed(() =>\n radioVariants({\n size: this.effectiveSize(),\n labelPosition: this.labelPosition(),\n checked: this.isSelected(),\n disabled: this.isDisabled(),\n errorState: this.errorState(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly circleWrapClasses = computed(() => this.variantResult().circleWrap());\n readonly labelWrapClasses = computed(() => this.variantResult().labelWrap());\n readonly labelClasses = computed(() => this.variantResult().label());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly dotWrapClasses = computed(() => this.variantResult().dotWrap());\n\n readonly circleClasses = computed(() => {\n const base = this.variantResult().circle();\n if (!this.isSelected()) return base;\n const ringLookup = this.effectiveVariant() === 'solid' ? SOLID_RING : OUTLINE_RING;\n return `${base} ${ringLookup[this.effectiveColor()]}`;\n });\n\n readonly dotClasses = computed(() => {\n const base = this.variantResult().dot();\n const dotLookup = this.effectiveVariant() === 'solid' ? SOLID_DOT : OUTLINE_DOT;\n return `${base} ${dotLookup[this.effectiveColor()]}`;\n });\n\n constructor() {\n // Material-style CVA wiring for standalone `<tw-radio>` use. Mirrors\n // `checkbox.ts` / `slider.ts` — avoids the circular-DI a static\n // `NG_VALUE_ACCESSOR` provider would create when `NgControl` is injected\n // with `self: true` on the same element. When this radio is wrapped in a\n // `tw-radio-group`, the group owns CVA and child `NgControl` bindings are\n // not expected (no `[(ngModel)]` on children).\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-radio] The radio has no accessible name. Provide a `label` input, project label content, or set `aria-label` / `aria-labelledby`.',\n );\n }\n });\n }\n\n /** Called by user click or group keyboard handler. Selects this radio. */\n onActivate(): void {\n if (this.isDisabled()) return;\n if (this.parent) {\n const wasSelected = this.isSelected();\n this.parent.selectValue(this.value());\n if (!wasSelected) {\n this.change.emit(true);\n }\n return;\n }\n // Standalone — match native <input type=\"radio\">: clicking does not toggle back off\n if (!this.internalChecked()) {\n this.internalChecked.set(true);\n this.checked.set(true);\n this.onChange(true);\n // Deliberately NOT `onTouched()` — that is the blur notification, and\n // `onBlur()` owns it. See the note on `RadioGroupComponent.selectValue`.\n this.change.emit(true);\n }\n }\n\n /** Handles keyboard activation. Space selects; Enter does NOT — matches native `<input type=\"radio\">` semantics. */\n onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) return;\n if (event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n this.onActivate();\n }\n }\n\n /** @internal Host blur. In a group, notifies the group's CVA touched callback; standalone, notifies the local CVA. */\n onBlur(): void {\n if (this.parent) {\n this.parent.notifyTouched();\n } else {\n this.onTouched();\n // Blur flips `touched` on `NgControl`; bump the revision so `errorState` recomputes.\n this.errorWiring.bump();\n }\n }\n\n /** Focuses the host element. Required for keyboard navigation from the group. */\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n\n // ── ControlValueAccessor (standalone use) ──\n\n writeValue(value: boolean | null | undefined): void {\n const next = !!value;\n this.internalChecked.set(next);\n this.checked.set(next);\n }\n\n registerOnChange(fn: (value: boolean) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n // Track validator status/value changes on a bound NgControl so `errorState`\n // re-evaluates when status flips. Mirrors `input.ts`'s pattern.\n this.errorWiring.connect();\n }\n\n private hasAccessibleNameHint(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n const host = this.elementRef.nativeElement;\n return host.textContent !== null && host.textContent.trim().length > 0;\n }\n}\n\n// ── RadioGroup tv() config ───────────────────────────────────────\n\nconst radioGroupVariants = tv(\n {\n base: 'flex',\n variants: {\n orientation: {\n vertical: 'flex-col gap-2',\n horizontal: 'flex-row flex-wrap gap-3',\n },\n disabled: {\n true: 'opacity-50 pointer-events-none cursor-not-allowed',\n false: '',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\nlet nextGroupId = 0;\n\n// ── RadioGroupComponent ──────────────────────────────────────────\n\n@Component({\n selector: 'tw-radio-group',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<ng-content />`,\n host: {\n 'role': 'radiogroup',\n '[id]': 'hostId',\n '[class]': 'rootClasses()',\n '[attr.aria-orientation]': 'orientation()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-required]': 'required() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'ariaLabelledby() || null',\n '[attr.aria-describedby]': 'ariaDescribedby() || null',\n '(keydown)': 'onKeydown($event)',\n },\n})\n/**\n * A keyboard-navigable group of `<tw-radio>` children with shared color, size,\n * variant, and an owned selected `value`. The `T` type parameter is the type\n * of each radio's `value` input — typically a string-literal union, but any\n * value that compares with `===` works. Inferred when consumers bind via\n * `[(value)]`; explicit on `[formControl]` of `FormControl<T | null>`.\n */\nexport class RadioGroupComponent<T = unknown> implements ControlValueAccessor, OnInit {\n /** Sets the semantic color applied to the selected radio's dot/ring. Propagated to children unless a child overrides it. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls the overall scale of radios inside the group. Propagated to children unless a child overrides it. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Visual style of the selected indicator. `'solid'` fills the dot with the color against a colored ring; `'outline'` keeps a transparent fill with a colored ring and colored dot. Propagated to children unless a child overrides it. Defaults to `'solid'`. */\n readonly variant = input<RadioVariant>('solid');\n\n /** Layout direction of the group. Sets `aria-orientation` and the visual axis; both arrow-key pairs navigate in either orientation, per WAI-ARIA APG. Defaults to `'vertical'`. */\n readonly orientation = input<RadioOrientation>('vertical');\n\n /** When true, disables every radio in the group and blocks keyboard interaction. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** When true, sets `aria-required=\"true\"` on the group for assistive tech. Also inferred from `Validators.required` on a bound control, so a reactive/template-driven form does not have to state it twice. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /**\n * @internal Shared `errorState` / `required` / `errors` derivation — see\n * `wireErrorState`. Declared here, above `required`, because class field\n * initializers run in declaration order.\n */\n private readonly errorWiring = wireErrorState({\n ngControl: () => this.ngControl,\n matcher: () => this.errorStateMatcher(),\n required: () => this.requiredInput(),\n });\n\n /**\n * @internal Resolved required state: the `required` input OR'd with\n * `Validators.required` on a bound `NgControl`.\n */\n readonly required: Signal<boolean> = this.errorWiring.required;\n\n /** Optional form-association name. Propagated to each child radio's host `name` attribute so standard HTML form semantics still apply. */\n readonly name = input<string | undefined>(undefined);\n\n /** Accessible name for the group when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the group. Mirrored to `aria-labelledby`. Defaults to `undefined`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the group. Mirrored to `aria-describedby`. Defaults to `undefined`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /**\n * Two-way bound selected value. `null` means no selection. Defaults to\n * `null`.\n *\n * The two-way binding mints a `valueChange` output. That output is the\n * *any-change* channel: it fires when the user picks a radio **and** when a\n * bound form writes into the group (`FormControl.setValue`, `ngModel`,\n * `writeValue`). `(change)` is the *user-gesture-only* channel — bind that\n * one for analytics or a confirmation prompt, where a programmatic write must\n * not count as a click. Writing back into the same form from a\n * `(valueChange)` handler will echo.\n */\n readonly value = model<T | null>(null);\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the group uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /**\n * Fires after the selected value changes from a user interaction. Does\n * **not** fire when the value is updated programmatically via `writeValue` /\n * `FormControl.setValue` / `ngModel` — for those, bind the two-way binding's\n * `(valueChange)` instead, which fires on any change.\n */\n readonly change = output<T | null>();\n\n /** @internal Child radios discovered via content projection. */\n readonly radios = contentChildren(RadioComponent, { descendants: true });\n\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n\n readonly hostId = `tw-radio-group-${nextGroupId++}`;\n\n private onChange: (value: T | null) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n /** Effective disabled state — input OR CVA disabled. */\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n /** Group-level error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher; child radios inherit from this when wrapped in the group. */\n readonly errorState: Signal<boolean> = this.errorWiring.errorState;\n\n readonly activeValue = linkedSignal(() => this.value());\n\n private readonly variantResult = computed(() =>\n radioGroupVariants({\n orientation: this.orientation(),\n disabled: this.isDisabled(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult());\n\n constructor() {\n // Material-style CVA wiring: declare ourselves as the value accessor on any\n // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids\n // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create\n // because `NgControl` is injected with `self: true` on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.ariaLabel() && !this.ariaLabelledby()) {\n console.warn(\n '[tw-radio-group] The radiogroup has no accessible name. Set `aria-label` or `aria-labelledby`.',\n );\n }\n });\n }\n\n /** Selects the given value from a user interaction. Updates the model and notifies forms. */\n selectValue(next: unknown): void {\n if (this.isDisabled()) return;\n const typed = next as T | null;\n if (typed === this.activeValue()) {\n return;\n }\n this.activeValue.set(typed);\n this.value.set(typed);\n this.onChange(typed);\n // Deliberately NOT `onTouched()`. Angular's CVA contract registers\n // `onTouched` as the BLUR notification; calling it on selection flipped\n // `touched` with no blur, so a consumer staging error display on `touched`\n // got different behaviour from `tw-radio-group` than from `tw-slider` /\n // `tw-input`. `notifyTouched()` — reached from a child radio's real blur —\n // is the only place that fires it.\n this.change.emit(typed);\n }\n\n /** @internal Called by child radios on blur — propagates to CVA onTouched and bumps the errorState revision so a blur on a child radio refreshes the group's `aria-invalid`. */\n notifyTouched(): void {\n this.onTouched();\n this.errorWiring.bump();\n }\n\n /** @internal Handles roving-focus keyboard navigation (Arrow keys, Space) across the radios in the group. */\n onKeydown(event: KeyboardEvent): void {\n if (this.isDisabled()) return;\n const radios = this.radios();\n if (radios.length === 0) return;\n\n const enabledCount = radios.reduce(\n (count, r) => (r.isDisabled() ? count : count + 1),\n 0,\n );\n if (enabledCount === 0) return;\n\n const currentIdx = radios.findIndex(\n (r: RadioComponent) => r.value() === this.activeValue(),\n );\n const startIdx = currentIdx >= 0 ? currentIdx : this.firstEnabledIndex(radios);\n\n let targetIndex = -1;\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n targetIndex = this.findNextEnabledIndex(radios, startIdx, 1);\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n targetIndex = this.findNextEnabledIndex(radios, startIdx, -1);\n break;\n case 'Home':\n targetIndex = this.firstEnabledIndex(radios);\n break;\n case 'End':\n targetIndex = this.lastEnabledIndex(radios);\n break;\n default:\n return;\n }\n\n if (targetIndex >= 0) {\n event.preventDefault();\n const target = radios[targetIndex];\n this.selectValue(target.value());\n target.focus();\n }\n }\n\n private findNextEnabledIndex(\n radios: readonly RadioComponent[],\n from: number,\n direction: 1 | -1,\n ): number {\n const len = radios.length;\n let idx = from;\n for (let i = 0; i < len; i++) {\n idx = (idx + direction + len) % len;\n if (!radios[idx].isDisabled()) return idx;\n }\n return -1;\n }\n\n private firstEnabledIndex(radios: readonly RadioComponent[]): number {\n for (let i = 0; i < radios.length; i++) {\n if (!radios[i].isDisabled()) return i;\n }\n return -1;\n }\n\n private lastEnabledIndex(radios: readonly RadioComponent[]): number {\n for (let i = radios.length - 1; i >= 0; i--) {\n if (!radios[i].isDisabled()) return i;\n }\n return -1;\n }\n\n // ── ControlValueAccessor ──\n\n writeValue(value: T | null): void {\n this.activeValue.set(value);\n this.value.set(value ?? null);\n }\n\n registerOnChange(fn: (value: T | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n ngOnInit(): void {\n this.focusMonitor.monitor(this.elementRef);\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n // NgControl's `control` is set by the parent FormControl* directive before\n // children's `ngOnInit`. Subscribe here so errorState reacts to status/value\n // changes on the bound control.\n this.errorWiring.connect();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, TemplateRef, Directive, input, contentChild, viewChild, ChangeDetectionStrategy, Component, ElementRef, computed, model, output, DestroyRef, contentChildren, viewChildren, linkedSignal, signal, afterNextRender, effect, untracked } from '@angular/core';
2
+ import { inject, TemplateRef, Directive, input, booleanAttribute, computed, contentChild, viewChild, ChangeDetectionStrategy, Component, ElementRef, model, output, DestroyRef, contentChildren, viewChildren, linkedSignal, signal, afterNextRender, effect, untracked } from '@angular/core';
3
3
  import { NgTemplateOutlet } from '@angular/common';
4
4
  import { LiveAnnouncer, FocusKeyManager } from '@angular/cdk/a11y';
5
5
  import { Directionality } from '@angular/cdk/bidi';
@@ -132,9 +132,29 @@ class TabComponent {
132
132
  /** When true, the tab cannot be selected and is skipped by keyboard navigation. Defaults to false. */
133
133
  disabled = input(false, /* @ts-ignore */
134
134
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
135
- /** When true, a dismiss control is rendered in the tab trigger. The control is pointer-only; the keyboard gesture is Delete on the focused tab. Defaults to false. */
136
- closable = input(false, /* @ts-ignore */
137
- ...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
135
+ /**
136
+ * When true, a dismiss control is rendered in the tab trigger. The control is pointer-only; the keyboard gesture is Delete on the focused tab. Defaults to false.
137
+ *
138
+ * @deprecated Bind `dismissible` instead. `closable` was the library's only
139
+ * spelling of this concept — `alert`, `badge` and `toast` all call it
140
+ * `dismissible` — and one idea should not have two names. Both work; `closable`
141
+ * is removed in the next major.
142
+ */
143
+ closable = input(false, { ...(ngDevMode ? { debugName: "closable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
144
+ /**
145
+ * When true, a dismiss control is rendered in the tab trigger. The control is pointer-only; the keyboard gesture is Delete on the focused tab. Defaults to false.
146
+ *
147
+ * Canonical spelling, matching `alert`, `badge` and `toast`. Supersedes the
148
+ * deprecated `closable`; binding either one enables the control.
149
+ */
150
+ dismissible = input(false, { ...(ngDevMode ? { debugName: "dismissible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
151
+ /**
152
+ * @internal Whether a dismiss control should render, from either spelling.
153
+ * Both inputs default to `false`, so `||` is the correct reconciliation: it is
154
+ * true exactly when the consumer opted in through one name or the other.
155
+ */
156
+ isDismissible = computed(() => this.dismissible() || this.closable(), /* @ts-ignore */
157
+ ...(ngDevMode ? [{ debugName: "isDismissible" }] : /* istanbul ignore next */ []));
138
158
  /** When true, the tab panel content is only instantiated when the tab becomes active for the first time. Defaults to false. */
139
159
  lazy = input(false, /* @ts-ignore */
140
160
  ...(ngDevMode ? [{ debugName: "lazy" }] : /* istanbul ignore next */ []));
@@ -148,7 +168,7 @@ class TabComponent {
148
168
  implicitContentTemplate = viewChild('implicitContent', /* @ts-ignore */
149
169
  ...(ngDevMode ? [{ debugName: "implicitContentTemplate" }] : /* istanbul ignore next */ []));
150
170
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
151
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.7", type: TabComponent, isStandalone: true, selector: "tw-tab", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: none" }, queries: [{ propertyName: "triggerTemplate", first: true, predicate: TabTriggerDirective, descendants: true, isSignal: true }, { propertyName: "contentTemplate", first: true, predicate: TabContentDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "implicitContentTemplate", first: true, predicate: ["implicitContent"], descendants: true, isSignal: true }], ngImport: i0, template: `
171
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.7", type: TabComponent, isStandalone: true, selector: "tw-tab", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: none" }, queries: [{ propertyName: "triggerTemplate", first: true, predicate: TabTriggerDirective, descendants: true, isSignal: true }, { propertyName: "contentTemplate", first: true, predicate: TabContentDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "implicitContentTemplate", first: true, predicate: ["implicitContent"], descendants: true, isSignal: true }], ngImport: i0, template: `
152
172
  <ng-template #implicitContent>
153
173
  <ng-content />
154
174
  </ng-template>
@@ -168,7 +188,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
168
188
  'style': 'display: none',
169
189
  },
170
190
  }]
171
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], triggerTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TabTriggerDirective), { isSignal: true }] }], contentTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TabContentDirective), { isSignal: true }] }], implicitContentTemplate: [{ type: i0.ViewChild, args: ['implicitContent', { isSignal: true }] }] } });
191
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], triggerTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TabTriggerDirective), { isSignal: true }] }], contentTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TabContentDirective), { isSignal: true }] }], implicitContentTemplate: [{ type: i0.ViewChild, args: ['implicitContent', { isSignal: true }] }] } });
172
192
  // ── Tab trigger element wrapper ──
173
193
  class TabTriggerElementDirective {
174
194
  elementRef = inject((ElementRef));
@@ -441,7 +461,7 @@ class TabsComponent {
441
461
  // on the trigger advertises this gesture to assistive tech.
442
462
  if (event.key === 'Delete' && focusedIdx >= 0) {
443
463
  const tab = this.tabs()[focusedIdx];
444
- if (tab.closable() && !tab.disabled()) {
464
+ if (tab.isDismissible() && !tab.disabled()) {
445
465
  event.preventDefault();
446
466
  this.closeTab(tab, event);
447
467
  return;
@@ -595,13 +615,13 @@ class TabsComponent {
595
615
  this.scrollCleanup = () => el.removeEventListener('scroll', onScroll);
596
616
  }
597
617
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
598
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: TabsComponent, isStandalone: true, selector: "tw-tabs", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, fitted: { classPropertyName: "fitted", publicName: "fitted", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", closed: "closed" }, host: { properties: { "class": "rootClasses()" } }, queries: [{ propertyName: "tabs", predicate: TabComponent, isSignal: true }], viewQueries: [{ propertyName: "triggerElements", predicate: TabTriggerElementDirective, descendants: true, isSignal: true }, { propertyName: "tablistInnerRef", first: true, predicate: ["tablistInner"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Tablist container. WAI-ARIA tablist owns roving focus on the tab elements\n inside; the container itself relays keydown but isn't tabbable. -->\n<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div\n [class]=\"tablistClasses()\"\n role=\"tablist\"\n [attr.aria-orientation]=\"orientation()\"\n (keydown)=\"onKeydown($event)\"\n>\n <!-- Scroll start button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollStart()\"\n (click)=\"scrollStart()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n\n <!-- Scrollable trigger strip -->\n <div #tablistInner [class]=\"tablistInnerClasses()\" style=\"scrollbar-width: none\">\n @for (tab of tabs(); track tab.value()) {\n <!-- Trigger is rendered as <div role=\"tab\">, not <button>: activation is\n wired explicitly via (click) and the parent tablist's keydown\n (Enter / Space), and the roving tab stop comes from\n twTabTriggerElement. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n role=\"tab\"\n twTabTriggerElement\n [isFocusStop]=\"isTabFocusStop(tab.value())\"\n [isDisabled]=\"tab.disabled()\"\n [id]=\"getTabId(tab.value())\"\n [attr.aria-selected]=\"isTabActive(tab.value())\"\n [attr.aria-controls]=\"getPanelId(tab.value())\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.aria-keyshortcuts]=\"tab.closable() && !tab.disabled() ? 'Delete' : null\"\n [class]=\"getTriggerClasses(tab.value(), isTabActive(tab.value()))\"\n [class.opacity-50]=\"tab.disabled()\"\n [class.pointer-events-none]=\"tab.disabled()\"\n (click)=\"selectTab(tab)\"\n >\n <!-- Custom trigger template or default label -->\n @if (tab.triggerTemplate(); as triggerDir) {\n <ng-container\n [ngTemplateOutlet]=\"triggerDir.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: { active: isTabActive(tab.value()), disabled: tab.disabled(), value: tab.value() } }\"\n />\n } @else {\n {{ tab.label() }}\n }\n\n <!-- Close affordance \u2014 a pointer-only span, deliberately NOT a button.\n Anything focusable inside an element carrying an interactive role\n fails axe's nested-interactive rule, and hoisting a real button\n out to a sibling only trades that for aria-required-children\n (a tablist may own nothing but tabs \u2014 both measured). The\n keyboard path is the APG-recommended Delete key on the tab\n itself, handled in onKeydown and advertised to assistive tech\n through aria-keyshortcuts on the trigger above. -->\n @if (tab.closable() && !tab.disabled()) {\n <span\n data-tw-tab-close\n aria-hidden=\"true\"\n [class]=\"closeButtonClasses()\"\n (click)=\"closeTab(tab, $event)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\"/>\n </svg>\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Scroll end button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollEnd()\"\n (click)=\"scrollEnd()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n</div>\n\n<!-- Tab panels -->\n@for (tab of tabs(); track tab.value()) {\n @if (shouldRenderPanel(tab)) {\n <div\n role=\"tabpanel\"\n [id]=\"getPanelId(tab.value())\"\n [attr.aria-labelledby]=\"getTabId(tab.value())\"\n [class]=\"panelClasses()\"\n [hidden]=\"!isTabActive(tab.value())\"\n tabindex=\"0\"\n >\n @if (tab.contentTemplate(); as contentDir) {\n <ng-container [ngTemplateOutlet]=\"contentDir.templateRef\" />\n } @else if (tab.implicitContentTemplate(); as implicitTpl) {\n <ng-container [ngTemplateOutlet]=\"implicitTpl\" />\n }\n </div>\n }\n}\n\n<!-- Hidden projection slot for tw-tab children -->\n<div style=\"display: none\">\n <ng-content />\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TabTriggerElementDirective, selector: "[twTabTriggerElement]", inputs: ["isFocusStop", "isDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
618
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: TabsComponent, isStandalone: true, selector: "tw-tabs", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, fitted: { classPropertyName: "fitted", publicName: "fitted", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", closed: "closed" }, host: { properties: { "class": "rootClasses()" } }, queries: [{ propertyName: "tabs", predicate: TabComponent, isSignal: true }], viewQueries: [{ propertyName: "triggerElements", predicate: TabTriggerElementDirective, descendants: true, isSignal: true }, { propertyName: "tablistInnerRef", first: true, predicate: ["tablistInner"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Tablist container. WAI-ARIA tablist owns roving focus on the tab elements\n inside; the container itself relays keydown but isn't tabbable. -->\n<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div\n [class]=\"tablistClasses()\"\n role=\"tablist\"\n [attr.aria-orientation]=\"orientation()\"\n (keydown)=\"onKeydown($event)\"\n>\n <!-- Scroll start button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollStart()\"\n (click)=\"scrollStart()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n\n <!-- Scrollable trigger strip -->\n <div #tablistInner [class]=\"tablistInnerClasses()\" style=\"scrollbar-width: none\">\n @for (tab of tabs(); track tab.value()) {\n <!-- Trigger is rendered as <div role=\"tab\">, not <button>: activation is\n wired explicitly via (click) and the parent tablist's keydown\n (Enter / Space), and the roving tab stop comes from\n twTabTriggerElement. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n role=\"tab\"\n twTabTriggerElement\n [isFocusStop]=\"isTabFocusStop(tab.value())\"\n [isDisabled]=\"tab.disabled()\"\n [id]=\"getTabId(tab.value())\"\n [attr.aria-selected]=\"isTabActive(tab.value())\"\n [attr.aria-controls]=\"getPanelId(tab.value())\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.aria-keyshortcuts]=\"tab.isDismissible() && !tab.disabled() ? 'Delete' : null\"\n [class]=\"getTriggerClasses(tab.value(), isTabActive(tab.value()))\"\n [class.opacity-50]=\"tab.disabled()\"\n [class.pointer-events-none]=\"tab.disabled()\"\n (click)=\"selectTab(tab)\"\n >\n <!-- Custom trigger template or default label -->\n @if (tab.triggerTemplate(); as triggerDir) {\n <ng-container\n [ngTemplateOutlet]=\"triggerDir.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: { active: isTabActive(tab.value()), disabled: tab.disabled(), value: tab.value() } }\"\n />\n } @else {\n {{ tab.label() }}\n }\n\n <!-- Close affordance \u2014 a pointer-only span, deliberately NOT a button.\n Anything focusable inside an element carrying an interactive role\n fails axe's nested-interactive rule, and hoisting a real button\n out to a sibling only trades that for aria-required-children\n (a tablist may own nothing but tabs \u2014 both measured). The\n keyboard path is the APG-recommended Delete key on the tab\n itself, handled in onKeydown and advertised to assistive tech\n through aria-keyshortcuts on the trigger above. -->\n @if (tab.isDismissible() && !tab.disabled()) {\n <span\n data-tw-tab-close\n aria-hidden=\"true\"\n [class]=\"closeButtonClasses()\"\n (click)=\"closeTab(tab, $event)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\"/>\n </svg>\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Scroll end button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollEnd()\"\n (click)=\"scrollEnd()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n</div>\n\n<!-- Tab panels -->\n@for (tab of tabs(); track tab.value()) {\n @if (shouldRenderPanel(tab)) {\n <div\n role=\"tabpanel\"\n [id]=\"getPanelId(tab.value())\"\n [attr.aria-labelledby]=\"getTabId(tab.value())\"\n [class]=\"panelClasses()\"\n [hidden]=\"!isTabActive(tab.value())\"\n tabindex=\"0\"\n >\n @if (tab.contentTemplate(); as contentDir) {\n <ng-container [ngTemplateOutlet]=\"contentDir.templateRef\" />\n } @else if (tab.implicitContentTemplate(); as implicitTpl) {\n <ng-container [ngTemplateOutlet]=\"implicitTpl\" />\n }\n </div>\n }\n}\n\n<!-- Hidden projection slot for tw-tab children -->\n<div style=\"display: none\">\n <ng-content />\n</div>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: TabTriggerElementDirective, selector: "[twTabTriggerElement]", inputs: ["isFocusStop", "isDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
599
619
  }
600
620
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: TabsComponent, decorators: [{
601
621
  type: Component,
602
622
  args: [{ selector: 'tw-tabs', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, TabTriggerElementDirective], host: {
603
623
  '[class]': 'rootClasses()',
604
- }, template: "<!-- Tablist container. WAI-ARIA tablist owns roving focus on the tab elements\n inside; the container itself relays keydown but isn't tabbable. -->\n<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div\n [class]=\"tablistClasses()\"\n role=\"tablist\"\n [attr.aria-orientation]=\"orientation()\"\n (keydown)=\"onKeydown($event)\"\n>\n <!-- Scroll start button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollStart()\"\n (click)=\"scrollStart()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n\n <!-- Scrollable trigger strip -->\n <div #tablistInner [class]=\"tablistInnerClasses()\" style=\"scrollbar-width: none\">\n @for (tab of tabs(); track tab.value()) {\n <!-- Trigger is rendered as <div role=\"tab\">, not <button>: activation is\n wired explicitly via (click) and the parent tablist's keydown\n (Enter / Space), and the roving tab stop comes from\n twTabTriggerElement. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n role=\"tab\"\n twTabTriggerElement\n [isFocusStop]=\"isTabFocusStop(tab.value())\"\n [isDisabled]=\"tab.disabled()\"\n [id]=\"getTabId(tab.value())\"\n [attr.aria-selected]=\"isTabActive(tab.value())\"\n [attr.aria-controls]=\"getPanelId(tab.value())\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.aria-keyshortcuts]=\"tab.closable() && !tab.disabled() ? 'Delete' : null\"\n [class]=\"getTriggerClasses(tab.value(), isTabActive(tab.value()))\"\n [class.opacity-50]=\"tab.disabled()\"\n [class.pointer-events-none]=\"tab.disabled()\"\n (click)=\"selectTab(tab)\"\n >\n <!-- Custom trigger template or default label -->\n @if (tab.triggerTemplate(); as triggerDir) {\n <ng-container\n [ngTemplateOutlet]=\"triggerDir.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: { active: isTabActive(tab.value()), disabled: tab.disabled(), value: tab.value() } }\"\n />\n } @else {\n {{ tab.label() }}\n }\n\n <!-- Close affordance \u2014 a pointer-only span, deliberately NOT a button.\n Anything focusable inside an element carrying an interactive role\n fails axe's nested-interactive rule, and hoisting a real button\n out to a sibling only trades that for aria-required-children\n (a tablist may own nothing but tabs \u2014 both measured). The\n keyboard path is the APG-recommended Delete key on the tab\n itself, handled in onKeydown and advertised to assistive tech\n through aria-keyshortcuts on the trigger above. -->\n @if (tab.closable() && !tab.disabled()) {\n <span\n data-tw-tab-close\n aria-hidden=\"true\"\n [class]=\"closeButtonClasses()\"\n (click)=\"closeTab(tab, $event)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\"/>\n </svg>\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Scroll end button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollEnd()\"\n (click)=\"scrollEnd()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n</div>\n\n<!-- Tab panels -->\n@for (tab of tabs(); track tab.value()) {\n @if (shouldRenderPanel(tab)) {\n <div\n role=\"tabpanel\"\n [id]=\"getPanelId(tab.value())\"\n [attr.aria-labelledby]=\"getTabId(tab.value())\"\n [class]=\"panelClasses()\"\n [hidden]=\"!isTabActive(tab.value())\"\n tabindex=\"0\"\n >\n @if (tab.contentTemplate(); as contentDir) {\n <ng-container [ngTemplateOutlet]=\"contentDir.templateRef\" />\n } @else if (tab.implicitContentTemplate(); as implicitTpl) {\n <ng-container [ngTemplateOutlet]=\"implicitTpl\" />\n }\n </div>\n }\n}\n\n<!-- Hidden projection slot for tw-tab children -->\n<div style=\"display: none\">\n <ng-content />\n</div>\n" }]
624
+ }, template: "<!-- Tablist container. WAI-ARIA tablist owns roving focus on the tab elements\n inside; the container itself relays keydown but isn't tabbable. -->\n<!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\n<div\n [class]=\"tablistClasses()\"\n role=\"tablist\"\n [attr.aria-orientation]=\"orientation()\"\n (keydown)=\"onKeydown($event)\"\n>\n <!-- Scroll start button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollStart()\"\n (click)=\"scrollStart()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M9.78 4.22a.75.75 0 0 1 0 1.06L7.06 8l2.72 2.72a.75.75 0 1 1-1.06 1.06L5.47 8.53a.75.75 0 0 1 0-1.06l3.25-3.25a.75.75 0 0 1 1.06 0Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n\n <!-- Scrollable trigger strip -->\n <div #tablistInner [class]=\"tablistInnerClasses()\" style=\"scrollbar-width: none\">\n @for (tab of tabs(); track tab.value()) {\n <!-- Trigger is rendered as <div role=\"tab\">, not <button>: activation is\n wired explicitly via (click) and the parent tablist's keydown\n (Enter / Space), and the roving tab stop comes from\n twTabTriggerElement. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n role=\"tab\"\n twTabTriggerElement\n [isFocusStop]=\"isTabFocusStop(tab.value())\"\n [isDisabled]=\"tab.disabled()\"\n [id]=\"getTabId(tab.value())\"\n [attr.aria-selected]=\"isTabActive(tab.value())\"\n [attr.aria-controls]=\"getPanelId(tab.value())\"\n [attr.aria-disabled]=\"tab.disabled() || null\"\n [attr.aria-keyshortcuts]=\"tab.isDismissible() && !tab.disabled() ? 'Delete' : null\"\n [class]=\"getTriggerClasses(tab.value(), isTabActive(tab.value()))\"\n [class.opacity-50]=\"tab.disabled()\"\n [class.pointer-events-none]=\"tab.disabled()\"\n (click)=\"selectTab(tab)\"\n >\n <!-- Custom trigger template or default label -->\n @if (tab.triggerTemplate(); as triggerDir) {\n <ng-container\n [ngTemplateOutlet]=\"triggerDir.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: { active: isTabActive(tab.value()), disabled: tab.disabled(), value: tab.value() } }\"\n />\n } @else {\n {{ tab.label() }}\n }\n\n <!-- Close affordance \u2014 a pointer-only span, deliberately NOT a button.\n Anything focusable inside an element carrying an interactive role\n fails axe's nested-interactive rule, and hoisting a real button\n out to a sibling only trades that for aria-required-children\n (a tablist may own nothing but tabs \u2014 both measured). The\n keyboard path is the APG-recommended Delete key on the tab\n itself, handled in onKeydown and advertised to assistive tech\n through aria-keyshortcuts on the trigger above. -->\n @if (tab.isDismissible() && !tab.disabled()) {\n <span\n data-tw-tab-close\n aria-hidden=\"true\"\n [class]=\"closeButtonClasses()\"\n (click)=\"closeTab(tab, $event)\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\"/>\n </svg>\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Scroll end button (horizontal only) -->\n @if (orientation() === 'horizontal' && (canScrollStart() || canScrollEnd())) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [class]=\"scrollButtonClasses()\"\n [disabled]=\"!canScrollEnd()\"\n (click)=\"scrollEnd()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" class=\"size-4 shrink-0\">\n <path fill-rule=\"evenodd\" d=\"M6.22 4.22a.75.75 0 0 1 1.06 0l3.25 3.25a.75.75 0 0 1 0 1.06l-3.25 3.25a.75.75 0 0 1-1.06-1.06L8.94 8 6.22 5.28a.75.75 0 0 1 0-1.06Z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n }\n</div>\n\n<!-- Tab panels -->\n@for (tab of tabs(); track tab.value()) {\n @if (shouldRenderPanel(tab)) {\n <div\n role=\"tabpanel\"\n [id]=\"getPanelId(tab.value())\"\n [attr.aria-labelledby]=\"getTabId(tab.value())\"\n [class]=\"panelClasses()\"\n [hidden]=\"!isTabActive(tab.value())\"\n tabindex=\"0\"\n >\n @if (tab.contentTemplate(); as contentDir) {\n <ng-container [ngTemplateOutlet]=\"contentDir.templateRef\" />\n } @else if (tab.implicitContentTemplate(); as implicitTpl) {\n <ng-container [ngTemplateOutlet]=\"implicitTpl\" />\n }\n </div>\n }\n}\n\n<!-- Hidden projection slot for tw-tab children -->\n<div style=\"display: none\">\n <ng-content />\n</div>\n" }]
605
625
  }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], fitted: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitted", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], closed: [{ type: i0.Output, args: ["closed"] }], tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TabComponent), { isSignal: true }] }], triggerElements: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => TabTriggerElementDirective), { isSignal: true }] }], tablistInnerRef: [{ type: i0.ViewChild, args: ['tablistInner', { isSignal: true }] }] } });
606
626
 
607
627
  /**