@ngflux/ngflux 2.1.1 → 2.2.1

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.
@@ -1,17 +1,34 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, ElementRef, input, computed, HostBinding, Component, ChangeDetectionStrategy, Injector, viewChild, ViewContainerRef, ApplicationRef, signal, createComponent, effect, Injectable, output, model, untracked, HostListener, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';
3
- import { TitleStrategy, Router, ActivationEnd, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
2
+ import { InjectionToken, input, Component, inject, ElementRef, computed, HostBinding, ChangeDetectionStrategy, Injector, viewChild, ViewContainerRef, ApplicationRef, signal, createComponent, effect, Injectable, linkedSignal, output, model, untracked, booleanAttribute, Directive, viewChildren, TemplateRef, debounced, HostListener, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';
3
+ import * as i1$1 from '@angular/router';
4
+ import { TitleStrategy, Router, ActivationEnd, RouterLink, RouterLinkActive, isActive, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
4
5
  import { filter, map, AsyncSubject } from 'rxjs';
5
- import { NgClass } from '@angular/common';
6
+ import { NgClass, KeyValuePipe, NgTemplateOutlet } from '@angular/common';
6
7
  import { Title, Meta } from '@angular/platform-browser';
7
8
  import * as i1 from '@angular/forms';
8
9
  import { FormsModule } from '@angular/forms';
10
+ import { toSignal } from '@angular/core/rxjs-interop';
9
11
 
10
12
  const NGF_CONFIG = new InjectionToken('ngf-config');
11
13
  // END: Pagination
12
14
 
13
15
  const NGF_DIALOG_DATA = new InjectionToken('ngf-dialog-data');
14
16
 
17
+ class NgFluxActions {
18
+ justify = input('end', /* @ts-ignore */
19
+ ...(ngDevMode ? [{ debugName: "justify" }] : /* istanbul ignore next */ []));
20
+ wrap = input(true, /* @ts-ignore */
21
+ ...(ngDevMode ? [{ debugName: "wrap" }] : /* istanbul ignore next */ []));
22
+ gap = input(10, /* @ts-ignore */
23
+ ...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []));
24
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxActions, deps: [], target: i0.ɵɵFactoryTarget.Component });
25
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: NgFluxActions, isStandalone: true, selector: "ngf-actions", inputs: { justify: { classPropertyName: "justify", publicName: "justify", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"wrapper\" [class.wrap]=\"wrap()\" [style.gap.px]=\"gap()\" [style.justify-content]=\"justify()\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block}:host>.wrapper{display:flex;flex-direction:row;align-items:center}:host>.wrapper.wrap{flex-wrap:wrap}\n"] });
26
+ }
27
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxActions, decorators: [{
28
+ type: Component,
29
+ args: [{ selector: 'ngf-actions', imports: [], template: "<div class=\"wrapper\" [class.wrap]=\"wrap()\" [style.gap.px]=\"gap()\" [style.justify-content]=\"justify()\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block}:host>.wrapper{display:flex;flex-direction:row;align-items:center}:host>.wrapper.wrap{flex-wrap:wrap}\n"] }]
30
+ }], propDecorators: { justify: [{ type: i0.Input, args: [{ isSignal: true, alias: "justify", required: false }] }], wrap: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrap", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }] } });
31
+
15
32
  class NgFluxButton {
16
33
  ref = inject(ElementRef);
17
34
  icon = input(/* @ts-ignore */
@@ -265,6 +282,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
265
282
  args: [{ providedIn: 'root' }]
266
283
  }] });
267
284
 
285
+ class TabNavController {
286
+ map = signal(new Map(), /* @ts-ignore */
287
+ ...(ngDevMode ? [{ debugName: "map" }] : /* istanbul ignore next */ []));
288
+ navs = computed(() => Array.from(this.map().keys()), /* @ts-ignore */
289
+ ...(ngDevMode ? [{ debugName: "navs" }] : /* istanbul ignore next */ []));
290
+ selected = linkedSignal({ ...(ngDevMode ? { debugName: "selected" } : /* istanbul ignore next */ {}), source: () => ({
291
+ navs: this.navs(),
292
+ selectedIndex: this.selectedIndex(),
293
+ }),
294
+ computation: (src, prev) => {
295
+ const { navs, selectedIndex } = src;
296
+ const value = prev?.value ?? null;
297
+ let index = Math.min(Math.max(selectedIndex, 0), navs.length - 1);
298
+ return navs.find(v => v === value) ?? navs.at(index) ?? null;
299
+ } });
300
+ selectedIndex = signal(0, /* @ts-ignore */
301
+ ...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
302
+ active = this.selected.asReadonly();
303
+ activeContent = computed(() => this.active()?.navContent(), /* @ts-ignore */
304
+ ...(ngDevMode ? [{ debugName: "activeContent" }] : /* istanbul ignore next */ []));
305
+ activate(nav) {
306
+ const map = this.map();
307
+ if (!map.has(nav))
308
+ return;
309
+ this.selected.set(nav);
310
+ }
311
+ add(nav) {
312
+ this.map.update(v => {
313
+ const map = new Map(v);
314
+ map.set(nav, true);
315
+ return map;
316
+ });
317
+ }
318
+ remove(nav) {
319
+ this.map.update(v => {
320
+ if (!v.has(nav))
321
+ return v;
322
+ const map = new Map(v);
323
+ map.delete(nav);
324
+ return map;
325
+ });
326
+ }
327
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabNavController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
328
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabNavController });
329
+ }
330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabNavController, decorators: [{
331
+ type: Injectable
332
+ }] });
333
+
334
+ class TabGroupController {
335
+ map = signal(new Map(), /* @ts-ignore */
336
+ ...(ngDevMode ? [{ debugName: "map" }] : /* istanbul ignore next */ []));
337
+ tabs = computed(() => Array.from(this.map().keys()), /* @ts-ignore */
338
+ ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
339
+ add(nav) {
340
+ this.map.update(v => {
341
+ const map = new Map(v);
342
+ map.set(nav, true);
343
+ return map;
344
+ });
345
+ }
346
+ remove(nav) {
347
+ this.map.update(v => {
348
+ if (!v.has(nav))
349
+ return v;
350
+ const map = new Map(v);
351
+ map.delete(nav);
352
+ return map;
353
+ });
354
+ }
355
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabGroupController, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
356
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabGroupController });
357
+ }
358
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabGroupController, decorators: [{
359
+ type: Injectable
360
+ }] });
361
+
268
362
  class NgFluxDialogHeaderComponent {
269
363
  config = inject(NGF_DIALOG_CONFIG);
270
364
  dialogRef = inject(NgFluxDialogRef);
@@ -437,6 +531,609 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
437
531
  args: [{ selector: 'ngf-pagination', changeDetection: ChangeDetectionStrategy.Eager, imports: [NgFluxPaginationInfo], template: "<ngf-pagination-info\n [data]=\"value()\"\n [(limit)]=\"limit\"\n [limitOptions]=\"limitOptions()\"\n (callback)=\"callback.emit($event)\"\n></ngf-pagination-info>\n\n<div class=\"content\">\n <ng-content></ng-content>\n</div>\n\n<ngf-pagination-info\n [data]=\"value()\"\n [(limit)]=\"limit\"\n [limitOptions]=\"limitOptions()\"\n (callback)=\"callback.emit($event)\"\n></ngf-pagination-info>\n", styles: [":host{display:block}:host>.content{margin:20px 0}\n"] }]
438
532
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], preload: [{ type: i0.Input, args: [{ isSignal: true, alias: "preload", required: false }] }], transform: [{ type: i0.Input, args: [{ isSignal: true, alias: "transform", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: false }] }, { type: i0.Output, args: ["limitChange"] }], limitOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "limitOptions", required: false }] }], callback: [{ type: i0.Output, args: ["callback"] }] } });
439
533
 
