ng-blatui 1.19.0 → 1.21.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.
@@ -77,7 +77,7 @@ const SIZES$3 = {
77
77
  default: 'px-2 py-0.5 text-xs',
78
78
  lg: 'px-3 py-1 text-sm [&>svg]:size-3.5',
79
79
  };
80
- const VARIANTS = {
80
+ const VARIANTS$1 = {
81
81
  default: 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
82
82
  secondary: 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
83
83
  destructive: 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
@@ -113,16 +113,16 @@ const TONES$2 = {
113
113
  function brandClass(variant) {
114
114
  switch (variant) {
115
115
  case 'secondary': {
116
- return VARIANTS.secondary;
116
+ return VARIANTS$1.secondary;
117
117
  }
118
118
  case 'destructive': {
119
- return VARIANTS.destructive;
119
+ return VARIANTS$1.destructive;
120
120
  }
121
121
  case 'outline': {
122
- return VARIANTS.outline;
122
+ return VARIANTS$1.outline;
123
123
  }
124
124
  default: {
125
- return VARIANTS.default;
125
+ return VARIANTS$1.default;
126
126
  }
127
127
  }
128
128
  }
@@ -5425,6 +5425,530 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
5425
5425
  }]
5426
5426
  }], propDecorators: { max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], scaleTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "scaleTo", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
5427
5427
 
