@cdevhub/ngx-tw 0.2.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.
- package/LICENSE +21 -0
- package/README.md +134 -0
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs +108 -0
- package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-alert.mjs +240 -0
- package/fesm2022/cdevhub-ngx-tw-alert.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs +287 -0
- package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-badge.mjs +332 -0
- package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +452 -0
- package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-button.mjs +227 -0
- package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +417 -0
- package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs +232 -0
- package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs +4482 -0
- package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-card.mjs +157 -0
- package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs +1454 -0
- package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +593 -0
- package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs +228 -0
- package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +510 -0
- package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs +1721 -0
- package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +721 -0
- package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-core.mjs +861 -0
- package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +1558 -0
- package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +1833 -0
- package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs +693 -0
- package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +331 -0
- package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +289 -0
- package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs +572 -0
- package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs +36 -0
- package/fesm2022/cdevhub-ngx-tw-icon-lucide.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-icon.mjs +278 -0
- package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-input.mjs +355 -0
- package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-item.mjs +241 -0
- package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-menu.mjs +433 -0
- package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs +691 -0
- package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-popover.mjs +678 -0
- package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +335 -0
- package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-radio.mjs +708 -0
- package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +319 -0
- package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-select.mjs +1722 -0
- package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-separator.mjs +115 -0
- package/fesm2022/cdevhub-ngx-tw-separator.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs +768 -0
- package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-skeleton.mjs +149 -0
- package/fesm2022/cdevhub-ngx-tw-skeleton.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-slider.mjs +1147 -0
- package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-sort.mjs +346 -0
- package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-spinner.mjs +186 -0
- package/fesm2022/cdevhub-ngx-tw-spinner.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-split.mjs +1082 -0
- package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-stat.mjs +579 -0
- package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs +443 -0
- package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-switch.mjs +391 -0
- package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +315 -0
- package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-table.mjs +994 -0
- package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs +508 -0
- package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs +147 -0
- package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-theme.mjs +178 -0
- package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +1344 -0
- package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs +1136 -0
- package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-toast.mjs +1311 -0
- package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +533 -0
- package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -0
- package/fesm2022/cdevhub-ngx-tw.mjs +61 -0
- package/fesm2022/cdevhub-ngx-tw.mjs.map +1 -0
- package/package.json +265 -0
- package/theme/_base.css +394 -0
- package/theme/_dark.css +510 -0
- package/theme/_high-contrast.css +290 -0
- package/theme/_semantic.css +317 -0
- package/theme/_typography.css +9 -0
- package/theme/index.css +54 -0
- package/types/cdevhub-ngx-tw-accordion.d.ts +48 -0
- package/types/cdevhub-ngx-tw-alert.d.ts +67 -0
- package/types/cdevhub-ngx-tw-avatar.d.ts +79 -0
- package/types/cdevhub-ngx-tw-badge.d.ts +94 -0
- package/types/cdevhub-ngx-tw-breadcrumbs.d.ts +227 -0
- package/types/cdevhub-ngx-tw-button.d.ts +74 -0
- package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +200 -0
- package/types/cdevhub-ngx-tw-calendar-testing.d.ts +113 -0
- package/types/cdevhub-ngx-tw-calendar.d.ts +1704 -0
- package/types/cdevhub-ngx-tw-card.d.ts +48 -0
- package/types/cdevhub-ngx-tw-carousel.d.ts +406 -0
- package/types/cdevhub-ngx-tw-checkbox.d.ts +136 -0
- package/types/cdevhub-ngx-tw-code-block.d.ts +93 -0
- package/types/cdevhub-ngx-tw-collapsible.d.ts +151 -0
- package/types/cdevhub-ngx-tw-combobox.d.ts +389 -0
- package/types/cdevhub-ngx-tw-command-palette.d.ts +215 -0
- package/types/cdevhub-ngx-tw-core.d.ts +719 -0
- package/types/cdevhub-ngx-tw-date-picker.d.ts +317 -0
- package/types/cdevhub-ngx-tw-date-range-picker.d.ts +313 -0
- package/types/cdevhub-ngx-tw-dialog.d.ts +303 -0
- package/types/cdevhub-ngx-tw-empty-state.d.ts +104 -0
- package/types/cdevhub-ngx-tw-flip-card.d.ts +95 -0
- package/types/cdevhub-ngx-tw-form-field.d.ts +210 -0
- package/types/cdevhub-ngx-tw-icon-lucide.d.ts +29 -0
- package/types/cdevhub-ngx-tw-icon.d.ts +134 -0
- package/types/cdevhub-ngx-tw-input.d.ts +110 -0
- package/types/cdevhub-ngx-tw-item.d.ts +70 -0
- package/types/cdevhub-ngx-tw-menu.d.ts +99 -0
- package/types/cdevhub-ngx-tw-paginator.d.ts +305 -0
- package/types/cdevhub-ngx-tw-popover.d.ts +157 -0
- package/types/cdevhub-ngx-tw-progress-bar.d.ts +100 -0
- package/types/cdevhub-ngx-tw-radio.d.ts +174 -0
- package/types/cdevhub-ngx-tw-segmented-control.d.ts +66 -0
- package/types/cdevhub-ngx-tw-select.d.ts +384 -0
- package/types/cdevhub-ngx-tw-separator.d.ts +28 -0
- package/types/cdevhub-ngx-tw-sheet.d.ts +335 -0
- package/types/cdevhub-ngx-tw-skeleton.d.ts +52 -0
- package/types/cdevhub-ngx-tw-slider.d.ts +258 -0
- package/types/cdevhub-ngx-tw-sort.d.ts +136 -0
- package/types/cdevhub-ngx-tw-spinner.d.ts +50 -0
- package/types/cdevhub-ngx-tw-split.d.ts +265 -0
- package/types/cdevhub-ngx-tw-stat.d.ts +140 -0
- package/types/cdevhub-ngx-tw-stepper.d.ts +127 -0
- package/types/cdevhub-ngx-tw-switch.d.ts +88 -0
- package/types/cdevhub-ngx-tw-tab-nav.d.ts +107 -0
- package/types/cdevhub-ngx-tw-table.d.ts +479 -0
- package/types/cdevhub-ngx-tw-tabs.d.ts +121 -0
- package/types/cdevhub-ngx-tw-textarea.d.ts +62 -0
- package/types/cdevhub-ngx-tw-theme.d.ts +106 -0
- package/types/cdevhub-ngx-tw-time-picker.d.ts +303 -0
- package/types/cdevhub-ngx-tw-timeline.d.ts +278 -0
- package/types/cdevhub-ngx-tw-toast.d.ts +388 -0
- package/types/cdevhub-ngx-tw-tooltip.d.ts +95 -0
- package/types/cdevhub-ngx-tw.d.ts +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdevhub-ngx-tw-popover.mjs","sources":["../../../projects/ngx-tw/popover/popover-tokens.ts","../../../projects/ngx-tw/popover/popover.ts","../../../projects/ngx-tw/popover/popover-close.ts","../../../projects/ngx-tw/popover/popover-title.ts","../../../projects/ngx-tw/popover/cdevhub-ngx-tw-popover.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/** Context object provided to popover template content. */\nexport interface PopoverTemplateContext<T = unknown> {\n /** The data passed via `twPopoverData` input. */\n $implicit: T;\n /** Closes the popover. */\n close: () => void;\n}\n\n/** Reference to control the popover from inside component content. */\nexport interface PopoverRef {\n /** Closes the popover. */\n close(): void;\n /** @internal — used by `PopoverTitleDirective` to register itself with `aria-labelledby`. */\n _addAriaLabelledBy?: (id: string) => void;\n /** @internal — used by `PopoverTitleDirective` to unregister itself. */\n _removeAriaLabelledBy?: (id: string) => void;\n}\n\n/** Injection token providing arbitrary data to popover component content. */\nexport const POPOVER_DATA = new InjectionToken<unknown>('POPOVER_DATA');\n\n/** Injection token providing a `PopoverRef` to popover component content. */\nexport const POPOVER_REF = new InjectionToken<PopoverRef>('POPOVER_REF');\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n Directive,\n effect,\n ElementRef,\n inject,\n Injector,\n input,\n model,\n output,\n signal,\n TemplateRef,\n type Type,\n untracked,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n type ConnectedPosition,\n type FlexibleConnectedPositionStrategy,\n Overlay,\n type OverlayRef,\n} from '@angular/cdk/overlay';\nimport { CdkPortalOutlet, ComponentPortal, TemplatePortal } from '@angular/cdk/portal';\nimport { FocusTrapFactory } from '@angular/cdk/a11y';\nimport { Subscription } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwSize } from '@cdevhub/ngx-tw/core';\nimport {\n POPOVER_DATA,\n POPOVER_REF,\n type PopoverRef,\n type PopoverTemplateContext,\n} from './popover-tokens';\n\n// ── Types ──\n\n/** Placement position of the popover relative to its trigger element. */\nexport type PopoverPosition =\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end'\n | 'right'\n | 'right-start'\n | 'right-end';\n\n/** Scroll strategy for the popover overlay. */\nexport type PopoverScrollStrategy = 'reposition' | 'close' | 'block' | 'noop';\n\n/** Backdrop behavior for the popover. */\nexport type PopoverBackdrop = 'transparent' | 'dimmed' | 'none';\n\n/** Trigger interaction that opens the popover. */\nexport type PopoverTrigger = 'click' | 'focus' | 'manual';\n\n/** Direction the arrow points toward (derived from resolved overlay position). */\ntype ArrowDirection = 'top' | 'bottom' | 'left' | 'right';\n\n/** Duration of leave animation in ms (must match _base.css scale-out/fade-out). */\nconst ANIMATION_DURATION = 120;\n\n// ── Variant config ──\n\nconst popoverVariants = tv(\n {\n slots: {\n wrapper: 'relative',\n panel:\n 'bg-surface-overlay text-fg text-sm border border-border rounded-lg shadow-md overflow-hidden',\n arrow: 'absolute size-2.5 rotate-45 bg-surface-overlay border border-border',\n },\n variants: {\n size: {\n xs: { panel: 'p-2' },\n sm: { panel: 'p-3' },\n md: { panel: 'p-4' },\n lg: { panel: 'p-6' },\n xl: { panel: 'p-8' },\n },\n },\n defaultVariants: { size: 'md' },\n },\n { twMerge: true },\n);\n\n// ── Color accent classes ──\n\nconst COLOR_ACCENT_CLASSES: Record<TwColor, string> = {\n primary: 'border-t-2 border-t-primary-500',\n secondary: 'border-t-2 border-t-secondary-500',\n accent: 'border-t-2 border-t-accent-500',\n neutral: 'border-t-2 border-t-neutral-500',\n info: 'border-t-2 border-t-info-500',\n success: 'border-t-2 border-t-success-500',\n warning: 'border-t-2 border-t-warning-500',\n error: 'border-t-2 border-t-error-500',\n};\n\n// ── Position mappings ──\n\nfunction buildPositionMap(offset: number): Record<PopoverPosition, ConnectedPosition> {\n return {\n top: {\n originX: 'center',\n originY: 'top',\n overlayX: 'center',\n overlayY: 'bottom',\n offsetY: -offset,\n },\n 'top-start': {\n originX: 'start',\n originY: 'top',\n overlayX: 'start',\n overlayY: 'bottom',\n offsetY: -offset,\n },\n 'top-end': {\n originX: 'end',\n originY: 'top',\n overlayX: 'end',\n overlayY: 'bottom',\n offsetY: -offset,\n },\n bottom: {\n originX: 'center',\n originY: 'bottom',\n overlayX: 'center',\n overlayY: 'top',\n offsetY: offset,\n },\n 'bottom-start': {\n originX: 'start',\n originY: 'bottom',\n overlayX: 'start',\n overlayY: 'top',\n offsetY: offset,\n },\n 'bottom-end': {\n originX: 'end',\n originY: 'bottom',\n overlayX: 'end',\n overlayY: 'top',\n offsetY: offset,\n },\n left: {\n originX: 'start',\n originY: 'center',\n overlayX: 'end',\n overlayY: 'center',\n offsetX: -offset,\n },\n 'left-start': {\n originX: 'start',\n originY: 'top',\n overlayX: 'end',\n overlayY: 'top',\n offsetX: -offset,\n },\n 'left-end': {\n originX: 'start',\n originY: 'bottom',\n overlayX: 'end',\n overlayY: 'bottom',\n offsetX: -offset,\n },\n right: {\n originX: 'end',\n originY: 'center',\n overlayX: 'start',\n overlayY: 'center',\n offsetX: offset,\n },\n 'right-start': {\n originX: 'end',\n originY: 'top',\n overlayX: 'start',\n overlayY: 'top',\n offsetX: offset,\n },\n 'right-end': {\n originX: 'end',\n originY: 'bottom',\n overlayX: 'start',\n overlayY: 'bottom',\n offsetX: offset,\n },\n };\n}\n\nconst FALLBACK_ORDER: Record<string, PopoverPosition[]> = {\n top: ['bottom', 'left', 'right'],\n bottom: ['top', 'left', 'right'],\n left: ['right', 'top', 'bottom'],\n right: ['left', 'top', 'bottom'],\n};\n\nfunction buildPositions(\n preferred: PopoverPosition,\n offset: number,\n): ConnectedPosition[] {\n const positionMap = buildPositionMap(offset);\n const primary = preferred.split('-')[0];\n const positions = [positionMap[preferred]];\n const fallbacks = FALLBACK_ORDER[primary] ?? FALLBACK_ORDER['top'];\n for (const fb of fallbacks) {\n positions.push(positionMap[fb]);\n }\n return positions;\n}\n\nfunction resolveArrowDirection(position: ConnectedPosition): ArrowDirection {\n if (position.overlayY === 'bottom') return 'bottom';\n if (position.overlayY === 'top') return 'top';\n if (position.overlayX === 'end') return 'right';\n return 'left';\n}\n\n/** Arrow position classes keyed by which side the arrow sits on. */\nconst ARROW_POSITION_CLASSES: Record<ArrowDirection, string> = {\n bottom: 'left-1/2 -translate-x-1/2 bottom-0 translate-y-1/2 border-t-0 border-l-0',\n top: 'left-1/2 -translate-x-1/2 top-0 -translate-y-1/2 border-b-0 border-r-0',\n right: 'top-1/2 -translate-y-1/2 right-0 translate-x-1/2 border-b-0 border-l-0',\n left: 'top-1/2 -translate-y-1/2 left-0 -translate-x-1/2 border-t-0 border-r-0',\n};\n\n// ── Internal overlay component (not exported) ──\n\nlet nextPopoverId = 0;\n\n@Component({\n selector: 'tw-popover-overlay',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [CdkPortalOutlet],\n host: {\n class: 'origin-center',\n '[id]': 'id',\n '[attr.role]': '\"dialog\"',\n '[attr.aria-modal]': 'ariaModal() ? \"true\" : null',\n '[attr.aria-label]': 'ariaLabel() ?? null',\n '[attr.aria-labelledby]': 'computedAriaLabelledBy()',\n '[animate.enter]': '\"scale-in\"',\n '[animate.leave]': '\"scale-out\"',\n },\n template: `\n <div [class]=\"wrapperClasses()\">\n <div [class]=\"panelClasses()\">\n <ng-template [cdkPortalOutlet]=\"portal()\" />\n </div>\n @if (showArrow()) {\n <span [class]=\"arrowClasses()\" aria-hidden=\"true\"></span>\n }\n </div>\n `,\n})\nclass PopoverOverlayComponent {\n readonly id = `tw-popover-${nextPopoverId++}`;\n\n readonly size = signal<TwSize>('md');\n readonly color = signal<TwColor | undefined>(undefined);\n readonly showArrow = signal(true);\n readonly arrowDirection = signal<ArrowDirection>('top');\n readonly ariaLabel = signal<string | undefined>(undefined);\n readonly ariaModal = signal(true);\n readonly ariaLabelledByQueue = signal<readonly string[]>([]);\n readonly panelClass = signal<string>('');\n readonly portal = signal<TemplatePortal<PopoverTemplateContext> | ComponentPortal<unknown> | null>(null);\n\n readonly computedAriaLabelledBy = computed(() => {\n if (this.ariaLabel()) return null;\n return this.ariaLabelledByQueue()[0] ?? null;\n });\n\n _addAriaLabelledBy(id: string): void {\n this.ariaLabelledByQueue.update((q) => (q.includes(id) ? q : [...q, id]));\n }\n\n _removeAriaLabelledBy(id: string): void {\n this.ariaLabelledByQueue.update((q) => q.filter((existing) => existing !== id));\n }\n\n private readonly variantResult = computed(() =>\n popoverVariants({ size: this.size() }),\n );\n\n readonly wrapperClasses = computed(() => this.variantResult().wrapper());\n\n readonly panelClasses = computed(() => {\n const base = this.variantResult().panel();\n const colorClass = this.color() ? COLOR_ACCENT_CLASSES[this.color()!] : '';\n const custom = this.panelClass();\n return [base, colorClass, custom].filter(Boolean).join(' ');\n });\n\n readonly arrowClasses = computed(() => {\n const base = this.variantResult().arrow();\n const position = ARROW_POSITION_CLASSES[this.arrowDirection()];\n return `${base} ${position}`;\n });\n}\n\n// ── Popover directive ──\n\n@Directive({\n selector: '[twPopover]',\n exportAs: 'twPopover',\n host: {\n '[attr.aria-haspopup]': '\"dialog\"',\n '[attr.aria-expanded]': 'twPopoverOpen()',\n '[attr.aria-controls]': 'overlayComponentId()',\n '(click)': 'onHostClick()',\n '(focus)': 'onHostFocus()',\n '(blur)': 'onHostBlur()',\n '(keydown.escape)': 'onEscape()',\n },\n})\nexport class PopoverDirective {\n /** The content to render. An `ng-template` receives context with `$implicit` (data) and `close` (function). A component class receives data and a ref via injection tokens. */\n readonly twPopover = input.required<\n TemplateRef<PopoverTemplateContext> | Type<unknown>\n >();\n\n /** Preferred placement relative to the trigger. CDK handles fallback when space is insufficient. Defaults to `'bottom'`. */\n readonly twPopoverPosition = input<PopoverPosition>('bottom');\n\n /** What user interaction opens the popover. `'manual'` means consumers call `open()`/`close()` programmatically. Defaults to `'click'`. */\n readonly twPopoverTriggerOn = input<PopoverTrigger>('click');\n\n /** When true, all trigger interactions are suppressed. Defaults to `false`. */\n readonly twPopoverDisabled = input(false);\n\n /** Two-way bindable open state. Setting to `true` opens the popover; the popover sets it to `false` on close. */\n readonly twPopoverOpen = model(false);\n\n /** Controls panel padding using the standard spacing scale. Defaults to `'md'`. */\n readonly twPopoverSize = input<TwSize>('md');\n\n /** Pixel distance between trigger and panel edge. Defaults to `8`. */\n readonly twPopoverOffset = input(8);\n\n // Default true: the panel reads as a floating callout without the arrow; opt-out\n // is intended for compact iconic triggers where the arrow would crowd the layout.\n /** Whether to render a directional arrow pointing at the trigger. Defaults to `true`. */\n readonly twPopoverArrow = input(true);\n\n /** Backdrop behavior. `'transparent'` catches outside clicks invisibly. `'dimmed'` adds a semi-transparent overlay. `'none'` disables the backdrop. Defaults to `'transparent'`. */\n readonly twPopoverBackdrop = input<PopoverBackdrop>('transparent');\n\n // Default true: clicking away is the universal dismiss gesture for floating panels;\n // opt-out is for popovers that own multi-step flows the user must complete.\n /** Whether clicking outside the panel closes the popover. Only relevant when backdrop is `'none'`. Defaults to `true`. */\n readonly twPopoverCloseOnOutside = input(true);\n\n // Default true: WAI-ARIA dialog pattern mandates Escape closes; opt-out is for\n // popovers that own a child layer (nested dialog/menu) that should consume Escape first.\n /** Whether pressing Escape closes the popover. Defaults to `true`. */\n readonly twPopoverCloseOnEscape = input(true);\n\n /** CDK scroll strategy for the overlay. Defaults to `'reposition'`. */\n readonly twPopoverScrollStrategy = input<PopoverScrollStrategy>('reposition');\n\n // Default true: matches the role=\"dialog\" baseline — a focus-trapped panel announces\n // itself as modal-ish; opt-out for inline popovers acting as informational tooltips.\n /** Whether to trap focus inside the popover panel using CDK FocusTrapFactory. Defaults to `true`. */\n readonly twPopoverTrapFocus = input(true);\n\n /** Arbitrary data passed to template context or component via `POPOVER_DATA` token. */\n readonly twPopoverData = input<unknown>(undefined);\n\n /** Additional CSS classes applied to the overlay panel for consumer customization. */\n readonly twPopoverPanelClass = input<string | string[]>('');\n\n /** Optional semantic color. When set, adds a colored top border accent to the panel. */\n readonly twPopoverColor = input<TwColor | undefined>(undefined);\n\n /** Explicit `aria-label` for the dialog panel. */\n readonly twPopoverAriaLabel = input<string | undefined>(undefined);\n\n /** Fires after the popover becomes visible. */\n readonly twPopoverOpened = output<void>();\n\n /** Fires after the popover is fully removed. */\n readonly twPopoverClosed = output<void>();\n\n private readonly overlay = inject(Overlay);\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly viewContainerRef = inject(ViewContainerRef);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusTrapFactory = inject(FocusTrapFactory);\n\n private overlayRef: OverlayRef | null = null;\n private popoverInstance: PopoverOverlayComponent | null = null;\n private focusTrap: ReturnType<FocusTrapFactory['create']> | null = null;\n private perOpenSubs: Subscription | null = null;\n private closing = false;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n /** Tracked focus-blur close timer; cleared on destroy so it can't fire post-teardown. */\n private blurCloseTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly overlayId = signal<string | null>(null);\n\n /** The overlay component's id for aria-controls binding. */\n protected readonly overlayComponentId = computed(() => this.overlayId());\n\n constructor() {\n // React to model changes from the parent\n effect(() => {\n const isOpen = this.twPopoverOpen();\n const disabled = this.twPopoverDisabled();\n if (disabled && this.popoverInstance) {\n this.closePopover();\n return;\n }\n if (isOpen && !this.popoverInstance && !disabled && !this.closing) {\n this.openPopover();\n } else if (!isOpen && this.popoverInstance) {\n this.closePopover();\n }\n });\n\n this.destroyRef.onDestroy(() => {\n this.clearCloseTimer();\n if (this.blurCloseTimer !== null) {\n clearTimeout(this.blurCloseTimer);\n this.blurCloseTimer = null;\n }\n this.destroyFocusTrap();\n this.perOpenSubs?.unsubscribe();\n this.disposeOverlay();\n });\n }\n\n /** Programmatically open the popover. */\n open(): void {\n if (this.twPopoverDisabled() || this.popoverInstance || this.closing) return;\n this.twPopoverOpen.set(true);\n }\n\n /** Programmatically close the popover. */\n close(): void {\n if (!this.popoverInstance && !this.closing) return;\n this.twPopoverOpen.set(false);\n }\n\n /** Toggle open/close. */\n toggle(): void {\n if (this.popoverInstance || this.closing) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /** Force CDK to recalculate overlay position. */\n reposition(): void {\n this.overlayRef?.updatePosition();\n }\n\n // ── Host event handlers ──\n\n protected onHostClick(): void {\n if (this.twPopoverTriggerOn() === 'click') {\n this.toggle();\n }\n }\n\n protected onHostFocus(): void {\n if (this.twPopoverTriggerOn() === 'focus') {\n this.open();\n }\n }\n\n protected onHostBlur(): void {\n if (this.twPopoverTriggerOn() === 'focus') {\n if (this.blurCloseTimer !== null) clearTimeout(this.blurCloseTimer);\n this.blurCloseTimer = setTimeout(() => {\n this.blurCloseTimer = null;\n const activeEl = document.activeElement;\n const overlayEl = this.overlayRef?.overlayElement;\n if (overlayEl && overlayEl.contains(activeEl)) return;\n this.close();\n });\n }\n }\n\n protected onEscape(): void {\n if (this.twPopoverCloseOnEscape() && this.popoverInstance) {\n this.close();\n }\n }\n\n // ── Private ──\n\n private openPopover(): void {\n this.ensureOverlay();\n this.updatePositionStrategy();\n this.attachContent();\n this.subscribePerOpen();\n this.overlayId.set(this.popoverInstance?.id ?? null);\n this.setupFocusTrap();\n this.twPopoverOpened.emit();\n }\n\n private closePopover(): void {\n if (this.closing) return;\n this.closing = true;\n\n // Restore focus to the trigger UNLESS the consumer has deliberately moved\n // focus to a different focusable element outside the overlay. We detect\n // that by checking whether the active element is a real focusable target\n // outside the overlay — body/null means focus is \"unset\" and we should\n // still restore (the typical case after Escape or backdrop click).\n const overlayEl = this.overlayRef?.overlayElement;\n const activeEl = document.activeElement as HTMLElement | null;\n const focusOutsideOverlayIntentionally =\n !!activeEl &&\n activeEl !== document.body &&\n activeEl !== this.elementRef.nativeElement &&\n !overlayEl?.contains(activeEl);\n\n // 1. Destroy focus trap so focus can leave\n this.destroyFocusTrap();\n\n // 2. Return focus to trigger only when appropriate\n if (!focusOutsideOverlayIntentionally) {\n this.elementRef.nativeElement.focus();\n }\n\n // 3. Wait for leave animation, then detach\n this.closeTimer = setTimeout(() => {\n this.closeTimer = null;\n\n if (this.overlayRef?.hasAttached()) {\n this.overlayRef.detach();\n }\n\n this.perOpenSubs?.unsubscribe();\n this.perOpenSubs = null;\n this.popoverInstance = null;\n this.overlayId.set(null);\n\n // Use untracked to prevent effect re-trigger\n untracked(() => this.twPopoverOpen.set(false));\n\n this.twPopoverClosed.emit();\n this.closing = false;\n }, ANIMATION_DURATION);\n }\n\n private currentPositionStrategy: FlexibleConnectedPositionStrategy | null = null;\n\n private buildPositionStrategy(): FlexibleConnectedPositionStrategy {\n const positions = buildPositions(\n this.twPopoverPosition(),\n this.twPopoverOffset(),\n );\n\n return this.overlay\n .position()\n .flexibleConnectedTo(this.elementRef)\n .withPositions(positions)\n .withFlexibleDimensions(false)\n .withPush(true)\n .withViewportMargin(8);\n }\n\n private ensureOverlay(): void {\n if (this.overlayRef) return;\n\n const positionStrategy = this.buildPositionStrategy();\n this.currentPositionStrategy = positionStrategy;\n\n const backdrop = this.twPopoverBackdrop();\n const hasBackdrop = backdrop !== 'none';\n const backdropClass =\n backdrop === 'dimmed' ? 'bg-black/20' : 'cdk-overlay-transparent-backdrop';\n\n const scrollStrategy = this.resolveScrollStrategy();\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy,\n hasBackdrop,\n backdropClass,\n panelClass: 'tw-popover-panel',\n });\n }\n\n private updatePositionStrategy(): void {\n if (!this.overlayRef) return;\n const positionStrategy = this.buildPositionStrategy();\n this.currentPositionStrategy = positionStrategy;\n this.overlayRef.updatePositionStrategy(positionStrategy);\n }\n\n private subscribePerOpen(): void {\n this.perOpenSubs?.unsubscribe();\n this.perOpenSubs = new Subscription();\n\n const backdrop = this.twPopoverBackdrop();\n const hasBackdrop = backdrop !== 'none';\n\n // Backdrop click closes\n if (hasBackdrop) {\n this.perOpenSubs.add(\n this.overlayRef!.backdropClick().subscribe(() => this.close()),\n );\n }\n\n // Outside pointer events when no backdrop\n if (!hasBackdrop && this.twPopoverCloseOnOutside()) {\n this.perOpenSubs.add(\n this.overlayRef!.outsidePointerEvents().subscribe(() => this.close()),\n );\n }\n\n // Escape from within the overlay\n this.perOpenSubs.add(\n this.overlayRef!.keydownEvents().subscribe((event) => {\n if (event.key === 'Escape' && this.twPopoverCloseOnEscape()) {\n this.close();\n }\n }),\n );\n\n // Per-open position change subscription — torn down on close to prevent\n // accumulation when the directive is opened/closed many times.\n if (this.currentPositionStrategy) {\n this.perOpenSubs.add(\n this.currentPositionStrategy.positionChanges.subscribe((change) => {\n if (this.popoverInstance) {\n const dir = resolveArrowDirection(change.connectionPair);\n this.popoverInstance.arrowDirection.set(dir);\n }\n }),\n );\n }\n }\n\n private attachContent(): void {\n const content = this.twPopover();\n\n // Attach the internal overlay component\n const overlayPortal = new ComponentPortal(\n PopoverOverlayComponent,\n this.viewContainerRef,\n );\n const componentRef = this.overlayRef!.attach(overlayPortal);\n this.popoverInstance = componentRef.instance;\n\n // Configure the overlay component\n this.popoverInstance.size.set(this.twPopoverSize());\n this.popoverInstance.color.set(this.twPopoverColor());\n this.popoverInstance.showArrow.set(this.twPopoverArrow());\n this.popoverInstance.ariaLabel.set(this.twPopoverAriaLabel());\n this.popoverInstance.ariaModal.set(this.twPopoverTrapFocus());\n this.popoverInstance.ariaLabelledByQueue.set([]);\n this.popoverInstance.panelClass.set(this.resolvePanelClass());\n\n // Provide POPOVER_REF for both template and component content. Title directives\n // call _addAriaLabelledBy / _removeAriaLabelledBy to register their id with the\n // overlay's aria-labelledby queue.\n const overlayInstance = this.popoverInstance;\n const popoverRef: PopoverRef = {\n close: () => this.close(),\n _addAriaLabelledBy: (id) => overlayInstance._addAriaLabelledBy(id),\n _removeAriaLabelledBy: (id) => overlayInstance._removeAriaLabelledBy(id),\n };\n\n // Create the content portal\n if (content instanceof TemplateRef) {\n const context: PopoverTemplateContext = {\n $implicit: this.twPopoverData(),\n close: () => this.close(),\n };\n const templateInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: POPOVER_DATA, useValue: this.twPopoverData() },\n { provide: POPOVER_REF, useValue: popoverRef },\n ],\n });\n const templatePortal = new TemplatePortal(\n content,\n this.viewContainerRef,\n context,\n templateInjector,\n );\n this.popoverInstance.portal.set(templatePortal);\n } else {\n const contentInjector = Injector.create({\n parent: this.injector,\n providers: [\n { provide: POPOVER_DATA, useValue: this.twPopoverData() },\n { provide: POPOVER_REF, useValue: popoverRef },\n ],\n });\n const componentPortal = new ComponentPortal(\n content,\n this.viewContainerRef,\n contentInjector,\n );\n this.popoverInstance.portal.set(componentPortal);\n }\n }\n\n private setupFocusTrap(): void {\n if (!this.twPopoverTrapFocus() || !this.overlayRef) return;\n const overlayEl = this.overlayRef.overlayElement;\n this.focusTrap = this.focusTrapFactory.create(overlayEl);\n this.focusTrap.focusInitialElementWhenReady();\n }\n\n private destroyFocusTrap(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n }\n\n private disposeOverlay(): void {\n this.overlayRef?.dispose();\n this.overlayRef = null;\n this.popoverInstance = null;\n }\n\n private clearCloseTimer(): void {\n if (this.closeTimer !== null) {\n clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n }\n\n private resolveScrollStrategy() {\n const strategy = this.twPopoverScrollStrategy();\n switch (strategy) {\n case 'close':\n return this.overlay.scrollStrategies.close();\n case 'block':\n return this.overlay.scrollStrategies.block();\n case 'noop':\n return this.overlay.scrollStrategies.noop();\n default:\n return this.overlay.scrollStrategies.reposition();\n }\n }\n\n private resolvePanelClass(): string {\n const raw = this.twPopoverPanelClass();\n return Array.isArray(raw) ? raw.join(' ') : raw;\n }\n}\n","import { Directive, inject } from '@angular/core';\nimport { POPOVER_REF } from './popover-tokens';\n\n/**\n * Convenience directive that closes the enclosing popover when the host element is clicked.\n * Place on any element inside popover content.\n *\n * ```html\n * <button twPopoverClose>Cancel</button>\n * ```\n */\n@Directive({\n selector: '[twPopoverClose]',\n host: {\n '(click)': 'closePopover()',\n '[attr.type]': '\"button\"',\n },\n})\nexport class PopoverCloseDirective {\n private readonly popoverRef = inject(POPOVER_REF, { optional: true });\n\n protected closePopover(): void {\n this.popoverRef?.close();\n }\n}\n","import {\n Directive,\n ElementRef,\n inject,\n input,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { _IdGenerator } from '@angular/cdk/a11y';\nimport { POPOVER_REF } from './popover-tokens';\n\n/**\n * Popover title. Registers its ID with the enclosing popover overlay's\n * `aria-labelledby` queue so screen readers announce it automatically.\n *\n * Mirrors `DialogTitleDirective` and is the recommended way to label a\n * popover whose content has a heading. Use `twPopoverAriaLabel` when no\n * heading is present.\n */\n@Directive({\n selector: '[twPopoverTitle], tw-popover-title',\n host: {\n class: 'text-sm font-semibold text-fg',\n '[id]': 'id()',\n },\n})\nexport class PopoverTitleDirective implements OnInit, OnDestroy {\n private readonly generatedId = inject(_IdGenerator).getId('tw-popover-title-');\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly popoverRef = inject(POPOVER_REF, { optional: true });\n\n /** Custom id for the title element. Defaults to a generated unique id. */\n readonly id = input<string>(this.generatedId);\n\n ngOnInit(): void {\n this.popoverRef?._addAriaLabelledBy?.(this.id());\n }\n\n ngOnDestroy(): void {\n this.popoverRef?._removeAriaLabelledBy?.(this.id());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, computed, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { tv } from 'tailwind-variants';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `tw-progress-bar` — visualises measurable progress.
|
|
7
|
+
*
|
|
8
|
+
* Composition usecases:
|
|
9
|
+
* - Upload progress (determinate linear with `options.formatter` → `"3.2 MB / 10 MB"`).
|
|
10
|
+
* - Multi-step wizard (segmented variant, `options.segments` = step count).
|
|
11
|
+
* - Skill / rating display (static determinate linear).
|
|
12
|
+
* - Inline list-row progress (compact `size="sm"`, constrained width via host class).
|
|
13
|
+
* - Card-footer task completion (`options.showValue=true`, `color` switches to `success`/`error`).
|
|
14
|
+
* - Indeterminate loading before first byte (omit `value` — the bar sweeps).
|
|
15
|
+
*
|
|
16
|
+
* For unknown-duration operations with no measurable progress, use `tw-spinner` instead.
|
|
17
|
+
*/
|
|
18
|
+
// ── Static fill-color lookup (Tailwind v4 scans class strings statically) ──
|
|
19
|
+
const FILL_COLORS = {
|
|
20
|
+
primary: 'bg-primary-500',
|
|
21
|
+
secondary: 'bg-secondary-500',
|
|
22
|
+
accent: 'bg-accent-500',
|
|
23
|
+
neutral: 'bg-fg',
|
|
24
|
+
info: 'bg-info-500',
|
|
25
|
+
success: 'bg-success-500',
|
|
26
|
+
warning: 'bg-warning-500',
|
|
27
|
+
error: 'bg-error-500',
|
|
28
|
+
};
|
|
29
|
+
// ── tv() config ──
|
|
30
|
+
const progressBarVariants = tv({
|
|
31
|
+
slots: {
|
|
32
|
+
root: 'flex flex-col w-full',
|
|
33
|
+
header: 'flex items-center justify-between gap-3',
|
|
34
|
+
label: 'text-xs text-fg-muted',
|
|
35
|
+
valueText: 'text-xs text-fg-muted font-medium tabular-nums',
|
|
36
|
+
rail: 'relative w-full overflow-hidden rounded-full bg-surface-muted',
|
|
37
|
+
fill: 'absolute inset-y-0 left-0 rounded-full',
|
|
38
|
+
segmentList: 'flex w-full gap-1',
|
|
39
|
+
segment: 'flex-1 rounded-full',
|
|
40
|
+
},
|
|
41
|
+
variants: {
|
|
42
|
+
size: {
|
|
43
|
+
sm: { rail: 'h-1', segment: 'h-1' },
|
|
44
|
+
md: { rail: 'h-2', segment: 'h-2' },
|
|
45
|
+
lg: { rail: 'h-3', segment: 'h-3' },
|
|
46
|
+
},
|
|
47
|
+
variant: {
|
|
48
|
+
linear: { segmentList: 'hidden' },
|
|
49
|
+
segmented: { rail: 'hidden' },
|
|
50
|
+
},
|
|
51
|
+
isIndeterminate: {
|
|
52
|
+
true: { fill: 'w-[30%] animate-progress-bar-indeterminate' },
|
|
53
|
+
false: { fill: 'transition-[width] duration-normal motion-reduce:transition-none' },
|
|
54
|
+
},
|
|
55
|
+
hasHeader: {
|
|
56
|
+
true: { root: 'gap-1.5' },
|
|
57
|
+
false: { root: 'gap-0' },
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
defaultVariants: {
|
|
61
|
+
size: 'md',
|
|
62
|
+
variant: 'linear',
|
|
63
|
+
isIndeterminate: false,
|
|
64
|
+
hasHeader: false,
|
|
65
|
+
},
|
|
66
|
+
}, {
|
|
67
|
+
twMerge: true,
|
|
68
|
+
});
|
|
69
|
+
let nextId = 0;
|
|
70
|
+
const DEFAULT_FORMATTER = (value, max, min) => {
|
|
71
|
+
const range = max - min;
|
|
72
|
+
if (range <= 0)
|
|
73
|
+
return '0%';
|
|
74
|
+
return `${Math.round(((value - min) / range) * 100)}%`;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Indicates progress toward the completion of a task.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```html
|
|
81
|
+
* <tw-progress-bar [value]="40" />
|
|
82
|
+
* <tw-progress-bar label="Fetching records" />
|
|
83
|
+
* <tw-progress-bar
|
|
84
|
+
* variant="segmented"
|
|
85
|
+
* [value]="step() * 25"
|
|
86
|
+
* [options]="{ segments: 4 }"
|
|
87
|
+
* />
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
class ProgressBarComponent {
|
|
91
|
+
/** Current progress value. When null or undefined, the bar renders indeterminate. Values outside `[options.min, options.max]` are clamped. */
|
|
92
|
+
value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
93
|
+
/** Visual style of the bar. `'linear'` renders a single fill; `'segmented'` splits the rail into discrete steps. Defaults to `'linear'`. */
|
|
94
|
+
variant = input('linear', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
95
|
+
/** Semantic color of the filled portion. Defaults to `'primary'`. Use status colors (`success`/`warning`/`error`) to reflect task outcome. */
|
|
96
|
+
color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
97
|
+
/** Bar thickness. `'sm'` = h-1, `'md'` = h-2, `'lg'` = h-3. Defaults to `'md'`. */
|
|
98
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
99
|
+
/** Visible label rendered above the bar. When set, the bar is wired to the label via `aria-labelledby`. */
|
|
100
|
+
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
101
|
+
/** Bundles non-visual configuration: value range (`min`/`max`/`segments`), value readout (`showValue`/`formatter`), and accessibility fallbacks (`ariaLabel`/`ariaLabelledby`). Every field is optional. */
|
|
102
|
+
options = input(undefined, ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
103
|
+
/** @internal */
|
|
104
|
+
labelId = `tw-progress-bar-${nextId++}-label`;
|
|
105
|
+
/** @internal */
|
|
106
|
+
resolvedMin = computed(() => this.options()?.min ?? 0, ...(ngDevMode ? [{ debugName: "resolvedMin" }] : /* istanbul ignore next */ []));
|
|
107
|
+
/** @internal */
|
|
108
|
+
resolvedMax = computed(() => this.options()?.max ?? 100, ...(ngDevMode ? [{ debugName: "resolvedMax" }] : /* istanbul ignore next */ []));
|
|
109
|
+
/** @internal */
|
|
110
|
+
resolvedSegments = computed(() => this.options()?.segments ?? 5, ...(ngDevMode ? [{ debugName: "resolvedSegments" }] : /* istanbul ignore next */ []));
|
|
111
|
+
/** @internal */
|
|
112
|
+
resolvedShowValue = computed(() => this.options()?.showValue ?? false, ...(ngDevMode ? [{ debugName: "resolvedShowValue" }] : /* istanbul ignore next */ []));
|
|
113
|
+
/** @internal */
|
|
114
|
+
isIndeterminate = computed(() => {
|
|
115
|
+
const v = this.value();
|
|
116
|
+
return v === null || v === undefined;
|
|
117
|
+
}, ...(ngDevMode ? [{ debugName: "isIndeterminate" }] : /* istanbul ignore next */ []));
|
|
118
|
+
/** @internal */
|
|
119
|
+
clampedValue = computed(() => {
|
|
120
|
+
const v = this.value();
|
|
121
|
+
if (v === null || v === undefined)
|
|
122
|
+
return this.resolvedMin();
|
|
123
|
+
const lo = this.resolvedMin();
|
|
124
|
+
const hi = this.resolvedMax();
|
|
125
|
+
if (v < lo)
|
|
126
|
+
return lo;
|
|
127
|
+
if (v > hi)
|
|
128
|
+
return hi;
|
|
129
|
+
return v;
|
|
130
|
+
}, ...(ngDevMode ? [{ debugName: "clampedValue" }] : /* istanbul ignore next */ []));
|
|
131
|
+
/** @internal */
|
|
132
|
+
progressRatio = computed(() => {
|
|
133
|
+
if (this.isIndeterminate())
|
|
134
|
+
return 0;
|
|
135
|
+
const range = this.resolvedMax() - this.resolvedMin();
|
|
136
|
+
if (range <= 0)
|
|
137
|
+
return 0;
|
|
138
|
+
return (this.clampedValue() - this.resolvedMin()) / range;
|
|
139
|
+
}, ...(ngDevMode ? [{ debugName: "progressRatio" }] : /* istanbul ignore next */ []));
|
|
140
|
+
/** @internal */
|
|
141
|
+
formattedValue = computed(() => {
|
|
142
|
+
if (this.isIndeterminate())
|
|
143
|
+
return '';
|
|
144
|
+
const fmt = this.options()?.formatter ?? DEFAULT_FORMATTER;
|
|
145
|
+
return fmt(this.clampedValue(), this.resolvedMax(), this.resolvedMin());
|
|
146
|
+
}, ...(ngDevMode ? [{ debugName: "formattedValue" }] : /* istanbul ignore next */ []));
|
|
147
|
+
/** @internal */
|
|
148
|
+
hasHeader = computed(() => !!this.label() || this.resolvedShowValue(), ...(ngDevMode ? [{ debugName: "hasHeader" }] : /* istanbul ignore next */ []));
|
|
149
|
+
/** @internal */
|
|
150
|
+
segmentIndices = computed(() => {
|
|
151
|
+
const n = Math.max(1, Math.floor(this.resolvedSegments()));
|
|
152
|
+
return Array.from({ length: n }, (_, i) => i);
|
|
153
|
+
}, ...(ngDevMode ? [{ debugName: "segmentIndices" }] : /* istanbul ignore next */ []));
|
|
154
|
+
/** @internal */
|
|
155
|
+
resolvedAriaLabel = computed(() => {
|
|
156
|
+
if (this.label())
|
|
157
|
+
return null;
|
|
158
|
+
if (this.options()?.ariaLabelledby)
|
|
159
|
+
return null;
|
|
160
|
+
return this.options()?.ariaLabel ?? null;
|
|
161
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
162
|
+
/** @internal */
|
|
163
|
+
resolvedAriaLabelledby = computed(() => {
|
|
164
|
+
if (this.label())
|
|
165
|
+
return this.labelId;
|
|
166
|
+
return this.options()?.ariaLabelledby ?? null;
|
|
167
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedAriaLabelledby" }] : /* istanbul ignore next */ []));
|
|
168
|
+
// ── tv() slot computeds ──
|
|
169
|
+
variantResult = computed(() => progressBarVariants({
|
|
170
|
+
size: this.size(),
|
|
171
|
+
variant: this.variant(),
|
|
172
|
+
isIndeterminate: this.isIndeterminate(),
|
|
173
|
+
hasHeader: this.hasHeader(),
|
|
174
|
+
}), ...(ngDevMode ? [{ debugName: "variantResult" }] : /* istanbul ignore next */ []));
|
|
175
|
+
rootClasses = computed(() => this.variantResult().root(), ...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
|
|
176
|
+
headerClasses = computed(() => this.variantResult().header(), ...(ngDevMode ? [{ debugName: "headerClasses" }] : /* istanbul ignore next */ []));
|
|
177
|
+
labelClasses = computed(() => this.variantResult().label(), ...(ngDevMode ? [{ debugName: "labelClasses" }] : /* istanbul ignore next */ []));
|
|
178
|
+
valueTextClasses = computed(() => this.variantResult().valueText(), ...(ngDevMode ? [{ debugName: "valueTextClasses" }] : /* istanbul ignore next */ []));
|
|
179
|
+
railClasses = computed(() => this.variantResult().rail(), ...(ngDevMode ? [{ debugName: "railClasses" }] : /* istanbul ignore next */ []));
|
|
180
|
+
fillClasses = computed(() => `${this.variantResult().fill()} ${FILL_COLORS[this.color()]}`, ...(ngDevMode ? [{ debugName: "fillClasses" }] : /* istanbul ignore next */ []));
|
|
181
|
+
segmentListClasses = computed(() => this.variantResult().segmentList(), ...(ngDevMode ? [{ debugName: "segmentListClasses" }] : /* istanbul ignore next */ []));
|
|
182
|
+
segmentBaseClasses = computed(() => this.variantResult().segment(), ...(ngDevMode ? [{ debugName: "segmentBaseClasses" }] : /* istanbul ignore next */ []));
|
|
183
|
+
/** @internal */
|
|
184
|
+
segmentClassFor(index) {
|
|
185
|
+
const base = this.segmentBaseClasses();
|
|
186
|
+
const filled = (index + 1) / this.segmentIndices().length <= this.progressRatio();
|
|
187
|
+
const bg = filled ? FILL_COLORS[this.color()] : 'bg-surface-muted';
|
|
188
|
+
return `${base} ${bg}`;
|
|
189
|
+
}
|
|
190
|
+
// ── Dev-mode accessible-name warning (fires once per instance) ──
|
|
191
|
+
//
|
|
192
|
+
// The effect is reactive on purpose: if a consumer mounts the component
|
|
193
|
+
// without a label and later removes the only accessible name they had, the
|
|
194
|
+
// warning still fires on the *first* render where no name is present. Once
|
|
195
|
+
// it has fired, `warned` short-circuits further evaluations. Production
|
|
196
|
+
// builds skip the entire effect setup because `ngDevMode` is statically
|
|
197
|
+
// `false` and the constructor returns early.
|
|
198
|
+
constructor() {
|
|
199
|
+
if (typeof ngDevMode !== 'undefined' && !ngDevMode)
|
|
200
|
+
return;
|
|
201
|
+
let warned = false;
|
|
202
|
+
effect(() => {
|
|
203
|
+
if (warned)
|
|
204
|
+
return;
|
|
205
|
+
const opts = this.options();
|
|
206
|
+
if (this.label() || opts?.ariaLabel || opts?.ariaLabelledby)
|
|
207
|
+
return;
|
|
208
|
+
// `untracked` wraps the side-effect so the console.warn / flag mutation
|
|
209
|
+
// can never create a reactive subscription — defensive in case future
|
|
210
|
+
// work adds signal reads inside the warning block.
|
|
211
|
+
untracked(() => {
|
|
212
|
+
warned = true;
|
|
213
|
+
console.warn('tw-progress-bar: no accessible name provided. Supply one of `label`, `options.ariaLabel`, or `options.ariaLabelledby`.');
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
218
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: ProgressBarComponent, isStandalone: true, selector: "tw-progress-bar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, 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 }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "rootClasses()" } }, ngImport: i0, template: `
|
|
219
|
+
@if (hasHeader()) {
|
|
220
|
+
<div [class]="headerClasses()">
|
|
221
|
+
@if (label(); as lbl) {
|
|
222
|
+
<span [id]="labelId" [class]="labelClasses()">{{ lbl }}</span>
|
|
223
|
+
} @else {
|
|
224
|
+
<span></span>
|
|
225
|
+
}
|
|
226
|
+
@if (resolvedShowValue() && !isIndeterminate()) {
|
|
227
|
+
<span [class]="valueTextClasses()">{{ formattedValue() }}</span>
|
|
228
|
+
}
|
|
229
|
+
</div>
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@if (variant() === 'linear') {
|
|
233
|
+
<div
|
|
234
|
+
[class]="railClasses()"
|
|
235
|
+
role="progressbar"
|
|
236
|
+
[attr.aria-valuemin]="resolvedMin()"
|
|
237
|
+
[attr.aria-valuemax]="resolvedMax()"
|
|
238
|
+
[attr.aria-valuenow]="isIndeterminate() ? null : clampedValue()"
|
|
239
|
+
[attr.aria-valuetext]="isIndeterminate() ? null : formattedValue()"
|
|
240
|
+
[attr.aria-busy]="isIndeterminate() ? true : null"
|
|
241
|
+
[attr.aria-label]="resolvedAriaLabel()"
|
|
242
|
+
[attr.aria-labelledby]="resolvedAriaLabelledby()"
|
|
243
|
+
>
|
|
244
|
+
@if (isIndeterminate()) {
|
|
245
|
+
<span [class]="fillClasses()"></span>
|
|
246
|
+
} @else {
|
|
247
|
+
<span [class]="fillClasses()" [style.width.%]="progressRatio() * 100"></span>
|
|
248
|
+
}
|
|
249
|
+
</div>
|
|
250
|
+
} @else {
|
|
251
|
+
<div
|
|
252
|
+
[class]="segmentListClasses()"
|
|
253
|
+
role="progressbar"
|
|
254
|
+
[attr.aria-valuemin]="resolvedMin()"
|
|
255
|
+
[attr.aria-valuemax]="resolvedMax()"
|
|
256
|
+
[attr.aria-valuenow]="isIndeterminate() ? null : clampedValue()"
|
|
257
|
+
[attr.aria-valuetext]="isIndeterminate() ? null : formattedValue()"
|
|
258
|
+
[attr.aria-busy]="isIndeterminate() ? true : null"
|
|
259
|
+
[attr.aria-label]="resolvedAriaLabel()"
|
|
260
|
+
[attr.aria-labelledby]="resolvedAriaLabelledby()"
|
|
261
|
+
>
|
|
262
|
+
@for (i of segmentIndices(); track i) {
|
|
263
|
+
<span [class]="segmentClassFor(i)"></span>
|
|
264
|
+
}
|
|
265
|
+
</div>
|
|
266
|
+
}
|
|
267
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
268
|
+
}
|
|
269
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ProgressBarComponent, decorators: [{
|
|
270
|
+
type: Component,
|
|
271
|
+
args: [{
|
|
272
|
+
selector: 'tw-progress-bar',
|
|
273
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
274
|
+
host: {
|
|
275
|
+
'[class]': 'rootClasses()',
|
|
276
|
+
},
|
|
277
|
+
template: `
|
|
278
|
+
@if (hasHeader()) {
|
|
279
|
+
<div [class]="headerClasses()">
|
|
280
|
+
@if (label(); as lbl) {
|
|
281
|
+
<span [id]="labelId" [class]="labelClasses()">{{ lbl }}</span>
|
|
282
|
+
} @else {
|
|
283
|
+
<span></span>
|
|
284
|
+
}
|
|
285
|
+
@if (resolvedShowValue() && !isIndeterminate()) {
|
|
286
|
+
<span [class]="valueTextClasses()">{{ formattedValue() }}</span>
|
|
287
|
+
}
|
|
288
|
+
</div>
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@if (variant() === 'linear') {
|
|
292
|
+
<div
|
|
293
|
+
[class]="railClasses()"
|
|
294
|
+
role="progressbar"
|
|
295
|
+
[attr.aria-valuemin]="resolvedMin()"
|
|
296
|
+
[attr.aria-valuemax]="resolvedMax()"
|
|
297
|
+
[attr.aria-valuenow]="isIndeterminate() ? null : clampedValue()"
|
|
298
|
+
[attr.aria-valuetext]="isIndeterminate() ? null : formattedValue()"
|
|
299
|
+
[attr.aria-busy]="isIndeterminate() ? true : null"
|
|
300
|
+
[attr.aria-label]="resolvedAriaLabel()"
|
|
301
|
+
[attr.aria-labelledby]="resolvedAriaLabelledby()"
|
|
302
|
+
>
|
|
303
|
+
@if (isIndeterminate()) {
|
|
304
|
+
<span [class]="fillClasses()"></span>
|
|
305
|
+
} @else {
|
|
306
|
+
<span [class]="fillClasses()" [style.width.%]="progressRatio() * 100"></span>
|
|
307
|
+
}
|
|
308
|
+
</div>
|
|
309
|
+
} @else {
|
|
310
|
+
<div
|
|
311
|
+
[class]="segmentListClasses()"
|
|
312
|
+
role="progressbar"
|
|
313
|
+
[attr.aria-valuemin]="resolvedMin()"
|
|
314
|
+
[attr.aria-valuemax]="resolvedMax()"
|
|
315
|
+
[attr.aria-valuenow]="isIndeterminate() ? null : clampedValue()"
|
|
316
|
+
[attr.aria-valuetext]="isIndeterminate() ? null : formattedValue()"
|
|
317
|
+
[attr.aria-busy]="isIndeterminate() ? true : null"
|
|
318
|
+
[attr.aria-label]="resolvedAriaLabel()"
|
|
319
|
+
[attr.aria-labelledby]="resolvedAriaLabelledby()"
|
|
320
|
+
>
|
|
321
|
+
@for (i of segmentIndices(); track i) {
|
|
322
|
+
<span [class]="segmentClassFor(i)"></span>
|
|
323
|
+
}
|
|
324
|
+
</div>
|
|
325
|
+
}
|
|
326
|
+
`,
|
|
327
|
+
}]
|
|
328
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], 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 }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }] } });
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Generated bundle index. Do not edit.
|
|
332
|
+
*/
|
|
333
|
+
|
|
334
|
+
export { ProgressBarComponent };
|
|
335
|
+
//# sourceMappingURL=cdevhub-ngx-tw-progress-bar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdevhub-ngx-tw-progress-bar.mjs","sources":["../../../projects/ngx-tw/progress-bar/progress-bar.ts","../../../projects/ngx-tw/progress-bar/cdevhub-ngx-tw-progress-bar.ts"],"sourcesContent":["/**\n * `tw-progress-bar` — visualises measurable progress.\n *\n * Composition usecases:\n * - Upload progress (determinate linear with `options.formatter` → `\"3.2 MB / 10 MB\"`).\n * - Multi-step wizard (segmented variant, `options.segments` = step count).\n * - Skill / rating display (static determinate linear).\n * - Inline list-row progress (compact `size=\"sm\"`, constrained width via host class).\n * - Card-footer task completion (`options.showValue=true`, `color` switches to `success`/`error`).\n * - Indeterminate loading before first byte (omit `value` — the bar sweeps).\n *\n * For unknown-duration operations with no measurable progress, use `tw-spinner` instead.\n */\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n input,\n untracked,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor } from '@cdevhub/ngx-tw/core';\n\n// `ngDevMode` is a globalThis flag set by Angular's build tooling — true in dev,\n// `false` in production builds. The `typeof` guard keeps the warning path safe\n// in environments (SSR, ad-hoc test harnesses) where the global is undeclared.\n// Preferred over `isDevMode()` because the latter is a runtime function call;\n// `ngDevMode` is a build-time constant the bundler can dead-code-eliminate.\ndeclare const ngDevMode: boolean | undefined;\n\n/** Visual style of the progress bar. */\nexport type ProgressBarVariant = 'linear' | 'segmented';\n\n/** Size scale specific to progress bars (bar thickness). */\nexport type ProgressBarSize = 'sm' | 'md' | 'lg';\n\n/** Function signature for formatting the visible / announced progress value. */\nexport type ProgressBarValueFormatter = (value: number, max: number, min: number) => string;\n\n/**\n * Non-visual configuration bundled into a single input to keep the component's public\n * surface small. Every field is optional and falls back to a sensible default.\n */\nexport interface ProgressBarOptions {\n /** Lower bound of the value range. Defaults to `0`. */\n min?: number;\n /** Upper bound of the value range. Defaults to `100`. */\n max?: number;\n /** Number of equal cells when `variant` is `'segmented'`. Ignored for `'linear'`. Defaults to `5`. */\n segments?: number;\n /** When true, renders the formatted progress value next to the label. Defaults to `false`. */\n showValue?: boolean;\n /** Custom formatter for the displayed and announced value. Defaults to an integer percentage, e.g. `'42%'`. */\n formatter?: ProgressBarValueFormatter;\n /** Accessible name when no visible `label` is provided. Mirrored to `aria-label` on the progressbar element. */\n ariaLabel?: string;\n /** ID of an external element that labels the progress bar. Mirrored to `aria-labelledby`. */\n ariaLabelledby?: string;\n}\n\n// ── Static fill-color lookup (Tailwind v4 scans class strings statically) ──\n\nconst FILL_COLORS: Record<TwColor, string> = {\n primary: 'bg-primary-500',\n secondary: 'bg-secondary-500',\n accent: 'bg-accent-500',\n neutral: 'bg-fg',\n info: 'bg-info-500',\n success: 'bg-success-500',\n warning: 'bg-warning-500',\n error: 'bg-error-500',\n};\n\n// ── tv() config ──\n\nconst progressBarVariants = tv({\n slots: {\n root: 'flex flex-col w-full',\n header: 'flex items-center justify-between gap-3',\n label: 'text-xs text-fg-muted',\n valueText: 'text-xs text-fg-muted font-medium tabular-nums',\n rail: 'relative w-full overflow-hidden rounded-full bg-surface-muted',\n fill: 'absolute inset-y-0 left-0 rounded-full',\n segmentList: 'flex w-full gap-1',\n segment: 'flex-1 rounded-full',\n },\n variants: {\n size: {\n sm: { rail: 'h-1', segment: 'h-1' },\n md: { rail: 'h-2', segment: 'h-2' },\n lg: { rail: 'h-3', segment: 'h-3' },\n },\n variant: {\n linear: { segmentList: 'hidden' },\n segmented: { rail: 'hidden' },\n },\n isIndeterminate: {\n true: { fill: 'w-[30%] animate-progress-bar-indeterminate' },\n false: { fill: 'transition-[width] duration-normal motion-reduce:transition-none' },\n },\n hasHeader: {\n true: { root: 'gap-1.5' },\n false: { root: 'gap-0' },\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'linear',\n isIndeterminate: false,\n hasHeader: false,\n },\n}, {\n twMerge: true,\n});\n\nlet nextId = 0;\n\nconst DEFAULT_FORMATTER: ProgressBarValueFormatter = (value, max, min) => {\n const range = max - min;\n if (range <= 0) return '0%';\n return `${Math.round(((value - min) / range) * 100)}%`;\n};\n\n/**\n * Indicates progress toward the completion of a task.\n *\n * @example\n * ```html\n * <tw-progress-bar [value]=\"40\" />\n * <tw-progress-bar label=\"Fetching records\" />\n * <tw-progress-bar\n * variant=\"segmented\"\n * [value]=\"step() * 25\"\n * [options]=\"{ segments: 4 }\"\n * />\n * ```\n */\n@Component({\n selector: 'tw-progress-bar',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n },\n template: `\n @if (hasHeader()) {\n <div [class]=\"headerClasses()\">\n @if (label(); as lbl) {\n <span [id]=\"labelId\" [class]=\"labelClasses()\">{{ lbl }}</span>\n } @else {\n <span></span>\n }\n @if (resolvedShowValue() && !isIndeterminate()) {\n <span [class]=\"valueTextClasses()\">{{ formattedValue() }}</span>\n }\n </div>\n }\n\n @if (variant() === 'linear') {\n <div\n [class]=\"railClasses()\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"resolvedMin()\"\n [attr.aria-valuemax]=\"resolvedMax()\"\n [attr.aria-valuenow]=\"isIndeterminate() ? null : clampedValue()\"\n [attr.aria-valuetext]=\"isIndeterminate() ? null : formattedValue()\"\n [attr.aria-busy]=\"isIndeterminate() ? true : null\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [attr.aria-labelledby]=\"resolvedAriaLabelledby()\"\n >\n @if (isIndeterminate()) {\n <span [class]=\"fillClasses()\"></span>\n } @else {\n <span [class]=\"fillClasses()\" [style.width.%]=\"progressRatio() * 100\"></span>\n }\n </div>\n } @else {\n <div\n [class]=\"segmentListClasses()\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"resolvedMin()\"\n [attr.aria-valuemax]=\"resolvedMax()\"\n [attr.aria-valuenow]=\"isIndeterminate() ? null : clampedValue()\"\n [attr.aria-valuetext]=\"isIndeterminate() ? null : formattedValue()\"\n [attr.aria-busy]=\"isIndeterminate() ? true : null\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [attr.aria-labelledby]=\"resolvedAriaLabelledby()\"\n >\n @for (i of segmentIndices(); track i) {\n <span [class]=\"segmentClassFor(i)\"></span>\n }\n </div>\n }\n `,\n})\nexport class ProgressBarComponent {\n /** Current progress value. When null or undefined, the bar renders indeterminate. Values outside `[options.min, options.max]` are clamped. */\n readonly value = input<number | null | undefined>(null);\n\n /** Visual style of the bar. `'linear'` renders a single fill; `'segmented'` splits the rail into discrete steps. Defaults to `'linear'`. */\n readonly variant = input<ProgressBarVariant>('linear');\n\n /** Semantic color of the filled portion. Defaults to `'primary'`. Use status colors (`success`/`warning`/`error`) to reflect task outcome. */\n readonly color = input<TwColor>('primary');\n\n /** Bar thickness. `'sm'` = h-1, `'md'` = h-2, `'lg'` = h-3. Defaults to `'md'`. */\n readonly size = input<ProgressBarSize>('md');\n\n /** Visible label rendered above the bar. When set, the bar is wired to the label via `aria-labelledby`. */\n readonly label = input<string | undefined>(undefined);\n\n /** Bundles non-visual configuration: value range (`min`/`max`/`segments`), value readout (`showValue`/`formatter`), and accessibility fallbacks (`ariaLabel`/`ariaLabelledby`). Every field is optional. */\n readonly options = input<ProgressBarOptions | undefined>(undefined);\n\n /** @internal */\n readonly labelId = `tw-progress-bar-${nextId++}-label`;\n\n /** @internal */\n readonly resolvedMin = computed(() => this.options()?.min ?? 0);\n\n /** @internal */\n readonly resolvedMax = computed(() => this.options()?.max ?? 100);\n\n /** @internal */\n readonly resolvedSegments = computed(() => this.options()?.segments ?? 5);\n\n /** @internal */\n readonly resolvedShowValue = computed(() => this.options()?.showValue ?? false);\n\n /** @internal */\n readonly isIndeterminate = computed(() => {\n const v = this.value();\n return v === null || v === undefined;\n });\n\n /** @internal */\n readonly clampedValue = computed(() => {\n const v = this.value();\n if (v === null || v === undefined) return this.resolvedMin();\n const lo = this.resolvedMin();\n const hi = this.resolvedMax();\n if (v < lo) return lo;\n if (v > hi) return hi;\n return v;\n });\n\n /** @internal */\n readonly progressRatio = computed(() => {\n if (this.isIndeterminate()) return 0;\n const range = this.resolvedMax() - this.resolvedMin();\n if (range <= 0) return 0;\n return (this.clampedValue() - this.resolvedMin()) / range;\n });\n\n /** @internal */\n readonly formattedValue = computed(() => {\n if (this.isIndeterminate()) return '';\n const fmt = this.options()?.formatter ?? DEFAULT_FORMATTER;\n return fmt(this.clampedValue(), this.resolvedMax(), this.resolvedMin());\n });\n\n /** @internal */\n readonly hasHeader = computed(() => !!this.label() || this.resolvedShowValue());\n\n /** @internal */\n readonly segmentIndices = computed(() => {\n const n = Math.max(1, Math.floor(this.resolvedSegments()));\n return Array.from({ length: n }, (_, i) => i);\n });\n\n /** @internal */\n readonly resolvedAriaLabel = computed(() => {\n if (this.label()) return null;\n if (this.options()?.ariaLabelledby) return null;\n return this.options()?.ariaLabel ?? null;\n });\n\n /** @internal */\n readonly resolvedAriaLabelledby = computed(() => {\n if (this.label()) return this.labelId;\n return this.options()?.ariaLabelledby ?? null;\n });\n\n // ── tv() slot computeds ──\n\n private readonly variantResult = computed(() =>\n progressBarVariants({\n size: this.size(),\n variant: this.variant(),\n isIndeterminate: this.isIndeterminate(),\n hasHeader: this.hasHeader(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly headerClasses = computed(() => this.variantResult().header());\n readonly labelClasses = computed(() => this.variantResult().label());\n readonly valueTextClasses = computed(() => this.variantResult().valueText());\n readonly railClasses = computed(() => this.variantResult().rail());\n readonly fillClasses = computed(() => `${this.variantResult().fill()} ${FILL_COLORS[this.color()]}`);\n readonly segmentListClasses = computed(() => this.variantResult().segmentList());\n private readonly segmentBaseClasses = computed(() => this.variantResult().segment());\n\n /** @internal */\n segmentClassFor(index: number): string {\n const base = this.segmentBaseClasses();\n const filled = (index + 1) / this.segmentIndices().length <= this.progressRatio();\n const bg = filled ? FILL_COLORS[this.color()] : 'bg-surface-muted';\n return `${base} ${bg}`;\n }\n\n // ── Dev-mode accessible-name warning (fires once per instance) ──\n //\n // The effect is reactive on purpose: if a consumer mounts the component\n // without a label and later removes the only accessible name they had, the\n // warning still fires on the *first* render where no name is present. Once\n // it has fired, `warned` short-circuits further evaluations. Production\n // builds skip the entire effect setup because `ngDevMode` is statically\n // `false` and the constructor returns early.\n\n constructor() {\n if (typeof ngDevMode !== 'undefined' && !ngDevMode) return;\n let warned = false;\n effect(() => {\n if (warned) return;\n const opts = this.options();\n if (this.label() || opts?.ariaLabel || opts?.ariaLabelledby) return;\n // `untracked` wraps the side-effect so the console.warn / flag mutation\n // can never create a reactive subscription — defensive in case future\n // work adds signal reads inside the warning block.\n untracked(() => {\n warned = true;\n console.warn(\n 'tw-progress-bar: no accessible name provided. Supply one of `label`, `options.ariaLabel`, or `options.ariaLabelledby`.',\n );\n });\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|