534
+ class NgFluxSelectItems {
535
+ parent = inject(NgFluxSelectItems, {
536
+ optional: true,
537
+ skipSelf: true,
538
+ });
539
+ data = input.required(/* @ts-ignore */
540
+ ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
541
+ options = input.required(/* @ts-ignore */
542
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
543
+ transform = input.required(/* @ts-ignore */
544
+ ...(ngDevMode ? [{ debugName: "transform" }] : /* istanbul ignore next */ []));
545
+ select = output();
546
+ getItem(item) {
547
+ const transform = this.transform();
548
+ return {
549
+ label: transform.getLabel(item),
550
+ value: transform.getValue(item),
551
+ children: transform.getChildren?.(item) ?? [],
552
+ disabled: transform.isDisabled?.(item) ?? false,
553
+ };
554
+ }
555
+ onSelect(item) {
556
+ const info = this.getItem(item);
557
+ if (info.disabled)
558
+ return;
559
+ this.select.emit(item);
560
+ }
561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxSelectItems, deps: [], target: i0.ɵɵFactoryTarget.Component });
562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgFluxSelectItems, isStandalone: true, selector: "ngf-select-items", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, transform: { classPropertyName: "transform", publicName: "transform", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { select: "select" }, host: { properties: { "class.has-parent": "!!parent" } }, ngImport: i0, template: "<ul class=\"wrapper\">\n @for (entry of data(); track $index) {\n @let item = getItem(entry);\n\n <li [class.disabled]=\"item.disabled\" [class.has-parent]=\"!!parent\" [class.active]=\"options().getSelected(entry)\">\n <div class=\"text\" (click)=\"onSelect(entry)\">\n <span>{{ item.label }}</span>\n </div>\n\n @if (item.children?.length) {\n <ngf-select-items [data]=\"item.children\" [options]=\"options()\" [transform]=\"transform()\" (select)=\"onSelect($event)\" />\n }\n </li>\n }\n</ul>\n", styles: [":host{display:block;position:relative;max-height:200px;overflow:hidden auto}:host.has-parent{padding:0 0 0 10px}:host.has-parent:before{display:block;position:absolute;inset:0 auto 0 5px;background-color:#0003;content:\"\";width:1px}:host>.wrapper{display:block;list-style:none;font-size:.9rem;padding:0;margin:0}:host>.wrapper>li{display:block;cursor:pointer;--background-color: transparent;--color: inherit}:host>.wrapper>li>.text{padding:5px;background-color:var(--background-color)!important;color:var(--color)!important}:host>.wrapper>li>.text:hover{--background-color: rgba(var(--ngf-primary-rgb), .1)}:host>.wrapper>li.disabled{pointer-events:none;cursor:not-allowed;--color: #666}:host>.wrapper>li.active>.text{--background-color: var(--ngf-primary);--color: #FFF}:host>.wrapper>li.has-parent{position:relative}:host>.wrapper>li.has-parent:before{display:block;position:absolute;inset:50% 100% auto -4px;transform:translateY(-50%);background-color:#0003;content:\"\";height:1px}\n"], dependencies: [{ kind: "component", type: NgFluxSelectItems, selector: "ngf-select-items", inputs: ["data", "options", "transform"], outputs: ["select"] }] });
563
+ }
564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxSelectItems, decorators: [{
565
+ type: Component,
566
+ args: [{ selector: 'ngf-select-items', imports: [], host: {
567
+ '[class.has-parent]': '!!parent',
568
+ }, template: "<ul class=\"wrapper\">\n @for (entry of data(); track $index) {\n @let item = getItem(entry);\n\n <li [class.disabled]=\"item.disabled\" [class.has-parent]=\"!!parent\" [class.active]=\"options().getSelected(entry)\">\n <div class=\"text\" (click)=\"onSelect(entry)\">\n <span>{{ item.label }}</span>\n </div>\n\n @if (item.children?.length) {\n <ngf-select-items [data]=\"item.children\" [options]=\"options()\" [transform]=\"transform()\" (select)=\"onSelect($event)\" />\n }\n </li>\n }\n</ul>\n", styles: [":host{display:block;position:relative;max-height:200px;overflow:hidden auto}:host.has-parent{padding:0 0 0 10px}:host.has-parent:before{display:block;position:absolute;inset:0 auto 0 5px;background-color:#0003;content:\"\";width:1px}:host>.wrapper{display:block;list-style:none;font-size:.9rem;padding:0;margin:0}:host>.wrapper>li{display:block;cursor:pointer;--background-color: transparent;--color: inherit}:host>.wrapper>li>.text{padding:5px;background-color:var(--background-color)!important;color:var(--color)!important}:host>.wrapper>li>.text:hover{--background-color: rgba(var(--ngf-primary-rgb), .1)}:host>.wrapper>li.disabled{pointer-events:none;cursor:not-allowed;--color: #666}:host>.wrapper>li.active>.text{--background-color: var(--ngf-primary);--color: #FFF}:host>.wrapper>li.has-parent{position:relative}:host>.wrapper>li.has-parent:before{display:block;position:absolute;inset:50% 100% auto -4px;transform:translateY(-50%);background-color:#0003;content:\"\";height:1px}\n"] }]
569
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], transform: [{ type: i0.Input, args: [{ isSignal: true, alias: "transform", required: true }] }], select: [{ type: i0.Output, args: ["select"] }] } });
570
+
571
+ class NgFluxSelect {
572
+ ref = inject(ElementRef);
573
+ data = input.required(/* @ts-ignore */
574
+ ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
575
+ block = input(false, { ...(ngDevMode ? { debugName: "block" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
576
+ multi = input(false, { ...(ngDevMode ? { debugName: "multi" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
577
+ placeholder = input(/* @ts-ignore */
578
+ ...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
579
+ transform = input({
580
+ getLabel: item => item.label ?? '',
581
+ getValue: item => item.value,
582
+ getChildren: item => item.children ?? [],
583
+ setChildren: (item, children) => item.children = children,
584
+ }, /* @ts-ignore */
585
+ ...(ngDevMode ? [{ debugName: "transform" }] : /* istanbul ignore next */ []));
586
+ mapper = computed(() => {
587
+ const data = this.data();
588
+ const value = new Map();
589
+ this.doFlatMap(value, data);
590
+ return value;
591
+ }, /* @ts-ignore */
592
+ ...(ngDevMode ? [{ debugName: "mapper" }] : /* istanbul ignore next */ []));
593
+ value = model(null, /* @ts-ignore */
594
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
595
+ vmap = computed(() => {
596
+ let value = this.value() ?? [];
597
+ value = Array.isArray(value) ? value : [value];
598
+ const mapper = this.mapper();
599
+ const result = new Map();
600
+ for (let val of value) {
601
+ const item = mapper.get(val);
602
+ if (!item)
603
+ continue;
604
+ result.set(val, item);
605
+ }
606
+ return result;
607
+ }, /* @ts-ignore */
608
+ ...(ngDevMode ? [{ debugName: "vmap" }] : /* istanbul ignore next */ []));
609
+ open = signal(false, /* @ts-ignore */
610
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
611
+ searchbox = signal('', /* @ts-ignore */
612
+ ...(ngDevMode ? [{ debugName: "searchbox" }] : /* istanbul ignore next */ []));
613
+ search = computed(() => {
614
+ const data = this.data();
615
+ const text = this.searchbox().toLowerCase();
616
+ if (!text)
617
+ return data;
618
+ return this.doSearch(text, data);
619
+ }, /* @ts-ignore */
620
+ ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
621
+ headerText = computed(() => {
622
+ const multi = this.multi();
623
+ const placeholder = this.placeholder() ?? 'Select Item' + (multi ? 's' : '');
624
+ const items = Array.from(this.vmap().values());
625
+ if (!items.length)
626
+ return placeholder;
627
+ const transform = this.transform();
628
+ const first = items.splice(0, 1).at(0);
629
+ let text = transform.getLabel(first);
630
+ if (items.length)
631
+ text += ` + ${items.length.toLocaleString()} more`;
632
+ return text;
633
+ }, /* @ts-ignore */
634
+ ...(ngDevMode ? [{ debugName: "headerText" }] : /* istanbul ignore next */ []));
635
+ doFlatMap(map, data) {
636
+ const transform = this.transform();
637
+ for (let item of data) {
638
+ const key = transform.getValue(item);
639
+ map.set(key, item);
640
+ const children = transform.getChildren?.(item) ?? [];
641
+ this.doFlatMap(map, children);
642
+ }
643
+ }
644
+ doSearch(text, data) {
645
+ const transform = this.transform();
646
+ const result = [];
647
+ for (let entry of data) {
648
+ const item = Object.assign({}, entry);
649
+ let children = transform.getChildren?.(item) ?? [];
650
+ children = this.doSearch(text, children);
651
+ transform.setChildren?.(item, children);
652
+ if (children.length) {
653
+ result.push(item);
654
+ continue;
655
+ }
656
+ const label = transform.getLabel(item).toLowerCase();
657
+ if (label.includes(text))
658
+ result.push(item);
659
+ }
660
+ return result;
661
+ }
662
+ toggleOpen() {
663
+ if (this.multi())
664
+ return;
665
+ this.open.update(v => !v);
666
+ }
667
+ toggle(item) {
668
+ const multi = this.multi();
669
+ const transform = this.transform();
670
+ const vmap = new Map(this.vmap());
671
+ const key = transform.getValue(item);
672
+ if (!key)
673
+ return;
674
+ if (!vmap.has(key)) {
675
+ if (!multi)
676
+ vmap.clear();
677
+ vmap.set(key, item);
678
+ }
679
+ else {
680
+ vmap.delete(key);
681
+ }
682
+ const values = Array.from(vmap.keys());
683
+ if (values.length) {
684
+ this.value.set(multi ? values : values[0]);
685
+ }
686
+ else {
687
+ this.value.set(null);
688
+ }
689
+ this.open.set(false);
690
+ }
691
+ options = {
692
+ getSelected: item => {
693
+ const transform = this.transform();
694
+ const key = transform.getValue(item);
695
+ if (!key)
696
+ return false;
697
+ return this.vmap().has(key);
698
+ },
699
+ };
700
+ onDocumentClick(e) {
701
+ if (this.multi())
702
+ return;
703
+ const { ref: { nativeElement: elem } } = this;
704
+ const target = e.target;
705
+ if (elem.contains(target))
706
+ return;
707
+ this.open.set(false);
708
+ }
709
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
710
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgFluxSelect, isStandalone: true, selector: "ngf-select", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null }, multi: { classPropertyName: "multi", publicName: "multi", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, transform: { classPropertyName: "transform", publicName: "transform", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class.block": "block()" } }, ngImport: i0, template: "<div class=\"wrapper\">\n <div class=\"header\" [class.single]=\"!multi()\" (click)=\"toggleOpen()\">\n <div class=\"text\">{{ headerText() }}</div>\n @if (!multi()) {\n @let icons = ['ngf-icon', (open() ? 'arrow-drop-up' : 'arrow-drop-down')];\n <i [className]=\"icons.join(' ')\"></i>\n }\n </div>\n\n <div class=\"body\" [class.single]=\"!multi()\" [class.show]=\"open()\">\n <div class=\"searchbox\">\n <input type=\"text\" placeholder=\"Search Items\" [(ngModel)]=\"searchbox\">\n\n @if (searchbox().length) {\n <div class=\"clear\" (click)=\"searchbox.set('')\">\n <i class=\"ngf-icon close\"></i>\n </div>\n }\n </div>\n\n <ngf-select-items [data]=\"search()\" [options]=\"options\" [transform]=\"transform()\" (select)=\"toggle($event)\" />\n </div>\n\n @if (multi()) {\n <div class=\"footer\">\n @if (!vmap().size) {\n <div class=\"none\">No item selected</div>\n } @else {\n <div class=\"entries\">\n @for (item of vmap() | keyvalue; track $index) {\n <div class=\"entries-item\">\n <div class=\"text\">{{ transform().getLabel(item.value) }}</div>\n <div class=\"btn\" (click)=\"toggle(item.value)\">\n <i class=\"ngf-icon close\"></i>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (multi()) {\n <div class=\"clear-btn\" (click)=\"value.set(null)\">\n <span>Clear All</span>\n </div>\n }\n</div>\n", styles: [":host{display:inline-block;border:var(--border)!important;border-radius:3px;width:200px;font-size:.8rem;--border: 1px solid rgba(0, 0, 0, .2);--height: 40px}:host.block{display:block;width:100%}:host>.wrapper{display:block;position:relative}:host>.wrapper .header{display:flex;flex-direction:row;align-items:center;border-bottom:var(--border)!important;height:var(--height)!important;padding:0 10px;font-weight:500;color:#333;gap:10px}:host>.wrapper .header.single{cursor:pointer;--border: none}:host>.wrapper .header>.text{flex:1 0 0;width:0px;overflow:hidden;text-overflow:ellipsis}:host>.wrapper .header .ngf-icon{font-size:1.8em}:host>.wrapper .body{display:block;background-color:#fff;font-size:1em}:host>.wrapper .body.single{display:none;position:absolute;inset:100% 0 auto;box-shadow:0 0 3px #000000b3;z-index:5}:host>.wrapper .body.single.show{display:block!important}:host>.wrapper .body>.searchbox{display:block;position:relative;border-bottom:var(--border)!important;padding:7px}:host>.wrapper .body>.searchbox>input{display:block;width:100%!important;border:var(--border)!important;background-color:#fff;font-size:.9rem;padding:5px}:host>.wrapper .body>.searchbox>input:focus{box-shadow:none!important;outline:none!important}:host>.wrapper .body>.searchbox>.clear{display:block;position:absolute;inset:50% 15px auto auto;transform:translateY(-50%);cursor:pointer}:host>.wrapper .body>.searchbox>.clear .ngf-icon{font-size:1em}:host>.wrapper .footer{display:block;border-top:var(--border)!important;font-size:.9em;padding:5px}:host>.wrapper .footer .none{text-align:center;color:#666}:host>.wrapper .footer .entries{display:flex;flex-direction:row;flex-wrap:wrap;gap:5px}:host>.wrapper .footer .entries-item{display:flex;flex-direction:row;align-items:center;padding:0 3px;border-radius:2px;background-color:var(--ngf-primary);color:#fff;gap:5px}:host>.wrapper .footer .entries-item .btn{cursor:pointer}:host>.wrapper .footer .entries-item .btn .ngf-icon{font-size:1em}:host>.wrapper>.clear-btn{display:block;border-top:var(--border)!important;font-size:.8em;padding:3px;text-align:center;background-color:#444;color:#fff;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NgFluxSelectItems, selector: "ngf-select-items", inputs: ["data", "options", "transform"], outputs: ["select"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }] });
711
+ }
712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxSelect, decorators: [{
713
+ type: Component,
714
+ args: [{ selector: 'ngf-select', imports: [
715
+ FormsModule,
716
+ NgFluxSelectItems,
717
+ KeyValuePipe,
718
+ ], host: {
719
+ '[class.block]': 'block()',
720
+ '(document:click)': 'onDocumentClick($event)',
721
+ }, template: "<div class=\"wrapper\">\n <div class=\"header\" [class.single]=\"!multi()\" (click)=\"toggleOpen()\">\n <div class=\"text\">{{ headerText() }}</div>\n @if (!multi()) {\n @let icons = ['ngf-icon', (open() ? 'arrow-drop-up' : 'arrow-drop-down')];\n <i [className]=\"icons.join(' ')\"></i>\n }\n </div>\n\n <div class=\"body\" [class.single]=\"!multi()\" [class.show]=\"open()\">\n <div class=\"searchbox\">\n <input type=\"text\" placeholder=\"Search Items\" [(ngModel)]=\"searchbox\">\n\n @if (searchbox().length) {\n <div class=\"clear\" (click)=\"searchbox.set('')\">\n <i class=\"ngf-icon close\"></i>\n </div>\n }\n </div>\n\n <ngf-select-items [data]=\"search()\" [options]=\"options\" [transform]=\"transform()\" (select)=\"toggle($event)\" />\n </div>\n\n @if (multi()) {\n <div class=\"footer\">\n @if (!vmap().size) {\n <div class=\"none\">No item selected</div>\n } @else {\n <div class=\"entries\">\n @for (item of vmap() | keyvalue; track $index) {\n <div class=\"entries-item\">\n <div class=\"text\">{{ transform().getLabel(item.value) }}</div>\n <div class=\"btn\" (click)=\"toggle(item.value)\">\n <i class=\"ngf-icon close\"></i>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (multi()) {\n <div class=\"clear-btn\" (click)=\"value.set(null)\">\n <span>Clear All</span>\n </div>\n }\n</div>\n", styles: [":host{display:inline-block;border:var(--border)!important;border-radius:3px;width:200px;font-size:.8rem;--border: 1px solid rgba(0, 0, 0, .2);--height: 40px}:host.block{display:block;width:100%}:host>.wrapper{display:block;position:relative}:host>.wrapper .header{display:flex;flex-direction:row;align-items:center;border-bottom:var(--border)!important;height:var(--height)!important;padding:0 10px;font-weight:500;color:#333;gap:10px}:host>.wrapper .header.single{cursor:pointer;--border: none}:host>.wrapper .header>.text{flex:1 0 0;width:0px;overflow:hidden;text-overflow:ellipsis}:host>.wrapper .header .ngf-icon{font-size:1.8em}:host>.wrapper .body{display:block;background-color:#fff;font-size:1em}:host>.wrapper .body.single{display:none;position:absolute;inset:100% 0 auto;box-shadow:0 0 3px #000000b3;z-index:5}:host>.wrapper .body.single.show{display:block!important}:host>.wrapper .body>.searchbox{display:block;position:relative;border-bottom:var(--border)!important;padding:7px}:host>.wrapper .body>.searchbox>input{display:block;width:100%!important;border:var(--border)!important;background-color:#fff;font-size:.9rem;padding:5px}:host>.wrapper .body>.searchbox>input:focus{box-shadow:none!important;outline:none!important}:host>.wrapper .body>.searchbox>.clear{display:block;position:absolute;inset:50% 15px auto auto;transform:translateY(-50%);cursor:pointer}:host>.wrapper .body>.searchbox>.clear .ngf-icon{font-size:1em}:host>.wrapper .footer{display:block;border-top:var(--border)!important;font-size:.9em;padding:5px}:host>.wrapper .footer .none{text-align:center;color:#666}:host>.wrapper .footer .entries{display:flex;flex-direction:row;flex-wrap:wrap;gap:5px}:host>.wrapper .footer .entries-item{display:flex;flex-direction:row;align-items:center;padding:0 3px;border-radius:2px;background-color:var(--ngf-primary);color:#fff;gap:5px}:host>.wrapper .footer .entries-item .btn{cursor:pointer}:host>.wrapper .footer .entries-item .btn .ngf-icon{font-size:1em}:host>.wrapper>.clear-btn{display:block;border-top:var(--border)!important;font-size:.8em;padding:3px;text-align:center;background-color:#444;color:#fff;cursor:pointer}\n"] }]
722
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }], multi: [{ type: i0.Input, args: [{ isSignal: true, alias: "multi", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], transform: [{ type: i0.Input, args: [{ isSignal: true, alias: "transform", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
723
+
724
+ class PinInputDirective {
725
+ ref = inject(ElementRef);
726
+ elem = this.ref.nativeElement;
727
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PinInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
728
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: PinInputDirective, isStandalone: true, selector: "[pinInput]", ngImport: i0 });
729
+ }
730
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PinInputDirective, decorators: [{
731
+ type: Directive,
732
+ args: [{
733
+ selector: '[pinInput]',
734
+ }]
735
+ }] });
736
+
737
+ class NgFluxPinInput {
738
+ chars = input(4, /* @ts-ignore */
739
+ ...(ngDevMode ? [{ debugName: "chars" }] : /* istanbul ignore next */ []));
740
+ block = input(false, { ...(ngDevMode ? { debugName: "block" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
741
+ value = model('', /* @ts-ignore */
742
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
743
+ values = computed(() => {
744
+ const chars = this.chars(), value = this.value() ?? '';
745
+ return Array.from({ length: chars }, (_, i) => value.charAt(i));
746
+ }, /* @ts-ignore */
747
+ ...(ngDevMode ? [{ debugName: "values" }] : /* istanbul ignore next */ []));
748
+ inputs = viewChildren(PinInputDirective, /* @ts-ignore */
749
+ ...(ngDevMode ? [{ debugName: "inputs" }] : /* istanbul ignore next */ []));
750
+ onKeyDown(e, index) {
751
+ const target = e.target;
752
+ const values = Array.from(this.values());
753
+ switch (e.key) {
754
+ case 'Backspace':
755
+ {
756
+ e.preventDefault();
757
+ values[index] = '';
758
+ this.setFocus(index - 1);
759
+ }
760
+ break;
761
+ case 'Delete':
762
+ {
763
+ e.preventDefault();
764
+ values[index] = '';
765
+ this.setFocus(index);
766
+ }
767
+ break;
768
+ default: {
769
+ if (e.key.length !== 1)
770
+ return;
771
+ if (e.ctrlKey || e.altKey || e.metaKey)
772
+ return;
773
+ e.preventDefault();
774
+ const code = e.key.charCodeAt(0);
775
+ if (!this.allowed(code))
776
+ return;
777
+ values[index] = e.key;
778
+ this.setFocus(index + 1);
779
+ }
780
+ }
781
+ this.value.set(values.join(''));
782
+ }
783
+ onPaste(e, index) {
784
+ e.preventDefault();
785
+ const values = Array.from(this.values());
786
+ const data = e.clipboardData?.getData('text/plain');
787
+ if (!data)
788
+ return;
789
+ let cursor = 0, lastIndex = index;
790
+ for (let i = index; i < values.length; i++) {
791
+ while (cursor < data.length) {
792
+ const ptr = cursor++;
793
+ let code = data.charCodeAt(ptr);
794
+ if (!this.allowed(code))
795
+ continue;
796
+ let char = data.charAt(ptr);
797
+ values[i] = char;
798
+ break;
799
+ }
800
+ if (cursor >= data.length)
801
+ break;
802
+ lastIndex++;
803
+ }
804
+ this.value.set(values.join(''));
805
+ this.setFocus(lastIndex + 1);
806
+ }
807
+ setFocus(index) {
808
+ const maxIndex = this.chars() - 1;
809
+ index = Math.min(maxIndex, Math.max(index, 0));
810
+ const input = this.inputs().at(index);
811
+ input?.elem.focus();
812
+ input?.elem.select();
813
+ }
814
+ allowed = (code) => ((code > 47 && code < 58) || // Numeric (0-9)
815
+ (code > 64 && code < 91) || // Uppercase (A-Z)
816
+ (code > 96 && code < 123) // Lowercase (a-z)
817
+ );
818
+ focus(options) {
819
+ const inputs = this.inputs();
820
+ inputs.at(0)?.elem.focus();
821
+ }
822
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxPinInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
823
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgFluxPinInput, isStandalone: true, selector: "ngf-pin-input", inputs: { chars: { classPropertyName: "chars", publicName: "chars", isSignal: true, isRequired: false, transformFunction: null }, block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "class.block": "block()" } }, viewQueries: [{ propertyName: "inputs", predicate: PinInputDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"wrapper\">\n @for (val of values(); track $index) {\n <input type=\"text\" pinInput [value]=\"val\" (keydown)=\"onKeyDown($event, $index)\" (paste)=\"onPaste($event, $index)\">\n }\n</div>\n", styles: [":host{display:inline-block;width:200px;--padding-y: 10px;--border: 1px solid rgba(0, 0, 0, .2);--background-color: #FFF;--color: inherit;--gap: 5px}:host.block{display:block;width:100%}:host>.wrapper{display:flex;flex-direction:row;gap:var(--gap)!important}:host>.wrapper>input{display:block;flex:1 0 0;width:0px;text-align:center;font-size:1em;color:var(--color)!important;padding:var(--padding-y) 0px var(--padding-y) 0px!important;background-color:var(--background-color)!important;border:var(--border)!important}:host>.wrapper>input:focus{outline:var(--border);box-shadow:none}\n"], dependencies: [{ kind: "directive", type: PinInputDirective, selector: "[pinInput]" }] });
824
+ }
825
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxPinInput, decorators: [{
826
+ type: Component,
827
+ args: [{ selector: 'ngf-pin-input', imports: [
828
+ PinInputDirective,
829
+ ], host: {
830
+ '[class.block]': 'block()',
831
+ }, template: "<div class=\"wrapper\">\n @for (val of values(); track $index) {\n <input type=\"text\" pinInput [value]=\"val\" (keydown)=\"onKeyDown($event, $index)\" (paste)=\"onPaste($event, $index)\">\n }\n</div>\n", styles: [":host{display:inline-block;width:200px;--padding-y: 10px;--border: 1px solid rgba(0, 0, 0, .2);--background-color: #FFF;--color: inherit;--gap: 5px}:host.block{display:block;width:100%}:host>.wrapper{display:flex;flex-direction:row;gap:var(--gap)!important}:host>.wrapper>input{display:block;flex:1 0 0;width:0px;text-align:center;font-size:1em;color:var(--color)!important;padding:var(--padding-y) 0px var(--padding-y) 0px!important;background-color:var(--background-color)!important;border:var(--border)!important}:host>.wrapper>input:focus{outline:var(--border);box-shadow:none}\n"] }]
832
+ }], propDecorators: { chars: [{ type: i0.Input, args: [{ isSignal: true, alias: "chars", required: false }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], inputs: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => PinInputDirective), { isSignal: true }] }] } });
833
+
834
+ class NgFluxTabNavDirective {
835
+ routerLink = inject(RouterLink);
836
+ routerLinkActive = inject(RouterLinkActive);
837
+ ctrl = inject(TabNavController);
838
+ content = input(/* @ts-ignore */
839
+ ...(ngDevMode ? [undefined, { debugName: "content" }] : /* istanbul ignore next */ []));
840
+ navContent = computed(() => this.content(), /* @ts-ignore */
841
+ ...(ngDevMode ? [{ debugName: "navContent" }] : /* istanbul ignore next */ []));
842
+ routeActive = toSignal(this.routerLinkActive.isActiveChange, { initialValue: false });
843
+ active = computed(() => this.ctrl.active() === this, /* @ts-ignore */
844
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
845
+ constructor() {
846
+ const { ctrl } = this;
847
+ effect((onCleanup) => {
848
+ ctrl.add(this);
849
+ onCleanup(() => {
850
+ ctrl.remove(this);
851
+ });
852
+ });
853
+ effect(() => {
854
+ const active = this.routeActive();
855
+ if (active)
856
+ ctrl.activate(this);
857
+ });
858
+ }
859
+ activate(e) {
860
+ const { ctrl, routerLink, routeActive } = this;
861
+ if (routerLink.href !== null && !routeActive())
862
+ return;
863
+ ctrl.activate(this);
864
+ }
865
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabNavDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
866
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: NgFluxTabNavDirective, isStandalone: true, selector: "[ngfTabNav]", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "activate($event)" }, properties: { "class.ngf-tab-nav": "true", "class.active": "active()" } }, hostDirectives: [{ directive: i1$1.RouterLink, inputs: ["routerLink", "link"] }, { directive: i1$1.RouterLinkActive }], ngImport: i0 });
867
+ }
868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabNavDirective, decorators: [{
869
+ type: Directive,
870
+ args: [{
871
+ selector: '[ngfTabNav]',
872
+ hostDirectives: [
873
+ { directive: RouterLink, inputs: ['routerLink: link'] },
874
+ RouterLinkActive,
875
+ ],
876
+ host: {
877
+ '[class.ngf-tab-nav]': 'true',
878
+ '[class.active]': 'active()',
879
+ '(click)': 'activate($event)',
880
+ },
881
+ }]
882
+ }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }] } });
883
+
884
+ class NgFluxTabContentDirective {
885
+ templateRef = inject(TemplateRef);
886
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
887
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: NgFluxTabContentDirective, isStandalone: true, selector: "[ngfTabContent]", exportAs: ["content"], ngImport: i0 });
888
+ }
889
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabContentDirective, decorators: [{
890
+ type: Directive,
891
+ args: [{
892
+ selector: '[ngfTabContent]',
893
+ exportAs: 'content',
894
+ }]
895
+ }] });
896
+
897
+ class NgFluxTab {
898
+ ctrl = inject(TabGroupController);
899
+ label = input.required(/* @ts-ignore */
900
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
901
+ navLabel = computed(() => this.label(), /* @ts-ignore */
902
+ ...(ngDevMode ? [{ debugName: "navLabel" }] : /* istanbul ignore next */ []));
903
+ content = viewChild.required(NgFluxTabContentDirective, /* @ts-ignore */
904
+ ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
905
+ constructor() {
906
+ const { ctrl } = this;
907
+ effect(onCleanup => {
908
+ ctrl.add(this);
909
+ onCleanup(() => {
910
+ ctrl.remove(this);
911
+ });
912
+ });
913
+ }
914
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTab, deps: [], target: i0.ɵɵFactoryTarget.Component });
915
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: NgFluxTab, isStandalone: true, selector: "ngf-tab", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "content", first: true, predicate: NgFluxTabContentDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template ngfTabContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgFluxTabContentDirective, selector: "[ngfTabContent]", exportAs: ["content"] }] });
916
+ }
917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTab, decorators: [{
918
+ type: Component,
919
+ args: [{ selector: 'ngf-tab', imports: [
920
+ NgFluxTabContentDirective,
921
+ ], template: "<ng-template ngfTabContent>\n <ng-content></ng-content>\n</ng-template>\n", styles: [":host{display:block}\n"] }]
922
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], content: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgFluxTabContentDirective), { isSignal: true }] }] } });
923
+
924
+ class NgFluxTabNavbar {
925
+ ctrl = inject(TabNavController);
926
+ panel = input(/* @ts-ignore */
927
+ ...(ngDevMode ? [undefined, { debugName: "panel" }] : /* istanbul ignore next */ []));
928
+ selectedIndex = input(0, /* @ts-ignore */
929
+ ...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
930
+ constructor() {
931
+ const { ctrl } = this;
932
+ effect(() => {
933
+ const index = this.selectedIndex();
934
+ ctrl.selectedIndex.set(index);
935
+ });
936
+ effect(() => {
937
+ const panel = this.panel();
938
+ const content = ctrl.activeContent();
939
+ panel?.setContent(content?.templateRef);
940
+ });
941
+ }
942
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabNavbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
943
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: NgFluxTabNavbar, isStandalone: true, selector: "ngf-tab-navbar", inputs: { panel: { classPropertyName: "panel", publicName: "panel", isSignal: true, isRequired: false, transformFunction: null }, selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null } }, providers: [TabNavController], ngImport: i0, template: "<div class=\"wrapper\">\n <ng-content select=\"[ngfTabNav]\"></ng-content>\n</div>\n", styles: [":host{display:block;border-bottom:1px solid #CCC;overflow:auto hidden}:host>.wrapper{display:flex;flex-direction:row}\n"] });
944
+ }
945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabNavbar, decorators: [{
946
+ type: Component,
947
+ args: [{ selector: 'ngf-tab-navbar', providers: [TabNavController], imports: [], template: "<div class=\"wrapper\">\n <ng-content select=\"[ngfTabNav]\"></ng-content>\n</div>\n", styles: [":host{display:block;border-bottom:1px solid #CCC;overflow:auto hidden}:host>.wrapper{display:flex;flex-direction:row}\n"] }]
948
+ }], ctorParameters: () => [], propDecorators: { panel: [{ type: i0.Input, args: [{ isSignal: true, alias: "panel", required: false }] }], selectedIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIndex", required: false }] }] } });
949
+
950
+ class NgFluxTabPanel {
951
+ label = input(/* @ts-ignore */
952
+ ...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
953
+ content = signal(null, /* @ts-ignore */
954
+ ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
955
+ setContent(tpl) {
956
+ this.content.set(tpl ?? null);
957
+ }
958
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
959
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: NgFluxTabPanel, isStandalone: true, selector: "ngf-tab-panel", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"wrapper\">\n <ng-container [ngTemplateOutlet]=\"content()\"></ng-container>\n</div>\n", styles: [".wrapper{display:block}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
960
+ }
961
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabPanel, decorators: [{
962
+ type: Component,
963
+ args: [{ selector: 'ngf-tab-panel', imports: [NgTemplateOutlet], template: "<div class=\"wrapper\">\n <ng-container [ngTemplateOutlet]=\"content()\"></ng-container>\n</div>\n", styles: [".wrapper{display:block}\n"] }]
964
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
965
+
966
+ class NgFluxTabGroup {
967
+ ctrl = inject(TabGroupController);
968
+ selectedIndex = input(0, /* @ts-ignore */
969
+ ...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
970
+ showTabs = false;
971
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
972
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgFluxTabGroup, isStandalone: true, selector: "ngf-tab-group", inputs: { selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null } }, providers: [TabGroupController], ngImport: i0, template: "<ngf-tab-navbar [panel]=\"panel\" [selectedIndex]=\"selectedIndex()\">\n @for (tab of ctrl.tabs(); track $index) {\n <div ngfTabNav [content]=\"tab.content()\">\n <span>{{ tab.navLabel() }}</span>\n </div>\n }\n</ngf-tab-navbar>\n\n<ngf-tab-panel #panel></ngf-tab-panel>\n\n@if (showTabs) {\n <ng-content select=\"ngf-tab\"></ng-content>\n}\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: NgFluxTabNavbar, selector: "ngf-tab-navbar", inputs: ["panel", "selectedIndex"] }, { kind: "directive", type: NgFluxTabNavDirective, selector: "[ngfTabNav]", inputs: ["content"] }, { kind: "component", type: NgFluxTabPanel, selector: "ngf-tab-panel", inputs: ["label"] }] });
973
+ }
974
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxTabGroup, decorators: [{
975
+ type: Component,
976
+ args: [{ selector: 'ngf-tab-group', providers: [TabGroupController], imports: [
977
+ NgFluxTabNavbar,
978
+ NgFluxTabNavDirective,
979
+ NgFluxTabPanel
980
+ ], template: "<ngf-tab-navbar [panel]=\"panel\" [selectedIndex]=\"selectedIndex()\">\n @for (tab of ctrl.tabs(); track $index) {\n <div ngfTabNav [content]=\"tab.content()\">\n <span>{{ tab.navLabel() }}</span>\n </div>\n }\n</ngf-tab-navbar>\n\n<ngf-tab-panel #panel></ngf-tab-panel>\n\n@if (showTabs) {\n <ng-content select=\"ngf-tab\"></ng-content>\n}\n", styles: [":host{display:block}\n"] }]
981
+ }], propDecorators: { selectedIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIndex", required: false }] }] } });
982
+
983
+ class NgFluxFrameSideMenu {
984
+ router = inject(Router, { optional: true });
985
+ parent = inject(NgFluxFrameSideMenu, {
986
+ optional: true,
987
+ skipSelf: true,
988
+ });
989
+ menu = input.required(/* @ts-ignore */
990
+ ...(ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []));
991
+ expanded = signal(new Map(), /* @ts-ignore */
992
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
993
+ map = computed(() => {
994
+ const { router } = this;
995
+ const menu = this.menu();
996
+ const map = new Map();
997
+ for (let item of menu) {
998
+ const active = (router && item.href && !item.isExternal) ? isActive(item.href, router) : () => false;
999
+ map.set(item, active);
1000
+ }
1001
+ return map;
1002
+ }, /* @ts-ignore */
1003
+ ...(ngDevMode ? [{ debugName: "map" }] : /* istanbul ignore next */ []));
1004
+ hasParent = computed(() => !!this.parent, /* @ts-ignore */
1005
+ ...(ngDevMode ? [{ debugName: "hasParent" }] : /* istanbul ignore next */ []));
1006
+ target = (item) => item.targetBlank ? '_blank' : null;
1007
+ isExpanded(item) {
1008
+ return this.expanded().has(item);
1009
+ }
1010
+ isActive(item) {
1011
+ return this.map().get(item)?.() ?? false;
1012
+ }
1013
+ toggle(e, item) {
1014
+ e.preventDefault();
1015
+ e.stopPropagation();
1016
+ this.expanded.update(v => {
1017
+ const map = new Map(v);
1018
+ if (!map.has(item)) {
1019
+ map.set(item, true);
1020
+ }
1021
+ else {
1022
+ map.delete(item);
1023
+ }
1024
+ return map;
1025
+ });
1026
+ }
1027
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxFrameSideMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
1028
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgFluxFrameSideMenu, isStandalone: true, selector: "ngf-frame-side-menu", inputs: { menu: { classPropertyName: "menu", publicName: "menu", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class.has-parent": "hasParent()" } }, ngImport: i0, template: "@if (menu().length) {\n <ul class=\"wrapper\">\n @for (item of menu(); track $index) {\n <li routerLinkActive=\"active\">\n @if(item.isExternal) {\n <a [href]=\"item.href ?? null\" [attr.target]=\"target(item)\" (click)=\"item.onClick?.($event, item)\">\n <div class=\"icon\">\n @if (item.icon) {<i [className]=\"item.icon\"></i>}\n </div>\n\n <div class=\"text\" [attr.title]=\"item.text\">{{ item.text }}</div>\n\n @if (item.children?.length) {\n @let icons = ['ngf-icon', isExpanded(item) ? 'unfold-less' : 'unfold-more'];\n <div class=\"toggle\" (click)=\"toggle($event, item)\">\n <i [className]=\"icons.join(' ')\"></i>\n </div>\n }\n </a>\n } @else {\n <a [routerLink]=\"item.href\" [attr.target]=\"target(item)\" (click)=\"item.onClick?.($event, item)\">\n <div class=\"icon\">\n @if (item.icon) {<i [className]=\"item.icon\"></i>}\n </div>\n\n <div class=\"text\" [attr.title]=\"item.text\">{{ item.text }}</div>\n\n @if (item.children?.length) {\n @let icons = ['ngf-icon', isExpanded(item) ? 'unfold-less' : 'unfold-more'];\n <div class=\"toggle\" (click)=\"toggle($event, item)\">\n <i [className]=\"icons.join(' ')\"></i>\n </div>\n }\n </a>\n }\n\n @if (item.children?.length && (isActive(item) || isExpanded(item))) {\n <ngf-frame-side-menu [menu]=\"item.children\" />\n }\n </li>\n }\n </ul>\n}\n", styles: [":host{display:block;font-size:var(--font-size)!important;--color: #333;--bg-color: transparent;--font-size: .9rem;--active-color: var(--ngf-primary);--active-bg-color: rgba(var(--ngf-primary-rgb), .1);--hover-color: var(--ngf-primary);--hover-bg-color: rgba(var(--ngf-primary-rgb), .1)}:host.has-parent{padding:0 0 0 20px}:host .wrapper{display:block;list-style:none;padding:0;margin:0}:host .wrapper>li{display:block;background-color:var(--bg-color)!important;padding:0;margin:0}:host .wrapper>li:hover{--bg-color: var(--hover-bg-color)}:host .wrapper>li.active{--color: var(--active-color);--bg-color: var(--active-bg-color)}:host .wrapper>li>a{display:flex;flex-direction:row;align-items:center;padding:10px 5px;text-decoration:none!important;cursor:pointer;width:100%;gap:5px}:host .wrapper>li>a,:host .wrapper>li>a:link{color:var(--color)!important}:host .wrapper>li>a>.icon{display:block;width:13px}:host .wrapper>li>a>.icon .ngf-icon{font-size:1em}:host .wrapper>li>a>.text{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:1 0 0;width:0px}:host .wrapper>li>a>.toggle{display:block;cursor:pointer}:host .wrapper>li>a>.toggle .ngf-icon{font-size:1em}\n"], dependencies: [{ kind: "component", type: NgFluxFrameSideMenu, selector: "ngf-frame-side-menu", inputs: ["menu"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
1029
+ }
1030
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxFrameSideMenu, decorators: [{
1031
+ type: Component,
1032
+ args: [{ selector: 'ngf-frame-side-menu', imports: [
1033
+ RouterLink,
1034
+ RouterLinkActive,
1035
+ ], host: {
1036
+ '[class.has-parent]': 'hasParent()',
1037
+ }, template: "@if (menu().length) {\n <ul class=\"wrapper\">\n @for (item of menu(); track $index) {\n <li routerLinkActive=\"active\">\n @if(item.isExternal) {\n <a [href]=\"item.href ?? null\" [attr.target]=\"target(item)\" (click)=\"item.onClick?.($event, item)\">\n <div class=\"icon\">\n @if (item.icon) {<i [className]=\"item.icon\"></i>}\n </div>\n\n <div class=\"text\" [attr.title]=\"item.text\">{{ item.text }}</div>\n\n @if (item.children?.length) {\n @let icons = ['ngf-icon', isExpanded(item) ? 'unfold-less' : 'unfold-more'];\n <div class=\"toggle\" (click)=\"toggle($event, item)\">\n <i [className]=\"icons.join(' ')\"></i>\n </div>\n }\n </a>\n } @else {\n <a [routerLink]=\"item.href\" [attr.target]=\"target(item)\" (click)=\"item.onClick?.($event, item)\">\n <div class=\"icon\">\n @if (item.icon) {<i [className]=\"item.icon\"></i>}\n </div>\n\n <div class=\"text\" [attr.title]=\"item.text\">{{ item.text }}</div>\n\n @if (item.children?.length) {\n @let icons = ['ngf-icon', isExpanded(item) ? 'unfold-less' : 'unfold-more'];\n <div class=\"toggle\" (click)=\"toggle($event, item)\">\n <i [className]=\"icons.join(' ')\"></i>\n </div>\n }\n </a>\n }\n\n @if (item.children?.length && (isActive(item) || isExpanded(item))) {\n <ngf-frame-side-menu [menu]=\"item.children\" />\n }\n </li>\n }\n </ul>\n}\n", styles: [":host{display:block;font-size:var(--font-size)!important;--color: #333;--bg-color: transparent;--font-size: .9rem;--active-color: var(--ngf-primary);--active-bg-color: rgba(var(--ngf-primary-rgb), .1);--hover-color: var(--ngf-primary);--hover-bg-color: rgba(var(--ngf-primary-rgb), .1)}:host.has-parent{padding:0 0 0 20px}:host .wrapper{display:block;list-style:none;padding:0;margin:0}:host .wrapper>li{display:block;background-color:var(--bg-color)!important;padding:0;margin:0}:host .wrapper>li:hover{--bg-color: var(--hover-bg-color)}:host .wrapper>li.active{--color: var(--active-color);--bg-color: var(--active-bg-color)}:host .wrapper>li>a{display:flex;flex-direction:row;align-items:center;padding:10px 5px;text-decoration:none!important;cursor:pointer;width:100%;gap:5px}:host .wrapper>li>a,:host .wrapper>li>a:link{color:var(--color)!important}:host .wrapper>li>a>.icon{display:block;width:13px}:host .wrapper>li>a>.icon .ngf-icon{font-size:1em}:host .wrapper>li>a>.text{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:1 0 0;width:0px}:host .wrapper>li>a>.toggle{display:block;cursor:pointer}:host .wrapper>li>a>.toggle .ngf-icon{font-size:1em}\n"] }]
1038
+ }], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "menu", required: true }] }] } });
1039
+
1040
+ class NgFluxFrameHeaderMenu {
1041
+ menu = input.required(/* @ts-ignore */
1042
+ ...(ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []));
1043
+ open = signal(false, /* @ts-ignore */
1044
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
1045
+ target = (item) => item.targetBlank ? '_blank' : null;
1046
+ toggle(e) {
1047
+ e.stopPropagation();
1048
+ this.open.update(v => !v);
1049
+ }
1050
+ onDocumentClick(e) {
1051
+ this.open.set(false);
1052
+ }
1053
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxFrameHeaderMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
1054
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgFluxFrameHeaderMenu, isStandalone: true, selector: "ngf-frame-header-menu", inputs: { menu: { classPropertyName: "menu", publicName: "menu", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div class=\"toggle\" (click)=\"toggle($event)\">\n @let icons = ['ngf-icon', open() ? 'close' : 'menu'];\n <i [className]=\"icons.join(' ')\"></i>\n</div>\n\n<div class=\"wrapper\" [class.open]=\"open()\">\n @if (menu().length) {\n <ul class=\"menu\">\n @for (item of menu(); track $index) {\n <li>\n @if (item.isExternal) {\n <a [href]=\"item.href\" [attr.target]=\"target(item)\">\n @if (item.icon) {\n <div class=\"icon\">\n <i [className]=\"item.icon\"></i>\n </div>\n }\n\n <div class=\"text\">{{ item.text }}</div>\n </a>\n } @else {\n <a [routerLink]=\"item.href\" [attr.target]=\"target(item)\">\n @if (item.icon) {\n <div class=\"icon\">\n <i [className]=\"item.icon\"></i>\n </div>\n }\n\n <div class=\"text\">{{ item.text }}</div>\n </a>\n }\n </li>\n }\n </ul>\n }\n</div>\n", styles: [":host{display:flex;flex-direction:row;justify-content:end;container:main/inline-size scroll-state!important;align-self:stretch;--border: 1px solid #DDD}:host .toggle{display:flex;flex-direction:row;align-items:center;justify-content:center;border-left:var(--border)!important;border-right:var(--border)!important;padding:0 10px;cursor:pointer}@container main (min-width: 576px){:host .toggle{display:none}}:host .wrapper{display:none;position:relative}:host .wrapper.open{display:block}@container main (min-width: 576px){:host .wrapper{display:block}}:host .wrapper>.menu{display:block;position:absolute;inset:100% 0 auto auto;box-shadow:0 3px 3px #00000080;background-color:#fff;list-style:none;height:auto;padding:0;margin:0}@container main (min-width: 576px){:host .wrapper>.menu{display:flex;flex-direction:row;align-items:center;justify-content:end;position:static;background-color:transparent;box-shadow:none;height:100%;inset:auto;gap:15px}}:host .wrapper>.menu>li{display:block;padding:0;margin:0}:host .wrapper>.menu>li>a{display:flex;flex-direction:row;align-items:center;text-decoration:none!important;padding:7px 20px;gap:5px}@container main (min-width: 576px){:host .wrapper>.menu>li>a{padding:0}}:host .wrapper>.menu>li>a>.icon{display:block}:host .wrapper>.menu>li>a>.icon>*{font-size:1.2em}:host .wrapper>.menu>li>a>.text{display:block;white-space:nowrap}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }] });
1055
+ }
1056
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxFrameHeaderMenu, decorators: [{
1057
+ type: Component,
1058
+ args: [{ selector: 'ngf-frame-header-menu', imports: [RouterLink], host: {
1059
+ '(document:click)': 'onDocumentClick($event)',
1060
+ }, template: "<div class=\"toggle\" (click)=\"toggle($event)\">\n @let icons = ['ngf-icon', open() ? 'close' : 'menu'];\n <i [className]=\"icons.join(' ')\"></i>\n</div>\n\n<div class=\"wrapper\" [class.open]=\"open()\">\n @if (menu().length) {\n <ul class=\"menu\">\n @for (item of menu(); track $index) {\n <li>\n @if (item.isExternal) {\n <a [href]=\"item.href\" [attr.target]=\"target(item)\">\n @if (item.icon) {\n <div class=\"icon\">\n <i [className]=\"item.icon\"></i>\n </div>\n }\n\n <div class=\"text\">{{ item.text }}</div>\n </a>\n } @else {\n <a [routerLink]=\"item.href\" [attr.target]=\"target(item)\">\n @if (item.icon) {\n <div class=\"icon\">\n <i [className]=\"item.icon\"></i>\n </div>\n }\n\n <div class=\"text\">{{ item.text }}</div>\n </a>\n }\n </li>\n }\n </ul>\n }\n</div>\n", styles: [":host{display:flex;flex-direction:row;justify-content:end;container:main/inline-size scroll-state!important;align-self:stretch;--border: 1px solid #DDD}:host .toggle{display:flex;flex-direction:row;align-items:center;justify-content:center;border-left:var(--border)!important;border-right:var(--border)!important;padding:0 10px;cursor:pointer}@container main (min-width: 576px){:host .toggle{display:none}}:host .wrapper{display:none;position:relative}:host .wrapper.open{display:block}@container main (min-width: 576px){:host .wrapper{display:block}}:host .wrapper>.menu{display:block;position:absolute;inset:100% 0 auto auto;box-shadow:0 3px 3px #00000080;background-color:#fff;list-style:none;height:auto;padding:0;margin:0}@container main (min-width: 576px){:host .wrapper>.menu{display:flex;flex-direction:row;align-items:center;justify-content:end;position:static;background-color:transparent;box-shadow:none;height:100%;inset:auto;gap:15px}}:host .wrapper>.menu>li{display:block;padding:0;margin:0}:host .wrapper>.menu>li>a{display:flex;flex-direction:row;align-items:center;text-decoration:none!important;padding:7px 20px;gap:5px}@container main (min-width: 576px){:host .wrapper>.menu>li>a{padding:0}}:host .wrapper>.menu>li>a>.icon{display:block}:host .wrapper>.menu>li>a>.icon>*{font-size:1.2em}:host .wrapper>.menu>li>a>.text{display:block;white-space:nowrap}\n"] }]
1061
+ }], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "menu", required: true }] }] } });
1062
+
1063
+ class NgFluxFrame {
1064
+ leftRef = viewChild.required('left', /* @ts-ignore */
1065
+ ...(ngDevMode ? [{ debugName: "leftRef" }] : /* istanbul ignore next */ []));
1066
+ viewport = input(false, { ...(ngDevMode ? { debugName: "viewport" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1067
+ options = input({}, /* @ts-ignore */
1068
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
1069
+ title = computed(() => this.options().title?.() ?? '', /* @ts-ignore */
1070
+ ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
1071
+ icon = computed(() => this.options().icon?.() ?? '', /* @ts-ignore */
1072
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
1073
+ image = computed(() => this.options().image?.() ?? '', /* @ts-ignore */
1074
+ ...(ngDevMode ? [{ debugName: "image" }] : /* istanbul ignore next */ []));
1075
+ toolbarItems = computed(() => this.options().toolbarItems?.() ?? [], /* @ts-ignore */
1076
+ ...(ngDevMode ? [{ debugName: "toolbarItems" }] : /* istanbul ignore next */ []));
1077
+ headerMenu = computed(() => this.options().headerMenu?.() ?? [], /* @ts-ignore */
1078
+ ...(ngDevMode ? [{ debugName: "headerMenu" }] : /* istanbul ignore next */ []));
1079
+ drawer = signal(false, /* @ts-ignore */
1080
+ ...(ngDevMode ? [{ debugName: "drawer" }] : /* istanbul ignore next */ []));
1081
+ search = signal('', /* @ts-ignore */
1082
+ ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
1083
+ searchText = debounced(this.search, 300);
1084
+ sideMenu = computed(() => {
1085
+ const menu = this.options().sideMenu?.() ?? [];
1086
+ const text = (this.searchText.value() ?? '').trim().toLowerCase();
1087
+ if (!text)
1088
+ return menu;
1089
+ return this.searchMenu(text, menu);
1090
+ }, /* @ts-ignore */
1091
+ ...(ngDevMode ? [{ debugName: "sideMenu" }] : /* istanbul ignore next */ []));
1092
+ searchMenu(text, menu) {
1093
+ const result = [];
1094
+ for (let entry of menu ?? []) {
1095
+ const item = Object.assign({}, entry);
1096
+ item.children = this.searchMenu(text, item.children);
1097
+ if (item.children.length) {
1098
+ result.push(item);
1099
+ continue;
1100
+ }
1101
+ const itemText = item.text.toLowerCase();
1102
+ if (itemText.includes(text))
1103
+ result.push(item);
1104
+ }
1105
+ return result;
1106
+ }
1107
+ toggleDrawer(e) {
1108
+ e?.stopPropagation();
1109
+ this.drawer.update(v => !v);
1110
+ }
1111
+ closeDrawer(e) {
1112
+ e?.stopPropagation();
1113
+ this.drawer.set(false);
1114
+ }
1115
+ onDocumentClick(e) {
1116
+ const target = e.target;
1117
+ const left = this.leftRef().nativeElement;
1118
+ if (left.contains(target))
1119
+ return;
1120
+ this.drawer.set(false);
1121
+ }
1122
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxFrame, deps: [], target: i0.ɵɵFactoryTarget.Component });
1123
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgFluxFrame, isStandalone: true, selector: "ngf-frame", inputs: { viewport: { classPropertyName: "viewport", publicName: "viewport", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class.viewport": "viewport()" } }, viewQueries: [{ propertyName: "leftRef", first: true, predicate: ["left"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"frame\">\n <!-- BEGIN: Frame Header -->\n <div class=\"frame-header\">\n @if (image()) {\n <img [src]=\"image()\" alt=\"\" class=\"image\">\n } @else if (icon()) {\n <div class=\"icon\">\n <i [className]=\"icon()\"></i>\n </div>\n }\n\n @if (title()) {<h1>{{ title() }}</h1>}\n\n <ngf-frame-header-menu [menu]=\"headerMenu()\" />\n </div>\n <!-- END: Frame Header -->\n\n <div class=\"frame-body\">\n <!-- BEGIN: Left Sidebar -->\n <div #left class=\"frame-body-left\" [class.drawer]=\"drawer()\">\n <div class=\"btn-row\">\n <div class=\"close-btn\" (click)=\"closeDrawer($event)\">\n <i class=\"ngf-icon close\"></i>\n </div>\n </div>\n\n <div class=\"search-form\">\n <input type=\"text\" placeholder=\"Search menu\" [(ngModel)]=\"search\">\n\n @if (search()) {\n <div class=\"clear\" (click)=\"search.set('')\">\n <i class=\"ngf-icon close\"></i>\n </div>\n }\n </div>\n\n <div class=\"menu-pane\">\n <ngf-frame-side-menu [menu]=\"sideMenu()\" />\n </div>\n </div>\n <!-- END: Left Sidebar -->\n\n <div class=\"frame-body-overlay\" [class.drawer]=\"drawer()\"></div>\n\n <!-- BEGIN: Right Sidebar -->\n <div class=\"frame-body-right\" [class.drawer]=\"drawer()\">\n <div class=\"frame-toolbar\">\n <div class=\"drawer-btn\" (click)=\"toggleDrawer($event)\">\n <i class=\"ngf-icon menu\"></i>\n </div>\n\n <div class=\"spacer\"></div>\n\n <!--\n <div class=\"drawer-btn\" (click)=\"toggleDrawer($event)\">\n <i class=\"ngf-icon close\"></i>\n </div>\n -->\n </div>\n\n <div class=\"frame-content\">\n <ng-content></ng-content>\n </div>\n </div>\n <!-- END: Right Sidebar -->\n </div>\n</div>\n", styles: [":host{display:block;border:var(--border)!important;font-size:1rem;color:#333;--border: 1px solid #CCC;--left-width: 100%}:host .frame{display:block;position:relative;container:frame/inline-size;overflow:hidden}:host .frame-header{display:flex;flex-direction:row;box-shadow:0 0 5px #00000080;background-color:#fff;align-items:center;position:relative;padding:0 20px;height:40px;z-index:20;gap:15px}:host .frame-header>.image{display:block;object-position:center;object-fit:cover;aspect-ratio:1;height:80%}:host .frame-header>.icon{display:block}:host .frame-header>.icon>*{font-size:1.5em}:host .frame-header>h1{display:block;font-size:1.1em;font-weight:600;color:inherit;margin:0}:host .frame-header>ngf-frame-header-menu{flex:1 0 0}:host .frame-body{display:flex;flex-direction:row;position:relative;min-height:100px}@container frame (min-width: 375px){:host .frame-body{--left-width: 200px}}@container frame (min-width: 992px){:host .frame-body{--left-width: 250px}}:host .frame-body-left{display:flex;flex-direction:column;position:relative;width:var(--left-width)!important;box-shadow:0 0 5px #00000080;margin-left:calc(var(--left-width) * -1);transition:all .3s ease-in-out;background-color:#fff;z-index:15}:host .frame-body-left.drawer{margin-left:0}@container frame (min-width: 768px){:host .frame-body-left{margin-left:0}}:host .frame-body-left .btn-row{display:flex;flex-direction:row;align-items:center;justify-content:end;border-bottom:var(--border)!important;padding:2px}@container frame (min-width: 375px){:host .frame-body-left .btn-row{display:none}}:host .frame-body-left .btn-row .close-btn{display:block;cursor:pointer;padding:0 3px}:host .frame-body-left .search-form{display:block;position:relative;border-bottom:var(--border)!important;padding:10px}:host .frame-body-left .search-form>input{display:block;background-color:#fff;border:var(--border)!important;border-radius:3px;padding:10px;width:100%}:host .frame-body-left .search-form>input:focus{outline:var(--border)!important;box-shadow:none}:host .frame-body-left .search-form>.clear{display:block;position:absolute;inset:50% 20px auto auto;transform:translateY(-50%);cursor:pointer;z-index:5}:host .frame-body-left .menu-pane{display:block;flex:1 1 auto;overflow:hidden auto}:host .frame-body-overlay{display:none;position:absolute;inset:0;background-color:#0003;z-index:10}:host .frame-body-overlay.drawer{display:block}@container frame (min-width: 768px){:host .frame-body-overlay{display:none}}:host .frame-body-right{display:flex;flex-direction:column;background-color:#eee;margin-right:calc(var(--left-width) * -1);transition:all .3s ease-in-out;flex:1 0 0;width:0px}:host .frame-body-right.drawer{margin-left:0}@container frame (min-width: 768px){:host .frame-body-right{margin-left:0}}:host .frame-toolbar{display:flex;flex-direction:row;border-bottom:var(--border)!important;background-color:#fff;height:30px}:host .frame-toolbar>.spacer{display:block;flex:1 0 0;width:0px}:host .frame-toolbar>.drawer-btn{display:block;position:relative;border-right:var(--border)!important;cursor:pointer;width:30px}@container frame (min-width: 768px){:host .frame-toolbar>.drawer-btn{display:none}}:host .frame-toolbar>.drawer-btn>.ngf-icon{position:absolute;inset:50% auto auto 50%;transform:translate(-50%,-50%);font-size:1em}:host .frame-content{display:block;flex:1 1 auto;overflow:hidden auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NgFluxFrameHeaderMenu, selector: "ngf-frame-header-menu", inputs: ["menu"] }, { kind: "component", type: NgFluxFrameSideMenu, selector: "ngf-frame-side-menu", inputs: ["menu"] }] });
1124
+ }
1125
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgFluxFrame, decorators: [{
1126
+ type: Component,
1127
+ args: [{ selector: 'ngf-frame', imports: [
1128
+ FormsModule,
1129
+ NgFluxFrameHeaderMenu,
1130
+ NgFluxFrameSideMenu,
1131
+ ], host: {
1132
+ '[class.viewport]': 'viewport()',
1133
+ '(document:click)': 'onDocumentClick($event)',
1134
+ }, template: "<div class=\"frame\">\n <!-- BEGIN: Frame Header -->\n <div class=\"frame-header\">\n @if (image()) {\n <img [src]=\"image()\" alt=\"\" class=\"image\">\n } @else if (icon()) {\n <div class=\"icon\">\n <i [className]=\"icon()\"></i>\n </div>\n }\n\n @if (title()) {<h1>{{ title() }}</h1>}\n\n <ngf-frame-header-menu [menu]=\"headerMenu()\" />\n </div>\n <!-- END: Frame Header -->\n\n <div class=\"frame-body\">\n <!-- BEGIN: Left Sidebar -->\n <div #left class=\"frame-body-left\" [class.drawer]=\"drawer()\">\n <div class=\"btn-row\">\n <div class=\"close-btn\" (click)=\"closeDrawer($event)\">\n <i class=\"ngf-icon close\"></i>\n </div>\n </div>\n\n <div class=\"search-form\">\n <input type=\"text\" placeholder=\"Search menu\" [(ngModel)]=\"search\">\n\n @if (search()) {\n <div class=\"clear\" (click)=\"search.set('')\">\n <i class=\"ngf-icon close\"></i>\n </div>\n }\n </div>\n\n <div class=\"menu-pane\">\n <ngf-frame-side-menu [menu]=\"sideMenu()\" />\n </div>\n </div>\n <!-- END: Left Sidebar -->\n\n <div class=\"frame-body-overlay\" [class.drawer]=\"drawer()\"></div>\n\n <!-- BEGIN: Right Sidebar -->\n <div class=\"frame-body-right\" [class.drawer]=\"drawer()\">\n <div class=\"frame-toolbar\">\n <div class=\"drawer-btn\" (click)=\"toggleDrawer($event)\">\n <i class=\"ngf-icon menu\"></i>\n </div>\n\n <div class=\"spacer\"></div>\n\n <!--\n <div class=\"drawer-btn\" (click)=\"toggleDrawer($event)\">\n <i class=\"ngf-icon close\"></i>\n </div>\n -->\n </div>\n\n <div class=\"frame-content\">\n <ng-content></ng-content>\n </div>\n </div>\n <!-- END: Right Sidebar -->\n </div>\n</div>\n", styles: [":host{display:block;border:var(--border)!important;font-size:1rem;color:#333;--border: 1px solid #CCC;--left-width: 100%}:host .frame{display:block;position:relative;container:frame/inline-size;overflow:hidden}:host .frame-header{display:flex;flex-direction:row;box-shadow:0 0 5px #00000080;background-color:#fff;align-items:center;position:relative;padding:0 20px;height:40px;z-index:20;gap:15px}:host .frame-header>.image{display:block;object-position:center;object-fit:cover;aspect-ratio:1;height:80%}:host .frame-header>.icon{display:block}:host .frame-header>.icon>*{font-size:1.5em}:host .frame-header>h1{display:block;font-size:1.1em;font-weight:600;color:inherit;margin:0}:host .frame-header>ngf-frame-header-menu{flex:1 0 0}:host .frame-body{display:flex;flex-direction:row;position:relative;min-height:100px}@container frame (min-width: 375px){:host .frame-body{--left-width: 200px}}@container frame (min-width: 992px){:host .frame-body{--left-width: 250px}}:host .frame-body-left{display:flex;flex-direction:column;position:relative;width:var(--left-width)!important;box-shadow:0 0 5px #00000080;margin-left:calc(var(--left-width) * -1);transition:all .3s ease-in-out;background-color:#fff;z-index:15}:host .frame-body-left.drawer{margin-left:0}@container frame (min-width: 768px){:host .frame-body-left{margin-left:0}}:host .frame-body-left .btn-row{display:flex;flex-direction:row;align-items:center;justify-content:end;border-bottom:var(--border)!important;padding:2px}@container frame (min-width: 375px){:host .frame-body-left .btn-row{display:none}}:host .frame-body-left .btn-row .close-btn{display:block;cursor:pointer;padding:0 3px}:host .frame-body-left .search-form{display:block;position:relative;border-bottom:var(--border)!important;padding:10px}:host .frame-body-left .search-form>input{display:block;background-color:#fff;border:var(--border)!important;border-radius:3px;padding:10px;width:100%}:host .frame-body-left .search-form>input:focus{outline:var(--border)!important;box-shadow:none}:host .frame-body-left .search-form>.clear{display:block;position:absolute;inset:50% 20px auto auto;transform:translateY(-50%);cursor:pointer;z-index:5}:host .frame-body-left .menu-pane{display:block;flex:1 1 auto;overflow:hidden auto}:host .frame-body-overlay{display:none;position:absolute;inset:0;background-color:#0003;z-index:10}:host .frame-body-overlay.drawer{display:block}@container frame (min-width: 768px){:host .frame-body-overlay{display:none}}:host .frame-body-right{display:flex;flex-direction:column;background-color:#eee;margin-right:calc(var(--left-width) * -1);transition:all .3s ease-in-out;flex:1 0 0;width:0px}:host .frame-body-right.drawer{margin-left:0}@container frame (min-width: 768px){:host .frame-body-right{margin-left:0}}:host .frame-toolbar{display:flex;flex-direction:row;border-bottom:var(--border)!important;background-color:#fff;height:30px}:host .frame-toolbar>.spacer{display:block;flex:1 0 0;width:0px}:host .frame-toolbar>.drawer-btn{display:block;position:relative;border-right:var(--border)!important;cursor:pointer;width:30px}@container frame (min-width: 768px){:host .frame-toolbar>.drawer-btn{display:none}}:host .frame-toolbar>.drawer-btn>.ngf-icon{position:absolute;inset:50% auto auto 50%;transform:translate(-50%,-50%);font-size:1em}:host .frame-content{display:block;flex:1 1 auto;overflow:hidden auto}\n"] }]
1135
+ }], propDecorators: { leftRef: [{ type: i0.ViewChild, args: ['left', { isSignal: true }] }], viewport: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewport", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }] } });
1136
+
440
1137
  class NgFluxLoadingInternal {
441
1138
  config = inject(NGF_CONFIG);
442
1139
  appRef = inject(ApplicationRef);
@@ -879,5 +1576,5 @@ const provideNgFlux = (config) => {
879
1576
  * Generated bundle index. Do not edit.
880
1577
  */
881
1578
 
882
- export { NGF_CONFIG, NGF_DIALOG_DATA, NgFluxButton, NgFluxDialog, NgFluxDialogBodyComponent, NgFluxDialogFooterComponent, NgFluxDialogHeaderComponent, NgFluxDialogInstance, NgFluxDialogRef, NgFluxDialogRootComponent, NgFluxLoading, NgFluxLoadingRootComponent, NgFluxPagination, provideNgFlux };
1579
+ export { NGF_CONFIG, NGF_DIALOG_DATA, NgFluxActions, NgFluxButton, NgFluxDialog, NgFluxDialogBodyComponent, NgFluxDialogFooterComponent, NgFluxDialogHeaderComponent, NgFluxDialogInstance, NgFluxDialogRef, NgFluxDialogRootComponent, NgFluxFrame, NgFluxLoading, NgFluxLoadingRootComponent, NgFluxPagination, NgFluxPinInput, NgFluxSelect, NgFluxTab, NgFluxTabContentDirective, NgFluxTabGroup, NgFluxTabNavDirective, NgFluxTabNavbar, NgFluxTabPanel, provideNgFlux };
883
1580
  //# sourceMappingURL=ngflux-ngflux.mjs.map