ngx-com 0.0.1 → 0.0.3

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.
Files changed (58) hide show
  1. package/fesm2022/ngx-com-components-badge.mjs +138 -0
  2. package/fesm2022/ngx-com-components-badge.mjs.map +1 -0
  3. package/fesm2022/ngx-com-components-button.mjs +146 -0
  4. package/fesm2022/ngx-com-components-button.mjs.map +1 -0
  5. package/fesm2022/ngx-com-components-calendar.mjs +5046 -0
  6. package/fesm2022/ngx-com-components-calendar.mjs.map +1 -0
  7. package/fesm2022/ngx-com-components-card.mjs +590 -0
  8. package/fesm2022/ngx-com-components-card.mjs.map +1 -0
  9. package/fesm2022/ngx-com-components-checkbox.mjs +344 -0
  10. package/fesm2022/ngx-com-components-checkbox.mjs.map +1 -0
  11. package/fesm2022/ngx-com-components-collapsible.mjs +612 -0
  12. package/fesm2022/ngx-com-components-collapsible.mjs.map +1 -0
  13. package/fesm2022/ngx-com-components-dropdown-testing.mjs +255 -0
  14. package/fesm2022/ngx-com-components-dropdown-testing.mjs.map +1 -0
  15. package/fesm2022/ngx-com-components-dropdown.mjs +2598 -0
  16. package/fesm2022/ngx-com-components-dropdown.mjs.map +1 -0
  17. package/fesm2022/ngx-com-components-form-field.mjs +923 -0
  18. package/fesm2022/ngx-com-components-form-field.mjs.map +1 -0
  19. package/fesm2022/ngx-com-components-icon.mjs +183 -0
  20. package/fesm2022/ngx-com-components-icon.mjs.map +1 -0
  21. package/fesm2022/ngx-com-components-menu.mjs +1200 -0
  22. package/fesm2022/ngx-com-components-menu.mjs.map +1 -0
  23. package/fesm2022/ngx-com-components-popover.mjs +901 -0
  24. package/fesm2022/ngx-com-components-popover.mjs.map +1 -0
  25. package/fesm2022/ngx-com-components-radio.mjs +621 -0
  26. package/fesm2022/ngx-com-components-radio.mjs.map +1 -0
  27. package/fesm2022/ngx-com-components-sort.mjs +368 -0
  28. package/fesm2022/ngx-com-components-sort.mjs.map +1 -0
  29. package/fesm2022/ngx-com-components-tabs.mjs +1522 -0
  30. package/fesm2022/ngx-com-components-tabs.mjs.map +1 -0
  31. package/fesm2022/ngx-com-components.mjs +17 -0
  32. package/fesm2022/ngx-com-components.mjs.map +1 -0
  33. package/fesm2022/ngx-com-tokens.mjs +12 -0
  34. package/fesm2022/ngx-com-tokens.mjs.map +1 -0
  35. package/fesm2022/ngx-com-utils.mjs +601 -0
  36. package/fesm2022/ngx-com-utils.mjs.map +1 -0
  37. package/fesm2022/ngx-com.mjs +9 -23
  38. package/fesm2022/ngx-com.mjs.map +1 -1
  39. package/package.json +73 -1
  40. package/types/ngx-com-components-badge.d.ts +97 -0
  41. package/types/ngx-com-components-button.d.ts +69 -0
  42. package/types/ngx-com-components-calendar.d.ts +1665 -0
  43. package/types/ngx-com-components-card.d.ts +373 -0
  44. package/types/ngx-com-components-checkbox.d.ts +116 -0
  45. package/types/ngx-com-components-collapsible.d.ts +379 -0
  46. package/types/ngx-com-components-dropdown-testing.d.ts +116 -0
  47. package/types/ngx-com-components-dropdown.d.ts +914 -0
  48. package/types/ngx-com-components-form-field.d.ts +531 -0
  49. package/types/ngx-com-components-icon.d.ts +94 -0
  50. package/types/ngx-com-components-menu.d.ts +479 -0
  51. package/types/ngx-com-components-popover.d.ts +309 -0
  52. package/types/ngx-com-components-radio.d.ts +258 -0
  53. package/types/ngx-com-components-sort.d.ts +133 -0
  54. package/types/ngx-com-components-tabs.d.ts +396 -0
  55. package/types/ngx-com-components.d.ts +12 -0
  56. package/types/ngx-com-tokens.d.ts +7 -0
  57. package/types/ngx-com-utils.d.ts +424 -0
  58. package/types/ngx-com.d.ts +10 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-com-components-collapsible.mjs","sources":["../../../projects/com/components/collapsible/collapsible.variants.ts","../../../projects/com/components/collapsible/collapsible-trigger.variants.ts","../../../projects/com/components/collapsible/directives/collapsible-trigger-tpl.directive.ts","../../../projects/com/components/collapsible/directives/collapsible-content-tpl.directive.ts","../../../projects/com/components/collapsible/directives/collapsible-icon-tpl.directive.ts","../../../projects/com/components/collapsible/directives/collapsible-lazy.directive.ts","../../../projects/com/components/collapsible/collapsible.utils.ts","../../../projects/com/components/collapsible/collapsible.directive.ts","../../../projects/com/components/collapsible/collapsible-trigger.component.ts","../../../projects/com/components/collapsible/collapsible-content.component.ts","../../../projects/com/components/collapsible/index.ts","../../../projects/com/components/collapsible/ngx-com-components-collapsible.ts"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\n\n/**\n * Shell variant type for the collapsible container.\n */\nexport type CollapsibleVariant = 'card' | 'bordered' | 'flush' | 'ghost' | 'unstyled';\n\n/**\n * CVA variants for the collapsible shell (root directive).\n *\n * @tokens `--color-border`, `--color-background`, `--color-foreground`, `--shadow-xs`, `--radius-collapsible`\n */\nexport const collapsibleVariants: (props?: {\n variant?: CollapsibleVariant;\n}) => string = cva(\n // Base — structural only\n 'com-collapsible block',\n {\n variants: {\n variant: {\n card: 'rounded-collapsible border border-border bg-background text-foreground shadow-xs',\n bordered: 'rounded-collapsible border border-border',\n flush: 'border-b border-border',\n ghost: '',\n unstyled: '',\n },\n },\n defaultVariants: {\n variant: 'ghost',\n },\n }\n);\n\nexport type CollapsibleVariants = VariantProps<typeof collapsibleVariants>;\n","import { cva, type VariantProps } from 'class-variance-authority';\n\n/**\n * Trigger variant type for the collapsible trigger.\n */\nexport type CollapsibleTriggerVariant = 'ghost' | 'filled' | 'header' | 'unstyled';\n\n/**\n * Trigger size type.\n */\nexport type CollapsibleTriggerSize = 'sm' | 'default' | 'lg';\n\n/**\n * CVA variants for the collapsible trigger directive.\n *\n * @tokens `--color-foreground`, `--color-muted`, `--color-muted-foreground`, `--color-muted-hover`,\n * `--color-ring`, `--color-disabled-foreground`, `--radius-collapsible`\n */\nexport const collapsibleTriggerVariants: (props?: {\n variant?: CollapsibleTriggerVariant;\n size?: CollapsibleTriggerSize;\n}) => string = cva(\n [\n 'com-collapsible-trigger',\n 'flex w-full items-center justify-between',\n 'cursor-pointer select-none',\n 'text-sm font-medium',\n 'transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:text-disabled-foreground',\n '[&>svg]:transition-transform [&>svg]:duration-200',\n '[&>svg.com-collapsible-icon]:data-[state=open]:rotate-180',\n ].join(' '),\n {\n variants: {\n variant: {\n ghost: 'rounded-collapsible text-foreground hover:bg-muted hover:text-muted-foreground',\n filled: 'rounded-collapsible bg-muted text-muted-foreground hover:bg-muted-hover',\n header: 'text-foreground hover:text-muted-foreground',\n unstyled: '',\n },\n size: {\n sm: 'px-2 py-1 text-xs gap-1',\n default: 'px-3 py-2 text-sm gap-2',\n lg: 'px-4 py-3 text-base gap-3',\n },\n },\n defaultVariants: {\n variant: 'ghost',\n size: 'default',\n },\n }\n);\n\nexport type CollapsibleTriggerVariants = VariantProps<typeof collapsibleTriggerVariants>;\n","import { Directive, TemplateRef, inject } from '@angular/core';\nimport type { ComCollapsibleTriggerContext } from '../collapsible.models';\n\n/**\n * Directive to mark a template as the custom trigger layout template.\n * Replaces the inner content of the trigger while preserving ARIA and keyboard handling.\n *\n * @example\n * ```html\n * <button comCollapsibleTrigger>\n * <ng-template comCollapsibleTriggerTpl let-open let-toggle=\"toggle\" let-disabled=\"disabled\">\n * <div class=\"flex items-center gap-3 w-full\">\n * <span class=\"h-2 w-2 rounded-full\" [class]=\"open ? 'bg-success' : 'bg-muted'\"></span>\n * <span class=\"font-medium\">Notifications</span>\n * <svg class=\"com-collapsible-icon h-4 w-4\" [attr.data-state]=\"open ? 'open' : 'closed'\">\n * <!-- chevron icon -->\n * </svg>\n * </div>\n * </ng-template>\n * </button>\n * ```\n */\n@Directive({\n selector: 'ng-template[comCollapsibleTriggerTpl]',\n})\nexport class ComCollapsibleTriggerTpl {\n /** Reference to the template. */\n readonly templateRef: TemplateRef<ComCollapsibleTriggerContext> =\n inject<TemplateRef<ComCollapsibleTriggerContext>>(TemplateRef);\n\n /**\n * Static type guard for template type checking.\n * Enables type-safe access to context properties in templates.\n */\n static ngTemplateContextGuard(\n _dir: ComCollapsibleTriggerTpl,\n ctx: unknown\n ): ctx is ComCollapsibleTriggerContext {\n return true;\n }\n}\n","import { Directive, TemplateRef, inject } from '@angular/core';\nimport type { ComCollapsibleContentContext } from '../collapsible.models';\n\n/**\n * Directive to mark a template as the custom content chrome template.\n * Wraps the content with custom chrome (headers, footers, padding).\n * The grid animation still applies on the host.\n *\n * @example\n * ```html\n * <com-collapsible-content>\n * <ng-template comCollapsibleContentTpl let-open=\"open\">\n * <div class=\"border-t border-border\">\n * <div class=\"p-4 space-y-3\">\n * <!-- Content here -->\n * </div>\n * <div class=\"flex justify-end gap-2 px-4 py-3 border-t border-border-subtle bg-muted\">\n * <button>Reset</button>\n * <button>Apply</button>\n * </div>\n * </div>\n * </ng-template>\n * </com-collapsible-content>\n * ```\n */\n@Directive({\n selector: 'ng-template[comCollapsibleContentTpl]',\n})\nexport class ComCollapsibleContentTpl {\n /** Reference to the template. */\n readonly templateRef: TemplateRef<ComCollapsibleContentContext> =\n inject<TemplateRef<ComCollapsibleContentContext>>(TemplateRef);\n\n /**\n * Static type guard for template type checking.\n * Enables type-safe access to context properties in templates.\n */\n static ngTemplateContextGuard(\n _dir: ComCollapsibleContentTpl,\n ctx: unknown\n ): ctx is ComCollapsibleContentContext {\n return true;\n }\n}\n","import { Directive, TemplateRef, inject } from '@angular/core';\nimport type { ComCollapsibleIconContext } from '../collapsible.models';\n\n/**\n * Directive to mark a template as the custom icon template.\n * Replaces only the chevron icon inside the default trigger layout.\n *\n * @example\n * ```html\n * <button comCollapsibleTrigger>\n * Settings\n * <ng-template comCollapsibleIcon let-open=\"open\">\n * <span class=\"text-muted-foreground text-xs\">{{ open ? '▲' : '▼' }}</span>\n * </ng-template>\n * </button>\n * ```\n */\n@Directive({\n selector: 'ng-template[comCollapsibleIcon]',\n})\nexport class ComCollapsibleIconTpl {\n /** Reference to the template. */\n readonly templateRef: TemplateRef<ComCollapsibleIconContext> =\n inject<TemplateRef<ComCollapsibleIconContext>>(TemplateRef);\n\n /**\n * Static type guard for template type checking.\n * Enables type-safe access to context properties in templates.\n */\n static ngTemplateContextGuard(\n _dir: ComCollapsibleIconTpl,\n ctx: unknown\n ): ctx is ComCollapsibleIconContext {\n return true;\n }\n}\n","import { Directive, TemplateRef, inject } from '@angular/core';\n\n/**\n * Structural directive for lazy content rendering.\n * Content is only instantiated on first expand, preserving state on subsequent toggles.\n *\n * @example\n * ```html\n * <com-collapsible-content>\n * <ng-template comCollapsibleLazy>\n * <app-heavy-chart [data]=\"chartData()\" />\n * </ng-template>\n * </com-collapsible-content>\n * ```\n */\n@Directive({\n selector: 'ng-template[comCollapsibleLazy]',\n})\nexport class ComCollapsibleLazy {\n /** Reference to the template. */\n readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n","export { mergeClasses } from 'ngx-com/utils';\n\nlet collapsibleIdCounter = 0;\n\n/**\n * Generates a unique ID for collapsible components.\n * @returns A unique string ID\n */\nexport function generateCollapsibleId(): string {\n return `com-collapsible-${++collapsibleIdCounter}`;\n}\n","import {\n booleanAttribute,\n computed,\n Directive,\n input,\n model,\n} from '@angular/core';\nimport type { InputSignal, InputSignalWithTransform, ModelSignal, Signal } from '@angular/core';\nimport { mergeClasses, generateCollapsibleId } from './collapsible.utils';\nimport { collapsibleVariants } from './collapsible.variants';\nimport type { CollapsibleVariant } from './collapsible.variants';\n\n/**\n * Root collapsible directive — manages state and provides shell styling.\n *\n * Works as a DI anchor for child directives (trigger, content).\n * Exposes programmatic control via template reference.\n *\n * @tokens `--color-border`, `--color-background`, `--color-foreground`, `--shadow-xs`\n *\n * @example Basic usage\n * ```html\n * <div comCollapsible variant=\"card\">\n * <button comCollapsibleTrigger>Section Title</button>\n * <com-collapsible-content>\n * <div class=\"p-4\">Content here.</div>\n * </com-collapsible-content>\n * </div>\n * ```\n *\n * @example Two-way binding with external control\n * ```html\n * <div comCollapsible [(open)]=\"sectionOpen\" #section=\"comCollapsible\">\n * <button comCollapsibleTrigger>Advanced</button>\n * <com-collapsible-content>...</com-collapsible-content>\n * </div>\n * <button (click)=\"section.toggle()\">Toggle externally</button>\n * ```\n */\n@Directive({\n selector: '[comCollapsible]',\n exportAs: 'comCollapsible',\n host: {\n '[class]': 'computedClass()',\n '[attr.data-state]': 'isOpen() ? \"open\" : \"closed\"',\n },\n})\nexport class ComCollapsible {\n /** Unique ID for the collapsible instance. */\n private readonly id: string = generateCollapsibleId();\n\n /** ID for the trigger element (used for aria-labelledby). */\n readonly triggerId: string = `${this.id}-trigger`;\n\n /** ID for the content panel (used for aria-controls). */\n readonly contentId: string = `${this.id}-content`;\n\n // ============ INPUTS ============\n\n /** Two-way bound open state. */\n readonly open: ModelSignal<boolean> = model<boolean>(false);\n\n /** Disables the collapsible, preventing state changes. */\n readonly disabled: InputSignalWithTransform<boolean, unknown> = input(false, {\n transform: booleanAttribute,\n });\n\n /** Shell preset variant. */\n readonly variant: InputSignal<CollapsibleVariant> = input<CollapsibleVariant>('ghost');\n\n /** Consumer CSS classes — merged with variant classes. */\n readonly userClass: InputSignal<string> = input<string>('', { alias: 'class' });\n\n // ============ COMPUTED STATE ============\n\n /** @internal Computed host class from CVA + consumer overrides. */\n protected readonly computedClass: Signal<string> = computed(() =>\n mergeClasses(\n collapsibleVariants({ variant: this.variant() }),\n this.userClass()\n )\n );\n\n // ============ PUBLIC API ============\n\n /** Returns the current open state. */\n isOpen(): boolean {\n return this.open();\n }\n\n /** Returns the current disabled state. */\n isDisabled(): boolean {\n return this.disabled();\n }\n\n /** Toggles the open state (if not disabled). */\n toggle(): void {\n if (this.disabled()) return;\n this.open.update((v) => !v);\n }\n\n /** Expands the collapsible (if not disabled). */\n expand(): void {\n if (this.disabled()) return;\n this.open.set(true);\n }\n\n /** Collapses the collapsible (if not disabled). */\n collapse(): void {\n if (this.disabled()) return;\n this.open.set(false);\n }\n}\n","import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n inject,\n input,\n} from '@angular/core';\nimport type { InputSignal, InputSignalWithTransform, Signal } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ComCollapsible } from './collapsible.directive';\nimport { ComCollapsibleTriggerTpl } from './directives/collapsible-trigger-tpl.directive';\nimport { ComCollapsibleIconTpl } from './directives/collapsible-icon-tpl.directive';\nimport { mergeClasses } from './collapsible.utils';\nimport { collapsibleTriggerVariants } from './collapsible-trigger.variants';\nimport type { CollapsibleTriggerVariant, CollapsibleTriggerSize } from './collapsible-trigger.variants';\nimport type { ComCollapsibleTriggerContext, ComCollapsibleIconContext } from './collapsible.models';\n\n/**\n * Collapsible trigger component — handles toggle interaction, ARIA, keyboard, and template rendering.\n *\n * Uses attribute selector so it can be applied to `<button>` or any focusable element.\n * Injects the parent `ComCollapsible` directive to access state.\n * Supports custom trigger layout via `comCollapsibleTriggerTpl` and custom icon via `comCollapsibleIcon`.\n *\n * @tokens `--color-foreground`, `--color-muted`, `--color-muted-foreground`, `--color-muted-hover`,\n * `--color-ring`, `--color-disabled-foreground`\n *\n * @example Default trigger with auto icon\n * ```html\n * <button comCollapsibleTrigger>Section Title</button>\n * ```\n *\n * @example Without icon\n * ```html\n * <button comCollapsibleTrigger [showIcon]=\"false\">Section Title</button>\n * ```\n *\n * @example With custom icon\n * ```html\n * <button comCollapsibleTrigger>\n * Settings\n * <ng-template comCollapsibleIcon let-open=\"open\">\n * <span class=\"text-xs text-muted-foreground\">{{ open ? '▲' : '▼' }}</span>\n * </ng-template>\n * </button>\n * ```\n *\n * @example Full trigger layout override\n * ```html\n * <button comCollapsibleTrigger>\n * <ng-template comCollapsibleTriggerTpl let-open let-toggle=\"toggle\">\n * <div class=\"flex items-center gap-3 w-full\">\n * <span class=\"h-2 w-2 rounded-full\" [class]=\"open ? 'bg-success' : 'bg-muted'\"></span>\n * <span class=\"font-medium\">Notifications</span>\n * <svg class=\"com-collapsible-icon h-4 w-4\" [attr.data-state]=\"open ? 'open' : 'closed'\">\n * <!-- chevron -->\n * </svg>\n * </div>\n * </ng-template>\n * </button>\n * ```\n */\n@Component({\n selector: '[comCollapsibleTrigger]',\n template: `\n @if (triggerTpl()) {\n <ng-container\n [ngTemplateOutlet]=\"triggerTpl()!.templateRef\"\n [ngTemplateOutletContext]=\"triggerContext()\"\n />\n } @else {\n <span class=\"flex-1 truncate text-left\">\n <ng-content />\n </span>\n @if (showIcon()) {\n @if (iconTpl()) {\n <ng-container\n [ngTemplateOutlet]=\"iconTpl()!.templateRef\"\n [ngTemplateOutletContext]=\"iconContext()\"\n />\n } @else {\n <svg\n class=\"com-collapsible-icon h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200\"\n [attr.data-state]=\"collapsible.isOpen() ? 'open' : 'closed'\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n }\n }\n }\n `,\n styles: `\n :host {\n display: flex;\n }\n `,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'computedClass()',\n '[attr.id]': 'collapsible.triggerId',\n '[attr.type]': '\"button\"',\n '[attr.aria-expanded]': 'collapsible.isOpen()',\n '[attr.aria-controls]': 'collapsible.contentId',\n '[attr.aria-disabled]': 'collapsible.isDisabled() || null',\n '[attr.data-state]': 'collapsible.isOpen() ? \"open\" : \"closed\"',\n '[attr.disabled]': 'collapsible.isDisabled() || null',\n '[tabindex]': 'collapsible.isDisabled() ? -1 : 0',\n '(click)': 'onClick($event)',\n '(keydown.enter)': 'onKeydown($event)',\n '(keydown.space)': 'onKeydown($event)',\n },\n})\nexport class ComCollapsibleTrigger {\n /** Parent collapsible directive (provides state). */\n protected readonly collapsible: ComCollapsible = inject(ComCollapsible);\n\n /** Custom trigger layout template (replaces inner content). */\n protected readonly triggerTpl: Signal<ComCollapsibleTriggerTpl | undefined> =\n contentChild(ComCollapsibleTriggerTpl);\n\n /** Custom icon template (replaces default chevron). */\n protected readonly iconTpl: Signal<ComCollapsibleIconTpl | undefined> =\n contentChild(ComCollapsibleIconTpl);\n\n // ============ INPUTS ============\n\n /** Trigger preset variant. */\n readonly variant: InputSignal<CollapsibleTriggerVariant> =\n input<CollapsibleTriggerVariant>('ghost');\n\n /** Trigger size. */\n readonly size: InputSignal<CollapsibleTriggerSize> =\n input<CollapsibleTriggerSize>('default');\n\n /** Show/hide the toggle icon. */\n readonly showIcon: InputSignalWithTransform<boolean, unknown> = input(true, {\n transform: booleanAttribute,\n });\n\n /** Consumer CSS classes — merged with variant classes. */\n readonly userClass: InputSignal<string> = input<string>('', { alias: 'class' });\n\n // ============ COMPUTED STATE ============\n\n /** @internal Computed host class from CVA + consumer overrides. */\n protected readonly computedClass: Signal<string> = computed(() =>\n mergeClasses(\n collapsibleTriggerVariants({\n variant: this.variant(),\n size: this.size(),\n }),\n this.userClass()\n )\n );\n\n /** Context for trigger template. */\n readonly triggerContext: Signal<ComCollapsibleTriggerContext> = computed(() => ({\n $implicit: this.collapsible.isOpen(),\n open: this.collapsible.isOpen(),\n disabled: this.collapsible.isDisabled(),\n toggle: () => this.collapsible.toggle(),\n }));\n\n /** Context for icon template. */\n readonly iconContext: Signal<ComCollapsibleIconContext> = computed(() => ({\n $implicit: this.collapsible.isOpen(),\n open: this.collapsible.isOpen(),\n }));\n\n // ============ EVENT HANDLERS ============\n\n /** @internal */\n protected onClick(event: Event): void {\n event.preventDefault();\n this.collapsible.toggle();\n }\n\n /** @internal */\n protected onKeydown(event: Event): void {\n event.preventDefault();\n this.collapsible.toggle();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n inject,\n input,\n signal,\n effect,\n} from '@angular/core';\nimport type { InputSignal, Signal, WritableSignal } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { ComCollapsible } from './collapsible.directive';\nimport { ComCollapsibleContentTpl } from './directives/collapsible-content-tpl.directive';\nimport { ComCollapsibleLazy } from './directives/collapsible-lazy.directive';\nimport { mergeClasses } from './collapsible.utils';\nimport type { ComCollapsibleContentContext } from './collapsible.models';\n\n/**\n * Collapsible content component — animated panel with region role.\n *\n * Uses CSS grid technique for smooth height animation without JS measurement.\n * Supports lazy rendering via `comCollapsibleLazy` directive.\n *\n * @tokens None (structural only — styling is applied via templates or consumer classes)\n *\n * @example Basic usage\n * ```html\n * <com-collapsible-content>\n * <div class=\"p-4\">Content here.</div>\n * </com-collapsible-content>\n * ```\n *\n * @example With custom duration\n * ```html\n * <com-collapsible-content [duration]=\"300\">\n * <div class=\"p-4\">Slower animation.</div>\n * </com-collapsible-content>\n * ```\n *\n * @example With content chrome template\n * ```html\n * <com-collapsible-content>\n * <ng-template comCollapsibleContentTpl let-open=\"open\">\n * <div class=\"border-t border-border p-4\">\n * <!-- Content with custom chrome -->\n * </div>\n * </ng-template>\n * </com-collapsible-content>\n * ```\n *\n * @example Lazy content\n * ```html\n * <com-collapsible-content>\n * <ng-template comCollapsibleLazy>\n * <app-heavy-component />\n * </ng-template>\n * </com-collapsible-content>\n * ```\n */\n@Component({\n selector: 'com-collapsible-content',\n template: `\n @if (contentTpl()) {\n <div class=\"com-collapsible-content-inner\" [class]=\"innerClass()\">\n <ng-container\n [ngTemplateOutlet]=\"contentTpl()!.templateRef\"\n [ngTemplateOutletContext]=\"templateContext()\"\n />\n </div>\n } @else if (lazyTpl()) {\n @if (hasBeenOpened()) {\n <div class=\"com-collapsible-content-inner\" [class]=\"innerClass()\">\n <ng-container [ngTemplateOutlet]=\"lazyTpl()!.templateRef\" />\n </div>\n }\n } @else {\n <div class=\"com-collapsible-content-inner\" [class]=\"innerClass()\">\n <ng-content />\n </div>\n }\n `,\n styles: `\n :host {\n display: grid;\n grid-template-rows: 0fr;\n transition: grid-template-rows var(--duration, 200ms) ease;\n }\n :host([data-state='open']) {\n grid-template-rows: 1fr;\n }\n .com-collapsible-content-inner {\n overflow: hidden;\n }\n `,\n imports: [NgTemplateOutlet],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'com-collapsible-content',\n '[style.--duration.ms]': 'duration()',\n '[attr.id]': 'collapsible.contentId',\n '[attr.role]': '\"region\"',\n '[attr.aria-labelledby]': 'collapsible.triggerId',\n '[attr.data-state]': 'collapsible.isOpen() ? \"open\" : \"closed\"',\n '[attr.inert]': '!collapsible.isOpen() || null',\n },\n})\nexport class ComCollapsibleContent {\n /** Parent collapsible directive (provides state). */\n protected readonly collapsible: ComCollapsible = inject(ComCollapsible);\n\n /** Custom content chrome template. */\n protected readonly contentTpl: Signal<ComCollapsibleContentTpl | undefined> =\n contentChild(ComCollapsibleContentTpl);\n\n /** Lazy content template. */\n protected readonly lazyTpl: Signal<ComCollapsibleLazy | undefined> =\n contentChild(ComCollapsibleLazy);\n\n /** Track if collapsible has ever been opened (for lazy rendering). */\n protected readonly hasBeenOpened: WritableSignal<boolean> = signal(false);\n\n // ============ INPUTS ============\n\n /** Transition duration in milliseconds. */\n readonly duration: InputSignal<number> = input<number>(200);\n\n /** Consumer CSS classes for the inner wrapper. */\n readonly userClass: InputSignal<string> = input<string>('', { alias: 'class' });\n\n // ============ COMPUTED STATE ============\n\n /** @internal Computed inner wrapper class. */\n protected readonly innerClass: Signal<string> = computed(() =>\n mergeClasses('com-collapsible-content-inner', this.userClass())\n );\n\n /** Context for content template. */\n readonly templateContext: Signal<ComCollapsibleContentContext> = computed(() => ({\n $implicit: this.collapsible.isOpen(),\n open: this.collapsible.isOpen(),\n }));\n\n constructor() {\n // Track first open for lazy rendering\n effect(() => {\n if (this.collapsible.isOpen() && !this.hasBeenOpened()) {\n this.hasBeenOpened.set(true);\n }\n });\n }\n}\n","// Public API for the collapsible component\n\n// Types\nexport type {\n ComCollapsibleTriggerContext,\n ComCollapsibleContentContext,\n ComCollapsibleIconContext,\n} from './collapsible.models';\n\n// Variants\nexport { collapsibleVariants } from './collapsible.variants';\nexport type { CollapsibleVariant, CollapsibleVariants } from './collapsible.variants';\n\nexport { collapsibleTriggerVariants } from './collapsible-trigger.variants';\nexport type {\n CollapsibleTriggerVariant,\n CollapsibleTriggerSize,\n CollapsibleTriggerVariants,\n} from './collapsible-trigger.variants';\n\n// Template directives\nexport { ComCollapsibleTriggerTpl } from './directives/collapsible-trigger-tpl.directive';\nexport { ComCollapsibleContentTpl } from './directives/collapsible-content-tpl.directive';\nexport { ComCollapsibleIconTpl } from './directives/collapsible-icon-tpl.directive';\nexport { ComCollapsibleLazy } from './directives/collapsible-lazy.directive';\n\n// Main components\nexport { ComCollapsible } from './collapsible.directive';\nexport { ComCollapsibleTrigger } from './collapsible-trigger.component';\nexport { ComCollapsibleContent } from './collapsible-content.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,255 @@
