@sneat/ui 0.1.3 → 0.1.4
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/esm2022/index.js +4 -0
- package/esm2022/index.js.map +1 -0
- package/esm2022/lib/components/index.js +3 -0
- package/esm2022/lib/components/index.js.map +1 -0
- package/esm2022/lib/components/sneat-base-modal.component.js +24 -0
- package/esm2022/lib/components/sneat-base-modal.component.js.map +1 -0
- package/esm2022/lib/components/sneat-base.component.js +58 -0
- package/esm2022/lib/components/sneat-base.component.js.map +1 -0
- package/esm2022/lib/focus.js +17 -0
- package/esm2022/lib/focus.js.map +1 -0
- package/esm2022/lib/selector/index.js +7 -0
- package/esm2022/lib/selector/index.js.map +1 -0
- package/esm2022/lib/selector/multi-selector/index.js +3 -0
- package/esm2022/lib/selector/multi-selector/index.js.map +1 -0
- package/esm2022/lib/selector/multi-selector/multi-selector.component.js +70 -0
- package/esm2022/lib/selector/multi-selector/multi-selector.component.js.map +1 -0
- package/esm2022/lib/selector/multi-selector/multi-selector.service.js +49 -0
- package/esm2022/lib/selector/multi-selector/multi-selector.service.js.map +1 -0
- package/esm2022/lib/selector/select-from-list/index.js +2 -0
- package/esm2022/lib/selector/select-from-list/index.js.map +1 -0
- package/esm2022/lib/selector/select-from-list/select-from-list.component.js +234 -0
- package/esm2022/lib/selector/select-from-list/select-from-list.component.js.map +1 -0
- package/esm2022/lib/selector/selector-base.component.js +36 -0
- package/esm2022/lib/selector/selector-base.component.js.map +1 -0
- package/esm2022/lib/selector/selector-base.service.js +49 -0
- package/esm2022/lib/selector/selector-base.service.js.map +1 -0
- package/esm2022/lib/selector/selector-interfaces.js +2 -0
- package/esm2022/lib/selector/selector-interfaces.js.map +1 -0
- package/esm2022/lib/selector/selector-options.js +2 -0
- package/esm2022/lib/selector/selector-options.js.map +1 -0
- package/esm2022/sneat-ui.js +5 -0
- package/esm2022/sneat-ui.js.map +1 -0
- package/lib/components/sneat-base-modal.component.d.ts +9 -0
- package/lib/components/sneat-base.component.d.ts +28 -0
- package/lib/focus.d.ts +3 -0
- package/lib/selector/multi-selector/multi-selector.component.d.ts +17 -0
- package/lib/selector/multi-selector/multi-selector.service.d.ts +9 -0
- package/lib/selector/select-from-list/select-from-list.component.d.ts +60 -0
- package/lib/selector/selector-base.component.d.ts +18 -0
- package/lib/selector/selector-base.service.d.ts +11 -0
- package/lib/selector/selector-interfaces.d.ts +17 -0
- package/lib/selector/selector-options.d.ts +15 -0
- package/package.json +14 -2
- package/sneat-ui.d.ts +5 -0
- package/eslint.config.js +0 -7
- package/ng-package.json +0 -7
- package/project.json +0 -38
- package/src/lib/components/sneat-base-modal.component.ts +0 -22
- package/src/lib/components/sneat-base.component.spec.ts +0 -71
- package/src/lib/components/sneat-base.component.ts +0 -78
- package/src/lib/focus.ts +0 -19
- package/src/lib/selector/multi-selector/multi-selector.component.html +0 -26
- package/src/lib/selector/multi-selector/multi-selector.component.spec.ts +0 -147
- package/src/lib/selector/multi-selector/multi-selector.component.ts +0 -79
- package/src/lib/selector/multi-selector/multi-selector.service.spec.ts +0 -91
- package/src/lib/selector/multi-selector/multi-selector.service.ts +0 -49
- package/src/lib/selector/select-from-list/select-from-list.component.html +0 -210
- package/src/lib/selector/select-from-list/select-from-list.component.spec.ts +0 -297
- package/src/lib/selector/select-from-list/select-from-list.component.ts +0 -283
- package/src/lib/selector/selector-base.component.ts +0 -43
- package/src/lib/selector/selector-base.service.ts +0 -62
- package/src/lib/selector/selector-interfaces.ts +0 -28
- package/src/lib/selector/selector-options.ts +0 -18
- package/src/test-setup.ts +0 -3
- package/tsconfig.json +0 -13
- package/tsconfig.lib.json +0 -19
- package/tsconfig.lib.prod.json +0 -7
- package/tsconfig.spec.json +0 -31
- package/vite.config.mts +0 -10
- /package/{src/index.ts → index.d.ts} +0 -0
- /package/{src/lib/components/index.ts → lib/components/index.d.ts} +0 -0
- /package/{src/lib/selector/index.ts → lib/selector/index.d.ts} +0 -0
- /package/{src/lib/selector/multi-selector/index.ts → lib/selector/multi-selector/index.d.ts} +0 -0
- /package/{src/lib/selector/select-from-list/index.ts → lib/selector/select-from-list/index.d.ts} +0 -0
package/esm2022/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/ui/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC","sourcesContent":["export * from './lib/focus';\nexport * from './lib/components';\nexport * from './lib/selector';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/ui/src/lib/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC","sourcesContent":["export * from './sneat-base.component';\nexport * from './sneat-base-modal.component';\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { inject, Injectable } from '@angular/core';
|
|
2
|
+
import { SneatBaseComponent } from './sneat-base.component';
|
|
3
|
+
import { ModalController } from '@ionic/angular/standalone';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export class SneatBaseModalComponent extends SneatBaseComponent {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.modalController = inject(ModalController);
|
|
9
|
+
}
|
|
10
|
+
close() {
|
|
11
|
+
this.dismissModal();
|
|
12
|
+
}
|
|
13
|
+
dismissModal(data, role, id) {
|
|
14
|
+
this.modalController
|
|
15
|
+
.dismiss(data, role, id)
|
|
16
|
+
.catch(this.errorLogger.logErrorHandler(`Failed to close modal ${this.className}`));
|
|
17
|
+
}
|
|
18
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SneatBaseModalComponent, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
19
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SneatBaseModalComponent }); }
|
|
20
|
+
}
|
|
21
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SneatBaseModalComponent, decorators: [{
|
|
22
|
+
type: Injectable
|
|
23
|
+
}] });
|
|
24
|
+
//# sourceMappingURL=sneat-base-modal.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sneat-base-modal.component.js","sourceRoot":"","sources":["../../../../../../libs/ui/src/lib/components/sneat-base-modal.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;;AAG5D,MAAM,OAAgB,uBAAwB,SAAQ,kBAAkB;IADxE;;QAEmB,oBAAe,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;KAe5D;IAbW,KAAK;QACb,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAES,YAAY,CAAC,IAAc,EAAE,IAAa,EAAE,EAAW;QAC/D,IAAI,CAAC,eAAe;aACjB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;aACvB,KAAK,CACJ,IAAI,CAAC,WAAW,CAAC,eAAe,CAC9B,yBAAyB,IAAI,CAAC,SAAS,EAAE,CAC1C,CACF,CAAC;IACN,CAAC;8GAfmB,uBAAuB;kHAAvB,uBAAuB;;2FAAvB,uBAAuB;kBAD5C,UAAU","sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { SneatBaseComponent } from './sneat-base.component';\nimport { ModalController } from '@ionic/angular/standalone';\n\n@Injectable()\nexport abstract class SneatBaseModalComponent extends SneatBaseComponent {\n private readonly modalController = inject(ModalController);\n\n protected close(): void {\n this.dismissModal();\n }\n\n protected dismissModal(data?: unknown, role?: string, id?: string): void {\n this.modalController\n .dismiss(data, role, id)\n .catch(\n this.errorLogger.logErrorHandler(\n `Failed to close modal ${this.className}`,\n ),\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { inject, Injectable, InjectionToken } from '@angular/core';
|
|
2
|
+
import { createSetFocusToInput } from '../focus';
|
|
3
|
+
import { ErrorLogger } from '@sneat/core';
|
|
4
|
+
import { Subject, Subscription } from 'rxjs';
|
|
5
|
+
import { takeUntil } from 'rxjs/operators';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
export const ClassName = new InjectionToken('className');
|
|
8
|
+
export class SneatBaseComponent {
|
|
9
|
+
constructor() {
|
|
10
|
+
// protected $isInitialized = signal(false);
|
|
11
|
+
//
|
|
12
|
+
// // eslint-disable-next-line @angular-eslint/contextual-lifecycle
|
|
13
|
+
// public ngOnInit() {
|
|
14
|
+
// console.info(`${this.className}.SneatBaseComponent.ngOnInit()`);
|
|
15
|
+
// // $isInitialized is for workaround for https://angular.dev/errors/NG0950
|
|
16
|
+
// // Required input is accessed before a value is set.
|
|
17
|
+
// // Might be excessive and should be removed if we can find a better way.
|
|
18
|
+
// this.$isInitialized.set(true);
|
|
19
|
+
// }
|
|
20
|
+
this.destroyed = new Subject();
|
|
21
|
+
// Signals that the component is destroyed and should not be used anymore
|
|
22
|
+
this.destroyed$ = this.destroyed.asObservable();
|
|
23
|
+
// All active subscriptions of a component. Will be unsubscribed on destroy
|
|
24
|
+
this.subs = new Subscription();
|
|
25
|
+
this.console = console;
|
|
26
|
+
this.errorLogger = inject(ErrorLogger);
|
|
27
|
+
this.logError = this.errorLogger.logError;
|
|
28
|
+
this.logErrorHandler = this.errorLogger.logErrorHandler;
|
|
29
|
+
// Passes focus to the input element
|
|
30
|
+
this.setFocusToInput = createSetFocusToInput(this.errorLogger);
|
|
31
|
+
this.className = inject(ClassName);
|
|
32
|
+
this.log(`${this.className}.SneatBaseComponent.constructor()`);
|
|
33
|
+
}
|
|
34
|
+
log(msg, ...data) {
|
|
35
|
+
this.console.log(msg, ...data);
|
|
36
|
+
}
|
|
37
|
+
// protected readonly takeUntilDestroyed = <T>() =>
|
|
38
|
+
// takeUntil<T>(this.destroyed$);
|
|
39
|
+
takeUntilDestroyed() {
|
|
40
|
+
return takeUntil(this.destroyed$);
|
|
41
|
+
}
|
|
42
|
+
ngOnDestroy() {
|
|
43
|
+
this.log(`${this.className}.SneatBaseComponent.ngOnDestroy()`);
|
|
44
|
+
this.unsubscribe(`${this.className}.SneatBaseComponent.ngOnDestroy()`);
|
|
45
|
+
this.destroyed?.next();
|
|
46
|
+
this.destroyed?.complete();
|
|
47
|
+
}
|
|
48
|
+
unsubscribe(reason) {
|
|
49
|
+
this.log(`${this.className}.SneatBaseComponent.unsubscribe(reason: ${reason})`);
|
|
50
|
+
this.subs.unsubscribe();
|
|
51
|
+
}
|
|
52
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SneatBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
53
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SneatBaseComponent }); }
|
|
54
|
+
}
|
|
55
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SneatBaseComponent, decorators: [{
|
|
56
|
+
type: Injectable
|
|
57
|
+
}], ctorParameters: () => [] });
|
|
58
|
+
//# sourceMappingURL=sneat-base.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sneat-base.component.js","sourceRoot":"","sources":["../../../../../../libs/ui/src/lib/components/sneat-base.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAa,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAA4B,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;;AAY3C,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,cAAc,CAAS,WAAW,CAAC,CAAC;AAGjE,MAAM,OAAgB,kBAAkB;IA+BtC;QA9BA,4CAA4C;QAC5C,EAAE;QACF,mEAAmE;QACnE,sBAAsB;QACtB,oEAAoE;QACpE,6EAA6E;QAC7E,wDAAwD;QACxD,4EAA4E;QAC5E,kCAAkC;QAClC,IAAI;QAEa,cAAS,GAAG,IAAI,OAAO,EAAQ,CAAC;QACjD,yEAAyE;QACtD,eAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;QAE9D,2EAA2E;QACxD,SAAI,GAAG,IAAI,YAAY,EAAE,CAAC;QAE1B,YAAO,GAAa,OAAO,CAAC;QAE5B,gBAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QAElC,aAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;QACrC,oBAAe,GAAG,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC;QAEtE,oCAAoC;QACjB,oBAAe,GAAG,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE1D,cAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAG/C,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,mCAAmC,CAAC,CAAC;IACjE,CAAC;IAES,GAAG,CAAC,GAAW,EAAE,GAAG,IAAe;QAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,mDAAmD;IACnD,kCAAkC;IACxB,kBAAkB;QAC1B,OAAO,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEM,WAAW;QAChB,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,mCAAmC,CAAC,CAAC;QAC/D,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,SAAS,mCAAmC,CAAC,CAAC;QACvE,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAES,WAAW,CAAC,MAAe;QACnC,IAAI,CAAC,GAAG,CACN,GAAG,IAAI,CAAC,SAAS,2CAA2C,MAAM,GAAG,CACtE,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;8GAzDmB,kBAAkB;kHAAlB,kBAAkB;;2FAAlB,kBAAkB;kBADvC,UAAU","sourcesContent":["import { inject, Injectable, InjectionToken, OnDestroy } from '@angular/core';\nimport { createSetFocusToInput } from '../focus';\nimport { ErrorLogger } from '@sneat/core';\nimport { MonoTypeOperatorFunction, Subject, Subscription } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\nexport interface IConsole {\n log(...data: unknown[]): void;\n\n warn(...data: unknown[]): void;\n\n trace(...data: unknown[]): void;\n\n error(...data: unknown[]): void;\n}\n\nexport const ClassName = new InjectionToken<string>('className');\n\n@Injectable()\nexport abstract class SneatBaseComponent implements OnDestroy {\n // protected $isInitialized = signal(false);\n //\n // // eslint-disable-next-line @angular-eslint/contextual-lifecycle\n // public ngOnInit() {\n // \tconsole.info(`${this.className}.SneatBaseComponent.ngOnInit()`);\n // \t// $isInitialized is for workaround for https://angular.dev/errors/NG0950\n // \t// Required input is accessed before a value is set.\n // \t// Might be excessive and should be removed if we can find a better way.\n // \tthis.$isInitialized.set(true);\n // }\n\n private readonly destroyed = new Subject<void>();\n // Signals that the component is destroyed and should not be used anymore\n protected readonly destroyed$ = this.destroyed.asObservable();\n\n // All active subscriptions of a component. Will be unsubscribed on destroy\n protected readonly subs = new Subscription();\n\n protected readonly console: IConsole = console;\n\n protected readonly errorLogger = inject(ErrorLogger);\n\n protected readonly logError = this.errorLogger.logError;\n protected readonly logErrorHandler = this.errorLogger.logErrorHandler;\n\n // Passes focus to the input element\n protected readonly setFocusToInput = createSetFocusToInput(this.errorLogger);\n\n protected readonly className = inject(ClassName);\n\n public constructor() {\n this.log(`${this.className}.SneatBaseComponent.constructor()`);\n }\n\n protected log(msg: string, ...data: unknown[]): void {\n this.console.log(msg, ...data);\n }\n\n // protected readonly takeUntilDestroyed = <T>() =>\n // \ttakeUntil<T>(this.destroyed$);\n protected takeUntilDestroyed<T>(): MonoTypeOperatorFunction<T> {\n return takeUntil(this.destroyed$);\n }\n\n public ngOnDestroy(): void {\n this.log(`${this.className}.SneatBaseComponent.ngOnDestroy()`);\n this.unsubscribe(`${this.className}.SneatBaseComponent.ngOnDestroy()`);\n this.destroyed?.next();\n this.destroyed?.complete();\n }\n\n protected unsubscribe(reason?: string): void {\n this.log(\n `${this.className}.SneatBaseComponent.unsubscribe(reason: ${reason})`,\n );\n this.subs.unsubscribe();\n }\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function createSetFocusToInput(errorLogger) {
|
|
2
|
+
return (input, delay = 100) => {
|
|
3
|
+
if (!input) {
|
|
4
|
+
console.error('can not set focus to undefined input');
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
setTimeout(() => {
|
|
8
|
+
requestAnimationFrame(() => {
|
|
9
|
+
// input.getInputElement().then(el => el.focus()).catch(errorLogger.logErrorHandler('failed to set focus to input'));
|
|
10
|
+
input
|
|
11
|
+
.setFocus()
|
|
12
|
+
.catch(errorLogger.logErrorHandler('failed to set focus to input'));
|
|
13
|
+
});
|
|
14
|
+
}, delay);
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=focus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/focus.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CAAC,WAAyB;IAC7D,OAAO,CAAC,KAA8B,EAAE,KAAK,GAAG,GAAG,EAAQ,EAAE;QAC3D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,UAAU,CAAC,GAAG,EAAE;YACd,qBAAqB,CAAC,GAAG,EAAE;gBACzB,qHAAqH;gBACrH,KAAK;qBACF,QAAQ,EAAE;qBACV,KAAK,CAAC,WAAW,CAAC,eAAe,CAAC,8BAA8B,CAAC,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { IonInput, IonTextarea } from '@ionic/angular/standalone';\nimport { IErrorLogger } from '@sneat/core';\n\nexport function createSetFocusToInput(errorLogger: IErrorLogger) {\n return (input?: IonInput | IonTextarea, delay = 100): void => {\n if (!input) {\n console.error('can not set focus to undefined input');\n return;\n }\n setTimeout(() => {\n requestAnimationFrame(() => {\n // input.getInputElement().then(el => el.focus()).catch(errorLogger.logErrorHandler('failed to set focus to input'));\n input\n .setFocus()\n .catch(errorLogger.logErrorHandler('failed to set focus to input'));\n });\n }, delay);\n };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './selector-interfaces';
|
|
2
|
+
export * from './selector-options';
|
|
3
|
+
export * from './selector-base.service';
|
|
4
|
+
export * from './selector-base.component';
|
|
5
|
+
export * from './multi-selector';
|
|
6
|
+
export * from './select-from-list';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/ui/src/lib/selector/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC","sourcesContent":["export * from './selector-interfaces';\nexport * from './selector-options';\nexport * from './selector-base.service';\nexport * from './selector-base.component';\nexport * from './multi-selector';\nexport * from './select-from-list';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/ui/src/lib/selector/multi-selector/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC","sourcesContent":["export * from './multi-selector.service';\nexport * from './multi-selector.component';\n"]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, } from '@angular/core';
|
|
2
|
+
import { IonButton, IonButtons, IonCard, IonIcon, IonItem, IonItemDivider, IonLabel, IonList, ModalController, } from '@ionic/angular/standalone';
|
|
3
|
+
import { ClassName } from '../../components';
|
|
4
|
+
import { OverlayController, SelectorBaseComponent, } from '../selector-base.component';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export class MultiSelectorComponent extends SelectorBaseComponent {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.title = 'Select';
|
|
10
|
+
this.canRemove = false;
|
|
11
|
+
this.removeItems = new EventEmitter();
|
|
12
|
+
this.addItems = new EventEmitter();
|
|
13
|
+
}
|
|
14
|
+
ngOnChanges(changes) {
|
|
15
|
+
if (changes['allItems']) {
|
|
16
|
+
this.selectedItems = this.allItems?.filter((item) => this.selectedIDs?.includes(item.id));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
removeItem(event, item) {
|
|
20
|
+
event.stopPropagation();
|
|
21
|
+
this.selectedItems = this.selectedItems?.filter((i) => i.id !== item.id);
|
|
22
|
+
this.removeItems.emit([{ event, item }]);
|
|
23
|
+
}
|
|
24
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MultiSelectorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
25
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: MultiSelectorComponent, isStandalone: true, selector: "sneat-multi-selector", inputs: { title: "title", canRemove: "canRemove", allItems: "allItems", selectedIDs: "selectedIDs" }, outputs: { removeItems: "removeItems", addItems: "addItems" }, providers: [
|
|
26
|
+
{
|
|
27
|
+
provide: ClassName,
|
|
28
|
+
useValue: 'MultiSelectorComponent',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
provide: OverlayController,
|
|
32
|
+
useClass: ModalController,
|
|
33
|
+
},
|
|
34
|
+
], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ion-card>\n <ion-item-divider color=\"light\">\n <ion-label color=\"medium\">{{ title }}</ion-label>\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\">\n <ion-icon name=\"add-outline\" />\n <ion-label>Add</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-item-divider>\n\n <ion-list>\n @for (item of selectedItems; track item.id) {\n <ion-item>\n <ion-label>{{ item.title }}</ion-label>\n @if (canRemove) {\n <ion-buttons slot=\"end\">\n <ion-button title=\"Remove\" (click)=\"removeItem($event, item)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n }\n </ion-list>\n</ion-card>\n", dependencies: [{ kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonItemDivider, selector: "ion-item-divider", inputs: ["color", "mode", "sticky"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }] }); }
|
|
35
|
+
}
|
|
36
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MultiSelectorComponent, decorators: [{
|
|
37
|
+
type: Component,
|
|
38
|
+
args: [{ selector: 'sneat-multi-selector', imports: [
|
|
39
|
+
IonCard,
|
|
40
|
+
IonItemDivider,
|
|
41
|
+
IonLabel,
|
|
42
|
+
IonButtons,
|
|
43
|
+
IonButton,
|
|
44
|
+
IonItem,
|
|
45
|
+
IonIcon,
|
|
46
|
+
IonList,
|
|
47
|
+
], providers: [
|
|
48
|
+
{
|
|
49
|
+
provide: ClassName,
|
|
50
|
+
useValue: 'MultiSelectorComponent',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
provide: OverlayController,
|
|
54
|
+
useClass: ModalController,
|
|
55
|
+
},
|
|
56
|
+
], template: "<ion-card>\n <ion-item-divider color=\"light\">\n <ion-label color=\"medium\">{{ title }}</ion-label>\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\">\n <ion-icon name=\"add-outline\" />\n <ion-label>Add</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-item-divider>\n\n <ion-list>\n @for (item of selectedItems; track item.id) {\n <ion-item>\n <ion-label>{{ item.title }}</ion-label>\n @if (canRemove) {\n <ion-buttons slot=\"end\">\n <ion-button title=\"Remove\" (click)=\"removeItem($event, item)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n }\n </ion-list>\n</ion-card>\n" }]
|
|
57
|
+
}], propDecorators: { title: [{
|
|
58
|
+
type: Input
|
|
59
|
+
}], canRemove: [{
|
|
60
|
+
type: Input
|
|
61
|
+
}], allItems: [{
|
|
62
|
+
type: Input
|
|
63
|
+
}], selectedIDs: [{
|
|
64
|
+
type: Input
|
|
65
|
+
}], removeItems: [{
|
|
66
|
+
type: Output
|
|
67
|
+
}], addItems: [{
|
|
68
|
+
type: Output
|
|
69
|
+
}] } });
|
|
70
|
+
//# sourceMappingURL=multi-selector.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-selector.component.js","sourceRoot":"","sources":["../../../../../../../libs/ui/src/lib/selector/multi-selector/multi-selector.component.ts","../../../../../../../libs/ui/src/lib/selector/multi-selector/multi-selector.component.html"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,YAAY,EACZ,KAAK,EAEL,MAAM,GAEP,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,SAAS,EACT,UAAU,EACV,OAAO,EACP,OAAO,EACP,OAAO,EACP,cAAc,EACd,QAAQ,EACR,OAAO,EACP,eAAe,GAChB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EACL,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;;AA0BpC,MAAM,OAAO,sBACX,SAAQ,qBAAwB;IAzBlC;;QA4BW,UAAK,GAAG,QAAQ,CAAC;QAEjB,cAAS,GAAG,KAAK,CAAC;QAIR,gBAAW,GAAG,IAAI,YAAY,EAAsB,CAAC;QACrD,aAAQ,GAAG,IAAI,YAAY,EAAsB,CAAC;KAiBtE;IAbC,WAAW,CAAC,OAAsB;QAChC,IAAI,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAClD,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CACpC,CAAC;QACJ,CAAC;IACH,CAAC;IAES,UAAU,CAAC,KAAY,EAAE,IAAiB;QAClD,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;8GA3BU,sBAAsB;kGAAtB,sBAAsB,wOAXtB;YACT;gBACE,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,wBAAwB;aACnC;YACD;gBACE,OAAO,EAAE,iBAAiB;gBAC1B,QAAQ,EAAE,eAAe;aAC1B;SACF,sEChDH,iwBA0BA,4CDII,OAAO,yLACP,cAAc,kGACd,QAAQ,6FACR,UAAU,8EACV,SAAS,oPACT,OAAO,0NACP,OAAO,2JACP,OAAO;;2FAaE,sBAAsB;kBAxBlC,SAAS;+BACE,sBAAsB,WAEvB;wBACP,OAAO;wBACP,cAAc;wBACd,QAAQ;wBACR,UAAU;wBACV,SAAS;wBACT,OAAO;wBACP,OAAO;wBACP,OAAO;qBACR,aACU;wBACT;4BACE,OAAO,EAAE,SAAS;4BAClB,QAAQ,EAAE,wBAAwB;yBACnC;wBACD;4BACE,OAAO,EAAE,iBAAiB;4BAC1B,QAAQ,EAAE,eAAe;yBAC1B;qBACF;;sBAMA,KAAK;;sBAEL,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBAEL,MAAM;;sBACN,MAAM","sourcesContent":["import {\n Component,\n EventEmitter,\n Input,\n OnChanges,\n Output,\n SimpleChanges,\n} from '@angular/core';\nimport {\n IonButton,\n IonButtons,\n IonCard,\n IonIcon,\n IonItem,\n IonItemDivider,\n IonLabel,\n IonList,\n ModalController,\n} from '@ionic/angular/standalone';\nimport { ClassName } from '../../components';\nimport { ISelectItem, ISelectItemEvent } from '../selector-interfaces';\nimport {\n OverlayController,\n SelectorBaseComponent,\n} from '../selector-base.component';\n\n@Component({\n selector: 'sneat-multi-selector',\n templateUrl: './multi-selector.component.html',\n imports: [\n IonCard,\n IonItemDivider,\n IonLabel,\n IonButtons,\n IonButton,\n IonItem,\n IonIcon,\n IonList,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'MultiSelectorComponent',\n },\n {\n provide: OverlayController,\n useClass: ModalController,\n },\n ],\n})\nexport class MultiSelectorComponent<T = ISelectItem>\n extends SelectorBaseComponent<T>\n implements OnChanges\n{\n @Input() title = 'Select';\n\n @Input() canRemove = false;\n @Input() public allItems?: ISelectItem[];\n @Input() public selectedIDs?: readonly string[];\n\n @Output() readonly removeItems = new EventEmitter<ISelectItemEvent[]>();\n @Output() readonly addItems = new EventEmitter<ISelectItemEvent[]>();\n\n protected selectedItems?: ISelectItem[];\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['allItems']) {\n this.selectedItems = this.allItems?.filter((item) =>\n this.selectedIDs?.includes(item.id),\n );\n }\n }\n\n protected removeItem(event: Event, item: ISelectItem): void {\n event.stopPropagation();\n this.selectedItems = this.selectedItems?.filter((i) => i.id !== item.id);\n this.removeItems.emit([{ event, item }]);\n }\n}\n","<ion-card>\n <ion-item-divider color=\"light\">\n <ion-label color=\"medium\">{{ title }}</ion-label>\n <ion-buttons slot=\"end\">\n <ion-button color=\"medium\">\n <ion-icon name=\"add-outline\" />\n <ion-label>Add</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-item-divider>\n\n <ion-list>\n @for (item of selectedItems; track item.id) {\n <ion-item>\n <ion-label>{{ item.title }}</ion-label>\n @if (canRemove) {\n <ion-buttons slot=\"end\">\n <ion-button title=\"Remove\" (click)=\"removeItem($event, item)\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n }\n </ion-list>\n</ion-card>\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { __decorate, __metadata, __param } from "tslib";
|
|
2
|
+
import { Inject } from '@angular/core';
|
|
3
|
+
import { ModalController } from '@ionic/angular/standalone';
|
|
4
|
+
import { ErrorLogger } from '@sneat/core';
|
|
5
|
+
import { MultiSelectorComponent } from './multi-selector.component';
|
|
6
|
+
let MultiSelectorService = class MultiSelectorService {
|
|
7
|
+
constructor(errorLogger, modalController) {
|
|
8
|
+
this.errorLogger = errorLogger;
|
|
9
|
+
this.modalController = modalController;
|
|
10
|
+
}
|
|
11
|
+
selectMultiple(items, selectedItems) {
|
|
12
|
+
const result = new Promise((resolve, reject) => {
|
|
13
|
+
const modalOptions = {
|
|
14
|
+
component: MultiSelectorComponent,
|
|
15
|
+
componentProps: {
|
|
16
|
+
items,
|
|
17
|
+
selectedItems,
|
|
18
|
+
},
|
|
19
|
+
keyboardClose: true,
|
|
20
|
+
};
|
|
21
|
+
this.modalController
|
|
22
|
+
.create(modalOptions)
|
|
23
|
+
.then((modal) => {
|
|
24
|
+
modal
|
|
25
|
+
.onDidDismiss()
|
|
26
|
+
.then((res) => resolve(res.data?.selectedItems || []))
|
|
27
|
+
.catch((err) => {
|
|
28
|
+
this.errorLogger.logError(err, 'Failed to handle modal dismiss');
|
|
29
|
+
reject(err);
|
|
30
|
+
});
|
|
31
|
+
modal.present().catch((err) => {
|
|
32
|
+
reject(err);
|
|
33
|
+
this.errorLogger.logError('Failed to present modal');
|
|
34
|
+
});
|
|
35
|
+
})
|
|
36
|
+
.catch((err) => {
|
|
37
|
+
this.errorLogger.logError(err, 'Failed to create modal');
|
|
38
|
+
reject(err);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
MultiSelectorService = __decorate([
|
|
45
|
+
__param(0, Inject(ErrorLogger)),
|
|
46
|
+
__metadata("design:paramtypes", [Object, ModalController])
|
|
47
|
+
], MultiSelectorService);
|
|
48
|
+
export { MultiSelectorService };
|
|
49
|
+
//# sourceMappingURL=multi-selector.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-selector.service.js","sourceRoot":"","sources":["../../../../../../../libs/ui/src/lib/selector/multi-selector/multi-selector.service.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,eAAe,EAAgB,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,IAAa,oBAAoB,GAAjC,MAAa,oBAAoB;IAC/B,YACwC,WAAyB,EAC9C,eAAgC;QADX,gBAAW,GAAX,WAAW,CAAc;QAC9C,oBAAe,GAAf,eAAe,CAAiB;IAChD,CAAC;IAEJ,cAAc,CACZ,KAAoB,EACpB,aAA4B;QAE5B,MAAM,MAAM,GAAG,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5D,MAAM,YAAY,GAAiB;gBACjC,SAAS,EAAE,sBAAsB;gBACjC,cAAc,EAAE;oBACd,KAAK;oBACL,aAAa;iBACd;gBACD,aAAa,EAAE,IAAI;aACpB,CAAC;YACF,IAAI,CAAC,eAAe;iBACjB,MAAM,CAAC,YAAY,CAAC;iBACpB,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBACd,KAAK;qBACF,YAAY,EAAE;qBACd,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC;qBACrD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACb,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,gCAAgC,CAAC,CAAC;oBACjE,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC,CAAC,CAAC;gBACL,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC5B,MAAM,CAAC,GAAG,CAAC,CAAC;oBACZ,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;gBACvD,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACb,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;gBACzD,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAA;AA1CY,oBAAoB;IAE5B,WAAA,MAAM,CAAC,WAAW,CAAC,CAAA;6CACc,eAAe;GAHxC,oBAAoB,CA0ChC","sourcesContent":["import { Inject } from '@angular/core';\nimport { ModalController, ModalOptions } from '@ionic/angular/standalone';\nimport { ErrorLogger, IErrorLogger } from '@sneat/core';\nimport { ISelectItem } from '../selector-interfaces';\nimport { MultiSelectorComponent } from './multi-selector.component';\n\nexport class MultiSelectorService {\n constructor(\n @Inject(ErrorLogger) private readonly errorLogger: IErrorLogger,\n private readonly modalController: ModalController,\n ) {}\n\n selectMultiple(\n items: ISelectItem[],\n selectedItems: ISelectItem[],\n ): Promise<ISelectItem[]> {\n const result = new Promise<ISelectItem[]>((resolve, reject) => {\n const modalOptions: ModalOptions = {\n component: MultiSelectorComponent,\n componentProps: {\n items,\n selectedItems,\n },\n keyboardClose: true,\n };\n this.modalController\n .create(modalOptions)\n .then((modal) => {\n modal\n .onDidDismiss()\n .then((res) => resolve(res.data?.selectedItems || []))\n .catch((err) => {\n this.errorLogger.logError(err, 'Failed to handle modal dismiss');\n reject(err);\n });\n modal.present().catch((err) => {\n reject(err);\n this.errorLogger.logError('Failed to present modal');\n });\n })\n .catch((err) => {\n this.errorLogger.logError(err, 'Failed to create modal');\n reject(err);\n });\n });\n\n return result;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../libs/ui/src/lib/selector/select-from-list/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC","sourcesContent":["export * from './select-from-list.component';\n"]}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, EventEmitter, forwardRef, input, Input, Output, signal, ViewChild, inject, } from '@angular/core';
|
|
2
|
+
import { FormsModule, NG_VALUE_ACCESSOR, } from '@angular/forms';
|
|
3
|
+
import { RouterModule } from '@angular/router';
|
|
4
|
+
import { IonButton, IonButtons, IonCheckbox, IonIcon, IonInput, IonItem, IonItemDivider, IonItemGroup, IonLabel, IonList, IonRadio, IonRadioGroup, IonSelect, IonSelectOption, IonSpinner, } from '@ionic/angular/standalone';
|
|
5
|
+
import { ErrorLogger } from '@sneat/core';
|
|
6
|
+
import { NEVER, Observable, Subject, takeUntil } from 'rxjs';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/forms";
|
|
9
|
+
export class SelectFromListComponent {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.errorLogger = inject(ErrorLogger);
|
|
12
|
+
this.value = '';
|
|
13
|
+
this.valueChange = new EventEmitter();
|
|
14
|
+
this.filterLabel = 'Find';
|
|
15
|
+
this.label = 'Please choose';
|
|
16
|
+
this.items$ = NEVER;
|
|
17
|
+
this.$items = signal(undefined, ...(ngDevMode ? [{ debugName: "$items" }] : []));
|
|
18
|
+
this.other = 'none';
|
|
19
|
+
this.canAdd = false;
|
|
20
|
+
this.filterChanged = new EventEmitter();
|
|
21
|
+
this.selectMode = 'single';
|
|
22
|
+
this.isReadonly = false;
|
|
23
|
+
this.$isProcessing = input(...(ngDevMode ? [undefined, { debugName: "$isProcessing" }] : []));
|
|
24
|
+
// @Input() ngModel?: string;
|
|
25
|
+
// @Output() readonly ngModelChange = new EventEmitter<string>();
|
|
26
|
+
this.destroyed = new Subject();
|
|
27
|
+
this.$displayItems = signal(undefined, ...(ngDevMode ? [{ debugName: "$displayItems" }] : []));
|
|
28
|
+
this.$hiddenCount = computed(() => {
|
|
29
|
+
return (this.$items()?.length || 0) - (this.$displayItems()?.length || 0);
|
|
30
|
+
}, ...(ngDevMode ? [{ debugName: "$hiddenCount" }] : []));
|
|
31
|
+
this.isDisabled = false;
|
|
32
|
+
this.$filter = signal('', ...(ngDevMode ? [{ debugName: "$filter" }] : []));
|
|
33
|
+
this.$selectedItem = signal(undefined, ...(ngDevMode ? [{ debugName: "$selectedItem" }] : []));
|
|
34
|
+
this.onChange = (id) => {
|
|
35
|
+
this.value = id;
|
|
36
|
+
if (this.$selectedItem()?.id !== id) {
|
|
37
|
+
const selectedItem = this.items?.find((item) => item.id === id);
|
|
38
|
+
this.$selectedItem.set(selectedItem);
|
|
39
|
+
}
|
|
40
|
+
this.valueChange.emit(this.value);
|
|
41
|
+
};
|
|
42
|
+
this.onTouched = () => void 0;
|
|
43
|
+
}
|
|
44
|
+
focus() {
|
|
45
|
+
setTimeout(() => {
|
|
46
|
+
this.filterInput
|
|
47
|
+
?.setFocus()
|
|
48
|
+
.catch(this.errorLogger.logErrorHandler('Failed to set focus to filter input'));
|
|
49
|
+
}, 100);
|
|
50
|
+
}
|
|
51
|
+
ngOnChanges(changes) {
|
|
52
|
+
if (changes['items']) {
|
|
53
|
+
this.$items.set(this.items);
|
|
54
|
+
this.applyFilter();
|
|
55
|
+
}
|
|
56
|
+
if (changes['items$'] && this.items$) {
|
|
57
|
+
this.items$?.pipe(takeUntil(this.destroyed)).subscribe((items) => {
|
|
58
|
+
this.$items.set(items);
|
|
59
|
+
this.applyFilter();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
applyFilter() {
|
|
64
|
+
const f = this.$filter().trim().toLowerCase();
|
|
65
|
+
// console.log('SelectFromListComponent.applyFilter', f);
|
|
66
|
+
const items = this.$items();
|
|
67
|
+
let displayItems = f
|
|
68
|
+
? items?.filter((v) => v.title.toLowerCase().includes(f) ||
|
|
69
|
+
v.longTitle?.toLowerCase().includes(f) ||
|
|
70
|
+
(this.filterItem && this.filterItem(v, f)))
|
|
71
|
+
: items;
|
|
72
|
+
if (displayItems && this.sortBy) {
|
|
73
|
+
switch (this.sortBy) {
|
|
74
|
+
case 'title':
|
|
75
|
+
displayItems = [...displayItems].toSorted((a, b) => a.title.localeCompare(b.title));
|
|
76
|
+
break;
|
|
77
|
+
case 'id':
|
|
78
|
+
displayItems = [...displayItems].toSorted((a, b) => a.id.localeCompare(b.id));
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.$displayItems.set(displayItems);
|
|
83
|
+
}
|
|
84
|
+
select(item) {
|
|
85
|
+
switch (this.selectMode) {
|
|
86
|
+
case 'multiple':
|
|
87
|
+
return;
|
|
88
|
+
case 'single':
|
|
89
|
+
this.$selectedItem.set(item);
|
|
90
|
+
this.onChange(item.id);
|
|
91
|
+
if (this.$filter()) {
|
|
92
|
+
this.clearFilter();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
onRadioChanged(event) {
|
|
97
|
+
if (this.selectMode !== 'single') {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const value = event.detail['value'];
|
|
101
|
+
this.value = value;
|
|
102
|
+
this.onChange(value);
|
|
103
|
+
this.clearFilter();
|
|
104
|
+
}
|
|
105
|
+
onSelectChanged() {
|
|
106
|
+
// this.value = (event as CustomEvent).detail['value'] as string;
|
|
107
|
+
this.onChange(this.value || '');
|
|
108
|
+
}
|
|
109
|
+
registerOnChange(fn) {
|
|
110
|
+
this.onChange = fn;
|
|
111
|
+
}
|
|
112
|
+
registerOnTouched(fn) {
|
|
113
|
+
this.onTouched = fn;
|
|
114
|
+
}
|
|
115
|
+
setDisabledState(isDisabled) {
|
|
116
|
+
this.isDisabled = isDisabled;
|
|
117
|
+
}
|
|
118
|
+
writeValue(obj) {
|
|
119
|
+
this.value = obj;
|
|
120
|
+
}
|
|
121
|
+
onFilterChanged(event, source) {
|
|
122
|
+
void source;
|
|
123
|
+
this.$filter.set(event.detail.value || '');
|
|
124
|
+
this.applyFilter();
|
|
125
|
+
this.filterChanged.emit(this.$filter());
|
|
126
|
+
}
|
|
127
|
+
clearFilter() {
|
|
128
|
+
this.$filter.set('');
|
|
129
|
+
this.filterChanged.emit(this.$filter());
|
|
130
|
+
this.applyFilter();
|
|
131
|
+
}
|
|
132
|
+
deselect() {
|
|
133
|
+
this.value = '';
|
|
134
|
+
this.onChange(this.value);
|
|
135
|
+
}
|
|
136
|
+
onAdd(event) {
|
|
137
|
+
event.preventDefault();
|
|
138
|
+
this.value = this.$filter();
|
|
139
|
+
this.onChange(this.value);
|
|
140
|
+
}
|
|
141
|
+
onCheckboxChange(event, item) {
|
|
142
|
+
void event;
|
|
143
|
+
void item;
|
|
144
|
+
}
|
|
145
|
+
ngOnDestroy() {
|
|
146
|
+
this.destroyed.next();
|
|
147
|
+
}
|
|
148
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SelectFromListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
149
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: SelectFromListComponent, isStandalone: true, selector: "sneat-select-from-list", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, filterLabel: { classPropertyName: "filterLabel", publicName: "filterLabel", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, listLabel: { classPropertyName: "listLabel", publicName: "listLabel", isSignal: false, isRequired: false, transformFunction: null }, listLabelColor: { classPropertyName: "listLabelColor", publicName: "listLabelColor", isSignal: false, isRequired: false, transformFunction: null }, isFilterable: { classPropertyName: "isFilterable", publicName: "isFilterable", isSignal: false, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: false, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: false, transformFunction: null }, items$: { classPropertyName: "items$", publicName: "items$", isSignal: false, isRequired: false, transformFunction: null }, lastItemLines: { classPropertyName: "lastItemLines", publicName: "lastItemLines", isSignal: false, isRequired: false, transformFunction: null }, labelPlacement: { classPropertyName: "labelPlacement", publicName: "labelPlacement", isSignal: false, isRequired: false, transformFunction: null }, justify: { classPropertyName: "justify", publicName: "justify", isSignal: false, isRequired: false, transformFunction: null }, other: { classPropertyName: "other", publicName: "other", isSignal: false, isRequired: false, transformFunction: null }, canAdd: { classPropertyName: "canAdd", publicName: "canAdd", isSignal: false, isRequired: false, transformFunction: null }, filterItem: { classPropertyName: "filterItem", publicName: "filterItem", isSignal: false, isRequired: false, transformFunction: null }, selectMode: { classPropertyName: "selectMode", publicName: "selectMode", isSignal: false, isRequired: false, transformFunction: null }, isReadonly: { classPropertyName: "isReadonly", publicName: "isReadonly", isSignal: false, isRequired: false, transformFunction: null }, $isProcessing: { classPropertyName: "$isProcessing", publicName: "$isProcessing", isSignal: true, isRequired: false, transformFunction: null }, sortBy: { classPropertyName: "sortBy", publicName: "sortBy", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", filterChanged: "filterChanged" }, providers: [
|
|
150
|
+
{
|
|
151
|
+
provide: NG_VALUE_ACCESSOR,
|
|
152
|
+
useExisting: forwardRef(() => SelectFromListComponent),
|
|
153
|
+
multi: true,
|
|
154
|
+
},
|
|
155
|
+
], viewQueries: [{ propertyName: "addInput", first: true, predicate: IonInput, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }, { propertyName: "selectInput", first: true, predicate: ["selectInput"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@if (value) {\n <ion-item\n [lines]=\"lastItemLines\"\n [class]=\"{ 'sneat-tiny-end-padding': !isReadonly }\"\n >\n @if ($selectedItem()?.iconName) {\n <ion-icon\n slot=\"start\"\n [name]=\"$selectedItem()?.iconName\"\n [color]=\"\n $selectedItem()?.iconColor || $selectedItem()?.labelColor || 'medium'\n \"\n />\n }\n <ion-select\n #selectInput\n interface=\"popover\"\n [label]=\"label\"\n [(ngModel)]=\"value\"\n (ionChange)=\"onSelectChanged()\"\n [disabled]=\"isReadonly || !!$isProcessing()\"\n >\n @for (item of items; track item.id) {\n <ion-select-option [value]=\"item.id\">\n {{ item.emoji }}\n @if (item.shortTitle) {\n {{ item.shortTitle }}\n } @else {\n {{ item.title }}\n }\n </ion-select-option>\n }\n <!--\t\t<ion-select-option value=\"other\">OTHER</ion-select-option>-->\n </ion-select>\n @if ($isProcessing()) {\n <ion-spinner name=\"lines-small\" color=\"medium\" slot=\"end\" />\n } @else if (!isReadonly) {\n <ion-buttons slot=\"end\" class=\"ion-no-margin\">\n <ion-button color=\"medium\" title=\"Deselect\" (click)=\"deselect()\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n} @else {\n @if (isFilterable) {\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n #filterInput\n color=\"medium\"\n placeholder=\"filter\"\n [label]=\"filterLabel\"\n [value]=\"$filter()\"\n (ionChange)=\"onFilterChanged($event, 'ionChange')\"\n (ionInput)=\"onFilterChanged($event, 'ionInput')\"\n />\n @if ($filter()) {\n <ion-buttons slot=\"end\">\n @if (canAdd && $hiddenCount()) {\n <ion-button\n title=\"Use this\"\n color=\"primary\"\n (click)=\"onAdd($event)\"\n >\n <ion-icon name=\"add-outline\" />\n <ion-label>Add</ion-label>\n </ion-button>\n }\n <ion-button (click)=\"clearFilter()\" title=\"Clear filter\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n }\n\n @if (items && !items.length) {\n <ion-item-divider>\n <ion-label>No items yet.</ion-label>\n </ion-item-divider>\n }\n\n @if (labelPlacement) {\n <ion-radio-group [(ngModel)]=\"value\" (ionChange)=\"onRadioChanged($event)\">\n <ion-list class=\"ion-no-padding\" lines=\"full\">\n @if (listLabel === \"divider\") {\n <ion-item [color]=\"listLabelColor\">\n <ion-label>{{ label }}</ion-label>\n </ion-item>\n }\n @for (item of $displayItems(); track item.id) {\n <ion-item\n [lines]=\"item.description1 ? 'inset' : 'full'\"\n (click)=\"select(item)\"\n tappable=\"true\"\n >\n @switch (selectMode) {\n @case (\"multiple\") {\n <ion-checkbox\n slot=\"start\"\n [value]=\"item.id\"\n [checked]=\"false\"\n [disabled]=\"isDisabled\"\n (ionChange)=\"onCheckboxChange($event, item)\"\n />\n <ion-label>\n <!-- TODO: duplicate code with the next case -->\n {{ item.emoji }}\n @if (item.shortTitle) {\n @if (item.longTitle) {\n {{ item.longTitle }} - {{ item.shortTitle }}\n } @else {\n {{ item.title }} - {{ item.shortTitle }}\n }\n } @else if (item.longTitle) {\n {{ item.longTitle }}\n } @else {\n {{ item.title }}\n }\n </ion-label>\n }\n @case (\"single\") {\n <ion-radio\n [value]=\"item.id\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"\n justify ||\n (!labelPlacement || labelPlacement === 'start'\n ? 'space-between'\n : 'start')\n \"\n >\n {{ item.emoji }}\n @if (item.shortTitle) {\n @if (item.longTitle) {\n {{ item.longTitle }} - {{ item.shortTitle }}\n } @else {\n {{ item.title }} - {{ item.shortTitle }}\n }\n } @else if (item.longTitle) {\n {{ item.longTitle }}\n } @else {\n {{ item.title }}\n }\n </ion-radio>\n }\n }\n </ion-item>\n @if (item.description1) {\n <ion-item-divider>\n <ion-label>\n {{ item.description1 }}\n @if (item.description2) {\n <i>{{ item.description2 }}</i>\n }\n </ion-label>\n </ion-item-divider>\n }\n }\n </ion-list>\n </ion-radio-group>\n } @else {\n <ion-item-group>\n @for (item of $displayItems(); track item.id; let last = $last) {\n <ion-item\n [lines]=\"item.description1 ? 'inset' : last ? lastItemLines : 'full'\"\n button\n (click)=\"select(item)\"\n >\n @if (item.iconName) {\n <ion-icon\n slot=\"start\"\n [name]=\"item.iconName\"\n [color]=\"item.iconColor || item.labelColor || 'medium'\"\n />\n }\n @if (!labelPlacement) {\n <ion-label [color]=\"item.labelColor\">\n <span class=\"ion-margin-end\">{{ item.emoji }}</span>\n {{ item.title }}\n </ion-label>\n }\n </ion-item>\n @if (item.description1) {\n <ion-item [lines]=\"last ? lastItemLines : 'full'\">\n <ion-label color=\"medium\">\n {{ item.description1 }}\n @if (item.description2) {\n <i>{{ item.description2 }}</i>\n }\n </ion-label>\n </ion-item>\n }\n }\n </ion-item-group>\n }\n @if ($hiddenCount(); as hiddenCount) {\n <ion-item-divider>\n <ion-label color=\"medium\"\n >{{ hiddenCount }} out of {{ items?.length }} items are hidden by filter\n </ion-label>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"clearFilter()\">\n <ion-icon name=\"close-outline\" slot=\"start\" />\n <ion-label>Clear filter</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-item-divider>\n }\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { 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: "ngmodule", type: RouterModule }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonInput, selector: "ion-input", inputs: ["accept", "autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "size", "spellcheck", "step", "type", "value"] }, { kind: "component", type: IonItemDivider, selector: "ion-item-divider", inputs: ["color", "mode", "sticky"] }, { kind: "component", type: IonRadioGroup, selector: "ion-radio-group", inputs: ["allowEmptySelection", "compareWith", "errorText", "helperText", "name", "value"] }, { kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonCheckbox, selector: "ion-checkbox", inputs: ["checked", "color", "disabled", "errorText", "helperText", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonRadio, selector: "ion-radio", inputs: ["alignment", "color", "disabled", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: IonItemGroup, selector: "ion-item-group" }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
156
|
+
}
|
|
157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SelectFromListComponent, decorators: [{
|
|
158
|
+
type: Component,
|
|
159
|
+
args: [{ providers: [
|
|
160
|
+
{
|
|
161
|
+
provide: NG_VALUE_ACCESSOR,
|
|
162
|
+
useExisting: forwardRef(() => SelectFromListComponent),
|
|
163
|
+
multi: true,
|
|
164
|
+
},
|
|
165
|
+
], imports: [
|
|
166
|
+
FormsModule,
|
|
167
|
+
RouterModule,
|
|
168
|
+
IonItem,
|
|
169
|
+
IonIcon,
|
|
170
|
+
IonSelect,
|
|
171
|
+
IonSelectOption,
|
|
172
|
+
IonButtons,
|
|
173
|
+
IonButton,
|
|
174
|
+
IonInput,
|
|
175
|
+
IonItemDivider,
|
|
176
|
+
IonRadioGroup,
|
|
177
|
+
IonList,
|
|
178
|
+
IonLabel,
|
|
179
|
+
IonCheckbox,
|
|
180
|
+
IonRadio,
|
|
181
|
+
IonItemGroup,
|
|
182
|
+
IonSpinner,
|
|
183
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, selector: 'sneat-select-from-list', template: "@if (value) {\n <ion-item\n [lines]=\"lastItemLines\"\n [class]=\"{ 'sneat-tiny-end-padding': !isReadonly }\"\n >\n @if ($selectedItem()?.iconName) {\n <ion-icon\n slot=\"start\"\n [name]=\"$selectedItem()?.iconName\"\n [color]=\"\n $selectedItem()?.iconColor || $selectedItem()?.labelColor || 'medium'\n \"\n />\n }\n <ion-select\n #selectInput\n interface=\"popover\"\n [label]=\"label\"\n [(ngModel)]=\"value\"\n (ionChange)=\"onSelectChanged()\"\n [disabled]=\"isReadonly || !!$isProcessing()\"\n >\n @for (item of items; track item.id) {\n <ion-select-option [value]=\"item.id\">\n {{ item.emoji }}\n @if (item.shortTitle) {\n {{ item.shortTitle }}\n } @else {\n {{ item.title }}\n }\n </ion-select-option>\n }\n <!--\t\t<ion-select-option value=\"other\">OTHER</ion-select-option>-->\n </ion-select>\n @if ($isProcessing()) {\n <ion-spinner name=\"lines-small\" color=\"medium\" slot=\"end\" />\n } @else if (!isReadonly) {\n <ion-buttons slot=\"end\" class=\"ion-no-margin\">\n <ion-button color=\"medium\" title=\"Deselect\" (click)=\"deselect()\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n} @else {\n @if (isFilterable) {\n <ion-item class=\"sneat-tiny-end-padding\">\n <ion-input\n #filterInput\n color=\"medium\"\n placeholder=\"filter\"\n [label]=\"filterLabel\"\n [value]=\"$filter()\"\n (ionChange)=\"onFilterChanged($event, 'ionChange')\"\n (ionInput)=\"onFilterChanged($event, 'ionInput')\"\n />\n @if ($filter()) {\n <ion-buttons slot=\"end\">\n @if (canAdd && $hiddenCount()) {\n <ion-button\n title=\"Use this\"\n color=\"primary\"\n (click)=\"onAdd($event)\"\n >\n <ion-icon name=\"add-outline\" />\n <ion-label>Add</ion-label>\n </ion-button>\n }\n <ion-button (click)=\"clearFilter()\" title=\"Clear filter\">\n <ion-icon name=\"close-outline\" />\n </ion-button>\n </ion-buttons>\n }\n </ion-item>\n }\n\n @if (items && !items.length) {\n <ion-item-divider>\n <ion-label>No items yet.</ion-label>\n </ion-item-divider>\n }\n\n @if (labelPlacement) {\n <ion-radio-group [(ngModel)]=\"value\" (ionChange)=\"onRadioChanged($event)\">\n <ion-list class=\"ion-no-padding\" lines=\"full\">\n @if (listLabel === \"divider\") {\n <ion-item [color]=\"listLabelColor\">\n <ion-label>{{ label }}</ion-label>\n </ion-item>\n }\n @for (item of $displayItems(); track item.id) {\n <ion-item\n [lines]=\"item.description1 ? 'inset' : 'full'\"\n (click)=\"select(item)\"\n tappable=\"true\"\n >\n @switch (selectMode) {\n @case (\"multiple\") {\n <ion-checkbox\n slot=\"start\"\n [value]=\"item.id\"\n [checked]=\"false\"\n [disabled]=\"isDisabled\"\n (ionChange)=\"onCheckboxChange($event, item)\"\n />\n <ion-label>\n <!-- TODO: duplicate code with the next case -->\n {{ item.emoji }}\n @if (item.shortTitle) {\n @if (item.longTitle) {\n {{ item.longTitle }} - {{ item.shortTitle }}\n } @else {\n {{ item.title }} - {{ item.shortTitle }}\n }\n } @else if (item.longTitle) {\n {{ item.longTitle }}\n } @else {\n {{ item.title }}\n }\n </ion-label>\n }\n @case (\"single\") {\n <ion-radio\n [value]=\"item.id\"\n [labelPlacement]=\"labelPlacement\"\n [justify]=\"\n justify ||\n (!labelPlacement || labelPlacement === 'start'\n ? 'space-between'\n : 'start')\n \"\n >\n {{ item.emoji }}\n @if (item.shortTitle) {\n @if (item.longTitle) {\n {{ item.longTitle }} - {{ item.shortTitle }}\n } @else {\n {{ item.title }} - {{ item.shortTitle }}\n }\n } @else if (item.longTitle) {\n {{ item.longTitle }}\n } @else {\n {{ item.title }}\n }\n </ion-radio>\n }\n }\n </ion-item>\n @if (item.description1) {\n <ion-item-divider>\n <ion-label>\n {{ item.description1 }}\n @if (item.description2) {\n <i>{{ item.description2 }}</i>\n }\n </ion-label>\n </ion-item-divider>\n }\n }\n </ion-list>\n </ion-radio-group>\n } @else {\n <ion-item-group>\n @for (item of $displayItems(); track item.id; let last = $last) {\n <ion-item\n [lines]=\"item.description1 ? 'inset' : last ? lastItemLines : 'full'\"\n button\n (click)=\"select(item)\"\n >\n @if (item.iconName) {\n <ion-icon\n slot=\"start\"\n [name]=\"item.iconName\"\n [color]=\"item.iconColor || item.labelColor || 'medium'\"\n />\n }\n @if (!labelPlacement) {\n <ion-label [color]=\"item.labelColor\">\n <span class=\"ion-margin-end\">{{ item.emoji }}</span>\n {{ item.title }}\n </ion-label>\n }\n </ion-item>\n @if (item.description1) {\n <ion-item [lines]=\"last ? lastItemLines : 'full'\">\n <ion-label color=\"medium\">\n {{ item.description1 }}\n @if (item.description2) {\n <i>{{ item.description2 }}</i>\n }\n </ion-label>\n </ion-item>\n }\n }\n </ion-item-group>\n }\n @if ($hiddenCount(); as hiddenCount) {\n <ion-item-divider>\n <ion-label color=\"medium\"\n >{{ hiddenCount }} out of {{ items?.length }} items are hidden by filter\n </ion-label>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"clearFilter()\">\n <ion-icon name=\"close-outline\" slot=\"start\" />\n <ion-label>Clear filter</ion-label>\n </ion-button>\n </ion-buttons>\n </ion-item-divider>\n }\n}\n" }]
|
|
184
|
+
}], propDecorators: { value: [{
|
|
185
|
+
type: Input
|
|
186
|
+
}], valueChange: [{
|
|
187
|
+
type: Output
|
|
188
|
+
}], filterLabel: [{
|
|
189
|
+
type: Input
|
|
190
|
+
}], label: [{
|
|
191
|
+
type: Input
|
|
192
|
+
}], listLabel: [{
|
|
193
|
+
type: Input
|
|
194
|
+
}], listLabelColor: [{
|
|
195
|
+
type: Input
|
|
196
|
+
}], isFilterable: [{
|
|
197
|
+
type: Input
|
|
198
|
+
}], isLoading: [{
|
|
199
|
+
type: Input
|
|
200
|
+
}], items: [{
|
|
201
|
+
type: Input
|
|
202
|
+
}], items$: [{
|
|
203
|
+
type: Input
|
|
204
|
+
}], lastItemLines: [{
|
|
205
|
+
type: Input
|
|
206
|
+
}], labelPlacement: [{
|
|
207
|
+
type: Input
|
|
208
|
+
}], justify: [{
|
|
209
|
+
type: Input
|
|
210
|
+
}], other: [{
|
|
211
|
+
type: Input
|
|
212
|
+
}], canAdd: [{
|
|
213
|
+
type: Input
|
|
214
|
+
}], filterItem: [{
|
|
215
|
+
type: Input
|
|
216
|
+
}], filterChanged: [{
|
|
217
|
+
type: Output
|
|
218
|
+
}], selectMode: [{
|
|
219
|
+
type: Input
|
|
220
|
+
}], isReadonly: [{
|
|
221
|
+
type: Input
|
|
222
|
+
}], $isProcessing: [{ type: i0.Input, args: [{ isSignal: true, alias: "$isProcessing", required: false }] }], sortBy: [{
|
|
223
|
+
type: Input
|
|
224
|
+
}], addInput: [{
|
|
225
|
+
type: ViewChild,
|
|
226
|
+
args: [IonInput, { static: false }]
|
|
227
|
+
}], filterInput: [{
|
|
228
|
+
type: ViewChild,
|
|
229
|
+
args: ['filterInput', { static: false }]
|
|
230
|
+
}], selectInput: [{
|
|
231
|
+
type: ViewChild,
|
|
232
|
+
args: ['selectInput', { static: false }]
|
|
233
|
+
}] } });
|
|
234
|
+
//# sourceMappingURL=select-from-list.component.js.map
|