5428
+ /**
5429
+ * An accessible select (combobox + listbox) using the `aria-activedescendant` pattern:
5430
+ * focus stays on the trigger while arrows move the active option. Full keyboard support
5431
+ * (arrows, Home/End, Enter, Escape) and outside-click close. SSR-safe.
5432
+ */
5433
+ class BuiSelect {
5434
+ value = model('', /* @ts-ignore */
5435
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
5436
+ options = input([], /* @ts-ignore */
5437
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
5438
+ placeholder = input('Select…', /* @ts-ignore */
5439
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
5440
+ disabled = input(false, /* @ts-ignore */
5441
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
5442
+ userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
5443
+ listId = inject(_IdGenerator).getId('bui-select-');
5444
+ host = inject(ElementRef);
5445
+ open = signal(false, /* @ts-ignore */
5446
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
5447
+ active = signal(0, /* @ts-ignore */
5448
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
5449
+ selectedLabel = computed(() => this.options().find((option) => option.value === this.value())?.label ?? '', /* @ts-ignore */
5450
+ ...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
5451
+ computedClass = computed(() => cn('relative block', this.userClass()), /* @ts-ignore */
5452
+ ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
5453
+ toggle() {
5454
+ if (this.open()) {
5455
+ this.close();
5456
+ }
5457
+ else {
5458
+ this.openList();
5459
+ }
5460
+ }
5461
+ select(option) {
5462
+ if (option.disabled) {
5463
+ return;
5464
+ }
5465
+ this.value.set(option.value);
5466
+ this.close();
5467
+ }
5468
+ onKeydown(event) {
5469
+ if (this.disabled()) {
5470
+ return;
5471
+ }
5472
+ if (!this.open()) {
5473
+ if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(event.key)) {
5474
+ event.preventDefault();
5475
+ this.openList();
5476
+ }
5477
+ return;
5478
+ }
5479
+ const options = this.options();
5480
+ switch (event.key) {
5481
+ case 'ArrowDown': {
5482
+ event.preventDefault();
5483
+ this.active.set(Math.min(options.length - 1, this.active() + 1));
5484
+ break;
5485
+ }
5486
+ case 'ArrowUp': {
5487
+ event.preventDefault();
5488
+ this.active.set(Math.max(0, this.active() - 1));
5489
+ break;
5490
+ }
5491
+ case 'Home': {
5492
+ event.preventDefault();
5493
+ this.active.set(0);
5494
+ break;
5495
+ }
5496
+ case 'End': {
5497
+ event.preventDefault();
5498
+ this.active.set(options.length - 1);
5499
+ break;
5500
+ }
5501
+ case 'Enter':
5502
+ case ' ': {
5503
+ event.preventDefault();
5504
+ if (options.length > 0) {
5505
+ this.select(options[this.active()]);
5506
+ }
5507
+ break;
5508
+ }
5509
+ case 'Escape': {
5510
+ event.preventDefault();
5511
+ this.close();
5512
+ break;
5513
+ }
5514
+ default: {
5515
+ break;
5516
+ }
5517
+ }
5518
+ }
5519
+ onDocumentClick(event) {
5520
+ if (this.open() && !this.host.nativeElement.contains(event.target)) {
5521
+ this.close();
5522
+ }
5523
+ }
5524
+ openList() {
5525
+ const current = this.options().findIndex((option) => option.value === this.value());
5526
+ this.active.set(current === -1 ? 0 : current);
5527
+ this.open.set(true);
5528
+ }
5529
+ close() {
5530
+ this.open.set(false);
5531
+ }
5532
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
5533
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BuiSelect, isStandalone: true, selector: "bui-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { attributes: { "data-slot": "select" }, listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class": "computedClass()" } }, ngImport: i0, template: `
5534
+ <button
5535
+ type="button"
5536
+ role="combobox"
5537
+ [attr.aria-expanded]="open()"
5538
+ aria-haspopup="listbox"
5539
+ [attr.aria-controls]="listId"
5540
+ [attr.aria-activedescendant]="open() ? listId + '-' + active() : null"
5541
+ [attr.data-placeholder]="selectedLabel() ? null : ''"
5542
+ [disabled]="disabled()"
5543
+ class="flex h-9 w-full items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground"
5544
+ (click)="toggle()"
5545
+ (keydown)="onKeydown($event)"
5546
+ >
5547
+ <span class="truncate">{{ selectedLabel() || placeholder() }}</span>
5548
+ <svg
5549
+ viewBox="0 0 24 24"
5550
+ fill="none"
5551
+ stroke="currentColor"
5552
+ stroke-width="2"
5553
+ stroke-linecap="round"
5554
+ stroke-linejoin="round"
5555
+ aria-hidden="true"
5556
+ class="size-4 opacity-50"
5557
+ >
5558
+ <path d="m6 9 6 6 6-6" />
5559
+ </svg>
5560
+ </button>
5561
+ @if (open()) {
5562
+ <ul
5563
+ [id]="listId"
5564
+ role="listbox"
5565
+ class="absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
5566
+ >
5567
+ @for (option of options(); track option.value; let i = $index) {
5568
+ <li
5569
+ [id]="listId + '-' + i"
5570
+ role="option"
5571
+ [attr.aria-selected]="option.value === value()"
5572
+ [attr.aria-disabled]="option.disabled ? true : null"
5573
+ class="relative flex cursor-default items-center justify-between gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none"
5574
+ [class]="i === active() ? 'bg-accent text-accent-foreground' : ''"
5575
+ (click)="select(option)"
5576
+ (mouseenter)="active.set(i)"
5577
+ >
5578
+ <span class="truncate">{{ option.label }}</span>
5579
+ @if (option.value === value()) {
5580
+ <svg
5581
+ viewBox="0 0 24 24"
5582
+ fill="none"
5583
+ stroke="currentColor"
5584
+ stroke-width="2"
5585
+ stroke-linecap="round"
5586
+ stroke-linejoin="round"
5587
+ aria-hidden="true"
5588
+ class="size-4"
5589
+ >
5590
+ <path d="M20 6 9 17l-5-5" />
5591
+ </svg>
5592
+ }
5593
+ </li>
5594
+ }
5595
+ </ul>
5596
+ }
5597
+ `, isInline: true });
5598
+ }
5599
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiSelect, decorators: [{
5600
+ type: Component,
5601
+ args: [{
5602
+ selector: 'bui-select',
5603
+ host: {
5604
+ 'data-slot': 'select',
5605
+ '[class]': 'computedClass()',
5606
+ '(document:click)': 'onDocumentClick($event)',
5607
+ },
5608
+ template: `
5609
+ <button
5610
+ type="button"
5611
+ role="combobox"
5612
+ [attr.aria-expanded]="open()"
5613
+ aria-haspopup="listbox"
5614
+ [attr.aria-controls]="listId"
5615
+ [attr.aria-activedescendant]="open() ? listId + '-' + active() : null"
5616
+ [attr.data-placeholder]="selectedLabel() ? null : ''"
5617
+ [disabled]="disabled()"
5618
+ class="flex h-9 w-full items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground"
5619
+ (click)="toggle()"
5620
+ (keydown)="onKeydown($event)"
5621
+ >
5622
+ <span class="truncate">{{ selectedLabel() || placeholder() }}</span>
5623
+ <svg
5624
+ viewBox="0 0 24 24"
5625
+ fill="none"
5626
+ stroke="currentColor"
5627
+ stroke-width="2"
5628
+ stroke-linecap="round"
5629
+ stroke-linejoin="round"
5630
+ aria-hidden="true"
5631
+ class="size-4 opacity-50"
5632
+ >
5633
+ <path d="m6 9 6 6 6-6" />
5634
+ </svg>
5635
+ </button>
5636
+ @if (open()) {
5637
+ <ul
5638
+ [id]="listId"
5639
+ role="listbox"
5640
+ class="absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
5641
+ >
5642
+ @for (option of options(); track option.value; let i = $index) {
5643
+ <li
5644
+ [id]="listId + '-' + i"
5645
+ role="option"
5646
+ [attr.aria-selected]="option.value === value()"
5647
+ [attr.aria-disabled]="option.disabled ? true : null"
5648
+ class="relative flex cursor-default items-center justify-between gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none"
5649
+ [class]="i === active() ? 'bg-accent text-accent-foreground' : ''"
5650
+ (click)="select(option)"
5651
+ (mouseenter)="active.set(i)"
5652
+ >
5653
+ <span class="truncate">{{ option.label }}</span>
5654
+ @if (option.value === value()) {
5655
+ <svg
5656
+ viewBox="0 0 24 24"
5657
+ fill="none"
5658
+ stroke="currentColor"
5659
+ stroke-width="2"
5660
+ stroke-linecap="round"
5661
+ stroke-linejoin="round"
5662
+ aria-hidden="true"
5663
+ class="size-4"
5664
+ >
5665
+ <path d="M20 6 9 17l-5-5" />
5666
+ </svg>
5667
+ }
5668
+ </li>
5669
+ }
5670
+ </ul>
5671
+ }
5672
+ `,
5673
+ }]
5674
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
5675
+
5676
+ const VARIANTS = {
5677
+ primary: 'bg-primary text-primary-foreground hover:bg-primary/90',
5678
+ subtle: 'bg-card text-foreground hover:bg-accent hover:text-accent-foreground border',
5679
+ };
5680
+ /**
5681
+ * A floating "scroll to top" button that reveals itself once the page scrolls past
5682
+ * `threshold` px. SSR-safe — the scroll position is only read in the browser.
5683
+ */
5684
+ class BuiBackToTop {
5685
+ threshold = input(300, /* @ts-ignore */
5686
+ ...(ngDevMode ? [{ debugName: "threshold" }] : /* istanbul ignore next */ []));
5687
+ variant = input('primary', /* @ts-ignore */
5688
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
5689
+ userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
5690
+ shown = signal(false, /* @ts-ignore */
5691
+ ...(ngDevMode ? [{ debugName: "shown" }] : /* istanbul ignore next */ []));
5692
+ variantClass = computed(() => VARIANTS[this.variant()], /* @ts-ignore */
5693
+ ...(ngDevMode ? [{ debugName: "variantClass" }] : /* istanbul ignore next */ []));
5694
+ computedClass = computed(() => cn('fixed end-6 bottom-6 z-40 block', this.userClass()), /* @ts-ignore */
5695
+ ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
5696
+ constructor() {
5697
+ afterNextRender(() => {
5698
+ this.onScroll();
5699
+ });
5700
+ }
5701
+ onScroll() {
5702
+ this.shown.set(globalThis.scrollY > this.threshold());
5703
+ }
5704
+ toTop() {
5705
+ globalThis.scrollTo({ top: 0, behavior: 'smooth' });
5706
+ }
5707
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiBackToTop, deps: [], target: i0.ɵɵFactoryTarget.Component });
5708
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.2", type: BuiBackToTop, isStandalone: true, selector: "bui-back-to-top", inputs: { threshold: { classPropertyName: "threshold", publicName: "threshold", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "back-to-top" }, listeners: { "window:scroll": "onScroll()" }, properties: { "hidden": "!shown()", "class": "computedClass()" } }, ngImport: i0, template: `
5709
+ <button
5710
+ type="button"
5711
+ aria-label="Back to top"
5712
+ class="inline-flex size-10 items-center justify-center rounded-full shadow-md transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50"
5713
+ [class]="variantClass()"
5714
+ (click)="toTop()"
5715
+ >
5716
+ <svg
5717
+ viewBox="0 0 24 24"
5718
+ fill="none"
5719
+ stroke="currentColor"
5720
+ stroke-width="2"
5721
+ stroke-linecap="round"
5722
+ stroke-linejoin="round"
5723
+ aria-hidden="true"
5724
+ class="size-5"
5725
+ >
5726
+ <path d="m5 12 7-7 7 7" />
5727
+ <path d="M12 19V5" />
5728
+ </svg>
5729
+ </button>
5730
+ `, isInline: true });
5731
+ }
5732
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiBackToTop, decorators: [{
5733
+ type: Component,
5734
+ args: [{
5735
+ selector: 'bui-back-to-top',
5736
+ host: {
5737
+ 'data-slot': 'back-to-top',
5738
+ '[hidden]': '!shown()',
5739
+ '[class]': 'computedClass()',
5740
+ '(window:scroll)': 'onScroll()',
5741
+ },
5742
+ template: `
5743
+ <button
5744
+ type="button"
5745
+ aria-label="Back to top"
5746
+ class="inline-flex size-10 items-center justify-center rounded-full shadow-md transition-colors outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50"
5747
+ [class]="variantClass()"
5748
+ (click)="toTop()"
5749
+ >
5750
+ <svg
5751
+ viewBox="0 0 24 24"
5752
+ fill="none"
5753
+ stroke="currentColor"
5754
+ stroke-width="2"
5755
+ stroke-linecap="round"
5756
+ stroke-linejoin="round"
5757
+ aria-hidden="true"
5758
+ class="size-5"
5759
+ >
5760
+ <path d="m5 12 7-7 7 7" />
5761
+ <path d="M12 19V5" />
5762
+ </svg>
5763
+ </button>
5764
+ `,
5765
+ }]
5766
+ }], ctorParameters: () => [], propDecorators: { threshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "threshold", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
5767
+
5768
+ /**
5769
+ * A filterable combobox: a text input (`role="combobox"`, `aria-autocomplete="list"`) over a
5770
+ * filtered listbox, using the `aria-activedescendant` pattern. Full keyboard + outside-click.
5771
+ */
5772
+ class BuiCombobox {
5773
+ value = model('', /* @ts-ignore */
5774
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
5775
+ options = input([], /* @ts-ignore */
5776
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
5777
+ placeholder = input('Search…', /* @ts-ignore */
5778
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
5779
+ disabled = input(false, /* @ts-ignore */
5780
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
5781
+ userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
5782
+ listId = inject(_IdGenerator).getId('bui-combobox-');
5783
+ host = inject(ElementRef);
5784
+ open = signal(false, /* @ts-ignore */
5785
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
5786
+ active = signal(0, /* @ts-ignore */
5787
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
5788
+ query = signal('', /* @ts-ignore */
5789
+ ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
5790
+ selectedLabel = computed(() => this.options().find((option) => option.value === this.value())?.label ?? '', /* @ts-ignore */
5791
+ ...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
5792
+ display = computed(() => (this.open() ? this.query() : this.selectedLabel()), /* @ts-ignore */
5793
+ ...(ngDevMode ? [{ debugName: "display" }] : /* istanbul ignore next */ []));
5794
+ filtered = computed(() => {
5795
+ const query = this.query().trim().toLowerCase();
5796
+ return query === ''
5797
+ ? this.options()
5798
+ : this.options().filter((option) => option.label.toLowerCase().includes(query));
5799
+ }, /* @ts-ignore */
5800
+ ...(ngDevMode ? [{ debugName: "filtered" }] : /* istanbul ignore next */ []));
5801
+ computedClass = computed(() => cn('relative block', this.userClass()), /* @ts-ignore */
5802
+ ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
5803
+ onInput(event) {
5804
+ this.query.set(event.target.value);
5805
+ this.active.set(0);
5806
+ this.open.set(true);
5807
+ }
5808
+ openList() {
5809
+ this.query.set('');
5810
+ this.active.set(0);
5811
+ this.open.set(true);
5812
+ }
5813
+ select(option) {
5814
+ this.value.set(option.value);
5815
+ this.query.set('');
5816
+ this.open.set(false);
5817
+ }
5818
+ onKeydown(event) {
5819
+ if (this.disabled()) {
5820
+ return;
5821
+ }
5822
+ if (event.key === 'Escape') {
5823
+ this.open.set(false);
5824
+ return;
5825
+ }
5826
+ if (!this.open() && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
5827
+ event.preventDefault();
5828
+ this.openList();
5829
+ return;
5830
+ }
5831
+ const items = this.filtered();
5832
+ switch (event.key) {
5833
+ case 'ArrowDown': {
5834
+ event.preventDefault();
5835
+ this.active.set(Math.min(items.length - 1, this.active() + 1));
5836
+ break;
5837
+ }
5838
+ case 'ArrowUp': {
5839
+ event.preventDefault();
5840
+ this.active.set(Math.max(0, this.active() - 1));
5841
+ break;
5842
+ }
5843
+ case 'Enter': {
5844
+ if (this.open() && items.length > 0) {
5845
+ event.preventDefault();
5846
+ this.select(items[this.active()]);
5847
+ }
5848
+ break;
5849
+ }
5850
+ default: {
5851
+ break;
5852
+ }
5853
+ }
5854
+ }
5855
+ onDocumentClick(event) {
5856
+ if (!(this.open() && !this.host.nativeElement.contains(event.target))) {
5857
+ return;
5858
+ }
5859
+ this.open.set(false);
5860
+ this.query.set('');
5861
+ }
5862
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiCombobox, deps: [], target: i0.ɵɵFactoryTarget.Component });
5863
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BuiCombobox, isStandalone: true, selector: "bui-combobox", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { attributes: { "data-slot": "combobox" }, listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class": "computedClass()" } }, ngImport: i0, template: `
5864
+ <input
5865
+ type="text"
5866
+ role="combobox"
5867
+ aria-autocomplete="list"
5868
+ [attr.aria-expanded]="open()"
5869
+ [attr.aria-controls]="listId"
5870
+ [attr.aria-activedescendant]="open() ? listId + '-' + active() : null"
5871
+ [value]="display()"
5872
+ [placeholder]="placeholder()"
5873
+ [disabled]="disabled()"
5874
+ class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50"
5875
+ (input)="onInput($event)"
5876
+ (focus)="openList()"
5877
+ (keydown)="onKeydown($event)"
5878
+ />
5879
+ @if (open() && filtered().length > 0) {
5880
+ <ul
5881
+ [id]="listId"
5882
+ role="listbox"
5883
+ class="absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
5884
+ >
5885
+ @for (option of filtered(); track option.value; let i = $index) {
5886
+ <li
5887
+ [id]="listId + '-' + i"
5888
+ role="option"
5889
+ [attr.aria-selected]="option.value === value()"
5890
+ class="relative flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none"
5891
+ [class]="i === active() ? 'bg-accent text-accent-foreground' : ''"
5892
+ (click)="select(option)"
5893
+ (mouseenter)="active.set(i)"
5894
+ >
5895
+ {{ option.label }}
5896
+ </li>
5897
+ }
5898
+ </ul>
5899
+ }
5900
+ `, isInline: true });
5901
+ }
5902
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiCombobox, decorators: [{
5903
+ type: Component,
5904
+ args: [{
5905
+ selector: 'bui-combobox',
5906
+ host: {
5907
+ 'data-slot': 'combobox',
5908
+ '[class]': 'computedClass()',
5909
+ '(document:click)': 'onDocumentClick($event)',
5910
+ },
5911
+ template: `
5912
+ <input
5913
+ type="text"
5914
+ role="combobox"
5915
+ aria-autocomplete="list"
5916
+ [attr.aria-expanded]="open()"
5917
+ [attr.aria-controls]="listId"
5918
+ [attr.aria-activedescendant]="open() ? listId + '-' + active() : null"
5919
+ [value]="display()"
5920
+ [placeholder]="placeholder()"
5921
+ [disabled]="disabled()"
5922
+ class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50"
5923
+ (input)="onInput($event)"
5924
+ (focus)="openList()"
5925
+ (keydown)="onKeydown($event)"
5926
+ />
5927
+ @if (open() && filtered().length > 0) {
5928
+ <ul
5929
+ [id]="listId"
5930
+ role="listbox"
5931
+ class="absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md"
5932
+ >
5933
+ @for (option of filtered(); track option.value; let i = $index) {
5934
+ <li
5935
+ [id]="listId + '-' + i"
5936
+ role="option"
5937
+ [attr.aria-selected]="option.value === value()"
5938
+ class="relative flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none"
5939
+ [class]="i === active() ? 'bg-accent text-accent-foreground' : ''"
5940
+ (click)="select(option)"
5941
+ (mouseenter)="active.set(i)"
5942
+ >
5943
+ {{ option.label }}
5944
+ </li>
5945
+ }
5946
+ </ul>
5947
+ }
5948
+ `,
5949
+ }]
5950
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
5951
+
5428
5952
  /*
5429
5953
  * Public API Surface of ng-blatui
5430
5954
  */
@@ -5433,5 +5957,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
5433
5957
  * Generated bundle index. Do not edit.
5434
5958
  */
5435
5959
 
5436
- export { BuiAccordion, BuiAccordionContent, BuiAccordionItem, BuiAccordionTrigger, BuiAlert, BuiAlertDescription, BuiAlertDialogAction, BuiAlertDialogCancel, BuiAlertDialogContent, BuiAlertDialogDescription, BuiAlertDialogFooter, BuiAlertDialogHeader, BuiAlertDialogTitle, BuiAlertTitle, BuiAspectRatio, BuiAutosizeTextarea, BuiAvatar, BuiAvatarGroup, BuiBadge, BuiBanner, BuiBreadcrumb, BuiBreadcrumbEllipsis, BuiBreadcrumbItem, BuiBreadcrumbLink, BuiBreadcrumbList, BuiBreadcrumbPage, BuiBreadcrumbSeparator, BuiButton, BuiButtonGroup, BuiButtonGroupText, BuiCard, BuiCardAction, BuiCardContent, BuiCardDescription, BuiCardFooter, BuiCardHeader, BuiCardTitle, BuiCheckbox, BuiCodeBlock, BuiCollapsible, BuiCollapsibleContent, BuiCollapsibleTrigger, BuiComparisonTable, BuiContainer, BuiCopyButton, BuiDialogContent, BuiDialogDescription, BuiDialogFooter, BuiDialogHeader, BuiDialogTitle, BuiDotPattern, BuiDropdownMenu, BuiDropdownMenuItem, BuiDropdownMenuLabel, BuiDropdownMenuSeparator, BuiEmpty, BuiEmptyContent, BuiEmptyDescription, BuiEmptyHeader, BuiEmptyMedia, BuiEmptyTitle, BuiField, BuiFieldContent, BuiFieldDescription, BuiFieldError, BuiFieldGroup, BuiFieldLabel, BuiFieldLegend, BuiFieldSeparator, BuiFieldSet, BuiFieldTitle, BuiFlipCard, BuiGridPattern, BuiHoverCard, BuiHoverCardContent, BuiInput, BuiInputGroup, BuiInputGroupAddon, BuiInputGroupButton, BuiInputGroupInput, BuiInputGroupText, BuiItem, BuiItemActions, BuiItemContent, BuiItemDescription, BuiItemGroup, BuiItemMedia, BuiItemTitle, BuiKbd, BuiLabel, BuiMenubar, BuiMenubarTrigger, BuiMeter, BuiPagination, BuiPaginationContent, BuiPaginationEllipsis, BuiPaginationItem, BuiPaginationLink, BuiPopover, BuiPopoverContent, BuiProgress, BuiQuantitySelector, BuiRadioGroup, BuiRadioGroupItem, BuiRating, BuiScrollArea, BuiSegmentedControl, BuiSeparator, BuiSkeleton, BuiSlider, BuiSpinner, BuiSpotlightCard, BuiStat, BuiSwitch, BuiTabList, BuiTabPanel, BuiTabTrigger, BuiTable, BuiTableBody, BuiTableCaption, BuiTableCell, BuiTableContainer, BuiTableFooter, BuiTableHead, BuiTableHeader, BuiTableRow, BuiTabs, BuiTerminal, BuiTextarea, BuiThemeCustomizer, BuiTiltCard, BuiToggle, BuiTooltip, BuiTooltipContent, BuiTypography, BuiVisuallyHidden, THEME_TOKENS, ThemeStore, buttonVariants, cn, toggleVariants };
5960
+ export { BuiAccordion, BuiAccordionContent, BuiAccordionItem, BuiAccordionTrigger, BuiAlert, BuiAlertDescription, BuiAlertDialogAction, BuiAlertDialogCancel, BuiAlertDialogContent, BuiAlertDialogDescription, BuiAlertDialogFooter, BuiAlertDialogHeader, BuiAlertDialogTitle, BuiAlertTitle, BuiAspectRatio, BuiAutosizeTextarea, BuiAvatar, BuiAvatarGroup, BuiBackToTop, BuiBadge, BuiBanner, BuiBreadcrumb, BuiBreadcrumbEllipsis, BuiBreadcrumbItem, BuiBreadcrumbLink, BuiBreadcrumbList, BuiBreadcrumbPage, BuiBreadcrumbSeparator, BuiButton, BuiButtonGroup, BuiButtonGroupText, BuiCard, BuiCardAction, BuiCardContent, BuiCardDescription, BuiCardFooter, BuiCardHeader, BuiCardTitle, BuiCheckbox, BuiCodeBlock, BuiCollapsible, BuiCollapsibleContent, BuiCollapsibleTrigger, BuiCombobox, BuiComparisonTable, BuiContainer, BuiCopyButton, BuiDialogContent, BuiDialogDescription, BuiDialogFooter, BuiDialogHeader, BuiDialogTitle, BuiDotPattern, BuiDropdownMenu, BuiDropdownMenuItem, BuiDropdownMenuLabel, BuiDropdownMenuSeparator, BuiEmpty, BuiEmptyContent, BuiEmptyDescription, BuiEmptyHeader, BuiEmptyMedia, BuiEmptyTitle, BuiField, BuiFieldContent, BuiFieldDescription, BuiFieldError, BuiFieldGroup, BuiFieldLabel, BuiFieldLegend, BuiFieldSeparator, BuiFieldSet, BuiFieldTitle, BuiFlipCard, BuiGridPattern, BuiHoverCard, BuiHoverCardContent, BuiInput, BuiInputGroup, BuiInputGroupAddon, BuiInputGroupButton, BuiInputGroupInput, BuiInputGroupText, BuiItem, BuiItemActions, BuiItemContent, BuiItemDescription, BuiItemGroup, BuiItemMedia, BuiItemTitle, BuiKbd, BuiLabel, BuiMenubar, BuiMenubarTrigger, BuiMeter, BuiPagination, BuiPaginationContent, BuiPaginationEllipsis, BuiPaginationItem, BuiPaginationLink, BuiPopover, BuiPopoverContent, BuiProgress, BuiQuantitySelector, BuiRadioGroup, BuiRadioGroupItem, BuiRating, BuiScrollArea, BuiSegmentedControl, BuiSelect, BuiSeparator, BuiSkeleton, BuiSlider, BuiSpinner, BuiSpotlightCard, BuiStat, BuiSwitch, BuiTabList, BuiTabPanel, BuiTabTrigger, BuiTable, BuiTableBody, BuiTableCaption, BuiTableCell, BuiTableContainer, BuiTableFooter, BuiTableHead, BuiTableHeader, BuiTableRow, BuiTabs, BuiTerminal, BuiTextarea, BuiThemeCustomizer, BuiTiltCard, BuiToggle, BuiTooltip, BuiTooltipContent, BuiTypography, BuiVisuallyHidden, THEME_TOKENS, ThemeStore, buttonVariants, cn, toggleVariants };
5437
5961
  //# sourceMappingURL=ng-blatui.mjs.map