@flusys/ng-ui 6.0.0 → 6.0.2
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/README.md +3 -5
- package/fesm2022/flusys-ng-ui.mjs +1139 -391
- package/fesm2022/flusys-ng-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/themes/tailwind.scss +2 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, booleanAttribute, computed, Component,
|
|
2
|
+
import { input, booleanAttribute, computed, Component, signal, Injectable, output, contentChild, inject, viewChild, effect, ElementRef, Directive, TemplateRef, contentChildren, afterNextRender, numberAttribute, model, forwardRef, DestroyRef, untracked, viewChildren, PLATFORM_ID, Renderer2, InjectionToken, Injector, SecurityContext, NgModule, makeEnvironmentProviders, APP_INITIALIZER } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
5
5
|
import * as lucideNamespace from '@lucide/angular';
|
|
@@ -167,6 +167,7 @@ class UiIconComponent {
|
|
|
167
167
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: UiIconComponent, isStandalone: true, selector: "ui-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, spin: { classPropertyName: "spin", publicName: "spin", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--ui-icon-size": "size() + 'px'" }, classAttribute: "inline-flex items-center leading-none" }, providers: [provideLucideIcons(...allLucideIcons)], ngImport: i0, template: `
|
|
168
168
|
@if (lucideName()) {
|
|
169
169
|
<svg
|
|
170
|
+
ngSkipHydration
|
|
170
171
|
[lucideIcon]="lucideName()"
|
|
171
172
|
[size]="size()"
|
|
172
173
|
[class]="iconClass()"
|
|
@@ -182,6 +183,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
182
183
|
}, template: `
|
|
183
184
|
@if (lucideName()) {
|
|
184
185
|
<svg
|
|
186
|
+
ngSkipHydration
|
|
185
187
|
[lucideIcon]="lucideName()"
|
|
186
188
|
[size]="size()"
|
|
187
189
|
[class]="iconClass()"
|
|
@@ -190,6 +192,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
190
192
|
`, styles: [":host ::ng-deep svg[lucideIcon]{width:var(--ui-icon-size);height:var(--ui-icon-size);display:block}\n"] }]
|
|
191
193
|
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], spin: [{ type: i0.Input, args: [{ isSignal: true, alias: "spin", required: false }] }], fill: [{ type: i0.Input, args: [{ isSignal: true, alias: "fill", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }] } });
|
|
192
194
|
|
|
195
|
+
class ConfirmationService {
|
|
196
|
+
_confirmation = signal(null, /* @ts-ignore */
|
|
197
|
+
...(ngDevMode ? [{ debugName: "_confirmation" }] : /* istanbul ignore next */ []));
|
|
198
|
+
confirmation = this._confirmation.asReadonly();
|
|
199
|
+
confirm(options) {
|
|
200
|
+
this._confirmation.set(options);
|
|
201
|
+
}
|
|
202
|
+
close() {
|
|
203
|
+
this._confirmation.set(null);
|
|
204
|
+
}
|
|
205
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ConfirmationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
206
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ConfirmationService, providedIn: 'root' });
|
|
207
|
+
}
|
|
208
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ConfirmationService, decorators: [{
|
|
209
|
+
type: Injectable,
|
|
210
|
+
args: [{ providedIn: 'root' }]
|
|
211
|
+
}] });
|
|
212
|
+
|
|
193
213
|
class BadgeComponent {
|
|
194
214
|
value = input('', /* @ts-ignore */
|
|
195
215
|
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
@@ -587,24 +607,6 @@ function plainVariant(kind) {
|
|
|
587
607
|
return 'bg-transparent text-(--f-text-color) hover:bg-(--f-content-hover-background) active:bg-(--f-content-hover-background) border border-transparent';
|
|
588
608
|
}
|
|
589
609
|
|
|
590
|
-
class ConfirmationService {
|
|
591
|
-
_confirmation = signal(null, /* @ts-ignore */
|
|
592
|
-
...(ngDevMode ? [{ debugName: "_confirmation" }] : /* istanbul ignore next */ []));
|
|
593
|
-
confirmation = this._confirmation.asReadonly();
|
|
594
|
-
confirm(options) {
|
|
595
|
-
this._confirmation.set(options);
|
|
596
|
-
}
|
|
597
|
-
close() {
|
|
598
|
-
this._confirmation.set(null);
|
|
599
|
-
}
|
|
600
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ConfirmationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
601
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ConfirmationService, providedIn: 'root' });
|
|
602
|
-
}
|
|
603
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ConfirmationService, decorators: [{
|
|
604
|
-
type: Injectable,
|
|
605
|
-
args: [{ providedIn: 'root' }]
|
|
606
|
-
}] });
|
|
607
|
-
|
|
608
610
|
const FOCUSABLE_SELECTOR$3 = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
609
611
|
class ConfirmDialog {
|
|
610
612
|
static idCounter = 0;
|
|
@@ -650,7 +652,10 @@ class ConfirmDialog {
|
|
|
650
652
|
effect(() => {
|
|
651
653
|
const visible = !!this.activeConfirmation();
|
|
652
654
|
if (visible) {
|
|
653
|
-
this._previouslyFocused =
|
|
655
|
+
this._previouslyFocused =
|
|
656
|
+
typeof document !== 'undefined'
|
|
657
|
+
? document.activeElement
|
|
658
|
+
: null;
|
|
654
659
|
if (this.blockScroll())
|
|
655
660
|
this._doc.body.style.overflow = 'hidden';
|
|
656
661
|
}
|
|
@@ -719,64 +724,89 @@ class ConfirmDialog {
|
|
|
719
724
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: ConfirmDialog, isStandalone: true, selector: "f-confirmdialog", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, acceptLabel: { classPropertyName: "acceptLabel", publicName: "acceptLabel", isSignal: true, isRequired: false, transformFunction: null }, rejectLabel: { classPropertyName: "rejectLabel", publicName: "rejectLabel", isSignal: true, isRequired: false, transformFunction: null }, acceptIcon: { classPropertyName: "acceptIcon", publicName: "acceptIcon", isSignal: true, isRequired: false, transformFunction: null }, rejectIcon: { classPropertyName: "rejectIcon", publicName: "rejectIcon", isSignal: true, isRequired: false, transformFunction: null }, acceptButtonStyleClass: { classPropertyName: "acceptButtonStyleClass", publicName: "acceptButtonStyleClass", isSignal: true, isRequired: false, transformFunction: null }, rejectButtonStyleClass: { classPropertyName: "rejectButtonStyleClass", publicName: "rejectButtonStyleClass", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, blockScroll: { classPropertyName: "blockScroll", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, defaultFocus: { classPropertyName: "defaultFocus", publicName: "defaultFocus", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "onEscape()" }, classAttribute: "block" }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
720
725
|
@if (activeConfirmation(); as c) {
|
|
721
726
|
@if (c.acceptVisible !== false || c.rejectVisible !== false) {
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
727
|
+
<div class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
728
|
+
<div
|
|
729
|
+
class="confirm-backdrop absolute inset-0 bg-black/50 backdrop-blur-[2px]"
|
|
730
|
+
(click)="c.closable !== false && reject(c.reject)"
|
|
731
|
+
></div>
|
|
732
|
+
<div
|
|
733
|
+
#panel
|
|
734
|
+
class="confirm-panel relative bg-(--f-overlay-popover-background) rounded-2xl shadow-2xl w-full max-w-sm mx-auto overflow-hidden"
|
|
735
|
+
[class]="styleClass()"
|
|
736
|
+
[style]="style()"
|
|
737
|
+
role="alertdialog"
|
|
738
|
+
aria-modal="true"
|
|
739
|
+
[attr.aria-labelledby]="c.header ? headerId : null"
|
|
740
|
+
[attr.aria-describedby]="c.message ? descId : null"
|
|
741
|
+
(keydown.tab)="onTab($event)"
|
|
742
|
+
(keydown.shift.tab)="onShiftTab($event)"
|
|
743
|
+
>
|
|
744
|
+
<div class="p-6">
|
|
745
|
+
<div class="flex items-start gap-4">
|
|
746
|
+
@if (resolvedIcon(c)) {
|
|
747
|
+
<div
|
|
748
|
+
class="w-10 h-10 rounded-full flex items-center justify-center shrink-0"
|
|
749
|
+
[style.background-color]="
|
|
750
|
+
'color-mix(in srgb, var(--f-yellow-500) 12%, transparent)'
|
|
751
|
+
"
|
|
752
|
+
>
|
|
753
|
+
<ui-icon
|
|
754
|
+
[name]="resolvedIcon(c)"
|
|
755
|
+
class="text-lg"
|
|
756
|
+
[style.color]="'var(--f-yellow-500)'"
|
|
757
|
+
></ui-icon>
|
|
758
|
+
</div>
|
|
752
759
|
}
|
|
760
|
+
<div class="flex-1 min-w-0">
|
|
761
|
+
@if (c.header) {
|
|
762
|
+
<h3
|
|
763
|
+
[id]="headerId"
|
|
764
|
+
class="text-base font-semibold text-(--f-text-color) tracking-tight"
|
|
765
|
+
>
|
|
766
|
+
{{ c.header }}
|
|
767
|
+
</h3>
|
|
768
|
+
}
|
|
769
|
+
@if (c.message) {
|
|
770
|
+
<p
|
|
771
|
+
[id]="descId"
|
|
772
|
+
class="text-sm text-(--f-text-muted-color) mt-1 leading-relaxed"
|
|
773
|
+
>
|
|
774
|
+
{{ c.message }}
|
|
775
|
+
</p>
|
|
776
|
+
}
|
|
777
|
+
</div>
|
|
753
778
|
</div>
|
|
754
779
|
</div>
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
780
|
+
<div
|
|
781
|
+
class="flex justify-end gap-2 px-6 py-2 bg-(--f-content-hover-background)/60 border-t border-(--f-content-border-color)"
|
|
782
|
+
>
|
|
783
|
+
@if (c.rejectVisible !== false) {
|
|
784
|
+
<f-button
|
|
785
|
+
severity="secondary"
|
|
786
|
+
[outlined]="true"
|
|
787
|
+
[label]="resolvedRejectLabel(c)"
|
|
788
|
+
[icon]="resolvedRejectIcon(c)"
|
|
789
|
+
[styleClass]="
|
|
790
|
+
c.rejectButtonStyleClass ?? rejectButtonStyleClass()
|
|
791
|
+
"
|
|
792
|
+
[autofocus]="defaultFocus() === 'reject'"
|
|
793
|
+
(onClick)="reject(c.reject)"
|
|
794
|
+
></f-button>
|
|
795
|
+
}
|
|
796
|
+
@if (c.acceptVisible !== false) {
|
|
797
|
+
<f-button
|
|
798
|
+
[label]="resolvedAcceptLabel(c)"
|
|
799
|
+
[icon]="resolvedAcceptIcon(c)"
|
|
800
|
+
[styleClass]="
|
|
801
|
+
c.acceptButtonStyleClass ?? acceptButtonStyleClass()
|
|
802
|
+
"
|
|
803
|
+
[autofocus]="defaultFocus() === 'accept'"
|
|
804
|
+
(onClick)="accept(c.accept)"
|
|
805
|
+
></f-button>
|
|
806
|
+
}
|
|
807
|
+
</div>
|
|
777
808
|
</div>
|
|
778
809
|
</div>
|
|
779
|
-
</div>
|
|
780
810
|
}
|
|
781
811
|
}
|
|
782
812
|
`, isInline: true, styles: ["@keyframes confirm-in{0%{opacity:0;transform:scale(.95) translateY(-8px)}to{opacity:1;transform:scale(1) translateY(0)}}.confirm-panel{animation:confirm-in .22s cubic-bezier(.16,1,.3,1)}@keyframes confirm-backdrop-in{0%{opacity:0}to{opacity:1}}.confirm-backdrop{animation:confirm-backdrop-in .15s ease-out}\n"], dependencies: [{ kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }, { kind: "component", type: ButtonComponent, selector: "f-button", inputs: ["label", "icon", "iconPos", "severity", "type", "disabled", "loading", "loadingIcon", "text", "link", "outlined", "plain", "variant", "raised", "rounded", "fluid", "size", "ariaLabel", "autofocus", "tabindex", "styleClass", "style", "badge", "badgeSeverity", "badgeClass"], outputs: ["onClick", "onFocus", "onBlur"] }] });
|
|
@@ -786,64 +816,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
786
816
|
args: [{ selector: 'f-confirmdialog', imports: [UiIconComponent, ButtonComponent], host: { class: 'block', '(document:keydown.escape)': 'onEscape()' }, template: `
|
|
787
817
|
@if (activeConfirmation(); as c) {
|
|
788
818
|
@if (c.acceptVisible !== false || c.rejectVisible !== false) {
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
+
<div class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
820
|
+
<div
|
|
821
|
+
class="confirm-backdrop absolute inset-0 bg-black/50 backdrop-blur-[2px]"
|
|
822
|
+
(click)="c.closable !== false && reject(c.reject)"
|
|
823
|
+
></div>
|
|
824
|
+
<div
|
|
825
|
+
#panel
|
|
826
|
+
class="confirm-panel relative bg-(--f-overlay-popover-background) rounded-2xl shadow-2xl w-full max-w-sm mx-auto overflow-hidden"
|
|
827
|
+
[class]="styleClass()"
|
|
828
|
+
[style]="style()"
|
|
829
|
+
role="alertdialog"
|
|
830
|
+
aria-modal="true"
|
|
831
|
+
[attr.aria-labelledby]="c.header ? headerId : null"
|
|
832
|
+
[attr.aria-describedby]="c.message ? descId : null"
|
|
833
|
+
(keydown.tab)="onTab($event)"
|
|
834
|
+
(keydown.shift.tab)="onShiftTab($event)"
|
|
835
|
+
>
|
|
836
|
+
<div class="p-6">
|
|
837
|
+
<div class="flex items-start gap-4">
|
|
838
|
+
@if (resolvedIcon(c)) {
|
|
839
|
+
<div
|
|
840
|
+
class="w-10 h-10 rounded-full flex items-center justify-center shrink-0"
|
|
841
|
+
[style.background-color]="
|
|
842
|
+
'color-mix(in srgb, var(--f-yellow-500) 12%, transparent)'
|
|
843
|
+
"
|
|
844
|
+
>
|
|
845
|
+
<ui-icon
|
|
846
|
+
[name]="resolvedIcon(c)"
|
|
847
|
+
class="text-lg"
|
|
848
|
+
[style.color]="'var(--f-yellow-500)'"
|
|
849
|
+
></ui-icon>
|
|
850
|
+
</div>
|
|
819
851
|
}
|
|
852
|
+
<div class="flex-1 min-w-0">
|
|
853
|
+
@if (c.header) {
|
|
854
|
+
<h3
|
|
855
|
+
[id]="headerId"
|
|
856
|
+
class="text-base font-semibold text-(--f-text-color) tracking-tight"
|
|
857
|
+
>
|
|
858
|
+
{{ c.header }}
|
|
859
|
+
</h3>
|
|
860
|
+
}
|
|
861
|
+
@if (c.message) {
|
|
862
|
+
<p
|
|
863
|
+
[id]="descId"
|
|
864
|
+
class="text-sm text-(--f-text-muted-color) mt-1 leading-relaxed"
|
|
865
|
+
>
|
|
866
|
+
{{ c.message }}
|
|
867
|
+
</p>
|
|
868
|
+
}
|
|
869
|
+
</div>
|
|
820
870
|
</div>
|
|
821
871
|
</div>
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
872
|
+
<div
|
|
873
|
+
class="flex justify-end gap-2 px-6 py-2 bg-(--f-content-hover-background)/60 border-t border-(--f-content-border-color)"
|
|
874
|
+
>
|
|
875
|
+
@if (c.rejectVisible !== false) {
|
|
876
|
+
<f-button
|
|
877
|
+
severity="secondary"
|
|
878
|
+
[outlined]="true"
|
|
879
|
+
[label]="resolvedRejectLabel(c)"
|
|
880
|
+
[icon]="resolvedRejectIcon(c)"
|
|
881
|
+
[styleClass]="
|
|
882
|
+
c.rejectButtonStyleClass ?? rejectButtonStyleClass()
|
|
883
|
+
"
|
|
884
|
+
[autofocus]="defaultFocus() === 'reject'"
|
|
885
|
+
(onClick)="reject(c.reject)"
|
|
886
|
+
></f-button>
|
|
887
|
+
}
|
|
888
|
+
@if (c.acceptVisible !== false) {
|
|
889
|
+
<f-button
|
|
890
|
+
[label]="resolvedAcceptLabel(c)"
|
|
891
|
+
[icon]="resolvedAcceptIcon(c)"
|
|
892
|
+
[styleClass]="
|
|
893
|
+
c.acceptButtonStyleClass ?? acceptButtonStyleClass()
|
|
894
|
+
"
|
|
895
|
+
[autofocus]="defaultFocus() === 'accept'"
|
|
896
|
+
(onClick)="accept(c.accept)"
|
|
897
|
+
></f-button>
|
|
898
|
+
}
|
|
899
|
+
</div>
|
|
844
900
|
</div>
|
|
845
901
|
</div>
|
|
846
|
-
</div>
|
|
847
902
|
}
|
|
848
903
|
}
|
|
849
904
|
`, styles: ["@keyframes confirm-in{0%{opacity:0;transform:scale(.95) translateY(-8px)}to{opacity:1;transform:scale(1) translateY(0)}}.confirm-panel{animation:confirm-in .22s cubic-bezier(.16,1,.3,1)}@keyframes confirm-backdrop-in{0%{opacity:0}to{opacity:1}}.confirm-backdrop{animation:confirm-backdrop-in .15s ease-out}\n"] }]
|
|
@@ -5384,7 +5439,10 @@ class MultiSelectComponent {
|
|
|
5384
5439
|
queueMicrotask(() => this._filterInputRef()?.nativeElement.focus());
|
|
5385
5440
|
}
|
|
5386
5441
|
});
|
|
5387
|
-
repositionOnScroll(() => this.open() && this.appendTo() === 'body', () => {
|
|
5442
|
+
repositionOnScroll(() => this.open() && this.appendTo() === 'body', () => {
|
|
5443
|
+
this.position();
|
|
5444
|
+
this.adjustForViewport();
|
|
5445
|
+
});
|
|
5388
5446
|
}
|
|
5389
5447
|
onDocumentClick(e) {
|
|
5390
5448
|
if (this.open() && !this._el.nativeElement.contains(e.target)) {
|
|
@@ -5411,7 +5469,11 @@ class MultiSelectComponent {
|
|
|
5411
5469
|
panelStyle = computed(() => {
|
|
5412
5470
|
if (this.appendTo() !== 'body')
|
|
5413
5471
|
return {};
|
|
5414
|
-
return {
|
|
5472
|
+
return {
|
|
5473
|
+
top: `${this._panelTop()}px`,
|
|
5474
|
+
left: `${this._panelLeft()}px`,
|
|
5475
|
+
width: `${this._panelWidth()}px`,
|
|
5476
|
+
};
|
|
5415
5477
|
}, /* @ts-ignore */
|
|
5416
5478
|
...(ngDevMode ? [{ debugName: "panelStyle" }] : /* istanbul ignore next */ []));
|
|
5417
5479
|
position() {
|
|
@@ -5437,12 +5499,20 @@ class MultiSelectComponent {
|
|
|
5437
5499
|
}
|
|
5438
5500
|
}
|
|
5439
5501
|
triggerClass = computed(() => {
|
|
5440
|
-
const base = 'w-full min-h-[
|
|
5502
|
+
const base = 'w-full min-h-[34px] flex items-center gap-2 px-3 py-1.5 text-sm rounded-lg border bg-(--f-form-field-background) focus:outline-none focus-visible:ring-focus transition-all duration-[var(--f-transition-duration)]';
|
|
5441
5503
|
const showInvalid = this.invalid() && this.touched();
|
|
5442
5504
|
const stateClass = this.open()
|
|
5443
|
-
?
|
|
5444
|
-
|
|
5445
|
-
|
|
5505
|
+
? showInvalid
|
|
5506
|
+
? 'border-red-400'
|
|
5507
|
+
: 'border-primary'
|
|
5508
|
+
: showInvalid
|
|
5509
|
+
? 'border-red-400 hover:border-red-300'
|
|
5510
|
+
: 'border-(--f-form-field-border-color) hover:border-(--f-form-field-hover-border-color)';
|
|
5511
|
+
const disabledClass = this.disabled()
|
|
5512
|
+
? 'opacity-60 cursor-not-allowed'
|
|
5513
|
+
: this.readonly()
|
|
5514
|
+
? 'cursor-default'
|
|
5515
|
+
: 'cursor-pointer';
|
|
5446
5516
|
return `${base} ${stateClass} ${disabledClass}`;
|
|
5447
5517
|
}, /* @ts-ignore */
|
|
5448
5518
|
...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
|
|
@@ -5554,7 +5624,7 @@ class MultiSelectComponent {
|
|
|
5554
5624
|
fTemplates = contentChildren(FTemplateDirective, /* @ts-ignore */
|
|
5555
5625
|
...(ngDevMode ? [{ debugName: "fTemplates" }] : /* istanbul ignore next */ []));
|
|
5556
5626
|
namedTemplate(name) {
|
|
5557
|
-
return this.fTemplates().find(t => t.fTemplate() === name)?.templateRef ?? null;
|
|
5627
|
+
return (this.fTemplates().find((t) => t.fTemplate() === name)?.templateRef ?? null);
|
|
5558
5628
|
}
|
|
5559
5629
|
selectedItemTpl = computed(() => this.selectedItemRef() ?? this.namedTemplate('selectedItem'), /* @ts-ignore */
|
|
5560
5630
|
...(ngDevMode ? [{ debugName: "selectedItemTpl" }] : /* istanbul ignore next */ []));
|
|
@@ -5588,20 +5658,32 @@ class MultiSelectComponent {
|
|
|
5588
5658
|
}
|
|
5589
5659
|
filterFieldList = computed(() => {
|
|
5590
5660
|
const by = this.filterBy();
|
|
5591
|
-
return by
|
|
5661
|
+
return by
|
|
5662
|
+
? by
|
|
5663
|
+
.split(',')
|
|
5664
|
+
.map((f) => f.trim())
|
|
5665
|
+
.filter(Boolean)
|
|
5666
|
+
: [this.optionLabel()];
|
|
5592
5667
|
}, /* @ts-ignore */
|
|
5593
5668
|
...(ngDevMode ? [{ debugName: "filterFieldList" }] : /* istanbul ignore next */ []));
|
|
5594
5669
|
matchesFilter(raw, query) {
|
|
5595
5670
|
const locale = this.filterLocale() || undefined;
|
|
5596
|
-
const s = locale
|
|
5671
|
+
const s = locale
|
|
5672
|
+
? String(raw ?? '').toLocaleLowerCase(locale)
|
|
5673
|
+
: String(raw ?? '').toLowerCase();
|
|
5597
5674
|
const q = locale ? query.toLocaleLowerCase(locale) : query.toLowerCase();
|
|
5598
5675
|
switch (this.filterMatchMode()) {
|
|
5599
|
-
case 'startsWith':
|
|
5600
|
-
|
|
5601
|
-
case '
|
|
5602
|
-
|
|
5676
|
+
case 'startsWith':
|
|
5677
|
+
return s.startsWith(q);
|
|
5678
|
+
case 'endsWith':
|
|
5679
|
+
return s.endsWith(q);
|
|
5680
|
+
case 'equals':
|
|
5681
|
+
return s === q;
|
|
5682
|
+
case 'notEquals':
|
|
5683
|
+
return s !== q;
|
|
5603
5684
|
case 'contains':
|
|
5604
|
-
default:
|
|
5685
|
+
default:
|
|
5686
|
+
return s.includes(q);
|
|
5605
5687
|
}
|
|
5606
5688
|
}
|
|
5607
5689
|
optionMatchesQuery(opt, query) {
|
|
@@ -5610,36 +5692,41 @@ class MultiSelectComponent {
|
|
|
5610
5692
|
if (opt === null || typeof opt !== 'object')
|
|
5611
5693
|
return this.matchesFilter(opt, query);
|
|
5612
5694
|
const rec = opt;
|
|
5613
|
-
return this.filterFieldList().some(f => this.matchesFilter(rec[f], query));
|
|
5695
|
+
return this.filterFieldList().some((f) => this.matchesFilter(rec[f], query));
|
|
5614
5696
|
}
|
|
5615
5697
|
filteredOptions = computed(() => {
|
|
5616
5698
|
const opts = this.options();
|
|
5617
5699
|
const q = this.filterText();
|
|
5618
5700
|
if (!q)
|
|
5619
5701
|
return opts;
|
|
5620
|
-
return opts.filter(o => this.optionMatchesQuery(o, q));
|
|
5702
|
+
return opts.filter((o) => this.optionMatchesQuery(o, q));
|
|
5621
5703
|
}, /* @ts-ignore */
|
|
5622
5704
|
...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
|
|
5623
5705
|
allLeafOptions = computed(() => {
|
|
5624
5706
|
if (!this.group())
|
|
5625
5707
|
return this.options();
|
|
5626
5708
|
const groups = this.options();
|
|
5627
|
-
return groups.flatMap(g => g[this.optionGroupChildren()] ?? []);
|
|
5709
|
+
return groups.flatMap((g) => g[this.optionGroupChildren()] ?? []);
|
|
5628
5710
|
}, /* @ts-ignore */
|
|
5629
5711
|
...(ngDevMode ? [{ debugName: "allLeafOptions" }] : /* istanbul ignore next */ []));
|
|
5630
5712
|
flatItems = computed(() => {
|
|
5631
5713
|
const q = this.filterText();
|
|
5632
5714
|
if (!this.group()) {
|
|
5633
|
-
return this.filteredOptions().map(o => ({ kind: 'option', option: o }));
|
|
5715
|
+
return this.filteredOptions().map((o) => ({ kind: 'option', option: o }));
|
|
5634
5716
|
}
|
|
5635
5717
|
const groups = this.options();
|
|
5636
5718
|
const out = [];
|
|
5637
5719
|
for (const g of groups) {
|
|
5638
5720
|
const children = g[this.optionGroupChildren()] ?? [];
|
|
5639
|
-
const filteredChildren = q
|
|
5721
|
+
const filteredChildren = q
|
|
5722
|
+
? children.filter((o) => this.optionMatchesQuery(o, q))
|
|
5723
|
+
: children;
|
|
5640
5724
|
if (!filteredChildren.length)
|
|
5641
5725
|
continue;
|
|
5642
|
-
out.push({
|
|
5726
|
+
out.push({
|
|
5727
|
+
kind: 'group',
|
|
5728
|
+
label: String(g[this.optionGroupLabel()] ?? ''),
|
|
5729
|
+
});
|
|
5643
5730
|
for (const c of filteredChildren)
|
|
5644
5731
|
out.push({ kind: 'option', option: c });
|
|
5645
5732
|
}
|
|
@@ -5648,7 +5735,7 @@ class MultiSelectComponent {
|
|
|
5648
5735
|
...(ngDevMode ? [{ debugName: "flatItems" }] : /* istanbul ignore next */ []));
|
|
5649
5736
|
navigableOptions = computed(() => this.flatItems()
|
|
5650
5737
|
.filter((i) => i.kind === 'option')
|
|
5651
|
-
.map(i => i.option), /* @ts-ignore */
|
|
5738
|
+
.map((i) => i.option), /* @ts-ignore */
|
|
5652
5739
|
...(ngDevMode ? [{ debugName: "navigableOptions" }] : /* istanbul ignore next */ []));
|
|
5653
5740
|
activeDescendantId = computed(() => {
|
|
5654
5741
|
const idx = this._focusedOptionIndex();
|
|
@@ -5671,10 +5758,10 @@ class MultiSelectComponent {
|
|
|
5671
5758
|
}
|
|
5672
5759
|
selectedOptions = computed(() => {
|
|
5673
5760
|
const vals = this.values();
|
|
5674
|
-
return this.allLeafOptions().filter(o => vals.includes(this.getOptionValue(o)));
|
|
5761
|
+
return this.allLeafOptions().filter((o) => vals.includes(this.getOptionValue(o)));
|
|
5675
5762
|
}, /* @ts-ignore */
|
|
5676
5763
|
...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
|
|
5677
|
-
selectedLabels = computed(() => this.selectedOptions().map(o => this.getOptionLabel(o)), /* @ts-ignore */
|
|
5764
|
+
selectedLabels = computed(() => this.selectedOptions().map((o) => this.getOptionLabel(o)), /* @ts-ignore */
|
|
5678
5765
|
...(ngDevMode ? [{ debugName: "selectedLabels" }] : /* istanbul ignore next */ []));
|
|
5679
5766
|
getOptionLabel(opt) {
|
|
5680
5767
|
if (opt === null || opt === undefined)
|
|
@@ -5690,7 +5777,9 @@ class MultiSelectComponent {
|
|
|
5690
5777
|
return opt;
|
|
5691
5778
|
return opt[this.optionValue()];
|
|
5692
5779
|
}
|
|
5693
|
-
isSelected(opt) {
|
|
5780
|
+
isSelected(opt) {
|
|
5781
|
+
return this.values().includes(this.getOptionValue(opt));
|
|
5782
|
+
}
|
|
5694
5783
|
isOptionDisabled(opt) {
|
|
5695
5784
|
const field = this.optionDisabled();
|
|
5696
5785
|
if (!field || opt === null || typeof opt !== 'object')
|
|
@@ -5737,7 +5826,7 @@ class MultiSelectComponent {
|
|
|
5737
5826
|
const limit = this.selectionLimit();
|
|
5738
5827
|
if (selecting && limit != null && cur.length >= limit)
|
|
5739
5828
|
return;
|
|
5740
|
-
const next = selecting ? [...cur, v] : cur.filter(x => x !== v);
|
|
5829
|
+
const next = selecting ? [...cur, v] : cur.filter((x) => x !== v);
|
|
5741
5830
|
this._values.set(next);
|
|
5742
5831
|
this._onChange(next);
|
|
5743
5832
|
this.onChange.emit(next);
|
|
@@ -5753,22 +5842,24 @@ class MultiSelectComponent {
|
|
|
5753
5842
|
this.onClear.emit();
|
|
5754
5843
|
}
|
|
5755
5844
|
allFilteredSelected = computed(() => {
|
|
5756
|
-
const selectable = this.filteredOptions().filter(o => !this.isOptionDisabled(o));
|
|
5757
|
-
return selectable.length > 0 && selectable.every(o => this.isSelected(o));
|
|
5845
|
+
const selectable = this.filteredOptions().filter((o) => !this.isOptionDisabled(o));
|
|
5846
|
+
return selectable.length > 0 && selectable.every((o) => this.isSelected(o));
|
|
5758
5847
|
}, /* @ts-ignore */
|
|
5759
5848
|
...(ngDevMode ? [{ debugName: "allFilteredSelected" }] : /* istanbul ignore next */ []));
|
|
5760
5849
|
toggleAll(e) {
|
|
5761
5850
|
e.stopPropagation();
|
|
5762
5851
|
if (this.readonly())
|
|
5763
5852
|
return;
|
|
5764
|
-
const selectable = this.filteredOptions().filter(o => !this.isOptionDisabled(o));
|
|
5765
|
-
const selectableValues = selectable.map(o => this.getOptionValue(o));
|
|
5853
|
+
const selectable = this.filteredOptions().filter((o) => !this.isOptionDisabled(o));
|
|
5854
|
+
const selectableValues = selectable.map((o) => this.getOptionValue(o));
|
|
5766
5855
|
const cur = this.values();
|
|
5767
5856
|
const selectingAll = !this.allFilteredSelected();
|
|
5768
5857
|
const next = selectingAll
|
|
5769
|
-
? [...cur, ...selectableValues.filter(v => !cur.includes(v))]
|
|
5770
|
-
: cur.filter(v => !selectableValues.includes(v));
|
|
5771
|
-
const limited = this.selectionLimit() != null
|
|
5858
|
+
? [...cur, ...selectableValues.filter((v) => !cur.includes(v))]
|
|
5859
|
+
: cur.filter((v) => !selectableValues.includes(v));
|
|
5860
|
+
const limited = this.selectionLimit() != null
|
|
5861
|
+
? next.slice(0, this.selectionLimit())
|
|
5862
|
+
: next;
|
|
5772
5863
|
this._values.set(limited);
|
|
5773
5864
|
this._onChange(limited);
|
|
5774
5865
|
this.onChange.emit(limited);
|
|
@@ -5786,7 +5877,11 @@ class MultiSelectComponent {
|
|
|
5786
5877
|
if (!len)
|
|
5787
5878
|
return;
|
|
5788
5879
|
const cur = this._focusedOptionIndex();
|
|
5789
|
-
const next = cur < 0
|
|
5880
|
+
const next = cur < 0
|
|
5881
|
+
? delta > 0
|
|
5882
|
+
? 0
|
|
5883
|
+
: len - 1
|
|
5884
|
+
: Math.min(len - 1, Math.max(0, cur + delta));
|
|
5790
5885
|
this._focusedOptionIndex.set(next);
|
|
5791
5886
|
}
|
|
5792
5887
|
_typeaheadStr = '';
|
|
@@ -5797,13 +5892,15 @@ class MultiSelectComponent {
|
|
|
5797
5892
|
this._typeaheadStr += char.toLowerCase();
|
|
5798
5893
|
if (this._typeaheadTimer)
|
|
5799
5894
|
clearTimeout(this._typeaheadTimer);
|
|
5800
|
-
this._typeaheadTimer = setTimeout(() => {
|
|
5895
|
+
this._typeaheadTimer = setTimeout(() => {
|
|
5896
|
+
this._typeaheadStr = '';
|
|
5897
|
+
}, 500);
|
|
5801
5898
|
const opts = this.navigableOptions();
|
|
5802
5899
|
if (!opts.length)
|
|
5803
5900
|
return;
|
|
5804
5901
|
const start = this._focusedOptionIndex() + 1;
|
|
5805
5902
|
const ordered = [...opts.slice(start), ...opts.slice(0, start)];
|
|
5806
|
-
const match = ordered.find(o => this.getOptionLabel(o).toLowerCase().startsWith(this._typeaheadStr));
|
|
5903
|
+
const match = ordered.find((o) => this.getOptionLabel(o).toLowerCase().startsWith(this._typeaheadStr));
|
|
5807
5904
|
if (match)
|
|
5808
5905
|
this._focusedOptionIndex.set(opts.indexOf(match));
|
|
5809
5906
|
}
|
|
@@ -5865,17 +5962,32 @@ class MultiSelectComponent {
|
|
|
5865
5962
|
this.closeList();
|
|
5866
5963
|
break;
|
|
5867
5964
|
default:
|
|
5868
|
-
if (event.key.length === 1 &&
|
|
5965
|
+
if (event.key.length === 1 &&
|
|
5966
|
+
!event.altKey &&
|
|
5967
|
+
!event.ctrlKey &&
|
|
5968
|
+
!event.metaKey) {
|
|
5869
5969
|
this.typeahead(event.key);
|
|
5870
5970
|
}
|
|
5871
5971
|
}
|
|
5872
5972
|
}
|
|
5873
|
-
writeValue(v) {
|
|
5874
|
-
|
|
5875
|
-
|
|
5973
|
+
writeValue(v) {
|
|
5974
|
+
this._values.set(Array.isArray(v) ? v : []);
|
|
5975
|
+
}
|
|
5976
|
+
registerOnChange(fn) {
|
|
5977
|
+
this._onChange = fn;
|
|
5978
|
+
}
|
|
5979
|
+
registerOnTouched(fn) {
|
|
5980
|
+
this._onTouched = fn;
|
|
5981
|
+
}
|
|
5876
5982
|
setDisabledState() { }
|
|
5877
5983
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MultiSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5878
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: MultiSelectComponent, isStandalone: true, selector: "f-multiselect", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", 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 }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, filterMatchMode: { classPropertyName: "filterMatchMode", publicName: "filterMatchMode", isSignal: true, isRequired: false, transformFunction: null }, filterLocale: { classPropertyName: "filterLocale", publicName: "filterLocale", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, resetFilterOnHide: { classPropertyName: "resetFilterOnHide", publicName: "resetFilterOnHide", isSignal: true, isRequired: false, transformFunction: null }, autofocusFilter: { classPropertyName: "autofocusFilter", publicName: "autofocusFilter", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyFilterMessage: { classPropertyName: "emptyFilterMessage", publicName: "emptyFilterMessage", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, optionDisabled: { classPropertyName: "optionDisabled", publicName: "optionDisabled", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, maxSelectedLabels: { classPropertyName: "maxSelectedLabels", publicName: "maxSelectedLabels", isSignal: true, isRequired: false, transformFunction: null }, selectionLimit: { classPropertyName: "selectionLimit", publicName: "selectionLimit", isSignal: true, isRequired: false, transformFunction: null }, showToggleAll: { classPropertyName: "showToggleAll", publicName: "showToggleAll", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingIcon: { classPropertyName: "loadingIcon", publicName: "loadingIcon", isSignal: true, isRequired: false, transformFunction: null }, dropdownIcon: { classPropertyName: "dropdownIcon", publicName: "dropdownIcon", isSignal: true, isRequired: false, transformFunction: null }, clearIcon: { classPropertyName: "clearIcon", publicName: "clearIcon", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, optionGroupLabel: { classPropertyName: "optionGroupLabel", publicName: "optionGroupLabel", isSignal: true, isRequired: false, transformFunction: null }, optionGroupChildren: { classPropertyName: "optionGroupChildren", publicName: "optionGroupChildren", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onBlur: "onBlur", onFocus: "onFocus", onChange: "onChange", onFilter: "onFilter", onShow: "onShow", onHide: "onHide", onClear: "onClear", onLazyLoad: "onLazyLoad", onSelectAllChange: "onSelectAllChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class": "hostClass()", "style": "style()" } }, providers: [
|
|
5984
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: MultiSelectComponent, isStandalone: true, selector: "f-multiselect", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", 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 }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, filterMatchMode: { classPropertyName: "filterMatchMode", publicName: "filterMatchMode", isSignal: true, isRequired: false, transformFunction: null }, filterLocale: { classPropertyName: "filterLocale", publicName: "filterLocale", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, resetFilterOnHide: { classPropertyName: "resetFilterOnHide", publicName: "resetFilterOnHide", isSignal: true, isRequired: false, transformFunction: null }, autofocusFilter: { classPropertyName: "autofocusFilter", publicName: "autofocusFilter", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyFilterMessage: { classPropertyName: "emptyFilterMessage", publicName: "emptyFilterMessage", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, optionDisabled: { classPropertyName: "optionDisabled", publicName: "optionDisabled", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, maxSelectedLabels: { classPropertyName: "maxSelectedLabels", publicName: "maxSelectedLabels", isSignal: true, isRequired: false, transformFunction: null }, selectionLimit: { classPropertyName: "selectionLimit", publicName: "selectionLimit", isSignal: true, isRequired: false, transformFunction: null }, showToggleAll: { classPropertyName: "showToggleAll", publicName: "showToggleAll", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingIcon: { classPropertyName: "loadingIcon", publicName: "loadingIcon", isSignal: true, isRequired: false, transformFunction: null }, dropdownIcon: { classPropertyName: "dropdownIcon", publicName: "dropdownIcon", isSignal: true, isRequired: false, transformFunction: null }, clearIcon: { classPropertyName: "clearIcon", publicName: "clearIcon", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, optionGroupLabel: { classPropertyName: "optionGroupLabel", publicName: "optionGroupLabel", isSignal: true, isRequired: false, transformFunction: null }, optionGroupChildren: { classPropertyName: "optionGroupChildren", publicName: "optionGroupChildren", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onBlur: "onBlur", onFocus: "onFocus", onChange: "onChange", onFilter: "onFilter", onShow: "onShow", onHide: "onHide", onClear: "onClear", onLazyLoad: "onLazyLoad", onSelectAllChange: "onSelectAllChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class": "hostClass()", "style": "style()" } }, providers: [
|
|
5985
|
+
{
|
|
5986
|
+
provide: NG_VALUE_ACCESSOR,
|
|
5987
|
+
useExisting: forwardRef(() => MultiSelectComponent),
|
|
5988
|
+
multi: true,
|
|
5989
|
+
},
|
|
5990
|
+
], queries: [{ propertyName: "selectedItemRef", first: true, predicate: ["selectedItem"], descendants: true, isSignal: true }, { propertyName: "itemRef", first: true, predicate: ["item"], descendants: true, isSignal: true }, { propertyName: "groupRef", first: true, predicate: ["group"], descendants: true, isSignal: true }, { propertyName: "headerRef", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "footerRef", first: true, predicate: ["footer"], descendants: true, isSignal: true }, { propertyName: "emptyRef", first: true, predicate: ["empty"], descendants: true, isSignal: true }, { propertyName: "emptyFilterRef", first: true, predicate: ["emptyfilter"], descendants: true, isSignal: true }, { propertyName: "loaderRef", first: true, predicate: ["loader"], descendants: true, isSignal: true }, { propertyName: "filterRef", first: true, predicate: ["filter"], descendants: true, isSignal: true }, { propertyName: "fTemplates", predicate: FTemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "_triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "_filterInputRef", first: true, predicate: ["filterInput"], descendants: true, isSignal: true }, { propertyName: "_panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
5879
5991
|
<div class="relative w-full">
|
|
5880
5992
|
<div
|
|
5881
5993
|
#trigger
|
|
@@ -5896,20 +6008,36 @@ class MultiSelectComponent {
|
|
|
5896
6008
|
>
|
|
5897
6009
|
@if (selectedLabels().length) {
|
|
5898
6010
|
@if (display() === 'comma') {
|
|
5899
|
-
<span
|
|
6011
|
+
<span
|
|
6012
|
+
class="flex-1 min-w-0 truncate text-sm text-(--f-form-field-color)"
|
|
6013
|
+
>{{ commaLabel() }}</span
|
|
6014
|
+
>
|
|
5900
6015
|
} @else if (selectedLabels().length > maxSelectedLabels()) {
|
|
5901
|
-
<span
|
|
6016
|
+
<span
|
|
6017
|
+
class="flex-1 min-w-0 truncate text-sm text-(--f-form-field-color)"
|
|
6018
|
+
>{{ selectedLabels().length }} items selected</span
|
|
6019
|
+
>
|
|
5902
6020
|
} @else {
|
|
5903
6021
|
<div class="flex flex-wrap items-center gap-1 flex-1 min-w-0">
|
|
5904
6022
|
@for (opt of selectedOptions(); track getOptionValue(opt)) {
|
|
5905
|
-
<span
|
|
6023
|
+
<span
|
|
6024
|
+
class="inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded-md text-xs font-medium shrink-0"
|
|
6025
|
+
>
|
|
5906
6026
|
@if (selectedItemTpl()) {
|
|
5907
|
-
<ng-container
|
|
6027
|
+
<ng-container
|
|
6028
|
+
[ngTemplateOutlet]="selectedItemTpl()"
|
|
6029
|
+
[ngTemplateOutletContext]="{ $implicit: opt }"
|
|
6030
|
+
/>
|
|
5908
6031
|
} @else {
|
|
5909
6032
|
{{ getOptionLabel(opt) }}
|
|
5910
6033
|
}
|
|
5911
6034
|
@if (!disabled() && !readonly()) {
|
|
5912
|
-
<button
|
|
6035
|
+
<button
|
|
6036
|
+
type="button"
|
|
6037
|
+
aria-label="Remove"
|
|
6038
|
+
class="inline-flex items-center justify-center hover:opacity-70 cursor-pointer"
|
|
6039
|
+
(click)="removeOption($event, opt)"
|
|
6040
|
+
>
|
|
5913
6041
|
<ui-icon name="times" class="text-[10px]"></ui-icon>
|
|
5914
6042
|
</button>
|
|
5915
6043
|
}
|
|
@@ -5918,16 +6046,30 @@ class MultiSelectComponent {
|
|
|
5918
6046
|
</div>
|
|
5919
6047
|
}
|
|
5920
6048
|
} @else {
|
|
5921
|
-
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
6049
|
+
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
6050
|
+
placeholder()
|
|
6051
|
+
}}</span>
|
|
5922
6052
|
}
|
|
5923
6053
|
<span class="flex items-center gap-1 shrink-0 ml-auto">
|
|
5924
6054
|
@if (showClear() && values().length && !disabled() && !readonly()) {
|
|
5925
|
-
<ui-icon
|
|
6055
|
+
<ui-icon
|
|
6056
|
+
[name]="clearIcon()"
|
|
6057
|
+
class="text-xs text-(--f-form-field-placeholder-color) hover:text-(--f-text-color) shrink-0"
|
|
6058
|
+
(click)="clearAll($event)"
|
|
6059
|
+
></ui-icon>
|
|
5926
6060
|
}
|
|
5927
6061
|
@if (loading()) {
|
|
5928
|
-
<ui-icon
|
|
6062
|
+
<ui-icon
|
|
6063
|
+
[name]="loadingIcon()"
|
|
6064
|
+
[spin]="true"
|
|
6065
|
+
class="text-xs text-(--f-form-field-placeholder-color) shrink-0"
|
|
6066
|
+
></ui-icon>
|
|
5929
6067
|
} @else {
|
|
5930
|
-
<ui-icon
|
|
6068
|
+
<ui-icon
|
|
6069
|
+
[name]="dropdownIcon()"
|
|
6070
|
+
class="text-xs text-(--f-form-field-placeholder-color) transition-transform duration-[var(--f-transition-duration)] shrink-0"
|
|
6071
|
+
[class.rotate-180]="open()"
|
|
6072
|
+
></ui-icon>
|
|
5931
6073
|
}
|
|
5932
6074
|
</span>
|
|
5933
6075
|
</div>
|
|
@@ -5942,10 +6084,21 @@ class MultiSelectComponent {
|
|
|
5942
6084
|
@if (filter()) {
|
|
5943
6085
|
<div class="p-2 border-b border-(--f-content-border-color)">
|
|
5944
6086
|
@if (filterTpl()) {
|
|
5945
|
-
<ng-container
|
|
6087
|
+
<ng-container
|
|
6088
|
+
[ngTemplateOutlet]="filterTpl()"
|
|
6089
|
+
[ngTemplateOutletContext]="{
|
|
6090
|
+
$implicit: filterText(),
|
|
6091
|
+
filter: setFilterFn,
|
|
6092
|
+
}"
|
|
6093
|
+
/>
|
|
5946
6094
|
} @else {
|
|
5947
|
-
<div
|
|
5948
|
-
|
|
6095
|
+
<div
|
|
6096
|
+
class="flex items-center gap-2 px-2 py-1.5 bg-(--f-content-hover-background) rounded-lg border border-(--f-content-border-color)"
|
|
6097
|
+
>
|
|
6098
|
+
<ui-icon
|
|
6099
|
+
name="search"
|
|
6100
|
+
class="text-xs text-(--f-text-muted-color) shrink-0"
|
|
6101
|
+
></ui-icon>
|
|
5949
6102
|
<input
|
|
5950
6103
|
#filterInput
|
|
5951
6104
|
type="text"
|
|
@@ -5961,36 +6114,67 @@ class MultiSelectComponent {
|
|
|
5961
6114
|
</div>
|
|
5962
6115
|
}
|
|
5963
6116
|
@if (showToggleAll() && filteredOptions().length) {
|
|
5964
|
-
<button
|
|
6117
|
+
<button
|
|
6118
|
+
type="button"
|
|
5965
6119
|
class="w-full text-left px-3 py-2 text-sm flex items-center gap-2.5 border-b border-(--f-content-border-color) text-(--f-text-color) hover:bg-(--f-content-hover-background) transition-colors cursor-pointer"
|
|
5966
|
-
(click)="toggleAll($event)"
|
|
5967
|
-
|
|
5968
|
-
|
|
6120
|
+
(click)="toggleAll($event)"
|
|
6121
|
+
>
|
|
6122
|
+
<div
|
|
6123
|
+
class="w-4 h-4 rounded-sm border flex items-center justify-center shrink-0 transition-colors"
|
|
6124
|
+
[class]="
|
|
6125
|
+
allFilteredSelected()
|
|
6126
|
+
? 'bg-primary border-primary'
|
|
6127
|
+
: 'border-(--f-form-field-border-color) bg-(--f-form-field-background)'
|
|
6128
|
+
"
|
|
6129
|
+
>
|
|
5969
6130
|
@if (allFilteredSelected()) {
|
|
5970
|
-
<ui-icon
|
|
6131
|
+
<ui-icon
|
|
6132
|
+
name="check"
|
|
6133
|
+
class="text-[9px] text-primary-contrast"
|
|
6134
|
+
></ui-icon>
|
|
5971
6135
|
}
|
|
5972
6136
|
</div>
|
|
5973
6137
|
<span class="flex-1 truncate font-medium">Select All</span>
|
|
5974
6138
|
</button>
|
|
5975
6139
|
}
|
|
5976
|
-
<div
|
|
6140
|
+
<div
|
|
6141
|
+
data-multiselect-list
|
|
6142
|
+
[id]="listId()"
|
|
6143
|
+
role="listbox"
|
|
6144
|
+
[attr.aria-multiselectable]="true"
|
|
6145
|
+
class="max-h-56 overflow-auto py-1"
|
|
6146
|
+
>
|
|
5977
6147
|
@if (loading()) {
|
|
5978
6148
|
@if (loaderTpl()) {
|
|
5979
6149
|
<ng-container [ngTemplateOutlet]="loaderTpl()" />
|
|
5980
6150
|
} @else {
|
|
5981
6151
|
<div class="py-6 flex flex-col items-center gap-2">
|
|
5982
|
-
<ui-icon
|
|
6152
|
+
<ui-icon
|
|
6153
|
+
[name]="loadingIcon()"
|
|
6154
|
+
[spin]="true"
|
|
6155
|
+
class="text-xl text-(--f-text-muted-color)"
|
|
6156
|
+
></ui-icon>
|
|
5983
6157
|
</div>
|
|
5984
6158
|
}
|
|
5985
6159
|
} @else if (virtualScroll()) {
|
|
5986
|
-
<f-scroller
|
|
6160
|
+
<f-scroller
|
|
6161
|
+
[items]="flatItems()"
|
|
6162
|
+
[itemSize]="virtualScrollItemSize()"
|
|
6163
|
+
scrollHeight="14rem"
|
|
6164
|
+
>
|
|
5987
6165
|
<ng-template let-item let-i="index">
|
|
5988
|
-
<ng-container
|
|
6166
|
+
<ng-container
|
|
6167
|
+
[ngTemplateOutlet]="rowTpl"
|
|
6168
|
+
[ngTemplateOutletContext]="{ $implicit: item, index: i }"
|
|
6169
|
+
/>
|
|
5989
6170
|
</ng-template>
|
|
5990
6171
|
</f-scroller>
|
|
5991
6172
|
} @else {
|
|
5992
6173
|
@for (item of flatItems(); track $index) {
|
|
5993
|
-
<ng-container
|
|
6174
|
+
<ng-container
|
|
6175
|
+
[ngTemplateOutlet]="rowTpl"
|
|
6176
|
+
[ngTemplateOutletContext]="{ $implicit: item, index: $index }"
|
|
6177
|
+
/>
|
|
5994
6178
|
} @empty {
|
|
5995
6179
|
<ng-container [ngTemplateOutlet]="emptyStateTpl" />
|
|
5996
6180
|
}
|
|
@@ -6007,9 +6191,14 @@ class MultiSelectComponent {
|
|
|
6007
6191
|
|
|
6008
6192
|
<ng-template #rowTpl let-item let-i="index">
|
|
6009
6193
|
@if (item.kind === 'group') {
|
|
6010
|
-
<div
|
|
6194
|
+
<div
|
|
6195
|
+
class="h-full flex items-center px-3 py-1.5 text-xs font-semibold uppercase tracking-wide text-(--f-text-muted-color) bg-(--f-content-hover-background)"
|
|
6196
|
+
>
|
|
6011
6197
|
@if (groupTpl()) {
|
|
6012
|
-
<ng-container
|
|
6198
|
+
<ng-container
|
|
6199
|
+
[ngTemplateOutlet]="groupTpl()"
|
|
6200
|
+
[ngTemplateOutletContext]="{ $implicit: item.label }"
|
|
6201
|
+
/>
|
|
6013
6202
|
} @else {
|
|
6014
6203
|
{{ item.label }}
|
|
6015
6204
|
}
|
|
@@ -6026,15 +6215,27 @@ class MultiSelectComponent {
|
|
|
6026
6215
|
(click)="toggleOption($event, item.option)"
|
|
6027
6216
|
(mouseenter)="onOptionMouseEnter(item.option)"
|
|
6028
6217
|
>
|
|
6029
|
-
<div
|
|
6030
|
-
|
|
6218
|
+
<div
|
|
6219
|
+
class="w-4 h-4 rounded-sm border flex items-center justify-center shrink-0 transition-colors"
|
|
6220
|
+
[class]="
|
|
6221
|
+
isSelected(item.option)
|
|
6222
|
+
? 'bg-primary border-primary'
|
|
6223
|
+
: 'border-(--f-form-field-border-color) bg-(--f-form-field-background)'
|
|
6224
|
+
"
|
|
6225
|
+
>
|
|
6031
6226
|
@if (isSelected(item.option)) {
|
|
6032
|
-
<ui-icon
|
|
6227
|
+
<ui-icon
|
|
6228
|
+
name="check"
|
|
6229
|
+
class="text-[9px] text-primary-contrast"
|
|
6230
|
+
></ui-icon>
|
|
6033
6231
|
}
|
|
6034
6232
|
</div>
|
|
6035
6233
|
<span class="flex-1 truncate">
|
|
6036
6234
|
@if (itemTpl()) {
|
|
6037
|
-
<ng-container
|
|
6235
|
+
<ng-container
|
|
6236
|
+
[ngTemplateOutlet]="itemTpl()"
|
|
6237
|
+
[ngTemplateOutletContext]="{ $implicit: item.option }"
|
|
6238
|
+
/>
|
|
6038
6239
|
} @else {
|
|
6039
6240
|
{{ getOptionLabel(item.option) }}
|
|
6040
6241
|
}
|
|
@@ -6048,15 +6249,25 @@ class MultiSelectComponent {
|
|
|
6048
6249
|
<ng-container [ngTemplateOutlet]="emptyFilterTpl()" />
|
|
6049
6250
|
} @else if (filterText()) {
|
|
6050
6251
|
<div class="py-6 flex flex-col items-center gap-2">
|
|
6051
|
-
<ui-icon
|
|
6052
|
-
|
|
6252
|
+
<ui-icon
|
|
6253
|
+
name="search"
|
|
6254
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
6255
|
+
></ui-icon>
|
|
6256
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
6257
|
+
emptyFilterMessage()
|
|
6258
|
+
}}</span>
|
|
6053
6259
|
</div>
|
|
6054
6260
|
} @else if (emptyTpl()) {
|
|
6055
6261
|
<ng-container [ngTemplateOutlet]="emptyTpl()" />
|
|
6056
6262
|
} @else {
|
|
6057
6263
|
<div class="py-6 flex flex-col items-center gap-2">
|
|
6058
|
-
<ui-icon
|
|
6059
|
-
|
|
6264
|
+
<ui-icon
|
|
6265
|
+
name="inbox"
|
|
6266
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
6267
|
+
></ui-icon>
|
|
6268
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
6269
|
+
emptyMessage()
|
|
6270
|
+
}}</span>
|
|
6060
6271
|
</div>
|
|
6061
6272
|
}
|
|
6062
6273
|
</ng-template>
|
|
@@ -6067,7 +6278,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6067
6278
|
args: [{
|
|
6068
6279
|
selector: 'f-multiselect',
|
|
6069
6280
|
imports: [UiIconComponent, NgTemplateOutlet, ScrollerComponent],
|
|
6070
|
-
providers: [
|
|
6281
|
+
providers: [
|
|
6282
|
+
{
|
|
6283
|
+
provide: NG_VALUE_ACCESSOR,
|
|
6284
|
+
useExisting: forwardRef(() => MultiSelectComponent),
|
|
6285
|
+
multi: true,
|
|
6286
|
+
},
|
|
6287
|
+
],
|
|
6071
6288
|
host: {
|
|
6072
6289
|
'[class]': 'hostClass()',
|
|
6073
6290
|
'[style]': 'style()',
|
|
@@ -6094,20 +6311,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6094
6311
|
>
|
|
6095
6312
|
@if (selectedLabels().length) {
|
|
6096
6313
|
@if (display() === 'comma') {
|
|
6097
|
-
<span
|
|
6314
|
+
<span
|
|
6315
|
+
class="flex-1 min-w-0 truncate text-sm text-(--f-form-field-color)"
|
|
6316
|
+
>{{ commaLabel() }}</span
|
|
6317
|
+
>
|
|
6098
6318
|
} @else if (selectedLabels().length > maxSelectedLabels()) {
|
|
6099
|
-
<span
|
|
6319
|
+
<span
|
|
6320
|
+
class="flex-1 min-w-0 truncate text-sm text-(--f-form-field-color)"
|
|
6321
|
+
>{{ selectedLabels().length }} items selected</span
|
|
6322
|
+
>
|
|
6100
6323
|
} @else {
|
|
6101
6324
|
<div class="flex flex-wrap items-center gap-1 flex-1 min-w-0">
|
|
6102
6325
|
@for (opt of selectedOptions(); track getOptionValue(opt)) {
|
|
6103
|
-
<span
|
|
6326
|
+
<span
|
|
6327
|
+
class="inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded-md text-xs font-medium shrink-0"
|
|
6328
|
+
>
|
|
6104
6329
|
@if (selectedItemTpl()) {
|
|
6105
|
-
<ng-container
|
|
6330
|
+
<ng-container
|
|
6331
|
+
[ngTemplateOutlet]="selectedItemTpl()"
|
|
6332
|
+
[ngTemplateOutletContext]="{ $implicit: opt }"
|
|
6333
|
+
/>
|
|
6106
6334
|
} @else {
|
|
6107
6335
|
{{ getOptionLabel(opt) }}
|
|
6108
6336
|
}
|
|
6109
6337
|
@if (!disabled() && !readonly()) {
|
|
6110
|
-
<button
|
|
6338
|
+
<button
|
|
6339
|
+
type="button"
|
|
6340
|
+
aria-label="Remove"
|
|
6341
|
+
class="inline-flex items-center justify-center hover:opacity-70 cursor-pointer"
|
|
6342
|
+
(click)="removeOption($event, opt)"
|
|
6343
|
+
>
|
|
6111
6344
|
<ui-icon name="times" class="text-[10px]"></ui-icon>
|
|
6112
6345
|
</button>
|
|
6113
6346
|
}
|
|
@@ -6116,16 +6349,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6116
6349
|
</div>
|
|
6117
6350
|
}
|
|
6118
6351
|
} @else {
|
|
6119
|
-
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
6352
|
+
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
6353
|
+
placeholder()
|
|
6354
|
+
}}</span>
|
|
6120
6355
|
}
|
|
6121
6356
|
<span class="flex items-center gap-1 shrink-0 ml-auto">
|
|
6122
6357
|
@if (showClear() && values().length && !disabled() && !readonly()) {
|
|
6123
|
-
<ui-icon
|
|
6358
|
+
<ui-icon
|
|
6359
|
+
[name]="clearIcon()"
|
|
6360
|
+
class="text-xs text-(--f-form-field-placeholder-color) hover:text-(--f-text-color) shrink-0"
|
|
6361
|
+
(click)="clearAll($event)"
|
|
6362
|
+
></ui-icon>
|
|
6124
6363
|
}
|
|
6125
6364
|
@if (loading()) {
|
|
6126
|
-
<ui-icon
|
|
6365
|
+
<ui-icon
|
|
6366
|
+
[name]="loadingIcon()"
|
|
6367
|
+
[spin]="true"
|
|
6368
|
+
class="text-xs text-(--f-form-field-placeholder-color) shrink-0"
|
|
6369
|
+
></ui-icon>
|
|
6127
6370
|
} @else {
|
|
6128
|
-
<ui-icon
|
|
6371
|
+
<ui-icon
|
|
6372
|
+
[name]="dropdownIcon()"
|
|
6373
|
+
class="text-xs text-(--f-form-field-placeholder-color) transition-transform duration-[var(--f-transition-duration)] shrink-0"
|
|
6374
|
+
[class.rotate-180]="open()"
|
|
6375
|
+
></ui-icon>
|
|
6129
6376
|
}
|
|
6130
6377
|
</span>
|
|
6131
6378
|
</div>
|
|
@@ -6140,10 +6387,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6140
6387
|
@if (filter()) {
|
|
6141
6388
|
<div class="p-2 border-b border-(--f-content-border-color)">
|
|
6142
6389
|
@if (filterTpl()) {
|
|
6143
|
-
<ng-container
|
|
6390
|
+
<ng-container
|
|
6391
|
+
[ngTemplateOutlet]="filterTpl()"
|
|
6392
|
+
[ngTemplateOutletContext]="{
|
|
6393
|
+
$implicit: filterText(),
|
|
6394
|
+
filter: setFilterFn,
|
|
6395
|
+
}"
|
|
6396
|
+
/>
|
|
6144
6397
|
} @else {
|
|
6145
|
-
<div
|
|
6146
|
-
|
|
6398
|
+
<div
|
|
6399
|
+
class="flex items-center gap-2 px-2 py-1.5 bg-(--f-content-hover-background) rounded-lg border border-(--f-content-border-color)"
|
|
6400
|
+
>
|
|
6401
|
+
<ui-icon
|
|
6402
|
+
name="search"
|
|
6403
|
+
class="text-xs text-(--f-text-muted-color) shrink-0"
|
|
6404
|
+
></ui-icon>
|
|
6147
6405
|
<input
|
|
6148
6406
|
#filterInput
|
|
6149
6407
|
type="text"
|
|
@@ -6159,36 +6417,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6159
6417
|
</div>
|
|
6160
6418
|
}
|
|
6161
6419
|
@if (showToggleAll() && filteredOptions().length) {
|
|
6162
|
-
<button
|
|
6420
|
+
<button
|
|
6421
|
+
type="button"
|
|
6163
6422
|
class="w-full text-left px-3 py-2 text-sm flex items-center gap-2.5 border-b border-(--f-content-border-color) text-(--f-text-color) hover:bg-(--f-content-hover-background) transition-colors cursor-pointer"
|
|
6164
|
-
(click)="toggleAll($event)"
|
|
6165
|
-
|
|
6166
|
-
|
|
6423
|
+
(click)="toggleAll($event)"
|
|
6424
|
+
>
|
|
6425
|
+
<div
|
|
6426
|
+
class="w-4 h-4 rounded-sm border flex items-center justify-center shrink-0 transition-colors"
|
|
6427
|
+
[class]="
|
|
6428
|
+
allFilteredSelected()
|
|
6429
|
+
? 'bg-primary border-primary'
|
|
6430
|
+
: 'border-(--f-form-field-border-color) bg-(--f-form-field-background)'
|
|
6431
|
+
"
|
|
6432
|
+
>
|
|
6167
6433
|
@if (allFilteredSelected()) {
|
|
6168
|
-
<ui-icon
|
|
6434
|
+
<ui-icon
|
|
6435
|
+
name="check"
|
|
6436
|
+
class="text-[9px] text-primary-contrast"
|
|
6437
|
+
></ui-icon>
|
|
6169
6438
|
}
|
|
6170
6439
|
</div>
|
|
6171
6440
|
<span class="flex-1 truncate font-medium">Select All</span>
|
|
6172
6441
|
</button>
|
|
6173
6442
|
}
|
|
6174
|
-
<div
|
|
6443
|
+
<div
|
|
6444
|
+
data-multiselect-list
|
|
6445
|
+
[id]="listId()"
|
|
6446
|
+
role="listbox"
|
|
6447
|
+
[attr.aria-multiselectable]="true"
|
|
6448
|
+
class="max-h-56 overflow-auto py-1"
|
|
6449
|
+
>
|
|
6175
6450
|
@if (loading()) {
|
|
6176
6451
|
@if (loaderTpl()) {
|
|
6177
6452
|
<ng-container [ngTemplateOutlet]="loaderTpl()" />
|
|
6178
6453
|
} @else {
|
|
6179
6454
|
<div class="py-6 flex flex-col items-center gap-2">
|
|
6180
|
-
<ui-icon
|
|
6455
|
+
<ui-icon
|
|
6456
|
+
[name]="loadingIcon()"
|
|
6457
|
+
[spin]="true"
|
|
6458
|
+
class="text-xl text-(--f-text-muted-color)"
|
|
6459
|
+
></ui-icon>
|
|
6181
6460
|
</div>
|
|
6182
6461
|
}
|
|
6183
6462
|
} @else if (virtualScroll()) {
|
|
6184
|
-
<f-scroller
|
|
6463
|
+
<f-scroller
|
|
6464
|
+
[items]="flatItems()"
|
|
6465
|
+
[itemSize]="virtualScrollItemSize()"
|
|
6466
|
+
scrollHeight="14rem"
|
|
6467
|
+
>
|
|
6185
6468
|
<ng-template let-item let-i="index">
|
|
6186
|
-
<ng-container
|
|
6469
|
+
<ng-container
|
|
6470
|
+
[ngTemplateOutlet]="rowTpl"
|
|
6471
|
+
[ngTemplateOutletContext]="{ $implicit: item, index: i }"
|
|
6472
|
+
/>
|
|
6187
6473
|
</ng-template>
|
|
6188
6474
|
</f-scroller>
|
|
6189
6475
|
} @else {
|
|
6190
6476
|
@for (item of flatItems(); track $index) {
|
|
6191
|
-
<ng-container
|
|
6477
|
+
<ng-container
|
|
6478
|
+
[ngTemplateOutlet]="rowTpl"
|
|
6479
|
+
[ngTemplateOutletContext]="{ $implicit: item, index: $index }"
|
|
6480
|
+
/>
|
|
6192
6481
|
} @empty {
|
|
6193
6482
|
<ng-container [ngTemplateOutlet]="emptyStateTpl" />
|
|
6194
6483
|
}
|
|
@@ -6205,9 +6494,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6205
6494
|
|
|
6206
6495
|
<ng-template #rowTpl let-item let-i="index">
|
|
6207
6496
|
@if (item.kind === 'group') {
|
|
6208
|
-
<div
|
|
6497
|
+
<div
|
|
6498
|
+
class="h-full flex items-center px-3 py-1.5 text-xs font-semibold uppercase tracking-wide text-(--f-text-muted-color) bg-(--f-content-hover-background)"
|
|
6499
|
+
>
|
|
6209
6500
|
@if (groupTpl()) {
|
|
6210
|
-
<ng-container
|
|
6501
|
+
<ng-container
|
|
6502
|
+
[ngTemplateOutlet]="groupTpl()"
|
|
6503
|
+
[ngTemplateOutletContext]="{ $implicit: item.label }"
|
|
6504
|
+
/>
|
|
6211
6505
|
} @else {
|
|
6212
6506
|
{{ item.label }}
|
|
6213
6507
|
}
|
|
@@ -6224,15 +6518,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6224
6518
|
(click)="toggleOption($event, item.option)"
|
|
6225
6519
|
(mouseenter)="onOptionMouseEnter(item.option)"
|
|
6226
6520
|
>
|
|
6227
|
-
<div
|
|
6228
|
-
|
|
6521
|
+
<div
|
|
6522
|
+
class="w-4 h-4 rounded-sm border flex items-center justify-center shrink-0 transition-colors"
|
|
6523
|
+
[class]="
|
|
6524
|
+
isSelected(item.option)
|
|
6525
|
+
? 'bg-primary border-primary'
|
|
6526
|
+
: 'border-(--f-form-field-border-color) bg-(--f-form-field-background)'
|
|
6527
|
+
"
|
|
6528
|
+
>
|
|
6229
6529
|
@if (isSelected(item.option)) {
|
|
6230
|
-
<ui-icon
|
|
6530
|
+
<ui-icon
|
|
6531
|
+
name="check"
|
|
6532
|
+
class="text-[9px] text-primary-contrast"
|
|
6533
|
+
></ui-icon>
|
|
6231
6534
|
}
|
|
6232
6535
|
</div>
|
|
6233
6536
|
<span class="flex-1 truncate">
|
|
6234
6537
|
@if (itemTpl()) {
|
|
6235
|
-
<ng-container
|
|
6538
|
+
<ng-container
|
|
6539
|
+
[ngTemplateOutlet]="itemTpl()"
|
|
6540
|
+
[ngTemplateOutletContext]="{ $implicit: item.option }"
|
|
6541
|
+
/>
|
|
6236
6542
|
} @else {
|
|
6237
6543
|
{{ getOptionLabel(item.option) }}
|
|
6238
6544
|
}
|
|
@@ -6246,15 +6552,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
6246
6552
|
<ng-container [ngTemplateOutlet]="emptyFilterTpl()" />
|
|
6247
6553
|
} @else if (filterText()) {
|
|
6248
6554
|
<div class="py-6 flex flex-col items-center gap-2">
|
|
6249
|
-
<ui-icon
|
|
6250
|
-
|
|
6555
|
+
<ui-icon
|
|
6556
|
+
name="search"
|
|
6557
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
6558
|
+
></ui-icon>
|
|
6559
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
6560
|
+
emptyFilterMessage()
|
|
6561
|
+
}}</span>
|
|
6251
6562
|
</div>
|
|
6252
6563
|
} @else if (emptyTpl()) {
|
|
6253
6564
|
<ng-container [ngTemplateOutlet]="emptyTpl()" />
|
|
6254
6565
|
} @else {
|
|
6255
6566
|
<div class="py-6 flex flex-col items-center gap-2">
|
|
6256
|
-
<ui-icon
|
|
6257
|
-
|
|
6567
|
+
<ui-icon
|
|
6568
|
+
name="inbox"
|
|
6569
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
6570
|
+
></ui-icon>
|
|
6571
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
6572
|
+
emptyMessage()
|
|
6573
|
+
}}</span>
|
|
6258
6574
|
</div>
|
|
6259
6575
|
}
|
|
6260
6576
|
</ng-template>
|
|
@@ -8259,7 +8575,9 @@ class DialogComponent {
|
|
|
8259
8575
|
_maximized = signal(false, /* @ts-ignore */
|
|
8260
8576
|
...(ngDevMode ? [{ debugName: "_maximized" }] : /* istanbul ignore next */ []));
|
|
8261
8577
|
maximized = this._maximized.asReadonly();
|
|
8262
|
-
_windowWidth = signal(typeof window !== 'undefined'
|
|
8578
|
+
_windowWidth = signal(typeof window !== 'undefined'
|
|
8579
|
+
? window.innerWidth
|
|
8580
|
+
: Number.POSITIVE_INFINITY, /* @ts-ignore */
|
|
8263
8581
|
...(ngDevMode ? [{ debugName: "_windowWidth" }] : /* istanbul ignore next */ []));
|
|
8264
8582
|
breakpointWidth = computed(() => {
|
|
8265
8583
|
const bp = this.breakpoints();
|
|
@@ -8275,7 +8593,13 @@ class DialogComponent {
|
|
|
8275
8593
|
}, /* @ts-ignore */
|
|
8276
8594
|
...(ngDevMode ? [{ debugName: "breakpointWidth" }] : /* istanbul ignore next */ []));
|
|
8277
8595
|
panelStyle = computed(() => {
|
|
8278
|
-
const maximizedStyle = {
|
|
8596
|
+
const maximizedStyle = {
|
|
8597
|
+
width: '100vw',
|
|
8598
|
+
height: '100vh',
|
|
8599
|
+
maxWidth: '100vw',
|
|
8600
|
+
maxHeight: '100vh',
|
|
8601
|
+
margin: '0',
|
|
8602
|
+
};
|
|
8279
8603
|
if (this._maximized())
|
|
8280
8604
|
return maximizedStyle;
|
|
8281
8605
|
return {
|
|
@@ -8305,7 +8629,9 @@ class DialogComponent {
|
|
|
8305
8629
|
panelClass = computed(() => {
|
|
8306
8630
|
const max = this._maximized();
|
|
8307
8631
|
const base = 'dialog-panel relative bg-(--f-overlay-popover-background) shadow-2xl flex flex-col overflow-hidden pointer-events-auto';
|
|
8308
|
-
const shape = max
|
|
8632
|
+
const shape = max
|
|
8633
|
+
? 'inset-0 w-screen h-screen rounded-none'
|
|
8634
|
+
: 'rounded-2xl max-h-[90vh] max-w-[calc(100vw-2rem)]';
|
|
8309
8635
|
return `${base} ${shape} ${this.styleClass()}`.trim();
|
|
8310
8636
|
}, /* @ts-ignore */
|
|
8311
8637
|
...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
|
|
@@ -8321,14 +8647,14 @@ class DialogComponent {
|
|
|
8321
8647
|
resolvedHeader = computed(() => {
|
|
8322
8648
|
if (this.headerRef())
|
|
8323
8649
|
return this.headerRef() ?? null;
|
|
8324
|
-
const tpl = this.fTemplates().find(t => t.fTemplate() === 'header');
|
|
8650
|
+
const tpl = this.fTemplates().find((t) => t.fTemplate() === 'header');
|
|
8325
8651
|
return tpl?.templateRef ?? null;
|
|
8326
8652
|
}, /* @ts-ignore */
|
|
8327
8653
|
...(ngDevMode ? [{ debugName: "resolvedHeader" }] : /* istanbul ignore next */ []));
|
|
8328
8654
|
resolvedFooter = computed(() => {
|
|
8329
8655
|
if (this.footerRef())
|
|
8330
8656
|
return this.footerRef() ?? null;
|
|
8331
|
-
const tpl = this.fTemplates().find(t => t.fTemplate() === 'footer');
|
|
8657
|
+
const tpl = this.fTemplates().find((t) => t.fTemplate() === 'footer');
|
|
8332
8658
|
return tpl?.templateRef ?? null;
|
|
8333
8659
|
}, /* @ts-ignore */
|
|
8334
8660
|
...(ngDevMode ? [{ debugName: "resolvedFooter" }] : /* istanbul ignore next */ []));
|
|
@@ -8352,7 +8678,10 @@ class DialogComponent {
|
|
|
8352
8678
|
if (visible) {
|
|
8353
8679
|
this._closing.set(false);
|
|
8354
8680
|
this._rendered.set(true);
|
|
8355
|
-
this._previouslyFocused =
|
|
8681
|
+
this._previouslyFocused =
|
|
8682
|
+
typeof document !== 'undefined'
|
|
8683
|
+
? document.activeElement
|
|
8684
|
+
: null;
|
|
8356
8685
|
if (this.modal() || this.blockScroll())
|
|
8357
8686
|
this._doc.body.style.overflow = 'hidden';
|
|
8358
8687
|
this.onShow.emit();
|
|
@@ -8384,7 +8713,7 @@ class DialogComponent {
|
|
|
8384
8713
|
this.onHide.emit();
|
|
8385
8714
|
}
|
|
8386
8715
|
toggleMaximize() {
|
|
8387
|
-
this._maximized.update(v => !v);
|
|
8716
|
+
this._maximized.update((v) => !v);
|
|
8388
8717
|
if (this._maximized()) {
|
|
8389
8718
|
this._resizedSize.set(null);
|
|
8390
8719
|
this._dragPosition.set(null);
|
|
@@ -8440,11 +8769,21 @@ class DialogComponent {
|
|
|
8440
8769
|
const startY = event.clientY;
|
|
8441
8770
|
const startLeft = rect.left;
|
|
8442
8771
|
const startTop = rect.top;
|
|
8443
|
-
this._dragPosition.set({
|
|
8772
|
+
this._dragPosition.set({
|
|
8773
|
+
position: 'fixed',
|
|
8774
|
+
margin: '0',
|
|
8775
|
+
left: `${startLeft}px`,
|
|
8776
|
+
top: `${startTop}px`,
|
|
8777
|
+
});
|
|
8444
8778
|
const onMove = (e) => {
|
|
8445
8779
|
const left = Math.max(0, startLeft + (e.clientX - startX));
|
|
8446
8780
|
const top = Math.max(0, startTop + (e.clientY - startY));
|
|
8447
|
-
this._dragPosition.set({
|
|
8781
|
+
this._dragPosition.set({
|
|
8782
|
+
position: 'fixed',
|
|
8783
|
+
margin: '0',
|
|
8784
|
+
left: `${left}px`,
|
|
8785
|
+
top: `${top}px`,
|
|
8786
|
+
});
|
|
8448
8787
|
};
|
|
8449
8788
|
const onUp = () => {
|
|
8450
8789
|
document.removeEventListener('pointermove', onMove);
|
|
@@ -8480,7 +8819,11 @@ class DialogComponent {
|
|
|
8480
8819
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8481
8820
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: DialogComponent, isStandalone: true, selector: "f-dialog", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, dismissableMask: { classPropertyName: "dismissableMask", publicName: "dismissableMask", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, maximizable: { classPropertyName: "maximizable", publicName: "maximizable", isSignal: true, isRequired: false, transformFunction: null }, blockScroll: { classPropertyName: "blockScroll", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, returnFocusOnClose: { classPropertyName: "returnFocusOnClose", publicName: "returnFocusOnClose", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, breakpoints: { classPropertyName: "breakpoints", publicName: "breakpoints", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", onShow: "onShow", onHide: "onHide", onMaximize: "onMaximize" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, queries: [{ propertyName: "headerRef", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "footerRef", first: true, predicate: ["footer"], descendants: true, isSignal: true }, { propertyName: "fTemplates", predicate: FTemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
8482
8821
|
@if (rendered()) {
|
|
8483
|
-
<div
|
|
8822
|
+
<div
|
|
8823
|
+
class="fixed inset-0 z-999 flex p-4"
|
|
8824
|
+
[class]="containerPositionClass()"
|
|
8825
|
+
[class.pointer-events-none]="!modal()"
|
|
8826
|
+
>
|
|
8484
8827
|
@if (modal()) {
|
|
8485
8828
|
<div
|
|
8486
8829
|
class="dialog-backdrop absolute inset-0 bg-black/50 backdrop-blur-[2px]"
|
|
@@ -8500,7 +8843,10 @@ class DialogComponent {
|
|
|
8500
8843
|
(keydown.shift.tab)="onShiftTab($event)"
|
|
8501
8844
|
>
|
|
8502
8845
|
@if (resizable() && !maximized()) {
|
|
8503
|
-
<div
|
|
8846
|
+
<div
|
|
8847
|
+
class="dialog-resize-handle"
|
|
8848
|
+
(pointerdown)="onResizeStart($event)"
|
|
8849
|
+
></div>
|
|
8504
8850
|
}
|
|
8505
8851
|
@if (header() || resolvedHeader() || closable() || maximizable()) {
|
|
8506
8852
|
<div
|
|
@@ -8511,7 +8857,12 @@ class DialogComponent {
|
|
|
8511
8857
|
@if (resolvedHeader()) {
|
|
8512
8858
|
<ng-container [ngTemplateOutlet]="resolvedHeader()" />
|
|
8513
8859
|
} @else {
|
|
8514
|
-
<h2
|
|
8860
|
+
<h2
|
|
8861
|
+
[id]="headerId"
|
|
8862
|
+
class="text-base font-semibold text-(--f-text-color) tracking-tight"
|
|
8863
|
+
>
|
|
8864
|
+
{{ header() }}
|
|
8865
|
+
</h2>
|
|
8515
8866
|
}
|
|
8516
8867
|
<div class="flex items-center gap-1">
|
|
8517
8868
|
@if (maximizable()) {
|
|
@@ -8521,7 +8872,10 @@ class DialogComponent {
|
|
|
8521
8872
|
class="w-7 h-7 flex items-center justify-center rounded-lg cursor-pointer text-(--f-text-muted-color) hover:text-(--f-text-hover-color) hover:bg-(--f-content-hover-background) transition-all duration-[var(--f-transition-duration)] focus-visible:outline-none focus-visible:ring-focus"
|
|
8522
8873
|
(click)="toggleMaximize()"
|
|
8523
8874
|
>
|
|
8524
|
-
<ui-icon
|
|
8875
|
+
<ui-icon
|
|
8876
|
+
[name]="maximized() ? 'minimize-2' : 'window-maximize'"
|
|
8877
|
+
class="text-xs"
|
|
8878
|
+
></ui-icon>
|
|
8525
8879
|
</button>
|
|
8526
8880
|
}
|
|
8527
8881
|
@if (closable()) {
|
|
@@ -8541,7 +8895,9 @@ class DialogComponent {
|
|
|
8541
8895
|
<ng-content />
|
|
8542
8896
|
</div>
|
|
8543
8897
|
@if (resolvedFooter()) {
|
|
8544
|
-
<div
|
|
8898
|
+
<div
|
|
8899
|
+
class="px-6 py-4 border-t border-(--f-content-border-color) shrink-0 flex items-center justify-end gap-2 bg-(--f-content-hover-background)/50"
|
|
8900
|
+
>
|
|
8545
8901
|
<ng-container [ngTemplateOutlet]="resolvedFooter()" />
|
|
8546
8902
|
</div>
|
|
8547
8903
|
}
|
|
@@ -8554,7 +8910,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8554
8910
|
type: Component,
|
|
8555
8911
|
args: [{ selector: 'f-dialog', imports: [NgTemplateOutlet, UiIconComponent], host: { '(document:keydown.escape)': 'onEscape()' }, template: `
|
|
8556
8912
|
@if (rendered()) {
|
|
8557
|
-
<div
|
|
8913
|
+
<div
|
|
8914
|
+
class="fixed inset-0 z-999 flex p-4"
|
|
8915
|
+
[class]="containerPositionClass()"
|
|
8916
|
+
[class.pointer-events-none]="!modal()"
|
|
8917
|
+
>
|
|
8558
8918
|
@if (modal()) {
|
|
8559
8919
|
<div
|
|
8560
8920
|
class="dialog-backdrop absolute inset-0 bg-black/50 backdrop-blur-[2px]"
|
|
@@ -8574,7 +8934,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8574
8934
|
(keydown.shift.tab)="onShiftTab($event)"
|
|
8575
8935
|
>
|
|
8576
8936
|
@if (resizable() && !maximized()) {
|
|
8577
|
-
<div
|
|
8937
|
+
<div
|
|
8938
|
+
class="dialog-resize-handle"
|
|
8939
|
+
(pointerdown)="onResizeStart($event)"
|
|
8940
|
+
></div>
|
|
8578
8941
|
}
|
|
8579
8942
|
@if (header() || resolvedHeader() || closable() || maximizable()) {
|
|
8580
8943
|
<div
|
|
@@ -8585,7 +8948,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8585
8948
|
@if (resolvedHeader()) {
|
|
8586
8949
|
<ng-container [ngTemplateOutlet]="resolvedHeader()" />
|
|
8587
8950
|
} @else {
|
|
8588
|
-
<h2
|
|
8951
|
+
<h2
|
|
8952
|
+
[id]="headerId"
|
|
8953
|
+
class="text-base font-semibold text-(--f-text-color) tracking-tight"
|
|
8954
|
+
>
|
|
8955
|
+
{{ header() }}
|
|
8956
|
+
</h2>
|
|
8589
8957
|
}
|
|
8590
8958
|
<div class="flex items-center gap-1">
|
|
8591
8959
|
@if (maximizable()) {
|
|
@@ -8595,7 +8963,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8595
8963
|
class="w-7 h-7 flex items-center justify-center rounded-lg cursor-pointer text-(--f-text-muted-color) hover:text-(--f-text-hover-color) hover:bg-(--f-content-hover-background) transition-all duration-[var(--f-transition-duration)] focus-visible:outline-none focus-visible:ring-focus"
|
|
8596
8964
|
(click)="toggleMaximize()"
|
|
8597
8965
|
>
|
|
8598
|
-
<ui-icon
|
|
8966
|
+
<ui-icon
|
|
8967
|
+
[name]="maximized() ? 'minimize-2' : 'window-maximize'"
|
|
8968
|
+
class="text-xs"
|
|
8969
|
+
></ui-icon>
|
|
8599
8970
|
</button>
|
|
8600
8971
|
}
|
|
8601
8972
|
@if (closable()) {
|
|
@@ -8615,7 +8986,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8615
8986
|
<ng-content />
|
|
8616
8987
|
</div>
|
|
8617
8988
|
@if (resolvedFooter()) {
|
|
8618
|
-
<div
|
|
8989
|
+
<div
|
|
8990
|
+
class="px-6 py-4 border-t border-(--f-content-border-color) shrink-0 flex items-center justify-end gap-2 bg-(--f-content-hover-background)/50"
|
|
8991
|
+
>
|
|
8619
8992
|
<ng-container [ngTemplateOutlet]="resolvedFooter()" />
|
|
8620
8993
|
</div>
|
|
8621
8994
|
}
|
|
@@ -8661,21 +9034,21 @@ class DrawerComponent {
|
|
|
8661
9034
|
resolvedHeader = computed(() => {
|
|
8662
9035
|
if (this.headerRef())
|
|
8663
9036
|
return this.headerRef() ?? null;
|
|
8664
|
-
const tpl = this.fTemplates().find(t => t.fTemplate() === 'header');
|
|
9037
|
+
const tpl = this.fTemplates().find((t) => t.fTemplate() === 'header');
|
|
8665
9038
|
return tpl?.templateRef ?? null;
|
|
8666
9039
|
}, /* @ts-ignore */
|
|
8667
9040
|
...(ngDevMode ? [{ debugName: "resolvedHeader" }] : /* istanbul ignore next */ []));
|
|
8668
9041
|
resolvedFooter = computed(() => {
|
|
8669
9042
|
if (this.footerRef())
|
|
8670
9043
|
return this.footerRef() ?? null;
|
|
8671
|
-
const tpl = this.fTemplates().find(t => t.fTemplate() === 'footer');
|
|
9044
|
+
const tpl = this.fTemplates().find((t) => t.fTemplate() === 'footer');
|
|
8672
9045
|
return tpl?.templateRef ?? null;
|
|
8673
9046
|
}, /* @ts-ignore */
|
|
8674
9047
|
...(ngDevMode ? [{ debugName: "resolvedFooter" }] : /* istanbul ignore next */ []));
|
|
8675
9048
|
resolvedContent = computed(() => {
|
|
8676
9049
|
if (this.contentRef())
|
|
8677
9050
|
return this.contentRef() ?? null;
|
|
8678
|
-
const tpl = this.fTemplates().find(t => t.fTemplate() === 'content');
|
|
9051
|
+
const tpl = this.fTemplates().find((t) => t.fTemplate() === 'content');
|
|
8679
9052
|
return tpl?.templateRef ?? null;
|
|
8680
9053
|
}, /* @ts-ignore */
|
|
8681
9054
|
...(ngDevMode ? [{ debugName: "resolvedContent" }] : /* istanbul ignore next */ []));
|
|
@@ -8710,7 +9083,10 @@ class DrawerComponent {
|
|
|
8710
9083
|
if (this.visible()) {
|
|
8711
9084
|
this._closing.set(false);
|
|
8712
9085
|
this._rendered.set(true);
|
|
8713
|
-
this._previouslyFocused =
|
|
9086
|
+
this._previouslyFocused =
|
|
9087
|
+
typeof document !== 'undefined'
|
|
9088
|
+
? document.activeElement
|
|
9089
|
+
: null;
|
|
8714
9090
|
if (this.modal() && this.blockScroll())
|
|
8715
9091
|
this._doc.body.style.overflow = 'hidden';
|
|
8716
9092
|
this.onShow.emit();
|
|
@@ -8776,9 +9152,16 @@ class DrawerComponent {
|
|
|
8776
9152
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: DrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8777
9153
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: DrawerComponent, isStandalone: true, selector: "f-drawer", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, fullScreen: { classPropertyName: "fullScreen", publicName: "fullScreen", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, dismissable: { classPropertyName: "dismissable", publicName: "dismissable", isSignal: true, isRequired: false, transformFunction: null }, blockScroll: { classPropertyName: "blockScroll", publicName: "blockScroll", isSignal: true, isRequired: false, transformFunction: null }, returnFocusOnClose: { classPropertyName: "returnFocusOnClose", publicName: "returnFocusOnClose", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", onShow: "onShow", onHide: "onHide" }, host: { listeners: { "document:keydown.escape": "onEscape()" }, classAttribute: "block" }, queries: [{ propertyName: "headerRef", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "footerRef", first: true, predicate: ["footer"], descendants: true, isSignal: true }, { propertyName: "contentRef", first: true, predicate: ["content"], descendants: true, isSignal: true }, { propertyName: "fTemplates", predicate: FTemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
8778
9154
|
@if (rendered()) {
|
|
8779
|
-
<div
|
|
9155
|
+
<div
|
|
9156
|
+
class="fixed inset-0 z-999 flex"
|
|
9157
|
+
[class.pointer-events-none]="!modal()"
|
|
9158
|
+
>
|
|
8780
9159
|
@if (modal()) {
|
|
8781
|
-
<div
|
|
9160
|
+
<div
|
|
9161
|
+
class="drawer-backdrop absolute inset-0 bg-black/50 backdrop-blur-[2px]"
|
|
9162
|
+
[class.closing]="closing()"
|
|
9163
|
+
(click)="dismissable() && close()"
|
|
9164
|
+
></div>
|
|
8782
9165
|
}
|
|
8783
9166
|
<div
|
|
8784
9167
|
#panel
|
|
@@ -8791,11 +9174,18 @@ class DrawerComponent {
|
|
|
8791
9174
|
(keydown.tab)="onTab($event)"
|
|
8792
9175
|
(keydown.shift.tab)="onShiftTab($event)"
|
|
8793
9176
|
>
|
|
8794
|
-
<div
|
|
9177
|
+
<div
|
|
9178
|
+
class="flex items-center justify-between px-6 py-4 border-b border-(--f-content-border-color) shrink-0"
|
|
9179
|
+
>
|
|
8795
9180
|
@if (resolvedHeader()) {
|
|
8796
9181
|
<ng-container [ngTemplateOutlet]="resolvedHeader()" />
|
|
8797
9182
|
} @else {
|
|
8798
|
-
<h2
|
|
9183
|
+
<h2
|
|
9184
|
+
[id]="headerId"
|
|
9185
|
+
class="text-base font-semibold text-(--f-text-color) tracking-tight"
|
|
9186
|
+
>
|
|
9187
|
+
{{ header() }}
|
|
9188
|
+
</h2>
|
|
8799
9189
|
}
|
|
8800
9190
|
@if (closable()) {
|
|
8801
9191
|
<button
|
|
@@ -8815,7 +9205,9 @@ class DrawerComponent {
|
|
|
8815
9205
|
<ng-content />
|
|
8816
9206
|
</div>
|
|
8817
9207
|
@if (resolvedFooter()) {
|
|
8818
|
-
<div
|
|
9208
|
+
<div
|
|
9209
|
+
class="px-6 py-4 border-t border-(--f-content-border-color) shrink-0"
|
|
9210
|
+
>
|
|
8819
9211
|
<ng-container [ngTemplateOutlet]="resolvedFooter()" />
|
|
8820
9212
|
</div>
|
|
8821
9213
|
}
|
|
@@ -8828,9 +9220,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8828
9220
|
type: Component,
|
|
8829
9221
|
args: [{ selector: 'f-drawer', imports: [UiIconComponent, NgTemplateOutlet], host: { class: 'block', '(document:keydown.escape)': 'onEscape()' }, template: `
|
|
8830
9222
|
@if (rendered()) {
|
|
8831
|
-
<div
|
|
9223
|
+
<div
|
|
9224
|
+
class="fixed inset-0 z-999 flex"
|
|
9225
|
+
[class.pointer-events-none]="!modal()"
|
|
9226
|
+
>
|
|
8832
9227
|
@if (modal()) {
|
|
8833
|
-
<div
|
|
9228
|
+
<div
|
|
9229
|
+
class="drawer-backdrop absolute inset-0 bg-black/50 backdrop-blur-[2px]"
|
|
9230
|
+
[class.closing]="closing()"
|
|
9231
|
+
(click)="dismissable() && close()"
|
|
9232
|
+
></div>
|
|
8834
9233
|
}
|
|
8835
9234
|
<div
|
|
8836
9235
|
#panel
|
|
@@ -8843,11 +9242,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8843
9242
|
(keydown.tab)="onTab($event)"
|
|
8844
9243
|
(keydown.shift.tab)="onShiftTab($event)"
|
|
8845
9244
|
>
|
|
8846
|
-
<div
|
|
9245
|
+
<div
|
|
9246
|
+
class="flex items-center justify-between px-6 py-4 border-b border-(--f-content-border-color) shrink-0"
|
|
9247
|
+
>
|
|
8847
9248
|
@if (resolvedHeader()) {
|
|
8848
9249
|
<ng-container [ngTemplateOutlet]="resolvedHeader()" />
|
|
8849
9250
|
} @else {
|
|
8850
|
-
<h2
|
|
9251
|
+
<h2
|
|
9252
|
+
[id]="headerId"
|
|
9253
|
+
class="text-base font-semibold text-(--f-text-color) tracking-tight"
|
|
9254
|
+
>
|
|
9255
|
+
{{ header() }}
|
|
9256
|
+
</h2>
|
|
8851
9257
|
}
|
|
8852
9258
|
@if (closable()) {
|
|
8853
9259
|
<button
|
|
@@ -8867,7 +9273,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
8867
9273
|
<ng-content />
|
|
8868
9274
|
</div>
|
|
8869
9275
|
@if (resolvedFooter()) {
|
|
8870
|
-
<div
|
|
9276
|
+
<div
|
|
9277
|
+
class="px-6 py-4 border-t border-(--f-content-border-color) shrink-0"
|
|
9278
|
+
>
|
|
8871
9279
|
<ng-container [ngTemplateOutlet]="resolvedFooter()" />
|
|
8872
9280
|
</div>
|
|
8873
9281
|
}
|
|
@@ -9699,7 +10107,7 @@ class TabsComponent {
|
|
|
9699
10107
|
});
|
|
9700
10108
|
}
|
|
9701
10109
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9702
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: TabsComponent, isStandalone: true, selector: "f-tabs", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onTabChange: "onTabChange" }, host: { classAttribute: "block" }, providers: [TabsContext], ngImport: i0, template: `<div [class]="'flex flex-col ' + styleClass()" [style]="style()"><ng-content /></div>`, isInline: true });
|
|
10110
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: TabsComponent, isStandalone: true, selector: "f-tabs", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onTabChange: "onTabChange" }, host: { classAttribute: "block" }, providers: [TabsContext], ngImport: i0, template: `<div [class]="'flex flex-col h-full ' + styleClass()" [style]="style()"><ng-content /></div>`, isInline: true });
|
|
9703
10111
|
}
|
|
9704
10112
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsComponent, decorators: [{
|
|
9705
10113
|
type: Component,
|
|
@@ -9707,7 +10115,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
9707
10115
|
selector: 'f-tabs',
|
|
9708
10116
|
providers: [TabsContext],
|
|
9709
10117
|
host: { class: 'block' },
|
|
9710
|
-
template: `<div [class]="'flex flex-col ' + styleClass()" [style]="style()"><ng-content /></div>`,
|
|
10118
|
+
template: `<div [class]="'flex flex-col h-full ' + styleClass()" [style]="style()"><ng-content /></div>`,
|
|
9711
10119
|
}]
|
|
9712
10120
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], scrollable: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollable", required: false }] }], styleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleClass", required: false }] }], style: [{ type: i0.Input, args: [{ isSignal: true, alias: "style", required: false }] }], onTabChange: [{ type: i0.Output, args: ["onTabChange"] }] } });
|
|
9713
10121
|
// ─── TabList — wraps tab buttons, with optional scroll navigators ────────────
|
|
@@ -9957,14 +10365,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
9957
10365
|
// ─── TabPanels — wrapper around individual panels ─────────────────────────────
|
|
9958
10366
|
class TabPanelsComponent {
|
|
9959
10367
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9960
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: TabPanelsComponent, isStandalone: true, selector: "f-tabpanels", host: { classAttribute: "block" }, ngImport: i0, template: `<div class="pt-5"><ng-content /></div>`, isInline: true });
|
|
10368
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: TabPanelsComponent, isStandalone: true, selector: "f-tabpanels", host: { classAttribute: "block" }, ngImport: i0, template: `<div class="pt-5 h-full min-h-0"><ng-content /></div>`, isInline: true });
|
|
9961
10369
|
}
|
|
9962
10370
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelsComponent, decorators: [{
|
|
9963
10371
|
type: Component,
|
|
9964
10372
|
args: [{
|
|
9965
10373
|
selector: 'f-tabpanels',
|
|
9966
10374
|
host: { class: 'block' },
|
|
9967
|
-
template: `<div class="pt-5"><ng-content /></div>`,
|
|
10375
|
+
template: `<div class="pt-5 h-full min-h-0"><ng-content /></div>`,
|
|
9968
10376
|
}]
|
|
9969
10377
|
}] });
|
|
9970
10378
|
// ─── TabPanel — renders content only when active ──────────────────────────────
|
|
@@ -9982,7 +10390,7 @@ class TabPanelComponent {
|
|
|
9982
10390
|
panelId = computed(() => `f-tab-panel-${this.value()}`, /* @ts-ignore */
|
|
9983
10391
|
...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
|
|
9984
10392
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9985
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabPanelComponent, isStandalone: true, selector: "f-tabpanel", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tabpanel" }, properties: { "id": "panelId()", "attr.aria-labelledby": "triggerId()" }, classAttribute: "block" }, ngImport: i0, template: `@if (isActive()) { <ng-content /> }`, isInline: true });
|
|
10393
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabPanelComponent, isStandalone: true, selector: "f-tabpanel", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "tabpanel" }, properties: { "class.hidden": "!isActive()", "id": "panelId()", "attr.aria-labelledby": "triggerId()" }, classAttribute: "block" }, ngImport: i0, template: `@if (isActive()) { <ng-content /> }`, isInline: true });
|
|
9986
10394
|
}
|
|
9987
10395
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelComponent, decorators: [{
|
|
9988
10396
|
type: Component,
|
|
@@ -9991,6 +10399,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
9991
10399
|
host: {
|
|
9992
10400
|
class: 'block',
|
|
9993
10401
|
role: 'tabpanel',
|
|
10402
|
+
'[class.hidden]': '!isActive()',
|
|
9994
10403
|
'[id]': 'panelId()',
|
|
9995
10404
|
'[attr.aria-labelledby]': 'triggerId()',
|
|
9996
10405
|
},
|
|
@@ -15271,7 +15680,10 @@ function assignKey$2(node) {
|
|
|
15271
15680
|
class TreeSelectComponent {
|
|
15272
15681
|
_el = inject(ElementRef);
|
|
15273
15682
|
constructor() {
|
|
15274
|
-
repositionOnScroll(() => this.open() && this.appendTo() === 'body', () => {
|
|
15683
|
+
repositionOnScroll(() => this.open() && this.appendTo() === 'body', () => {
|
|
15684
|
+
this.position();
|
|
15685
|
+
this.adjustForViewport();
|
|
15686
|
+
});
|
|
15275
15687
|
}
|
|
15276
15688
|
options = input([], /* @ts-ignore */
|
|
15277
15689
|
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
@@ -15323,7 +15735,11 @@ class TreeSelectComponent {
|
|
|
15323
15735
|
panelStyle = computed(() => {
|
|
15324
15736
|
if (this.appendTo() !== 'body')
|
|
15325
15737
|
return {};
|
|
15326
|
-
return {
|
|
15738
|
+
return {
|
|
15739
|
+
top: `${this._panelTop()}px`,
|
|
15740
|
+
left: `${this._panelLeft()}px`,
|
|
15741
|
+
width: `${this._panelWidth()}px`,
|
|
15742
|
+
};
|
|
15327
15743
|
}, /* @ts-ignore */
|
|
15328
15744
|
...(ngDevMode ? [{ debugName: "panelStyle" }] : /* istanbul ignore next */ []));
|
|
15329
15745
|
position() {
|
|
@@ -15373,21 +15789,35 @@ class TreeSelectComponent {
|
|
|
15373
15789
|
...(ngDevMode ? [{ debugName: "emptyRef" }] : /* istanbul ignore next */ []));
|
|
15374
15790
|
fTemplates = contentChildren(FTemplateDirective, /* @ts-ignore */
|
|
15375
15791
|
...(ngDevMode ? [{ debugName: "fTemplates" }] : /* istanbul ignore next */ []));
|
|
15376
|
-
valueTpl = computed(() => this.valueRef() ??
|
|
15792
|
+
valueTpl = computed(() => this.valueRef() ??
|
|
15793
|
+
this.fTemplates().find((t) => t.fTemplate() === 'value')?.templateRef ??
|
|
15794
|
+
null, /* @ts-ignore */
|
|
15377
15795
|
...(ngDevMode ? [{ debugName: "valueTpl" }] : /* istanbul ignore next */ []));
|
|
15378
|
-
headerTpl = computed(() => this.headerRef() ??
|
|
15796
|
+
headerTpl = computed(() => this.headerRef() ??
|
|
15797
|
+
this.fTemplates().find((t) => t.fTemplate() === 'header')?.templateRef ??
|
|
15798
|
+
null, /* @ts-ignore */
|
|
15379
15799
|
...(ngDevMode ? [{ debugName: "headerTpl" }] : /* istanbul ignore next */ []));
|
|
15380
|
-
footerTpl = computed(() => this.footerRef() ??
|
|
15800
|
+
footerTpl = computed(() => this.footerRef() ??
|
|
15801
|
+
this.fTemplates().find((t) => t.fTemplate() === 'footer')?.templateRef ??
|
|
15802
|
+
null, /* @ts-ignore */
|
|
15381
15803
|
...(ngDevMode ? [{ debugName: "footerTpl" }] : /* istanbul ignore next */ []));
|
|
15382
|
-
emptyTpl = computed(() => this.emptyRef() ??
|
|
15804
|
+
emptyTpl = computed(() => this.emptyRef() ??
|
|
15805
|
+
this.fTemplates().find((t) => t.fTemplate() === 'empty')?.templateRef ??
|
|
15806
|
+
null, /* @ts-ignore */
|
|
15383
15807
|
...(ngDevMode ? [{ debugName: "emptyTpl" }] : /* istanbul ignore next */ []));
|
|
15384
15808
|
triggerClass = computed(() => {
|
|
15385
|
-
const base = 'w-full min-h-[
|
|
15809
|
+
const base = 'w-full min-h-[34px] flex items-center gap-2 px-3 py-1.5 text-sm rounded-lg border bg-(--f-form-field-background) focus:outline-none focus-visible:ring-focus transition-all duration-[var(--f-transition-duration)]';
|
|
15386
15810
|
const showInvalid = this.invalid() && this.touched();
|
|
15387
15811
|
const stateClass = this.open()
|
|
15388
|
-
?
|
|
15389
|
-
|
|
15390
|
-
|
|
15812
|
+
? showInvalid
|
|
15813
|
+
? 'border-red-400'
|
|
15814
|
+
: 'border-primary'
|
|
15815
|
+
: showInvalid
|
|
15816
|
+
? 'border-red-400'
|
|
15817
|
+
: 'border-(--f-form-field-border-color) hover:border-(--f-form-field-hover-border-color)';
|
|
15818
|
+
const disabledClass = this.disabled()
|
|
15819
|
+
? 'opacity-60 cursor-not-allowed'
|
|
15820
|
+
: 'cursor-pointer';
|
|
15391
15821
|
return `${base} ${stateClass} ${disabledClass}`;
|
|
15392
15822
|
}, /* @ts-ignore */
|
|
15393
15823
|
...(ngDevMode ? [{ debugName: "triggerClass" }] : /* istanbul ignore next */ []));
|
|
@@ -15418,10 +15848,15 @@ class TreeSelectComponent {
|
|
|
15418
15848
|
matchesFilter(node, query) {
|
|
15419
15849
|
if (!query)
|
|
15420
15850
|
return true;
|
|
15421
|
-
const fields = this.filterBy()
|
|
15851
|
+
const fields = this.filterBy()
|
|
15852
|
+
.split(',')
|
|
15853
|
+
.map((f) => f.trim())
|
|
15854
|
+
.filter(Boolean);
|
|
15422
15855
|
if (!fields.length)
|
|
15423
15856
|
fields.push('label');
|
|
15424
|
-
return fields.some((field) => String(node[field] ?? '')
|
|
15857
|
+
return fields.some((field) => String(node[field] ?? '')
|
|
15858
|
+
.toLowerCase()
|
|
15859
|
+
.includes(query));
|
|
15425
15860
|
}
|
|
15426
15861
|
_flatten(nodes, out, level, parentVisible, expanded, query, parent) {
|
|
15427
15862
|
let anyMatch = false;
|
|
@@ -15449,11 +15884,13 @@ class TreeSelectComponent {
|
|
|
15449
15884
|
this._onTouched();
|
|
15450
15885
|
}
|
|
15451
15886
|
}
|
|
15452
|
-
onFilterInput(v) {
|
|
15887
|
+
onFilterInput(v) {
|
|
15888
|
+
this._filterText.set(v);
|
|
15889
|
+
}
|
|
15453
15890
|
toggleOpen() {
|
|
15454
15891
|
if (this.disabled())
|
|
15455
15892
|
return;
|
|
15456
|
-
this._open.update(v => !v);
|
|
15893
|
+
this._open.update((v) => !v);
|
|
15457
15894
|
if (!this.open()) {
|
|
15458
15895
|
this._onTouched();
|
|
15459
15896
|
return;
|
|
@@ -15478,7 +15915,7 @@ class TreeSelectComponent {
|
|
|
15478
15915
|
}
|
|
15479
15916
|
toggleExpand(e, key) {
|
|
15480
15917
|
e.stopPropagation();
|
|
15481
|
-
this.expandedKeys.update(s => {
|
|
15918
|
+
this.expandedKeys.update((s) => {
|
|
15482
15919
|
const next = new Set(s);
|
|
15483
15920
|
next.has(key) ? next.delete(key) : next.add(key);
|
|
15484
15921
|
return next;
|
|
@@ -15522,7 +15959,7 @@ class TreeSelectComponent {
|
|
|
15522
15959
|
}
|
|
15523
15960
|
}
|
|
15524
15961
|
toggleMultiple(key) {
|
|
15525
|
-
this._selectedKeys.update(s => {
|
|
15962
|
+
this._selectedKeys.update((s) => {
|
|
15526
15963
|
const next = new Set(s);
|
|
15527
15964
|
next.has(key) ? next.delete(key) : next.add(key);
|
|
15528
15965
|
return next;
|
|
@@ -15608,11 +16045,21 @@ class TreeSelectComponent {
|
|
|
15608
16045
|
this._selectedKeys.set(new Set([v]));
|
|
15609
16046
|
}
|
|
15610
16047
|
}
|
|
15611
|
-
registerOnChange(fn) {
|
|
15612
|
-
|
|
16048
|
+
registerOnChange(fn) {
|
|
16049
|
+
this._onChange = fn;
|
|
16050
|
+
}
|
|
16051
|
+
registerOnTouched(fn) {
|
|
16052
|
+
this._onTouched = fn;
|
|
16053
|
+
}
|
|
15613
16054
|
setDisabledState() { }
|
|
15614
16055
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TreeSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
15615
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TreeSelectComponent, isStandalone: true, selector: "f-treeselect", inputs: { 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 }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, propagateSelectionDown: { classPropertyName: "propagateSelectionDown", publicName: "propagateSelectionDown", isSignal: true, isRequired: false, transformFunction: null }, propagateSelectionUp: { classPropertyName: "propagateSelectionUp", publicName: "propagateSelectionUp", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class": "hostClass()", "style": "style()" } }, providers: [
|
|
16056
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TreeSelectComponent, isStandalone: true, selector: "f-treeselect", inputs: { 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 }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, propagateSelectionDown: { classPropertyName: "propagateSelectionDown", publicName: "propagateSelectionDown", isSignal: true, isRequired: false, transformFunction: null }, propagateSelectionUp: { classPropertyName: "propagateSelectionUp", publicName: "propagateSelectionUp", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, appendTo: { classPropertyName: "appendTo", publicName: "appendTo", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class": "hostClass()", "style": "style()" } }, providers: [
|
|
16057
|
+
{
|
|
16058
|
+
provide: NG_VALUE_ACCESSOR,
|
|
16059
|
+
useExisting: forwardRef(() => TreeSelectComponent),
|
|
16060
|
+
multi: true,
|
|
16061
|
+
},
|
|
16062
|
+
], queries: [{ propertyName: "valueRef", first: true, predicate: ["value"], descendants: true, isSignal: true }, { propertyName: "headerRef", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "footerRef", first: true, predicate: ["footer"], descendants: true, isSignal: true }, { propertyName: "emptyRef", first: true, predicate: ["empty"], descendants: true, isSignal: true }, { propertyName: "fTemplates", predicate: FTemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
15616
16063
|
<div class="relative w-full">
|
|
15617
16064
|
<div
|
|
15618
16065
|
#trigger
|
|
@@ -15627,10 +16074,21 @@ class TreeSelectComponent {
|
|
|
15627
16074
|
>
|
|
15628
16075
|
@if (valueTpl()) {
|
|
15629
16076
|
<span class="flex-1 min-w-0 truncate text-left text-sm">
|
|
15630
|
-
<ng-container
|
|
16077
|
+
<ng-container
|
|
16078
|
+
[ngTemplateOutlet]="valueTpl()"
|
|
16079
|
+
[ngTemplateOutletContext]="{
|
|
16080
|
+
$implicit: selectedNodes(),
|
|
16081
|
+
placeholder: placeholder(),
|
|
16082
|
+
}"
|
|
16083
|
+
/>
|
|
15631
16084
|
</span>
|
|
15632
16085
|
} @else if (selectionMode() === 'single') {
|
|
15633
|
-
<span
|
|
16086
|
+
<span
|
|
16087
|
+
class="truncate text-sm"
|
|
16088
|
+
[class.text-(--f-form-field-placeholder-color)]="
|
|
16089
|
+
!selectedLabels().length
|
|
16090
|
+
"
|
|
16091
|
+
>
|
|
15634
16092
|
@if (selectedLabels().length) {
|
|
15635
16093
|
{{ selectedLabels()[0] }}
|
|
15636
16094
|
} @else {
|
|
@@ -15640,38 +16098,71 @@ class TreeSelectComponent {
|
|
|
15640
16098
|
} @else if (selectedLabels().length && display() === 'chip') {
|
|
15641
16099
|
<div class="flex flex-wrap items-center gap-1 flex-1 min-w-0">
|
|
15642
16100
|
@for (lbl of selectedLabels(); track $index) {
|
|
15643
|
-
<span
|
|
16101
|
+
<span
|
|
16102
|
+
class="inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded-md text-xs font-medium shrink-0"
|
|
16103
|
+
>
|
|
15644
16104
|
{{ lbl }}
|
|
15645
|
-
<button
|
|
16105
|
+
<button
|
|
16106
|
+
type="button"
|
|
16107
|
+
aria-label="Remove"
|
|
16108
|
+
class="inline-flex items-center justify-center hover:opacity-70 cursor-pointer"
|
|
16109
|
+
(click)="removeByKey($event, findKeyByLabel(lbl))"
|
|
16110
|
+
>
|
|
15646
16111
|
<ui-icon name="times" class="text-[10px]"></ui-icon>
|
|
15647
16112
|
</button>
|
|
15648
16113
|
</span>
|
|
15649
16114
|
}
|
|
15650
16115
|
</div>
|
|
15651
16116
|
} @else if (selectedLabels().length) {
|
|
15652
|
-
<span class="flex-1 min-w-0 truncate text-sm text-(--f-text-color)">{{
|
|
16117
|
+
<span class="flex-1 min-w-0 truncate text-sm text-(--f-text-color)">{{
|
|
16118
|
+
selectedLabels().join(', ')
|
|
16119
|
+
}}</span>
|
|
15653
16120
|
} @else {
|
|
15654
|
-
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
16121
|
+
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
16122
|
+
placeholder()
|
|
16123
|
+
}}</span>
|
|
15655
16124
|
}
|
|
15656
16125
|
<span class="ml-auto flex items-center gap-1 shrink-0">
|
|
15657
16126
|
@if (showClear() && selectedKeys().size && !disabled()) {
|
|
15658
|
-
<ui-icon
|
|
16127
|
+
<ui-icon
|
|
16128
|
+
name="x"
|
|
16129
|
+
class="text-xs text-(--f-form-field-placeholder-color) hover:text-(--f-text-color) shrink-0"
|
|
16130
|
+
(click)="clear($event)"
|
|
16131
|
+
></ui-icon>
|
|
15659
16132
|
}
|
|
15660
|
-
<ui-icon
|
|
16133
|
+
<ui-icon
|
|
16134
|
+
name="chevron-down"
|
|
16135
|
+
class="text-xs text-(--f-form-field-placeholder-color) shrink-0 transition-transform duration-[var(--f-transition-duration)]"
|
|
16136
|
+
[class.rotate-180]="open()"
|
|
16137
|
+
></ui-icon>
|
|
15661
16138
|
</span>
|
|
15662
16139
|
</div>
|
|
15663
16140
|
|
|
15664
16141
|
@if (open()) {
|
|
15665
16142
|
<div #panel [class]="panelClass()" [style]="panelStyle()">
|
|
15666
16143
|
@if (headerTpl()) {
|
|
15667
|
-
<ng-container
|
|
16144
|
+
<ng-container
|
|
16145
|
+
[ngTemplateOutlet]="headerTpl()"
|
|
16146
|
+
[ngTemplateOutletContext]="{ $implicit: options() }"
|
|
16147
|
+
/>
|
|
15668
16148
|
}
|
|
15669
16149
|
@if (filter()) {
|
|
15670
16150
|
<div class="p-2 border-b border-(--f-content-border-color)">
|
|
15671
|
-
<div
|
|
15672
|
-
|
|
15673
|
-
|
|
15674
|
-
|
|
16151
|
+
<div
|
|
16152
|
+
class="flex items-center gap-2 px-2 py-1.5 bg-(--f-content-hover-background) rounded-lg border border-(--f-content-border-color)"
|
|
16153
|
+
>
|
|
16154
|
+
<ui-icon
|
|
16155
|
+
name="search"
|
|
16156
|
+
class="text-xs text-(--f-text-muted-color) shrink-0"
|
|
16157
|
+
></ui-icon>
|
|
16158
|
+
<input
|
|
16159
|
+
type="text"
|
|
16160
|
+
class="flex-1 text-sm bg-transparent focus:outline-none text-(--f-text-color) placeholder:text-(--f-form-field-placeholder-color)"
|
|
16161
|
+
placeholder="Search..."
|
|
16162
|
+
[value]="filterText()"
|
|
16163
|
+
(input)="onFilterInput($any($event.target).value)"
|
|
16164
|
+
(click)="$event.stopPropagation()"
|
|
16165
|
+
/>
|
|
15675
16166
|
</div>
|
|
15676
16167
|
</div>
|
|
15677
16168
|
}
|
|
@@ -15681,26 +16172,45 @@ class TreeSelectComponent {
|
|
|
15681
16172
|
@if (emptyTpl()) {
|
|
15682
16173
|
<ng-container [ngTemplateOutlet]="emptyTpl()" />
|
|
15683
16174
|
} @else {
|
|
15684
|
-
<ui-icon
|
|
15685
|
-
|
|
16175
|
+
<ui-icon
|
|
16176
|
+
name="inbox"
|
|
16177
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
16178
|
+
></ui-icon>
|
|
16179
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
16180
|
+
emptyMessage()
|
|
16181
|
+
}}</span>
|
|
15686
16182
|
}
|
|
15687
16183
|
</div>
|
|
15688
16184
|
} @else if (virtualScroll()) {
|
|
15689
|
-
<f-scroller
|
|
16185
|
+
<f-scroller
|
|
16186
|
+
role="tree"
|
|
16187
|
+
[items]="visibleFlatNodes()"
|
|
16188
|
+
[itemSize]="virtualScrollItemSize()"
|
|
16189
|
+
scrollHeight="16rem"
|
|
16190
|
+
>
|
|
15690
16191
|
<ng-template let-row>
|
|
15691
|
-
<ng-container
|
|
16192
|
+
<ng-container
|
|
16193
|
+
[ngTemplateOutlet]="rowTpl"
|
|
16194
|
+
[ngTemplateOutletContext]="{ $implicit: row }"
|
|
16195
|
+
/>
|
|
15692
16196
|
</ng-template>
|
|
15693
16197
|
</f-scroller>
|
|
15694
16198
|
} @else {
|
|
15695
16199
|
<div class="max-h-64 overflow-auto py-1" role="tree">
|
|
15696
16200
|
@for (row of visibleFlatNodes(); track row.key) {
|
|
15697
|
-
<ng-container
|
|
16201
|
+
<ng-container
|
|
16202
|
+
[ngTemplateOutlet]="rowTpl"
|
|
16203
|
+
[ngTemplateOutletContext]="{ $implicit: row }"
|
|
16204
|
+
/>
|
|
15698
16205
|
}
|
|
15699
16206
|
</div>
|
|
15700
16207
|
}
|
|
15701
16208
|
|
|
15702
16209
|
@if (footerTpl()) {
|
|
15703
|
-
<ng-container
|
|
16210
|
+
<ng-container
|
|
16211
|
+
[ngTemplateOutlet]="footerTpl()"
|
|
16212
|
+
[ngTemplateOutletContext]="{ $implicit: options() }"
|
|
16213
|
+
/>
|
|
15704
16214
|
}
|
|
15705
16215
|
</div>
|
|
15706
16216
|
}
|
|
@@ -15710,7 +16220,11 @@ class TreeSelectComponent {
|
|
|
15710
16220
|
<div
|
|
15711
16221
|
class="w-full text-left px-2 py-1.5 text-sm flex items-center gap-1.5 transition-colors cursor-pointer"
|
|
15712
16222
|
[style.padding-left.px]="row.level * 16 + 8"
|
|
15713
|
-
[class]="
|
|
16223
|
+
[class]="
|
|
16224
|
+
isSelected(row.key) && selectionMode() !== 'checkbox'
|
|
16225
|
+
? 'bg-(--f-highlight-background) text-(--f-highlight-color)'
|
|
16226
|
+
: 'text-(--f-text-color) hover:bg-(--f-content-hover-background)'
|
|
16227
|
+
"
|
|
15714
16228
|
role="treeitem"
|
|
15715
16229
|
[attr.aria-level]="row.level + 1"
|
|
15716
16230
|
[attr.aria-expanded]="row.leaf ? null : isExpanded(row.key)"
|
|
@@ -15718,26 +16232,51 @@ class TreeSelectComponent {
|
|
|
15718
16232
|
(click)="onNodeClick($event, row)"
|
|
15719
16233
|
>
|
|
15720
16234
|
@if (!row.leaf) {
|
|
15721
|
-
<button
|
|
15722
|
-
|
|
16235
|
+
<button
|
|
16236
|
+
type="button"
|
|
16237
|
+
class="inline-flex items-center justify-center w-5 h-5 rounded-md hover:bg-(--f-content-hover-background) shrink-0 cursor-pointer"
|
|
16238
|
+
(click)="toggleExpand($event, row.key)"
|
|
16239
|
+
>
|
|
16240
|
+
<ui-icon
|
|
16241
|
+
name="chevron-right"
|
|
16242
|
+
class="text-[10px] transition-transform duration-150"
|
|
16243
|
+
[class.rotate-90]="isExpanded(row.key)"
|
|
16244
|
+
></ui-icon>
|
|
15723
16245
|
</button>
|
|
15724
16246
|
} @else {
|
|
15725
16247
|
<span class="inline-block w-5 h-5 shrink-0"></span>
|
|
15726
16248
|
}
|
|
15727
16249
|
|
|
15728
16250
|
@if (selectionMode() === 'checkbox') {
|
|
15729
|
-
<div
|
|
15730
|
-
|
|
16251
|
+
<div
|
|
16252
|
+
class="w-4 h-4 rounded-sm border flex items-center justify-center shrink-0 transition-colors"
|
|
16253
|
+
[class]="
|
|
16254
|
+
isSelected(row.key)
|
|
16255
|
+
? 'bg-primary border-primary'
|
|
16256
|
+
: isPartial(row.key)
|
|
16257
|
+
? 'bg-primary/30 border-primary'
|
|
16258
|
+
: 'border-(--f-form-field-border-color) bg-(--f-form-field-background)'
|
|
16259
|
+
"
|
|
16260
|
+
>
|
|
15731
16261
|
@if (isSelected(row.key)) {
|
|
15732
|
-
<ui-icon
|
|
16262
|
+
<ui-icon
|
|
16263
|
+
name="check"
|
|
16264
|
+
class="text-[9px] text-primary-contrast"
|
|
16265
|
+
></ui-icon>
|
|
15733
16266
|
} @else if (isPartial(row.key)) {
|
|
15734
|
-
<ui-icon
|
|
16267
|
+
<ui-icon
|
|
16268
|
+
name="minus"
|
|
16269
|
+
class="text-[9px] text-primary-contrast"
|
|
16270
|
+
></ui-icon>
|
|
15735
16271
|
}
|
|
15736
16272
|
</div>
|
|
15737
16273
|
}
|
|
15738
16274
|
|
|
15739
16275
|
@if (row.node.icon) {
|
|
15740
|
-
<ui-icon
|
|
16276
|
+
<ui-icon
|
|
16277
|
+
[name]="row.node.icon"
|
|
16278
|
+
class="text-xs text-(--f-text-muted-color) shrink-0"
|
|
16279
|
+
></ui-icon>
|
|
15741
16280
|
}
|
|
15742
16281
|
<span class="flex-1 truncate">{{ row.node.label }}</span>
|
|
15743
16282
|
</div>
|
|
@@ -15749,8 +16288,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
15749
16288
|
args: [{
|
|
15750
16289
|
selector: 'f-treeselect',
|
|
15751
16290
|
imports: [UiIconComponent, NgTemplateOutlet, ScrollerComponent],
|
|
15752
|
-
providers: [
|
|
15753
|
-
|
|
16291
|
+
providers: [
|
|
16292
|
+
{
|
|
16293
|
+
provide: NG_VALUE_ACCESSOR,
|
|
16294
|
+
useExisting: forwardRef(() => TreeSelectComponent),
|
|
16295
|
+
multi: true,
|
|
16296
|
+
},
|
|
16297
|
+
],
|
|
16298
|
+
host: {
|
|
16299
|
+
'[class]': 'hostClass()',
|
|
16300
|
+
'[style]': 'style()',
|
|
16301
|
+
'(document:click)': 'onDocumentClick($event)',
|
|
16302
|
+
},
|
|
15754
16303
|
template: `
|
|
15755
16304
|
<div class="relative w-full">
|
|
15756
16305
|
<div
|
|
@@ -15766,10 +16315,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
15766
16315
|
>
|
|
15767
16316
|
@if (valueTpl()) {
|
|
15768
16317
|
<span class="flex-1 min-w-0 truncate text-left text-sm">
|
|
15769
|
-
<ng-container
|
|
16318
|
+
<ng-container
|
|
16319
|
+
[ngTemplateOutlet]="valueTpl()"
|
|
16320
|
+
[ngTemplateOutletContext]="{
|
|
16321
|
+
$implicit: selectedNodes(),
|
|
16322
|
+
placeholder: placeholder(),
|
|
16323
|
+
}"
|
|
16324
|
+
/>
|
|
15770
16325
|
</span>
|
|
15771
16326
|
} @else if (selectionMode() === 'single') {
|
|
15772
|
-
<span
|
|
16327
|
+
<span
|
|
16328
|
+
class="truncate text-sm"
|
|
16329
|
+
[class.text-(--f-form-field-placeholder-color)]="
|
|
16330
|
+
!selectedLabels().length
|
|
16331
|
+
"
|
|
16332
|
+
>
|
|
15773
16333
|
@if (selectedLabels().length) {
|
|
15774
16334
|
{{ selectedLabels()[0] }}
|
|
15775
16335
|
} @else {
|
|
@@ -15779,38 +16339,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
15779
16339
|
} @else if (selectedLabels().length && display() === 'chip') {
|
|
15780
16340
|
<div class="flex flex-wrap items-center gap-1 flex-1 min-w-0">
|
|
15781
16341
|
@for (lbl of selectedLabels(); track $index) {
|
|
15782
|
-
<span
|
|
16342
|
+
<span
|
|
16343
|
+
class="inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded-md text-xs font-medium shrink-0"
|
|
16344
|
+
>
|
|
15783
16345
|
{{ lbl }}
|
|
15784
|
-
<button
|
|
16346
|
+
<button
|
|
16347
|
+
type="button"
|
|
16348
|
+
aria-label="Remove"
|
|
16349
|
+
class="inline-flex items-center justify-center hover:opacity-70 cursor-pointer"
|
|
16350
|
+
(click)="removeByKey($event, findKeyByLabel(lbl))"
|
|
16351
|
+
>
|
|
15785
16352
|
<ui-icon name="times" class="text-[10px]"></ui-icon>
|
|
15786
16353
|
</button>
|
|
15787
16354
|
</span>
|
|
15788
16355
|
}
|
|
15789
16356
|
</div>
|
|
15790
16357
|
} @else if (selectedLabels().length) {
|
|
15791
|
-
<span class="flex-1 min-w-0 truncate text-sm text-(--f-text-color)">{{
|
|
16358
|
+
<span class="flex-1 min-w-0 truncate text-sm text-(--f-text-color)">{{
|
|
16359
|
+
selectedLabels().join(', ')
|
|
16360
|
+
}}</span>
|
|
15792
16361
|
} @else {
|
|
15793
|
-
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
16362
|
+
<span class="text-(--f-form-field-placeholder-color) text-sm">{{
|
|
16363
|
+
placeholder()
|
|
16364
|
+
}}</span>
|
|
15794
16365
|
}
|
|
15795
16366
|
<span class="ml-auto flex items-center gap-1 shrink-0">
|
|
15796
16367
|
@if (showClear() && selectedKeys().size && !disabled()) {
|
|
15797
|
-
<ui-icon
|
|
16368
|
+
<ui-icon
|
|
16369
|
+
name="x"
|
|
16370
|
+
class="text-xs text-(--f-form-field-placeholder-color) hover:text-(--f-text-color) shrink-0"
|
|
16371
|
+
(click)="clear($event)"
|
|
16372
|
+
></ui-icon>
|
|
15798
16373
|
}
|
|
15799
|
-
<ui-icon
|
|
16374
|
+
<ui-icon
|
|
16375
|
+
name="chevron-down"
|
|
16376
|
+
class="text-xs text-(--f-form-field-placeholder-color) shrink-0 transition-transform duration-[var(--f-transition-duration)]"
|
|
16377
|
+
[class.rotate-180]="open()"
|
|
16378
|
+
></ui-icon>
|
|
15800
16379
|
</span>
|
|
15801
16380
|
</div>
|
|
15802
16381
|
|
|
15803
16382
|
@if (open()) {
|
|
15804
16383
|
<div #panel [class]="panelClass()" [style]="panelStyle()">
|
|
15805
16384
|
@if (headerTpl()) {
|
|
15806
|
-
<ng-container
|
|
16385
|
+
<ng-container
|
|
16386
|
+
[ngTemplateOutlet]="headerTpl()"
|
|
16387
|
+
[ngTemplateOutletContext]="{ $implicit: options() }"
|
|
16388
|
+
/>
|
|
15807
16389
|
}
|
|
15808
16390
|
@if (filter()) {
|
|
15809
16391
|
<div class="p-2 border-b border-(--f-content-border-color)">
|
|
15810
|
-
<div
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
16392
|
+
<div
|
|
16393
|
+
class="flex items-center gap-2 px-2 py-1.5 bg-(--f-content-hover-background) rounded-lg border border-(--f-content-border-color)"
|
|
16394
|
+
>
|
|
16395
|
+
<ui-icon
|
|
16396
|
+
name="search"
|
|
16397
|
+
class="text-xs text-(--f-text-muted-color) shrink-0"
|
|
16398
|
+
></ui-icon>
|
|
16399
|
+
<input
|
|
16400
|
+
type="text"
|
|
16401
|
+
class="flex-1 text-sm bg-transparent focus:outline-none text-(--f-text-color) placeholder:text-(--f-form-field-placeholder-color)"
|
|
16402
|
+
placeholder="Search..."
|
|
16403
|
+
[value]="filterText()"
|
|
16404
|
+
(input)="onFilterInput($any($event.target).value)"
|
|
16405
|
+
(click)="$event.stopPropagation()"
|
|
16406
|
+
/>
|
|
15814
16407
|
</div>
|
|
15815
16408
|
</div>
|
|
15816
16409
|
}
|
|
@@ -15820,26 +16413,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
15820
16413
|
@if (emptyTpl()) {
|
|
15821
16414
|
<ng-container [ngTemplateOutlet]="emptyTpl()" />
|
|
15822
16415
|
} @else {
|
|
15823
|
-
<ui-icon
|
|
15824
|
-
|
|
16416
|
+
<ui-icon
|
|
16417
|
+
name="inbox"
|
|
16418
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
16419
|
+
></ui-icon>
|
|
16420
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
16421
|
+
emptyMessage()
|
|
16422
|
+
}}</span>
|
|
15825
16423
|
}
|
|
15826
16424
|
</div>
|
|
15827
16425
|
} @else if (virtualScroll()) {
|
|
15828
|
-
<f-scroller
|
|
16426
|
+
<f-scroller
|
|
16427
|
+
role="tree"
|
|
16428
|
+
[items]="visibleFlatNodes()"
|
|
16429
|
+
[itemSize]="virtualScrollItemSize()"
|
|
16430
|
+
scrollHeight="16rem"
|
|
16431
|
+
>
|
|
15829
16432
|
<ng-template let-row>
|
|
15830
|
-
<ng-container
|
|
16433
|
+
<ng-container
|
|
16434
|
+
[ngTemplateOutlet]="rowTpl"
|
|
16435
|
+
[ngTemplateOutletContext]="{ $implicit: row }"
|
|
16436
|
+
/>
|
|
15831
16437
|
</ng-template>
|
|
15832
16438
|
</f-scroller>
|
|
15833
16439
|
} @else {
|
|
15834
16440
|
<div class="max-h-64 overflow-auto py-1" role="tree">
|
|
15835
16441
|
@for (row of visibleFlatNodes(); track row.key) {
|
|
15836
|
-
<ng-container
|
|
16442
|
+
<ng-container
|
|
16443
|
+
[ngTemplateOutlet]="rowTpl"
|
|
16444
|
+
[ngTemplateOutletContext]="{ $implicit: row }"
|
|
16445
|
+
/>
|
|
15837
16446
|
}
|
|
15838
16447
|
</div>
|
|
15839
16448
|
}
|
|
15840
16449
|
|
|
15841
16450
|
@if (footerTpl()) {
|
|
15842
|
-
<ng-container
|
|
16451
|
+
<ng-container
|
|
16452
|
+
[ngTemplateOutlet]="footerTpl()"
|
|
16453
|
+
[ngTemplateOutletContext]="{ $implicit: options() }"
|
|
16454
|
+
/>
|
|
15843
16455
|
}
|
|
15844
16456
|
</div>
|
|
15845
16457
|
}
|
|
@@ -15849,7 +16461,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
15849
16461
|
<div
|
|
15850
16462
|
class="w-full text-left px-2 py-1.5 text-sm flex items-center gap-1.5 transition-colors cursor-pointer"
|
|
15851
16463
|
[style.padding-left.px]="row.level * 16 + 8"
|
|
15852
|
-
[class]="
|
|
16464
|
+
[class]="
|
|
16465
|
+
isSelected(row.key) && selectionMode() !== 'checkbox'
|
|
16466
|
+
? 'bg-(--f-highlight-background) text-(--f-highlight-color)'
|
|
16467
|
+
: 'text-(--f-text-color) hover:bg-(--f-content-hover-background)'
|
|
16468
|
+
"
|
|
15853
16469
|
role="treeitem"
|
|
15854
16470
|
[attr.aria-level]="row.level + 1"
|
|
15855
16471
|
[attr.aria-expanded]="row.leaf ? null : isExpanded(row.key)"
|
|
@@ -15857,26 +16473,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
15857
16473
|
(click)="onNodeClick($event, row)"
|
|
15858
16474
|
>
|
|
15859
16475
|
@if (!row.leaf) {
|
|
15860
|
-
<button
|
|
15861
|
-
|
|
16476
|
+
<button
|
|
16477
|
+
type="button"
|
|
16478
|
+
class="inline-flex items-center justify-center w-5 h-5 rounded-md hover:bg-(--f-content-hover-background) shrink-0 cursor-pointer"
|
|
16479
|
+
(click)="toggleExpand($event, row.key)"
|
|
16480
|
+
>
|
|
16481
|
+
<ui-icon
|
|
16482
|
+
name="chevron-right"
|
|
16483
|
+
class="text-[10px] transition-transform duration-150"
|
|
16484
|
+
[class.rotate-90]="isExpanded(row.key)"
|
|
16485
|
+
></ui-icon>
|
|
15862
16486
|
</button>
|
|
15863
16487
|
} @else {
|
|
15864
16488
|
<span class="inline-block w-5 h-5 shrink-0"></span>
|
|
15865
16489
|
}
|
|
15866
16490
|
|
|
15867
16491
|
@if (selectionMode() === 'checkbox') {
|
|
15868
|
-
<div
|
|
15869
|
-
|
|
16492
|
+
<div
|
|
16493
|
+
class="w-4 h-4 rounded-sm border flex items-center justify-center shrink-0 transition-colors"
|
|
16494
|
+
[class]="
|
|
16495
|
+
isSelected(row.key)
|
|
16496
|
+
? 'bg-primary border-primary'
|
|
16497
|
+
: isPartial(row.key)
|
|
16498
|
+
? 'bg-primary/30 border-primary'
|
|
16499
|
+
: 'border-(--f-form-field-border-color) bg-(--f-form-field-background)'
|
|
16500
|
+
"
|
|
16501
|
+
>
|
|
15870
16502
|
@if (isSelected(row.key)) {
|
|
15871
|
-
<ui-icon
|
|
16503
|
+
<ui-icon
|
|
16504
|
+
name="check"
|
|
16505
|
+
class="text-[9px] text-primary-contrast"
|
|
16506
|
+
></ui-icon>
|
|
15872
16507
|
} @else if (isPartial(row.key)) {
|
|
15873
|
-
<ui-icon
|
|
16508
|
+
<ui-icon
|
|
16509
|
+
name="minus"
|
|
16510
|
+
class="text-[9px] text-primary-contrast"
|
|
16511
|
+
></ui-icon>
|
|
15874
16512
|
}
|
|
15875
16513
|
</div>
|
|
15876
16514
|
}
|
|
15877
16515
|
|
|
15878
16516
|
@if (row.node.icon) {
|
|
15879
|
-
<ui-icon
|
|
16517
|
+
<ui-icon
|
|
16518
|
+
[name]="row.node.icon"
|
|
16519
|
+
class="text-xs text-(--f-text-muted-color) shrink-0"
|
|
16520
|
+
></ui-icon>
|
|
15880
16521
|
}
|
|
15881
16522
|
<span class="flex-1 truncate">{{ row.node.label }}</span>
|
|
15882
16523
|
</div>
|
|
@@ -19369,7 +20010,9 @@ class SpeedDialComponent {
|
|
|
19369
20010
|
}, /* @ts-ignore */
|
|
19370
20011
|
...(ngDevMode ? [{ debugName: "buttonIcon" }] : /* istanbul ignore next */ []));
|
|
19371
20012
|
onDocumentClick(e) {
|
|
19372
|
-
if (this.visible() &&
|
|
20013
|
+
if (this.visible() &&
|
|
20014
|
+
this.hideOnClickOutside() &&
|
|
20015
|
+
!this._el.nativeElement.contains(e.target)) {
|
|
19373
20016
|
this.hide();
|
|
19374
20017
|
}
|
|
19375
20018
|
}
|
|
@@ -19415,7 +20058,8 @@ class SpeedDialComponent {
|
|
|
19415
20058
|
}
|
|
19416
20059
|
const rad = (deg * Math.PI) / 180;
|
|
19417
20060
|
style['position'] = 'absolute';
|
|
19418
|
-
style['transform'] =
|
|
20061
|
+
style['transform'] =
|
|
20062
|
+
`translate(${Math.cos(rad) * r}px, ${Math.sin(rad) * r}px)`;
|
|
19419
20063
|
return style;
|
|
19420
20064
|
}
|
|
19421
20065
|
show() {
|
|
@@ -19449,7 +20093,11 @@ class SpeedDialComponent {
|
|
|
19449
20093
|
}
|
|
19450
20094
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: SpeedDialComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19451
20095
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: SpeedDialComponent, isStandalone: true, selector: "f-speeddial", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, showIcon: { classPropertyName: "showIcon", publicName: "showIcon", isSignal: true, isRequired: false, transformFunction: null }, hideIcon: { classPropertyName: "hideIcon", publicName: "hideIcon", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, rotateAnimation: { classPropertyName: "rotateAnimation", publicName: "rotateAnimation", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, transitionDelay: { classPropertyName: "transitionDelay", publicName: "transitionDelay", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hideOnClickOutside: { classPropertyName: "hideOnClickOutside", publicName: "hideOnClickOutside", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, styleClass: { classPropertyName: "styleClass", publicName: "styleClass", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", onClick: "onClick", onShow: "onShow", onHide: "onHide", onVisibleChange: "onVisibleChange" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscapeKey()" }, properties: { "class": "hostClass()", "style": "style()" } }, viewQueries: [{ propertyName: "_toggleBtn", first: true, predicate: ["toggleButton"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
19452
|
-
<div
|
|
20096
|
+
<div
|
|
20097
|
+
[class]="containerClass()"
|
|
20098
|
+
[class.opacity-60]="disabled()"
|
|
20099
|
+
[class.pointer-events-none]="disabled()"
|
|
20100
|
+
>
|
|
19453
20101
|
<div class="contents" role="menu" [attr.aria-label]="ariaLabel() || null">
|
|
19454
20102
|
@if (visible()) {
|
|
19455
20103
|
@for (item of model(); track $index) {
|
|
@@ -19486,7 +20134,10 @@ class SpeedDialComponent {
|
|
|
19486
20134
|
</button>
|
|
19487
20135
|
</div>
|
|
19488
20136
|
@if (mask() && visible()) {
|
|
19489
|
-
<div
|
|
20137
|
+
<div
|
|
20138
|
+
class="fixed inset-0 z-999 bg-(--f-mask-background)"
|
|
20139
|
+
(click)="hide()"
|
|
20140
|
+
></div>
|
|
19490
20141
|
}
|
|
19491
20142
|
`, isInline: true, dependencies: [{ kind: "component", type: UiIconComponent, selector: "ui-icon", inputs: ["name", "size", "spin", "fill", "severity"] }] });
|
|
19492
20143
|
}
|
|
@@ -19502,7 +20153,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
19502
20153
|
'(document:keydown.escape)': 'onEscapeKey()',
|
|
19503
20154
|
},
|
|
19504
20155
|
template: `
|
|
19505
|
-
<div
|
|
20156
|
+
<div
|
|
20157
|
+
[class]="containerClass()"
|
|
20158
|
+
[class.opacity-60]="disabled()"
|
|
20159
|
+
[class.pointer-events-none]="disabled()"
|
|
20160
|
+
>
|
|
19506
20161
|
<div class="contents" role="menu" [attr.aria-label]="ariaLabel() || null">
|
|
19507
20162
|
@if (visible()) {
|
|
19508
20163
|
@for (item of model(); track $index) {
|
|
@@ -19539,7 +20194,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
19539
20194
|
</button>
|
|
19540
20195
|
</div>
|
|
19541
20196
|
@if (mask() && visible()) {
|
|
19542
|
-
<div
|
|
20197
|
+
<div
|
|
20198
|
+
class="fixed inset-0 z-999 bg-(--f-mask-background)"
|
|
20199
|
+
(click)="hide()"
|
|
20200
|
+
></div>
|
|
19543
20201
|
}
|
|
19544
20202
|
`,
|
|
19545
20203
|
}]
|
|
@@ -20517,7 +21175,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
20517
21175
|
class CascadeSelectComponent {
|
|
20518
21176
|
_el = inject(ElementRef);
|
|
20519
21177
|
constructor() {
|
|
20520
|
-
repositionOnScroll(() => this.open() && this.appendTo() === 'body', () => {
|
|
21178
|
+
repositionOnScroll(() => this.open() && this.appendTo() === 'body', () => {
|
|
21179
|
+
this.position();
|
|
21180
|
+
this.adjustForViewport();
|
|
21181
|
+
});
|
|
20521
21182
|
}
|
|
20522
21183
|
options = input([], /* @ts-ignore */
|
|
20523
21184
|
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
@@ -20619,16 +21280,24 @@ class CascadeSelectComponent {
|
|
|
20619
21280
|
...(ngDevMode ? [{ debugName: "emptyRef" }] : /* istanbul ignore next */ []));
|
|
20620
21281
|
fTemplates = contentChildren(FTemplateDirective, /* @ts-ignore */
|
|
20621
21282
|
...(ngDevMode ? [{ debugName: "fTemplates" }] : /* istanbul ignore next */ []));
|
|
20622
|
-
valueTpl = computed(() => this.valueRef() ??
|
|
21283
|
+
valueTpl = computed(() => this.valueRef() ??
|
|
21284
|
+
this.fTemplates().find((t) => t.fTemplate() === 'value')?.templateRef ??
|
|
21285
|
+
null, /* @ts-ignore */
|
|
20623
21286
|
...(ngDevMode ? [{ debugName: "valueTpl" }] : /* istanbul ignore next */ []));
|
|
20624
|
-
optionTpl = computed(() => this.optionRef() ??
|
|
21287
|
+
optionTpl = computed(() => this.optionRef() ??
|
|
21288
|
+
this.fTemplates().find((t) => t.fTemplate() === 'option')?.templateRef ??
|
|
21289
|
+
null, /* @ts-ignore */
|
|
20625
21290
|
...(ngDevMode ? [{ debugName: "optionTpl" }] : /* istanbul ignore next */ []));
|
|
20626
|
-
groupTpl = computed(() => this.groupRef() ??
|
|
21291
|
+
groupTpl = computed(() => this.groupRef() ??
|
|
21292
|
+
this.fTemplates().find((t) => t.fTemplate() === 'group')?.templateRef ??
|
|
21293
|
+
null, /* @ts-ignore */
|
|
20627
21294
|
...(ngDevMode ? [{ debugName: "groupTpl" }] : /* istanbul ignore next */ []));
|
|
20628
|
-
emptyTpl = computed(() => this.emptyRef() ??
|
|
21295
|
+
emptyTpl = computed(() => this.emptyRef() ??
|
|
21296
|
+
this.fTemplates().find((t) => t.fTemplate() === 'empty')?.templateRef ??
|
|
21297
|
+
null, /* @ts-ignore */
|
|
20629
21298
|
...(ngDevMode ? [{ debugName: "emptyTpl" }] : /* istanbul ignore next */ []));
|
|
20630
21299
|
triggerClass = computed(() => {
|
|
20631
|
-
const base = 'w-full min-h-[
|
|
21300
|
+
const base = 'w-full min-h-[34px] flex items-center gap-2 px-3 py-1.5 text-sm rounded-lg border bg-(--f-form-field-background) focus:outline-none focus-visible:ring-focus transition-all duration-[var(--f-transition-duration)]';
|
|
20632
21301
|
const showInvalid = this.invalid() && this.touched();
|
|
20633
21302
|
const stateClass = this.open()
|
|
20634
21303
|
? showInvalid
|
|
@@ -20780,7 +21449,10 @@ class CascadeSelectComponent {
|
|
|
20780
21449
|
if (!children.length)
|
|
20781
21450
|
return;
|
|
20782
21451
|
this.openGroup(opt, level);
|
|
20783
|
-
this._focusedPath.set([
|
|
21452
|
+
this._focusedPath.set([
|
|
21453
|
+
...this._focusedPath().slice(0, level + 1),
|
|
21454
|
+
children[0],
|
|
21455
|
+
]);
|
|
20784
21456
|
}
|
|
20785
21457
|
drillOut() {
|
|
20786
21458
|
const level = this._focusedPath().length - 1;
|
|
@@ -20860,12 +21532,20 @@ class CascadeSelectComponent {
|
|
|
20860
21532
|
>
|
|
20861
21533
|
@if (valueTpl()) {
|
|
20862
21534
|
<span class="flex-1 min-w-0 truncate text-left text-sm">
|
|
20863
|
-
<ng-container
|
|
21535
|
+
<ng-container
|
|
21536
|
+
[ngTemplateOutlet]="valueTpl()"
|
|
21537
|
+
[ngTemplateOutletContext]="{
|
|
21538
|
+
$implicit: value(),
|
|
21539
|
+
placeholder: placeholder(),
|
|
21540
|
+
}"
|
|
21541
|
+
/>
|
|
20864
21542
|
</span>
|
|
20865
21543
|
} @else {
|
|
20866
21544
|
<span
|
|
20867
21545
|
class="flex-1 min-w-0 truncate text-left text-sm"
|
|
20868
|
-
[class.text-(--f-form-field-placeholder-color)]="
|
|
21546
|
+
[class.text-(--f-form-field-placeholder-color)]="
|
|
21547
|
+
!selectedPath().length
|
|
21548
|
+
"
|
|
20869
21549
|
>
|
|
20870
21550
|
{{
|
|
20871
21551
|
selectedPath().length ? selectedPath().join(' / ') : placeholder()
|
|
@@ -20873,11 +21553,21 @@ class CascadeSelectComponent {
|
|
|
20873
21553
|
</span>
|
|
20874
21554
|
}
|
|
20875
21555
|
<span class="flex items-center gap-1 shrink-0">
|
|
20876
|
-
@if (
|
|
20877
|
-
|
|
21556
|
+
@if (
|
|
21557
|
+
showClear() && selectedPath().length && !disabled() && !loading()
|
|
21558
|
+
) {
|
|
21559
|
+
<ui-icon
|
|
21560
|
+
name="x"
|
|
21561
|
+
class="text-xs text-(--f-form-field-placeholder-color) hover:text-(--f-text-color) shrink-0"
|
|
21562
|
+
(click)="clear($event)"
|
|
21563
|
+
></ui-icon>
|
|
20878
21564
|
}
|
|
20879
21565
|
@if (loading()) {
|
|
20880
|
-
<ui-icon
|
|
21566
|
+
<ui-icon
|
|
21567
|
+
name="loader-circle"
|
|
21568
|
+
[spin]="true"
|
|
21569
|
+
class="text-xs text-(--f-form-field-placeholder-color) shrink-0"
|
|
21570
|
+
></ui-icon>
|
|
20881
21571
|
} @else {
|
|
20882
21572
|
<ui-icon
|
|
20883
21573
|
[name]="dropdownIcon()"
|
|
@@ -20889,12 +21579,7 @@ class CascadeSelectComponent {
|
|
|
20889
21579
|
</button>
|
|
20890
21580
|
|
|
20891
21581
|
@if (open()) {
|
|
20892
|
-
<div
|
|
20893
|
-
#panel
|
|
20894
|
-
[class]="panelClass()"
|
|
20895
|
-
[style]="panelStyle()"
|
|
20896
|
-
role="tree"
|
|
20897
|
-
>
|
|
21582
|
+
<div #panel [class]="panelClass()" [style]="panelStyle()" role="tree">
|
|
20898
21583
|
@if (levels()[0].length) {
|
|
20899
21584
|
@for (level of levels(); track $index) {
|
|
20900
21585
|
<ul
|
|
@@ -20905,8 +21590,16 @@ class CascadeSelectComponent {
|
|
|
20905
21590
|
<li
|
|
20906
21591
|
role="treeitem"
|
|
20907
21592
|
[attr.aria-level]="$index + 1"
|
|
20908
|
-
[attr.aria-expanded]="
|
|
20909
|
-
|
|
21593
|
+
[attr.aria-expanded]="
|
|
21594
|
+
getChildren(opt, $index).length
|
|
21595
|
+
? isActive(opt, $index)
|
|
21596
|
+
: null
|
|
21597
|
+
"
|
|
21598
|
+
[attr.aria-selected]="
|
|
21599
|
+
getChildren(opt, $index).length
|
|
21600
|
+
? null
|
|
21601
|
+
: isSelectedOption(opt)
|
|
21602
|
+
"
|
|
20910
21603
|
>
|
|
20911
21604
|
<button
|
|
20912
21605
|
type="button"
|
|
@@ -20921,9 +21614,21 @@ class CascadeSelectComponent {
|
|
|
20921
21614
|
>
|
|
20922
21615
|
<span class="truncate">
|
|
20923
21616
|
@if (getChildren(opt, $index).length && groupTpl()) {
|
|
20924
|
-
<ng-container
|
|
21617
|
+
<ng-container
|
|
21618
|
+
[ngTemplateOutlet]="groupTpl()"
|
|
21619
|
+
[ngTemplateOutletContext]="{
|
|
21620
|
+
$implicit: opt,
|
|
21621
|
+
level: $index,
|
|
21622
|
+
}"
|
|
21623
|
+
/>
|
|
20925
21624
|
} @else if (optionTpl()) {
|
|
20926
|
-
<ng-container
|
|
21625
|
+
<ng-container
|
|
21626
|
+
[ngTemplateOutlet]="optionTpl()"
|
|
21627
|
+
[ngTemplateOutletContext]="{
|
|
21628
|
+
$implicit: opt,
|
|
21629
|
+
level: $index,
|
|
21630
|
+
}"
|
|
21631
|
+
/>
|
|
20927
21632
|
} @else {
|
|
20928
21633
|
{{ getLabel(opt) }}
|
|
20929
21634
|
}
|
|
@@ -20945,8 +21650,13 @@ class CascadeSelectComponent {
|
|
|
20945
21650
|
<ng-container [ngTemplateOutlet]="emptyTpl()" />
|
|
20946
21651
|
} @else {
|
|
20947
21652
|
<div class="py-6 px-4 flex flex-col items-center gap-2">
|
|
20948
|
-
<ui-icon
|
|
20949
|
-
|
|
21653
|
+
<ui-icon
|
|
21654
|
+
name="inbox"
|
|
21655
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
21656
|
+
></ui-icon>
|
|
21657
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
21658
|
+
emptyMessage()
|
|
21659
|
+
}}</span>
|
|
20950
21660
|
</div>
|
|
20951
21661
|
}
|
|
20952
21662
|
</div>
|
|
@@ -20989,12 +21699,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
20989
21699
|
>
|
|
20990
21700
|
@if (valueTpl()) {
|
|
20991
21701
|
<span class="flex-1 min-w-0 truncate text-left text-sm">
|
|
20992
|
-
<ng-container
|
|
21702
|
+
<ng-container
|
|
21703
|
+
[ngTemplateOutlet]="valueTpl()"
|
|
21704
|
+
[ngTemplateOutletContext]="{
|
|
21705
|
+
$implicit: value(),
|
|
21706
|
+
placeholder: placeholder(),
|
|
21707
|
+
}"
|
|
21708
|
+
/>
|
|
20993
21709
|
</span>
|
|
20994
21710
|
} @else {
|
|
20995
21711
|
<span
|
|
20996
21712
|
class="flex-1 min-w-0 truncate text-left text-sm"
|
|
20997
|
-
[class.text-(--f-form-field-placeholder-color)]="
|
|
21713
|
+
[class.text-(--f-form-field-placeholder-color)]="
|
|
21714
|
+
!selectedPath().length
|
|
21715
|
+
"
|
|
20998
21716
|
>
|
|
20999
21717
|
{{
|
|
21000
21718
|
selectedPath().length ? selectedPath().join(' / ') : placeholder()
|
|
@@ -21002,11 +21720,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
21002
21720
|
</span>
|
|
21003
21721
|
}
|
|
21004
21722
|
<span class="flex items-center gap-1 shrink-0">
|
|
21005
|
-
@if (
|
|
21006
|
-
|
|
21723
|
+
@if (
|
|
21724
|
+
showClear() && selectedPath().length && !disabled() && !loading()
|
|
21725
|
+
) {
|
|
21726
|
+
<ui-icon
|
|
21727
|
+
name="x"
|
|
21728
|
+
class="text-xs text-(--f-form-field-placeholder-color) hover:text-(--f-text-color) shrink-0"
|
|
21729
|
+
(click)="clear($event)"
|
|
21730
|
+
></ui-icon>
|
|
21007
21731
|
}
|
|
21008
21732
|
@if (loading()) {
|
|
21009
|
-
<ui-icon
|
|
21733
|
+
<ui-icon
|
|
21734
|
+
name="loader-circle"
|
|
21735
|
+
[spin]="true"
|
|
21736
|
+
class="text-xs text-(--f-form-field-placeholder-color) shrink-0"
|
|
21737
|
+
></ui-icon>
|
|
21010
21738
|
} @else {
|
|
21011
21739
|
<ui-icon
|
|
21012
21740
|
[name]="dropdownIcon()"
|
|
@@ -21018,12 +21746,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
21018
21746
|
</button>
|
|
21019
21747
|
|
|
21020
21748
|
@if (open()) {
|
|
21021
|
-
<div
|
|
21022
|
-
#panel
|
|
21023
|
-
[class]="panelClass()"
|
|
21024
|
-
[style]="panelStyle()"
|
|
21025
|
-
role="tree"
|
|
21026
|
-
>
|
|
21749
|
+
<div #panel [class]="panelClass()" [style]="panelStyle()" role="tree">
|
|
21027
21750
|
@if (levels()[0].length) {
|
|
21028
21751
|
@for (level of levels(); track $index) {
|
|
21029
21752
|
<ul
|
|
@@ -21034,8 +21757,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
21034
21757
|
<li
|
|
21035
21758
|
role="treeitem"
|
|
21036
21759
|
[attr.aria-level]="$index + 1"
|
|
21037
|
-
[attr.aria-expanded]="
|
|
21038
|
-
|
|
21760
|
+
[attr.aria-expanded]="
|
|
21761
|
+
getChildren(opt, $index).length
|
|
21762
|
+
? isActive(opt, $index)
|
|
21763
|
+
: null
|
|
21764
|
+
"
|
|
21765
|
+
[attr.aria-selected]="
|
|
21766
|
+
getChildren(opt, $index).length
|
|
21767
|
+
? null
|
|
21768
|
+
: isSelectedOption(opt)
|
|
21769
|
+
"
|
|
21039
21770
|
>
|
|
21040
21771
|
<button
|
|
21041
21772
|
type="button"
|
|
@@ -21050,9 +21781,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
21050
21781
|
>
|
|
21051
21782
|
<span class="truncate">
|
|
21052
21783
|
@if (getChildren(opt, $index).length && groupTpl()) {
|
|
21053
|
-
<ng-container
|
|
21784
|
+
<ng-container
|
|
21785
|
+
[ngTemplateOutlet]="groupTpl()"
|
|
21786
|
+
[ngTemplateOutletContext]="{
|
|
21787
|
+
$implicit: opt,
|
|
21788
|
+
level: $index,
|
|
21789
|
+
}"
|
|
21790
|
+
/>
|
|
21054
21791
|
} @else if (optionTpl()) {
|
|
21055
|
-
<ng-container
|
|
21792
|
+
<ng-container
|
|
21793
|
+
[ngTemplateOutlet]="optionTpl()"
|
|
21794
|
+
[ngTemplateOutletContext]="{
|
|
21795
|
+
$implicit: opt,
|
|
21796
|
+
level: $index,
|
|
21797
|
+
}"
|
|
21798
|
+
/>
|
|
21056
21799
|
} @else {
|
|
21057
21800
|
{{ getLabel(opt) }}
|
|
21058
21801
|
}
|
|
@@ -21074,8 +21817,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
|
|
|
21074
21817
|
<ng-container [ngTemplateOutlet]="emptyTpl()" />
|
|
21075
21818
|
} @else {
|
|
21076
21819
|
<div class="py-6 px-4 flex flex-col items-center gap-2">
|
|
21077
|
-
<ui-icon
|
|
21078
|
-
|
|
21820
|
+
<ui-icon
|
|
21821
|
+
name="inbox"
|
|
21822
|
+
class="text-2xl text-(--f-text-muted-color)"
|
|
21823
|
+
></ui-icon>
|
|
21824
|
+
<span class="text-sm text-(--f-text-muted-color)">{{
|
|
21825
|
+
emptyMessage()
|
|
21826
|
+
}}</span>
|
|
21079
21827
|
</div>
|
|
21080
21828
|
}
|
|
21081
21829
|
</div>
|