1
+ import { ComponentHarness, HarnessPredicate, TestKey, parallel } from '@angular/cdk/testing';
2
+
3
+ /**
4
+ * Harness for interacting with a dropdown option in tests.
5
+ */
6
+ class ComDropdownOptionHarness extends ComponentHarness {
7
+ static hostSelector = 'com-dropdown-option';
8
+ optionElement = this.locatorFor('[role="option"]');
9
+ /**
10
+ * Gets a HarnessPredicate for matching dropdown options.
11
+ * @param options Filter options.
12
+ */
13
+ static with(options = {}) {
14
+ return new HarnessPredicate(ComDropdownOptionHarness, options)
15
+ .addOption('text', options.text, async (harness, text) => {
16
+ const optionText = await harness.getText();
17
+ return HarnessPredicate.stringMatches(optionText, text);
18
+ })
19
+ .addOption('selected', options.selected, async (harness, selected) => {
20
+ return (await harness.isSelected()) === selected;
21
+ })
22
+ .addOption('disabled', options.disabled, async (harness, disabled) => {
23
+ return (await harness.isDisabled()) === disabled;
24
+ });
25
+ }
26
+ /** Gets the option's text content. */
27
+ async getText() {
28
+ const el = await this.optionElement();
29
+ return el.text();
30
+ }
31
+ /** Whether the option is currently selected. */
32
+ async isSelected() {
33
+ const el = await this.optionElement();
34
+ return (await el.getAttribute('aria-selected')) === 'true';
35
+ }
36
+ /** Whether the option is disabled. */
37
+ async isDisabled() {
38
+ const el = await this.optionElement();
39
+ return (await el.getAttribute('aria-disabled')) === 'true';
40
+ }
41
+ /** Whether the option is active (keyboard focused). */
42
+ async isActive() {
43
+ const el = await this.optionElement();
44
+ return (await el.getAttribute('data-active')) === 'true';
45
+ }
46
+ /** Clicks the option to select it. */
47
+ async click() {
48
+ const el = await this.optionElement();
49
+ return el.click();
50
+ }
51
+ /** Hovers over the option. */
52
+ async hover() {
53
+ const el = await this.optionElement();
54
+ return el.hover();
55
+ }
56
+ }
57
+ /**
58
+ * Harness for interacting with a ComDropdown in tests.
59
+ */
60
+ class ComDropdownHarness extends ComponentHarness {
61
+ static hostSelector = 'com-dropdown';
62
+ trigger = this.locatorFor('button[role="combobox"]');
63
+ panel = this.locatorForOptional('[role="listbox"]');
64
+ searchInput = this.locatorForOptional('com-dropdown-search input');
65
+ clearButton = this.locatorForOptional('button[aria-label="Clear selection"]');
66
+ /**
67
+ * Gets a HarnessPredicate for matching dropdowns.
68
+ * @param options Filter options.
69
+ */
70
+ static with(options = {}) {
71
+ return new HarnessPredicate(ComDropdownHarness, options)
72
+ .addOption('placeholder', options.placeholder, async (harness, placeholder) => {
73
+ const text = await harness.getTriggerText();
74
+ return HarnessPredicate.stringMatches(text, placeholder);
75
+ })
76
+ .addOption('disabled', options.disabled, async (harness, disabled) => {
77
+ return (await harness.isDisabled()) === disabled;
78
+ })
79
+ .addOption('open', options.open, async (harness, open) => {
80
+ return (await harness.isOpen()) === open;
81
+ });
82
+ }
83
+ /** Gets the dropdown's trigger button text. */
84
+ async getTriggerText() {
85
+ const triggerEl = await this.trigger();
86
+ return triggerEl.text();
87
+ }
88
+ /** Whether the dropdown is currently open. */
89
+ async isOpen() {
90
+ const triggerEl = await this.trigger();
91
+ return (await triggerEl.getAttribute('aria-expanded')) === 'true';
92
+ }
93
+ /** Whether the dropdown is disabled. */
94
+ async isDisabled() {
95
+ const triggerEl = await this.trigger();
96
+ const disabled = await triggerEl.getAttribute('disabled');
97
+ return disabled !== null;
98
+ }
99
+ /** Whether the dropdown has a value selected. */
100
+ async hasValue() {
101
+ const clearBtn = await this.clearButton();
102
+ return clearBtn !== null;
103
+ }
104
+ /** Opens the dropdown if it's closed. */
105
+ async open() {
106
+ if (!(await this.isOpen())) {
107
+ await this.click();
108
+ }
109
+ }
110
+ /** Closes the dropdown if it's open. */
111
+ async close() {
112
+ if (await this.isOpen()) {
113
+ await this.sendKeys(TestKey.ESCAPE);
114
+ }
115
+ }
116
+ /** Clicks the dropdown trigger. */
117
+ async click() {
118
+ const triggerEl = await this.trigger();
119
+ return triggerEl.click();
120
+ }
121
+ /** Clears the current selection. */
122
+ async clear() {
123
+ const clearBtn = await this.clearButton();
124
+ if (clearBtn) {
125
+ return clearBtn.click();
126
+ }
127
+ throw new Error('Dropdown does not have a clearable selection');
128
+ }
129
+ /** Sends keyboard input to the dropdown. */
130
+ async sendKeys(...keys) {
131
+ const triggerEl = await this.trigger();
132
+ return triggerEl.sendKeys(...keys);
133
+ }
134
+ /** Gets all options in the dropdown. */
135
+ async getOptions(filters = {}) {
136
+ await this.open();
137
+ return this.locatorForAll(ComDropdownOptionHarness.with(filters))();
138
+ }
139
+ /** Gets an option by its text. */
140
+ async getOption(text) {
141
+ await this.open();
142
+ const options = await this.getOptions({ text });
143
+ return options[0] ?? null;
144
+ }
145
+ /** Selects an option by its text. */
146
+ async selectOption(text) {
147
+ const option = await this.getOption(text);
148
+ if (!option) {
149
+ throw new Error(`Could not find option with text: ${text}`);
150
+ }
151
+ return option.click();
152
+ }
153
+ /** Gets the currently selected option(s). */
154
+ async getSelectedOptions() {
155
+ await this.open();
156
+ return this.getOptions({ selected: true });
157
+ }
158
+ /** Whether the dropdown has a search input. */
159
+ async isSearchable() {
160
+ await this.open();
161
+ const input = await this.searchInput();
162
+ return input !== null;
163
+ }
164
+ /** Gets the current search query. */
165
+ async getSearchQuery() {
166
+ await this.open();
167
+ const input = await this.searchInput();
168
+ if (!input) {
169
+ throw new Error('Dropdown is not searchable');
170
+ }
171
+ return input.getProperty('value');
172
+ }
173
+ /** Types in the search input. */
174
+ async search(query) {
175
+ await this.open();
176
+ const input = await this.searchInput();
177
+ if (!input) {
178
+ throw new Error('Dropdown is not searchable');
179
+ }
180
+ await input.clear();
181
+ return input.sendKeys(query);
182
+ }
183
+ /** Clears the search input. */
184
+ async clearSearch() {
185
+ await this.open();
186
+ const input = await this.searchInput();
187
+ if (!input) {
188
+ throw new Error('Dropdown is not searchable');
189
+ }
190
+ return input.clear();
191
+ }
192
+ /** Gets the number of visible options. */
193
+ async getOptionsCount() {
194
+ const options = await this.getOptions();
195
+ return options.length;
196
+ }
197
+ /** Gets all option texts. */
198
+ async getOptionTexts() {
199
+ const options = await this.getOptions();
200
+ return parallel(() => options.map((opt) => opt.getText()));
201
+ }
202
+ /** Navigates to an option using keyboard. */
203
+ async navigateToOption(direction, times = 1) {
204
+ await this.open();
205
+ const key = direction === 'down' ? TestKey.DOWN_ARROW : TestKey.UP_ARROW;
206
+ for (let i = 0; i < times; i++) {
207
+ await this.sendKeys(key);
208
+ }
209
+ }
210
+ /** Selects the currently active option. */
211
+ async selectActiveOption() {
212
+ await this.sendKeys(TestKey.ENTER);
213
+ }
214
+ /** Gets the ID of the active descendant. */
215
+ async getActiveDescendantId() {
216
+ await this.open();
217
+ const triggerEl = await this.trigger();
218
+ return triggerEl.getAttribute('aria-activedescendant');
219
+ }
220
+ /** Gets the panel ID. */
221
+ async getPanelId() {
222
+ await this.open();
223
+ const panelEl = await this.panel();
224
+ return panelEl ? panelEl.getAttribute('id') : null;
225
+ }
226
+ /** Gets the aria-controls value from the trigger. */
227
+ async getAriaControls() {
228
+ const triggerEl = await this.trigger();
229
+ return triggerEl.getAttribute('aria-controls');
230
+ }
231
+ /** Focuses the dropdown trigger. */
232
+ async focus() {
233
+ const triggerEl = await this.trigger();
234
+ return triggerEl.focus();
235
+ }
236
+ /** Blurs the dropdown trigger. */
237
+ async blur() {
238
+ const triggerEl = await this.trigger();
239
+ return triggerEl.blur();
240
+ }
241
+ /** Whether the dropdown trigger is focused. */
242
+ async isFocused() {
243
+ const triggerEl = await this.trigger();
244
+ return triggerEl.isFocused();
245
+ }
246
+ }
247
+
248
+ // Testing utilities for the dropdown component
249
+
250
+ /**
251
+ * Generated bundle index. Do not edit.
252
+ */
253
+
254
+ export { ComDropdownHarness, ComDropdownOptionHarness };
255
+ //# sourceMappingURL=ngx-com-components-dropdown-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-com-components-dropdown-testing.mjs","sources":["../../../projects/com/components/dropdown/testing/dropdown.harness.ts","../../../projects/com/components/dropdown/testing/index.ts","../../../projects/com/components/dropdown/testing/ngx-com-components-dropdown-testing.ts"],"sourcesContent":["import {\n ComponentHarness,\n HarnessPredicate,\n TestKey,\n parallel,\n} from '@angular/cdk/testing';\nimport type { BaseHarnessFilters } from '@angular/cdk/testing';\n\n/** Harness filters for ComDropdownHarness. */\nexport interface ComDropdownHarnessFilters extends BaseHarnessFilters {\n /** Filter by the dropdown's placeholder text. */\n placeholder?: string | RegExp;\n /** Filter by whether the dropdown is disabled. */\n disabled?: boolean;\n /** Filter by whether the dropdown is open. */\n open?: boolean;\n}\n\n/** Harness filters for ComDropdownOptionHarness. */\nexport interface ComDropdownOptionHarnessFilters extends BaseHarnessFilters {\n /** Filter by the option's text. */\n text?: string | RegExp;\n /** Filter by whether the option is selected. */\n selected?: boolean;\n /** Filter by whether the option is disabled. */\n disabled?: boolean;\n}\n\n/**\n * Harness for interacting with a dropdown option in tests.\n */\nexport class ComDropdownOptionHarness extends ComponentHarness {\n static hostSelector = 'com-dropdown-option';\n\n private readonly optionElement = this.locatorFor('[role=\"option\"]');\n\n /**\n * Gets a HarnessPredicate for matching dropdown options.\n * @param options Filter options.\n */\n static with(options: ComDropdownOptionHarnessFilters = {}): HarnessPredicate<ComDropdownOptionHarness> {\n return new HarnessPredicate(ComDropdownOptionHarness, options)\n .addOption('text', options.text, async (harness, text) => {\n const optionText = await harness.getText();\n return HarnessPredicate.stringMatches(optionText, text);\n })\n .addOption('selected', options.selected, async (harness, selected) => {\n return (await harness.isSelected()) === selected;\n })\n .addOption('disabled', options.disabled, async (harness, disabled) => {\n return (await harness.isDisabled()) === disabled;\n });\n }\n\n /** Gets the option's text content. */\n async getText(): Promise<string> {\n const el = await this.optionElement();\n return el.text();\n }\n\n /** Whether the option is currently selected. */\n async isSelected(): Promise<boolean> {\n const el = await this.optionElement();\n return (await el.getAttribute('aria-selected')) === 'true';\n }\n\n /** Whether the option is disabled. */\n async isDisabled(): Promise<boolean> {\n const el = await this.optionElement();\n return (await el.getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the option is active (keyboard focused). */\n async isActive(): Promise<boolean> {\n const el = await this.optionElement();\n return (await el.getAttribute('data-active')) === 'true';\n }\n\n /** Clicks the option to select it. */\n async click(): Promise<void> {\n const el = await this.optionElement();\n return el.click();\n }\n\n /** Hovers over the option. */\n async hover(): Promise<void> {\n const el = await this.optionElement();\n return el.hover();\n }\n}\n\n/**\n * Harness for interacting with a ComDropdown in tests.\n */\nexport class ComDropdownHarness extends ComponentHarness {\n static hostSelector = 'com-dropdown';\n\n private readonly trigger = this.locatorFor('button[role=\"combobox\"]');\n private readonly panel = this.locatorForOptional('[role=\"listbox\"]');\n private readonly searchInput = this.locatorForOptional('com-dropdown-search input');\n private readonly clearButton = this.locatorForOptional('button[aria-label=\"Clear selection\"]');\n\n /**\n * Gets a HarnessPredicate for matching dropdowns.\n * @param options Filter options.\n */\n static with(options: ComDropdownHarnessFilters = {}): HarnessPredicate<ComDropdownHarness> {\n return new HarnessPredicate(ComDropdownHarness, options)\n .addOption('placeholder', options.placeholder, async (harness, placeholder) => {\n const text = await harness.getTriggerText();\n return HarnessPredicate.stringMatches(text, placeholder);\n })\n .addOption('disabled', options.disabled, async (harness, disabled) => {\n return (await harness.isDisabled()) === disabled;\n })\n .addOption('open', options.open, async (harness, open) => {\n return (await harness.isOpen()) === open;\n });\n }\n\n /** Gets the dropdown's trigger button text. */\n async getTriggerText(): Promise<string> {\n const triggerEl = await this.trigger();\n return triggerEl.text();\n }\n\n /** Whether the dropdown is currently open. */\n async isOpen(): Promise<boolean> {\n const triggerEl = await this.trigger();\n return (await triggerEl.getAttribute('aria-expanded')) === 'true';\n }\n\n /** Whether the dropdown is disabled. */\n async isDisabled(): Promise<boolean> {\n const triggerEl = await this.trigger();\n const disabled = await triggerEl.getAttribute('disabled');\n return disabled !== null;\n }\n\n /** Whether the dropdown has a value selected. */\n async hasValue(): Promise<boolean> {\n const clearBtn = await this.clearButton();\n return clearBtn !== null;\n }\n\n /** Opens the dropdown if it's closed. */\n async open(): Promise<void> {\n if (!(await this.isOpen())) {\n await this.click();\n }\n }\n\n /** Closes the dropdown if it's open. */\n async close(): Promise<void> {\n if (await this.isOpen()) {\n await this.sendKeys(TestKey.ESCAPE);\n }\n }\n\n /** Clicks the dropdown trigger. */\n async click(): Promise<void> {\n const triggerEl = await this.trigger();\n return triggerEl.click();\n }\n\n /** Clears the current selection. */\n async clear(): Promise<void> {\n const clearBtn = await this.clearButton();\n if (clearBtn) {\n return clearBtn.click();\n }\n throw new Error('Dropdown does not have a clearable selection');\n }\n\n /** Sends keyboard input to the dropdown. */\n async sendKeys(...keys: (string | TestKey)[]): Promise<void> {\n const triggerEl = await this.trigger();\n return triggerEl.sendKeys(...keys);\n }\n\n /** Gets all options in the dropdown. */\n async getOptions(filters: ComDropdownOptionHarnessFilters = {}): Promise<ComDropdownOptionHarness[]> {\n await this.open();\n return this.locatorForAll(ComDropdownOptionHarness.with(filters))();\n }\n\n /** Gets an option by its text. */\n async getOption(text: string | RegExp): Promise<ComDropdownOptionHarness | null> {\n await this.open();\n const options = await this.getOptions({ text });\n return options[0] ?? null;\n }\n\n /** Selects an option by its text. */\n async selectOption(text: string | RegExp): Promise<void> {\n const option = await this.getOption(text);\n if (!option) {\n throw new Error(`Could not find option with text: ${text}`);\n }\n return option.click();\n }\n\n /** Gets the currently selected option(s). */\n async getSelectedOptions(): Promise<ComDropdownOptionHarness[]> {\n await this.open();\n return this.getOptions({ selected: true });\n }\n\n /** Whether the dropdown has a search input. */\n async isSearchable(): Promise<boolean> {\n await this.open();\n const input = await this.searchInput();\n return input !== null;\n }\n\n /** Gets the current search query. */\n async getSearchQuery(): Promise<string> {\n await this.open();\n const input = await this.searchInput();\n if (!input) {\n throw new Error('Dropdown is not searchable');\n }\n return input.getProperty<string>('value');\n }\n\n /** Types in the search input. */\n async search(query: string): Promise<void> {\n await this.open();\n const input = await this.searchInput();\n if (!input) {\n throw new Error('Dropdown is not searchable');\n }\n await input.clear();\n return input.sendKeys(query);\n }\n\n /** Clears the search input. */\n async clearSearch(): Promise<void> {\n await this.open();\n const input = await this.searchInput();\n if (!input) {\n throw new Error('Dropdown is not searchable');\n }\n return input.clear();\n }\n\n /** Gets the number of visible options. */\n async getOptionsCount(): Promise<number> {\n const options = await this.getOptions();\n return options.length;\n }\n\n /** Gets all option texts. */\n async getOptionTexts(): Promise<string[]> {\n const options = await this.getOptions();\n return parallel(() => options.map((opt) => opt.getText()));\n }\n\n /** Navigates to an option using keyboard. */\n async navigateToOption(direction: 'up' | 'down', times = 1): Promise<void> {\n await this.open();\n const key = direction === 'down' ? TestKey.DOWN_ARROW : TestKey.UP_ARROW;\n for (let i = 0; i < times; i++) {\n await this.sendKeys(key);\n }\n }\n\n /** Selects the currently active option. */\n async selectActiveOption(): Promise<void> {\n await this.sendKeys(TestKey.ENTER);\n }\n\n /** Gets the ID of the active descendant. */\n async getActiveDescendantId(): Promise<string | null> {\n await this.open();\n const triggerEl = await this.trigger();\n return triggerEl.getAttribute('aria-activedescendant');\n }\n\n /** Gets the panel ID. */\n async getPanelId(): Promise<string | null> {\n await this.open();\n const panelEl = await this.panel();\n return panelEl ? panelEl.getAttribute('id') : null;\n }\n\n /** Gets the aria-controls value from the trigger. */\n async getAriaControls(): Promise<string | null> {\n const triggerEl = await this.trigger();\n return triggerEl.getAttribute('aria-controls');\n }\n\n /** Focuses the dropdown trigger. */\n async focus(): Promise<void> {\n const triggerEl = await this.trigger();\n return triggerEl.focus();\n }\n\n /** Blurs the dropdown trigger. */\n async blur(): Promise<void> {\n const triggerEl = await this.trigger();\n return triggerEl.blur();\n }\n\n /** Whether the dropdown trigger is focused. */\n async isFocused(): Promise<boolean> {\n const triggerEl = await this.trigger();\n return triggerEl.isFocused();\n }\n}\n","// Testing utilities for the dropdown component\n\nexport {\n ComDropdownHarness,\n ComDropdownOptionHarness,\n} from './dropdown.harness';\n\nexport type {\n ComDropdownHarnessFilters,\n ComDropdownOptionHarnessFilters,\n} from './dropdown.harness';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}