ng-blatui 1.20.0 → 1.22.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/fesm2022/ng-blatui.mjs +457 -6
- package/fesm2022/ng-blatui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ng-blatui.d.ts +97 -2
package/fesm2022/ng-blatui.mjs
CHANGED
|
@@ -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
|
}
|
|
@@ -5673,6 +5673,457 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
5673
5673
|
}]
|
|
5674
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
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
|
+
|
|
5952
|
+
/** A live countdown to a target time (`role="timer"`). SSR-safe — ticks only in the browser. */
|
|
5953
|
+
class BuiCountdown {
|
|
5954
|
+
to = input.required(/* @ts-ignore */
|
|
5955
|
+
...(ngDevMode ? [{ debugName: "to" }] : /* istanbul ignore next */ []));
|
|
5956
|
+
expired = input('Expired', /* @ts-ignore */
|
|
5957
|
+
...(ngDevMode ? [{ debugName: "expired" }] : /* istanbul ignore next */ []));
|
|
5958
|
+
userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
|
|
5959
|
+
now = signal(Date.now(), /* @ts-ignore */
|
|
5960
|
+
...(ngDevMode ? [{ debugName: "now" }] : /* istanbul ignore next */ []));
|
|
5961
|
+
timer;
|
|
5962
|
+
targetMs = computed(() => new Date(this.to()).getTime(), /* @ts-ignore */
|
|
5963
|
+
...(ngDevMode ? [{ debugName: "targetMs" }] : /* istanbul ignore next */ []));
|
|
5964
|
+
diff = computed(() => Math.max(0, this.targetMs() - this.now()), /* @ts-ignore */
|
|
5965
|
+
...(ngDevMode ? [{ debugName: "diff" }] : /* istanbul ignore next */ []));
|
|
5966
|
+
done = computed(() => this.diff() <= 0, /* @ts-ignore */
|
|
5967
|
+
...(ngDevMode ? [{ debugName: "done" }] : /* istanbul ignore next */ []));
|
|
5968
|
+
units = computed(() => {
|
|
5969
|
+
const diff = this.diff();
|
|
5970
|
+
const pad = (value) => String(value).padStart(2, '0');
|
|
5971
|
+
return [
|
|
5972
|
+
{ key: 'days', label: 'Days', value: pad(Math.floor(diff / 86_400_000)) },
|
|
5973
|
+
{ key: 'hours', label: 'Hrs', value: pad(Math.floor(diff / 3_600_000) % 24) },
|
|
5974
|
+
{ key: 'minutes', label: 'Min', value: pad(Math.floor(diff / 60_000) % 60) },
|
|
5975
|
+
{ key: 'seconds', label: 'Sec', value: pad(Math.floor(diff / 1000) % 60) },
|
|
5976
|
+
];
|
|
5977
|
+
}, /* @ts-ignore */
|
|
5978
|
+
...(ngDevMode ? [{ debugName: "units" }] : /* istanbul ignore next */ []));
|
|
5979
|
+
computedClass = computed(() => cn('inline-flex items-center gap-2', this.userClass()), /* @ts-ignore */
|
|
5980
|
+
...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
5981
|
+
constructor() {
|
|
5982
|
+
afterNextRender(() => {
|
|
5983
|
+
this.timer = setInterval(() => {
|
|
5984
|
+
this.now.set(Date.now());
|
|
5985
|
+
}, 1000);
|
|
5986
|
+
});
|
|
5987
|
+
}
|
|
5988
|
+
ngOnDestroy() {
|
|
5989
|
+
if (this.timer !== undefined) {
|
|
5990
|
+
clearInterval(this.timer);
|
|
5991
|
+
}
|
|
5992
|
+
}
|
|
5993
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiCountdown, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5994
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BuiCountdown, isStandalone: true, selector: "bui-countdown", inputs: { to: { classPropertyName: "to", publicName: "to", isSignal: true, isRequired: true, transformFunction: null }, expired: { classPropertyName: "expired", publicName: "expired", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "countdown", "role": "timer", "aria-live": "off" }, properties: { "class": "computedClass()" } }, ngImport: i0, template: `
|
|
5995
|
+
@if (done()) {
|
|
5996
|
+
<span data-slot="countdown-expired" class="text-sm font-medium text-muted-foreground">
|
|
5997
|
+
{{ expired() }}
|
|
5998
|
+
</span>
|
|
5999
|
+
} @else {
|
|
6000
|
+
<div class="flex items-center gap-2">
|
|
6001
|
+
@for (unit of units(); track unit.key) {
|
|
6002
|
+
<div
|
|
6003
|
+
data-slot="countdown-unit"
|
|
6004
|
+
class="flex min-w-[3.25rem] flex-col items-center rounded-lg border bg-card px-2 py-1.5 shadow-xs"
|
|
6005
|
+
>
|
|
6006
|
+
<span class="text-xl font-bold tabular-nums">{{ unit.value }}</span>
|
|
6007
|
+
<span class="text-[10px] font-medium tracking-wide text-muted-foreground uppercase">
|
|
6008
|
+
{{ unit.label }}
|
|
6009
|
+
</span>
|
|
6010
|
+
</div>
|
|
6011
|
+
}
|
|
6012
|
+
</div>
|
|
6013
|
+
}
|
|
6014
|
+
`, isInline: true });
|
|
6015
|
+
}
|
|
6016
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiCountdown, decorators: [{
|
|
6017
|
+
type: Component,
|
|
6018
|
+
args: [{
|
|
6019
|
+
selector: 'bui-countdown',
|
|
6020
|
+
host: {
|
|
6021
|
+
'data-slot': 'countdown',
|
|
6022
|
+
role: 'timer',
|
|
6023
|
+
'aria-live': 'off',
|
|
6024
|
+
'[class]': 'computedClass()',
|
|
6025
|
+
},
|
|
6026
|
+
template: `
|
|
6027
|
+
@if (done()) {
|
|
6028
|
+
<span data-slot="countdown-expired" class="text-sm font-medium text-muted-foreground">
|
|
6029
|
+
{{ expired() }}
|
|
6030
|
+
</span>
|
|
6031
|
+
} @else {
|
|
6032
|
+
<div class="flex items-center gap-2">
|
|
6033
|
+
@for (unit of units(); track unit.key) {
|
|
6034
|
+
<div
|
|
6035
|
+
data-slot="countdown-unit"
|
|
6036
|
+
class="flex min-w-[3.25rem] flex-col items-center rounded-lg border bg-card px-2 py-1.5 shadow-xs"
|
|
6037
|
+
>
|
|
6038
|
+
<span class="text-xl font-bold tabular-nums">{{ unit.value }}</span>
|
|
6039
|
+
<span class="text-[10px] font-medium tracking-wide text-muted-foreground uppercase">
|
|
6040
|
+
{{ unit.label }}
|
|
6041
|
+
</span>
|
|
6042
|
+
</div>
|
|
6043
|
+
}
|
|
6044
|
+
</div>
|
|
6045
|
+
}
|
|
6046
|
+
`,
|
|
6047
|
+
}]
|
|
6048
|
+
}], ctorParameters: () => [], propDecorators: { to: [{ type: i0.Input, args: [{ isSignal: true, alias: "to", required: true }] }], expired: [{ type: i0.Input, args: [{ isSignal: true, alias: "expired", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
6049
|
+
|
|
6050
|
+
/**
|
|
6051
|
+
* Animates a number counting up to its target on first render. The animated digits are
|
|
6052
|
+
* `aria-hidden`; an sr-only span carries the final value (SSR/no-JS read the real number).
|
|
6053
|
+
*/
|
|
6054
|
+
class BuiNumberTicker {
|
|
6055
|
+
value = input(0, /* @ts-ignore */
|
|
6056
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
6057
|
+
from = input(0, /* @ts-ignore */
|
|
6058
|
+
...(ngDevMode ? [{ debugName: "from" }] : /* istanbul ignore next */ []));
|
|
6059
|
+
duration = input(1500, /* @ts-ignore */
|
|
6060
|
+
...(ngDevMode ? [{ debugName: "duration" }] : /* istanbul ignore next */ []));
|
|
6061
|
+
decimals = input(0, /* @ts-ignore */
|
|
6062
|
+
...(ngDevMode ? [{ debugName: "decimals" }] : /* istanbul ignore next */ []));
|
|
6063
|
+
prefix = input('', /* @ts-ignore */
|
|
6064
|
+
...(ngDevMode ? [{ debugName: "prefix" }] : /* istanbul ignore next */ []));
|
|
6065
|
+
suffix = input('', /* @ts-ignore */
|
|
6066
|
+
...(ngDevMode ? [{ debugName: "suffix" }] : /* istanbul ignore next */ []));
|
|
6067
|
+
separator = input(',', /* @ts-ignore */
|
|
6068
|
+
...(ngDevMode ? [{ debugName: "separator" }] : /* istanbul ignore next */ []));
|
|
6069
|
+
userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
|
|
6070
|
+
current = signal(0, /* @ts-ignore */
|
|
6071
|
+
...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
|
|
6072
|
+
computedClass = computed(() => cn('tabular-nums', this.userClass()), /* @ts-ignore */
|
|
6073
|
+
...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
|
|
6074
|
+
constructor() {
|
|
6075
|
+
afterNextRender(() => {
|
|
6076
|
+
this.animate();
|
|
6077
|
+
});
|
|
6078
|
+
}
|
|
6079
|
+
format(value) {
|
|
6080
|
+
const fixed = value.toFixed(Math.max(0, this.decimals()));
|
|
6081
|
+
const [integer, decimal] = fixed.split('.');
|
|
6082
|
+
const decimalPart = decimal ? `.${decimal}` : '';
|
|
6083
|
+
return this.prefix() + this.group(integer) + decimalPart + this.suffix();
|
|
6084
|
+
}
|
|
6085
|
+
group(value) {
|
|
6086
|
+
return value.length <= 3
|
|
6087
|
+
? value
|
|
6088
|
+
: this.group(value.slice(0, -3)) + this.separator() + value.slice(-3);
|
|
6089
|
+
}
|
|
6090
|
+
animate() {
|
|
6091
|
+
const start = this.from();
|
|
6092
|
+
const end = this.value();
|
|
6093
|
+
const duration = this.duration();
|
|
6094
|
+
if (duration <= 0) {
|
|
6095
|
+
this.current.set(end);
|
|
6096
|
+
return;
|
|
6097
|
+
}
|
|
6098
|
+
this.current.set(start);
|
|
6099
|
+
const startTime = performance.now();
|
|
6100
|
+
const step = (time) => {
|
|
6101
|
+
const progress = Math.min(1, (time - startTime) / duration);
|
|
6102
|
+
this.current.set(start + (end - start) * progress);
|
|
6103
|
+
if (progress < 1) {
|
|
6104
|
+
requestAnimationFrame(step);
|
|
6105
|
+
}
|
|
6106
|
+
};
|
|
6107
|
+
requestAnimationFrame(step);
|
|
6108
|
+
}
|
|
6109
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiNumberTicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6110
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.2", type: BuiNumberTicker, isStandalone: true, selector: "bui-number-ticker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, from: { classPropertyName: "from", publicName: "from", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, decimals: { classPropertyName: "decimals", publicName: "decimals", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "number-ticker" }, properties: { "class": "computedClass()" } }, ngImport: i0, template: `
|
|
6111
|
+
<span aria-hidden="true">{{ format(current()) }}</span>
|
|
6112
|
+
<span class="sr-only">{{ format(value()) }}</span>
|
|
6113
|
+
`, isInline: true });
|
|
6114
|
+
}
|
|
6115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BuiNumberTicker, decorators: [{
|
|
6116
|
+
type: Component,
|
|
6117
|
+
args: [{
|
|
6118
|
+
selector: 'bui-number-ticker',
|
|
6119
|
+
host: { 'data-slot': 'number-ticker', '[class]': 'computedClass()' },
|
|
6120
|
+
template: `
|
|
6121
|
+
<span aria-hidden="true">{{ format(current()) }}</span>
|
|
6122
|
+
<span class="sr-only">{{ format(value()) }}</span>
|
|
6123
|
+
`,
|
|
6124
|
+
}]
|
|
6125
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], from: [{ type: i0.Input, args: [{ isSignal: true, alias: "from", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], decimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "decimals", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
|
|
6126
|
+
|
|
5676
6127
|
/*
|
|
5677
6128
|
* Public API Surface of ng-blatui
|
|
5678
6129
|
*/
|
|
@@ -5681,5 +6132,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
5681
6132
|
* Generated bundle index. Do not edit.
|
|
5682
6133
|
*/
|
|
5683
6134
|
|
|
5684
|
-
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, 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 };
|
|
6135
|
+
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, BuiCountdown, 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, BuiNumberTicker, 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 };
|
|
5685
6136
|
//# sourceMappingURL=ng-blatui.mjs.map
|