@recursyve/nice-selectable-list 19.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,360 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, computed, InjectionToken, inject, input, contentChildren, Injector, effect, untracked, forwardRef, Directive, DestroyRef, afterRenderEffect } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
+ import { MatCheckbox } from '@angular/material/checkbox';
5
+ import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
6
+ import { filter, take } from 'rxjs';
7
+
8
+ class NiceSelectableListStore {
9
+ _config;
10
+ _entities = signal([]);
11
+ _activeEntity = signal(null);
12
+ _checkboxes = signal([]);
13
+ entities = this._entities.asReadonly();
14
+ activeEntity = this._activeEntity.asReadonly();
15
+ total = computed(() => this._entities().length);
16
+ entitiesIds = computed(() => this._entities().map((entity) => entity.id));
17
+ activeEntityId = computed(() => this._activeEntity()?.id ?? null);
18
+ constructor(_config) {
19
+ this._config = _config;
20
+ }
21
+ registerCheckbox(checkbox) {
22
+ this._checkboxes.update((checkboxes) => [...checkboxes, checkbox]);
23
+ const id = this._resolveEntityId(checkbox.selectableEntity());
24
+ const entity = this._entities().find((_entity) => _entity.id === id);
25
+ if (entity && entity.entity === null) {
26
+ this._entities.update((_entities) => _entities.map((_entity) => _entity.id === id ? { id, entity: checkbox.selectableEntity() } : _entity));
27
+ entity.entity = checkbox.selectableEntity();
28
+ }
29
+ }
30
+ unregisterCheckbox(checkbox) {
31
+ this._checkboxes.update((checkboxes) => checkboxes.filter((_checkbox) => _checkbox !== checkbox));
32
+ }
33
+ isEntitySelected(entity) {
34
+ return computed(() => this._isEntitySelected(entity));
35
+ }
36
+ setEntitiesFromSelections(selections) {
37
+ const ids = this._config.idType === "string" ? selections : selections.map((id) => +id);
38
+ const registeredEntities = this._checkboxes().map((checkbox) => ({
39
+ id: this._resolveEntityId(checkbox.selectableEntity()), entity: checkbox.selectableEntity()
40
+ }));
41
+ const entities = ids.map((id) => ({
42
+ id,
43
+ entity: registeredEntities.find(_entity => _entity.id === id)?.entity ?? null
44
+ }));
45
+ this._entities.set(entities);
46
+ }
47
+ selectEntity(entity) {
48
+ const isSelected = this._isEntitySelected(entity);
49
+ if (isSelected) {
50
+ return;
51
+ }
52
+ const id = this._resolveEntityId(entity);
53
+ this._entities.update((entities) => [...entities, { id, entity }]);
54
+ }
55
+ deselectEntity(entity) {
56
+ const isSelected = this._isEntitySelected(entity);
57
+ if (!isSelected) {
58
+ return;
59
+ }
60
+ const id = this._resolveEntityId(entity);
61
+ this._entities.update((entities) => entities.filter((_entity) => _entity.id !== id));
62
+ }
63
+ clear() {
64
+ this._entities.set([]);
65
+ this._activeEntity.set(null);
66
+ }
67
+ setActiveFromSelected(selected) {
68
+ const id = this._config.idType === "string" ? selected : +selected;
69
+ const entity = this._entities().find((_entity) => _entity.id === id);
70
+ if (!entity) {
71
+ return;
72
+ }
73
+ this._activeEntity.set(entity);
74
+ }
75
+ setActiveEntity(entity) {
76
+ if (!entity) {
77
+ this._activeEntity.set(null);
78
+ return;
79
+ }
80
+ const id = this._resolveEntityId(entity);
81
+ this._activeEntity.set({ id, entity });
82
+ }
83
+ selectFirstEntity() {
84
+ const entity = this._entities()[0];
85
+ if (!entity) {
86
+ return;
87
+ }
88
+ this._activeEntity.set(entity);
89
+ }
90
+ selectNextEntity() {
91
+ const entities = this._entities();
92
+ const activeEntity = this._activeEntity();
93
+ if (!activeEntity) {
94
+ this.selectFirstEntity();
95
+ return;
96
+ }
97
+ const index = entities.findIndex((_entity) => activeEntity.id === _entity.id);
98
+ const nextEntity = entities[index + 1];
99
+ if (!nextEntity) {
100
+ return;
101
+ }
102
+ this._activeEntity.set(nextEntity);
103
+ }
104
+ selectPreviousEntity() {
105
+ const entities = this._entities();
106
+ const activeEntity = this._activeEntity();
107
+ if (!activeEntity) {
108
+ this.selectFirstEntity();
109
+ return;
110
+ }
111
+ const index = entities.findIndex((_entity) => activeEntity.id === _entity.id);
112
+ if (index === 0) {
113
+ return;
114
+ }
115
+ const previousEntity = entities[index - 1];
116
+ if (!previousEntity) {
117
+ return;
118
+ }
119
+ this._activeEntity.set(previousEntity);
120
+ }
121
+ selectLastEntity() {
122
+ const entities = this._entities();
123
+ if (entities.length === 0) {
124
+ return;
125
+ }
126
+ const lastEntity = entities[entities.length - 1];
127
+ if (!lastEntity) {
128
+ return;
129
+ }
130
+ this._activeEntity.set(lastEntity);
131
+ }
132
+ _isEntitySelected(entity) {
133
+ const id = this._resolveEntityId(entity);
134
+ return this._entities().findIndex((_entity) => _entity.id === id) >= 0;
135
+ }
136
+ _resolveEntityId(entity) {
137
+ const idProperty = this._config.idProperty;
138
+ const id = entity[idProperty];
139
+ if (typeof id !== "string" && typeof id !== "number") {
140
+ throw new Error(`The id property must be a string or a number, but got ${typeof id}`);
141
+ }
142
+ return id;
143
+ }
144
+ }
145
+
146
+ const NICE_SELECTABLE_LISTS = new InjectionToken("_selectable_list_providers");
147
+ function provideNiceSelectableList(name, config) {
148
+ return {
149
+ provide: NICE_SELECTABLE_LISTS,
150
+ useValue: {
151
+ name,
152
+ store: new NiceSelectableListStore({
153
+ idProperty: config?.idProperty ?? "id",
154
+ idType: config?.idType ?? "number"
155
+ })
156
+ },
157
+ multi: true
158
+ };
159
+ }
160
+ function resolveNiceSelectableList(name, options) {
161
+ const selectableLists = options?.injector
162
+ ? options.injector.get(NICE_SELECTABLE_LISTS)
163
+ : inject(NICE_SELECTABLE_LISTS);
164
+ const provider = selectableLists.find((_provider) => _provider.name === name);
165
+ if (!provider) {
166
+ throw new Error(`No selectable list provider found for name: ${name}`);
167
+ }
168
+ return provider.store;
169
+ }
170
+
171
+ const NICE_SELECTABLE_LIST = new InjectionToken("_selectable_list");
172
+ class SelectableListDirective {
173
+ name = input.required({ alias: "niceSelectableList" });
174
+ enableQueryParams = input(false);
175
+ checkboxes = contentChildren(NiceSelectableListEntityCheckboxDirective, { descendants: true });
176
+ _initialized = signal(false);
177
+ initialized = this._initialized.asReadonly();
178
+ route = inject(ActivatedRoute);
179
+ router = inject(Router);
180
+ injector = inject(Injector);
181
+ selectableLists;
182
+ constructor() {
183
+ effect(() => {
184
+ this.selectableLists = resolveNiceSelectableList(this.name(), { injector: this.injector });
185
+ });
186
+ effect(() => {
187
+ if (!this._initialized()) {
188
+ return;
189
+ }
190
+ if (!this.enableQueryParams()) {
191
+ this.router.navigate([], {
192
+ relativeTo: this.route,
193
+ queryParams: {
194
+ selections: null,
195
+ selected: null
196
+ }
197
+ });
198
+ return;
199
+ }
200
+ });
201
+ effect(() => {
202
+ if (!this._initialized()) {
203
+ return;
204
+ }
205
+ const shouldWrite = untracked(() => this.enableQueryParams());
206
+ if (!shouldWrite) {
207
+ return;
208
+ }
209
+ const entities = this.selectableLists.entitiesIds();
210
+ const activeEntity = this.selectableLists.activeEntityId();
211
+ this.router.navigate([], {
212
+ relativeTo: this.route,
213
+ queryParams: {
214
+ selections: entities,
215
+ selected: activeEntity
216
+ }
217
+ });
218
+ });
219
+ }
220
+ ngOnInit() {
221
+ this.loadQueryParams();
222
+ }
223
+ loadQueryParams() {
224
+ if (this.router.navigated) {
225
+ this.parseQueryParams(this.route.snapshot.queryParams);
226
+ this._initialized.set(true);
227
+ return;
228
+ }
229
+ this.router.events
230
+ .pipe(filter((event) => event instanceof NavigationEnd), take(1))
231
+ .subscribe(() => {
232
+ this.parseQueryParams(this.route.snapshot.queryParams);
233
+ this._initialized.set(true);
234
+ });
235
+ }
236
+ parseQueryParams(params) {
237
+ if (params.selections) {
238
+ const selections = Array.isArray(params.selections)
239
+ ? params.selections
240
+ : [params.selections];
241
+ this.selectableLists.setEntitiesFromSelections(selections);
242
+ }
243
+ if (params.selected) {
244
+ this.selectableLists.setActiveFromSelected(params.selected);
245
+ }
246
+ }
247
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SelectableListDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
248
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.2.14", type: SelectableListDirective, isStandalone: true, selector: "[niceSelectableList]", inputs: { name: { classPropertyName: "name", publicName: "niceSelectableList", isSignal: true, isRequired: true, transformFunction: null }, enableQueryParams: { classPropertyName: "enableQueryParams", publicName: "enableQueryParams", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
249
+ { provide: NICE_SELECTABLE_LIST, useExisting: forwardRef(() => SelectableListDirective) }
250
+ ], queries: [{ propertyName: "checkboxes", predicate: NiceSelectableListEntityCheckboxDirective, descendants: true, isSignal: true }], ngImport: i0 });
251
+ }
252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SelectableListDirective, decorators: [{
253
+ type: Directive,
254
+ args: [{
255
+ selector: "[niceSelectableList]",
256
+ providers: [
257
+ { provide: NICE_SELECTABLE_LIST, useExisting: forwardRef(() => SelectableListDirective) }
258
+ ]
259
+ }]
260
+ }], ctorParameters: () => [] });
261
+
262
+ function injectNiceSelectableListDirective() {
263
+ return inject(NICE_SELECTABLE_LIST);
264
+ }
265
+ function injectNiceSelectableList(name) {
266
+ if (!name) {
267
+ name = injectNiceSelectableListDirective().name();
268
+ }
269
+ const selectableLists = inject(NICE_SELECTABLE_LISTS);
270
+ const provider = selectableLists.find((_provider) => _provider.name === name);
271
+ if (!provider) {
272
+ throw new Error(`No selectable list provider found for name: ${name}`);
273
+ }
274
+ return provider.store;
275
+ }
276
+
277
+ class NiceSelectableListEntityCheckboxDirective {
278
+ matCheckbox = inject(MatCheckbox);
279
+ destroyRef = inject(DestroyRef);
280
+ niceSelectableList = injectNiceSelectableList();
281
+ selectableEntity = input.required();
282
+ isSelected = computed(() => this.niceSelectableList.isEntitySelected(this.selectableEntity())());
283
+ constructor() {
284
+ effect(() => {
285
+ this.matCheckbox.checked = this.niceSelectableList.isEntitySelected(this.selectableEntity())();
286
+ });
287
+ }
288
+ ngOnInit() {
289
+ this.niceSelectableList.registerCheckbox(this);
290
+ this.matCheckbox.change.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ checked }) => {
291
+ if (checked) {
292
+ this.niceSelectableList.selectEntity(this.selectableEntity());
293
+ }
294
+ else {
295
+ this.niceSelectableList.deselectEntity(this.selectableEntity());
296
+ }
297
+ });
298
+ }
299
+ ngOnDestroy() {
300
+ this.niceSelectableList.unregisterCheckbox(this);
301
+ }
302
+ selectEntity() {
303
+ this.matCheckbox.checked = true;
304
+ this.matCheckbox.change.emit({ checked: true, source: this.matCheckbox });
305
+ }
306
+ deselectEntity() {
307
+ this.matCheckbox.checked = false;
308
+ this.matCheckbox.change.emit({ checked: false, source: this.matCheckbox });
309
+ }
310
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NiceSelectableListEntityCheckboxDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
311
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.14", type: NiceSelectableListEntityCheckboxDirective, isStandalone: true, selector: "mat-checkbox[niceSelectableListEntityCheckbox]", inputs: { selectableEntity: { classPropertyName: "selectableEntity", publicName: "selectableEntity", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
312
+ }
313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NiceSelectableListEntityCheckboxDirective, decorators: [{
314
+ type: Directive,
315
+ args: [{
316
+ selector: "mat-checkbox[niceSelectableListEntityCheckbox]"
317
+ }]
318
+ }], ctorParameters: () => [] });
319
+
320
+ class NiceSelectableListHeaderCheckboxDirective {
321
+ niceSelectableListDirective = injectNiceSelectableListDirective();
322
+ matCheckbox = inject(MatCheckbox);
323
+ destroyRef = inject(DestroyRef);
324
+ constructor() {
325
+ afterRenderEffect({
326
+ read: () => {
327
+ const checkboxes = this.niceSelectableListDirective.checkboxes();
328
+ const empty = checkboxes.length === 0;
329
+ this.matCheckbox.checked = !empty && checkboxes.every((checkbox) => checkbox.isSelected());
330
+ this.matCheckbox.indeterminate = !this.matCheckbox.checked
331
+ && checkboxes.some((checkbox) => checkbox.isSelected());
332
+ }
333
+ });
334
+ }
335
+ ngOnInit() {
336
+ this.matCheckbox.change.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ checked }) => {
337
+ if (checked) {
338
+ this.niceSelectableListDirective.checkboxes().forEach((checkbox) => checkbox.selectEntity());
339
+ }
340
+ else {
341
+ this.niceSelectableListDirective.checkboxes().forEach((checkbox) => checkbox.deselectEntity());
342
+ }
343
+ });
344
+ }
345
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NiceSelectableListHeaderCheckboxDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
346
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: NiceSelectableListHeaderCheckboxDirective, isStandalone: true, selector: "mat-checkbox[niceSelectableListHeaderCheckbox]", ngImport: i0 });
347
+ }
348
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: NiceSelectableListHeaderCheckboxDirective, decorators: [{
349
+ type: Directive,
350
+ args: [{
351
+ selector: "mat-checkbox[niceSelectableListHeaderCheckbox]"
352
+ }]
353
+ }], ctorParameters: () => [] });
354
+
355
+ /**
356
+ * Generated bundle index. Do not edit.
357
+ */
358
+
359
+ export { NICE_SELECTABLE_LIST, NICE_SELECTABLE_LISTS, NiceSelectableListEntityCheckboxDirective, NiceSelectableListHeaderCheckboxDirective, NiceSelectableListStore, SelectableListDirective, injectNiceSelectableList, injectNiceSelectableListDirective, provideNiceSelectableList, resolveNiceSelectableList };
360
+ //# sourceMappingURL=recursyve-nice-selectable-list.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recursyve-nice-selectable-list.mjs","sources":["../../../src/nice-selectable-list/selectable-list/store.ts","../../../src/nice-selectable-list/selectable-list/provider.ts","../../../src/nice-selectable-list/selectable-list/selectable-list.ts","../../../src/nice-selectable-list/selectable-list/injector.ts","../../../src/nice-selectable-list/selectable-list/entity-checkbox.directive.ts","../../../src/nice-selectable-list/selectable-list/header-checkbox.directive.ts","../../../src/nice-selectable-list/recursyve-nice-selectable-list.ts"],"sourcesContent":["import { computed, Signal, signal } from \"@angular/core\";\nimport { NiceSelectableListEntityCheckboxDirective } from \"./entity-checkbox.directive\";\n\nexport type NiceSelectableListConfig<T> = {\n idProperty: keyof T;\n idType?: \"string\" | \"number\";\n}\n\nexport type NiceSelectableListEntity<T> = {\n id: string | number;\n entity: T | null;\n};\n\nexport class NiceSelectableListStore<T> {\n private readonly _entities = signal<NiceSelectableListEntity<T>[]>([]);\n private readonly _activeEntity = signal<NiceSelectableListEntity<T> | null>(null);\n private readonly _checkboxes = signal<NiceSelectableListEntityCheckboxDirective<T>[]>([]);\n\n public readonly entities = this._entities.asReadonly();\n public readonly activeEntity = this._activeEntity.asReadonly();\n\n public readonly total = computed(() => this._entities().length);\n public readonly entitiesIds = computed(() => this._entities().map((entity) => entity.id));\n public readonly activeEntityId = computed(() => this._activeEntity()?.id ?? null);\n\n constructor(private readonly _config: NiceSelectableListConfig<T>) {}\n\n public registerCheckbox(checkbox: NiceSelectableListEntityCheckboxDirective<T>): void {\n this._checkboxes.update((checkboxes) => [...checkboxes, checkbox]);\n\n const id = this._resolveEntityId(checkbox.selectableEntity());\n const entity = this._entities().find((_entity) => _entity.id === id);\n if (entity && entity.entity === null) {\n this._entities.update(\n (_entities) => _entities.map((_entity) =>\n _entity.id === id ? { id, entity: checkbox.selectableEntity() } : _entity\n )\n );\n entity.entity = checkbox.selectableEntity();\n }\n }\n\n public unregisterCheckbox(checkbox: NiceSelectableListEntityCheckboxDirective<T>): void {\n this._checkboxes.update((checkboxes) => checkboxes.filter((_checkbox) => _checkbox !== checkbox));\n }\n\n public isEntitySelected(entity: T): Signal<boolean> {\n return computed(() => this._isEntitySelected(entity));\n }\n\n public setEntitiesFromSelections(selections: string[]): void {\n const ids: (string | number)[] = this._config.idType === \"string\" ? selections : selections.map((id) => +id);\n\n const registeredEntities = this._checkboxes().map((checkbox) => ({\n id: this._resolveEntityId(checkbox.selectableEntity()), entity: checkbox.selectableEntity()\n }));\n const entities = ids.map((id) => ({\n id,\n entity: registeredEntities.find(_entity => _entity.id === id)?.entity ?? null\n }));\n this._entities.set(entities);\n }\n\n public selectEntity(entity: T): void {\n const isSelected = this._isEntitySelected(entity);\n if (isSelected) {\n return;\n }\n\n const id = this._resolveEntityId(entity);\n this._entities.update((entities) => [...entities, { id, entity }]);\n }\n\n public deselectEntity(entity: T): void {\n const isSelected = this._isEntitySelected(entity);\n if (!isSelected) {\n return;\n }\n\n const id = this._resolveEntityId(entity);\n this._entities.update((entities) => entities.filter((_entity) => _entity.id !== id));\n }\n\n public clear(): void {\n this._entities.set([]);\n this._activeEntity.set(null);\n }\n\n public setActiveFromSelected(selected: string): void {\n const id = this._config.idType === \"string\" ? selected : +selected;\n const entity = this._entities().find((_entity) => _entity.id === id);\n if (!entity) {\n return;\n }\n\n this._activeEntity.set(entity);\n }\n\n public setActiveEntity(entity: T | null): void {\n if (!entity) {\n this._activeEntity.set(null);\n return;\n }\n\n const id = this._resolveEntityId(entity);\n this._activeEntity.set({ id, entity });\n }\n\n public selectFirstEntity(): void {\n const entity = this._entities()[0];\n if (!entity) {\n return;\n }\n\n this._activeEntity.set(entity);\n }\n\n public selectNextEntity(): void {\n const entities = this._entities();\n const activeEntity = this._activeEntity();\n if (!activeEntity) {\n this.selectFirstEntity();\n return;\n }\n\n const index = entities.findIndex((_entity) => activeEntity.id === _entity.id);\n const nextEntity = entities[index + 1];\n if (!nextEntity) {\n return;\n }\n\n this._activeEntity.set(nextEntity);\n }\n\n public selectPreviousEntity(): void {\n const entities = this._entities();\n const activeEntity = this._activeEntity();\n if (!activeEntity) {\n this.selectFirstEntity();\n return;\n }\n\n const index = entities.findIndex((_entity) => activeEntity.id === _entity.id);\n if (index === 0) {\n return;\n }\n\n const previousEntity = entities[index - 1];\n if (!previousEntity) {\n return;\n }\n\n this._activeEntity.set(previousEntity);\n }\n\n public selectLastEntity(): void {\n const entities = this._entities();\n if (entities.length === 0) {\n return;\n }\n\n const lastEntity = entities[entities.length - 1];\n if (!lastEntity) {\n return;\n }\n\n this._activeEntity.set(lastEntity);\n }\n\n private _isEntitySelected(entity: T): boolean {\n const id = this._resolveEntityId(entity);\n return this._entities().findIndex((_entity) => _entity.id === id) >= 0;\n }\n\n private _resolveEntityId(entity: T): string | number {\n const idProperty = this._config.idProperty;\n const id = entity[idProperty];\n if (typeof id !== \"string\" && typeof id !== \"number\") {\n throw new Error(`The id property must be a string or a number, but got ${typeof id}`);\n }\n\n return id;\n }\n}\n","import { inject, InjectionToken, Injector, Provider } from \"@angular/core\";\nimport { NiceSelectableListConfig, NiceSelectableListStore } from \"./store\";\n\nexport const NICE_SELECTABLE_LISTS\n = new InjectionToken<NiceSelectableListProvider<unknown>[]>(\"_selectable_list_providers\");\n\nexport type NiceSelectableListProvider<T> = {\n name: string;\n store: NiceSelectableListStore<T>;\n};\n\nexport function provideNiceSelectableList<T>(name: string, config?: NiceSelectableListConfig<T>): Provider {\n return {\n provide: NICE_SELECTABLE_LISTS,\n useValue: {\n name,\n store: new NiceSelectableListStore({\n idProperty: config?.idProperty ?? \"id\" as keyof T,\n idType: config?.idType ?? \"number\" as \"string\" | \"number\"\n })\n },\n multi: true\n };\n}\n\nexport function resolveNiceSelectableList<T>(name: string, options?: {\n injector: Injector\n}): NiceSelectableListStore<T> {\n const selectableLists = options?.injector\n ? options.injector.get(NICE_SELECTABLE_LISTS)\n : inject(NICE_SELECTABLE_LISTS);\n\n const provider = selectableLists.find((_provider) => _provider.name === name);\n if (!provider) {\n throw new Error(`No selectable list provider found for name: ${name}`);\n }\n\n return provider.store as NiceSelectableListStore<T>;\n}\n","import {\n contentChildren,\n Directive,\n effect,\n forwardRef,\n inject,\n InjectionToken,\n Injector,\n input,\n OnInit,\n signal,\n Signal,\n untracked\n} from \"@angular/core\";\nimport { ActivatedRoute, NavigationEnd, Router } from \"@angular/router\";\nimport { filter, take } from \"rxjs\";\nimport { NiceSelectableListEntityCheckboxDirective } from \"./entity-checkbox.directive\";\nimport { resolveNiceSelectableList } from \"./provider\";\nimport { NiceSelectableListStore } from \"./store\";\n\nexport const NICE_SELECTABLE_LIST = new InjectionToken<NiceSelectableList<unknown>>(\"_selectable_list\");\nexport type NiceSelectableList<T> = {\n name: Signal<string>;\n checkboxes: Signal<readonly NiceSelectableListEntityCheckboxDirective<T>[]>;\n};\n\n@Directive({\n selector: \"[niceSelectableList]\",\n providers: [\n { provide: NICE_SELECTABLE_LIST, useExisting: forwardRef(() => SelectableListDirective) }\n ]\n})\nexport class SelectableListDirective<T> implements NiceSelectableList<T>, OnInit {\n public readonly name = input.required<string>({ alias: \"niceSelectableList\" });\n public readonly enableQueryParams = input<boolean>(false);\n\n public readonly checkboxes = contentChildren<NiceSelectableListEntityCheckboxDirective<T>>(\n NiceSelectableListEntityCheckboxDirective,\n { descendants: true }\n );\n\n private readonly _initialized = signal(false);\n public readonly initialized = this._initialized.asReadonly();\n\n protected readonly route = inject(ActivatedRoute);\n protected readonly router = inject(Router);\n protected readonly injector = inject(Injector);\n\n protected selectableLists!: NiceSelectableListStore<T>;\n\n constructor() {\n effect(() => {\n this.selectableLists = resolveNiceSelectableList(this.name(), { injector: this.injector });\n });\n\n effect(() => {\n if (!this._initialized()) {\n return;\n }\n\n if (!this.enableQueryParams()) {\n this.router.navigate([], {\n relativeTo: this.route,\n queryParams: {\n selections: null,\n selected: null\n }\n });\n return;\n }\n });\n\n effect(() => {\n if (!this._initialized()) {\n return;\n }\n\n const shouldWrite = untracked(() => this.enableQueryParams());\n if (!shouldWrite) {\n return;\n }\n\n const entities = this.selectableLists.entitiesIds();\n const activeEntity = this.selectableLists.activeEntityId();\n this.router.navigate([], {\n relativeTo: this.route,\n queryParams: {\n selections: entities,\n selected: activeEntity\n }\n });\n });\n }\n\n public ngOnInit(): void {\n this.loadQueryParams();\n }\n\n private loadQueryParams(): void {\n if (this.router.navigated) {\n this.parseQueryParams(this.route.snapshot.queryParams);\n this._initialized.set(true);\n return;\n }\n\n this.router.events\n .pipe(\n filter((event) => event instanceof NavigationEnd),\n take(1)\n )\n .subscribe(() => {\n this.parseQueryParams(this.route.snapshot.queryParams);\n this._initialized.set(true);\n });\n }\n\n private parseQueryParams(params: {\n selections?: string | string[];\n selected?: string;\n }): void {\n if (params.selections) {\n const selections = Array.isArray(params.selections)\n ? params.selections\n : [params.selections]\n this.selectableLists.setEntitiesFromSelections(selections);\n }\n\n if (params.selected) {\n this.selectableLists.setActiveFromSelected(params.selected);\n }\n }\n}\n","import { inject } from \"@angular/core\";\nimport { NICE_SELECTABLE_LISTS } from \"./provider\";\nimport { NICE_SELECTABLE_LIST, NiceSelectableList } from \"./selectable-list\";\nimport { NiceSelectableListStore } from \"./store\";\n\nexport function injectNiceSelectableListDirective<T>(): NiceSelectableList<T> {\n return inject(NICE_SELECTABLE_LIST) as NiceSelectableList<T>;\n}\n\nexport function injectNiceSelectableList<T>(name?: string): NiceSelectableListStore<T> {\n if (!name) {\n name = injectNiceSelectableListDirective().name();\n }\n\n const selectableLists = inject(NICE_SELECTABLE_LISTS);\n const provider = selectableLists.find((_provider) => _provider.name === name);\n if (!provider) {\n throw new Error(`No selectable list provider found for name: ${name}`);\n }\n\n return provider.store as NiceSelectableListStore<T>;\n}\n","import { computed, DestroyRef, Directive, effect, inject, input, OnDestroy, OnInit } from \"@angular/core\";\nimport { takeUntilDestroyed } from \"@angular/core/rxjs-interop\";\nimport { MatCheckbox } from \"@angular/material/checkbox\";\nimport { injectNiceSelectableList } from \"./injector\";\n\n@Directive({\n selector: \"mat-checkbox[niceSelectableListEntityCheckbox]\"\n})\nexport class NiceSelectableListEntityCheckboxDirective<T> implements OnInit, OnDestroy {\n protected readonly matCheckbox = inject(MatCheckbox);\n protected readonly destroyRef = inject(DestroyRef);\n protected readonly niceSelectableList = injectNiceSelectableList<T>();\n\n public readonly selectableEntity = input.required<T>();\n public readonly isSelected = computed(() => this.niceSelectableList.isEntitySelected(this.selectableEntity())());\n\n constructor() {\n effect(() => {\n this.matCheckbox.checked = this.niceSelectableList.isEntitySelected(this.selectableEntity())();\n });\n }\n\n public ngOnInit(): void {\n this.niceSelectableList.registerCheckbox(this);\n\n this.matCheckbox.change.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ checked }) => {\n if (checked) {\n this.niceSelectableList.selectEntity(this.selectableEntity());\n } else {\n this.niceSelectableList.deselectEntity(this.selectableEntity());\n }\n });\n }\n\n public ngOnDestroy(): void {\n this.niceSelectableList.unregisterCheckbox(this);\n }\n\n public selectEntity(): void {\n this.matCheckbox.checked = true;\n this.matCheckbox.change.emit({ checked: true, source: this.matCheckbox });\n }\n\n public deselectEntity(): void {\n this.matCheckbox.checked = false;\n this.matCheckbox.change.emit({ checked: false, source: this.matCheckbox });\n }\n}\n","import { afterRenderEffect, DestroyRef, Directive, inject, OnInit } from \"@angular/core\";\nimport { takeUntilDestroyed } from \"@angular/core/rxjs-interop\";\nimport { MatCheckbox } from \"@angular/material/checkbox\";\nimport { injectNiceSelectableListDirective } from \"./injector\";\n\n@Directive({\n selector: \"mat-checkbox[niceSelectableListHeaderCheckbox]\"\n})\nexport class NiceSelectableListHeaderCheckboxDirective<T> implements OnInit {\n private readonly niceSelectableListDirective = injectNiceSelectableListDirective<T>();\n private readonly matCheckbox = inject(MatCheckbox);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n afterRenderEffect({\n read: () => {\n const checkboxes = this.niceSelectableListDirective.checkboxes();\n const empty = checkboxes.length === 0;\n\n this.matCheckbox.checked = !empty && checkboxes.every((checkbox) => checkbox.isSelected());\n this.matCheckbox.indeterminate = !this.matCheckbox.checked\n && checkboxes.some((checkbox) => checkbox.isSelected());\n }\n });\n }\n\n public ngOnInit(): void {\n this.matCheckbox.change.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ checked }) => {\n if (checked) {\n this.niceSelectableListDirective.checkboxes().forEach((checkbox) => checkbox.selectEntity());\n } else {\n this.niceSelectableListDirective.checkboxes().forEach((checkbox) => checkbox.deselectEntity());\n }\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;MAaa,uBAAuB,CAAA;AAYH,IAAA,OAAA;AAXZ,IAAA,SAAS,GAAG,MAAM,CAAgC,EAAE,CAAC;AACrD,IAAA,aAAa,GAAG,MAAM,CAAqC,IAAI,CAAC;AAChE,IAAA,WAAW,GAAG,MAAM,CAAiD,EAAE,CAAC;AAEzE,IAAA,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;AACtC,IAAA,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;AAE9C,IAAA,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;IAC/C,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC;AACzE,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC;AAEjF,IAAA,WAAA,CAA6B,OAAoC,EAAA;QAApC,IAAO,CAAA,OAAA,GAAP,OAAO;;AAE7B,IAAA,gBAAgB,CAAC,QAAsD,EAAA;AAC1E,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,KAAK,CAAC,GAAG,UAAU,EAAE,QAAQ,CAAC,CAAC;QAElE,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;QACpE,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,EAAE;AAClC,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CACjB,CAAC,SAAS,KAAK,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,KACjC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,EAAE,EAAE,GAAG,OAAO,CAC5E,CACJ;AACD,YAAA,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,gBAAgB,EAAE;;;AAI5C,IAAA,kBAAkB,CAAC,QAAsD,EAAA;QAC5E,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,KAAK,QAAQ,CAAC,CAAC;;AAG9F,IAAA,gBAAgB,CAAC,MAAS,EAAA;AAC7B,QAAA,OAAO,QAAQ,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;;AAGlD,IAAA,yBAAyB,CAAC,UAAoB,EAAA;AACjD,QAAA,MAAM,GAAG,GAAwB,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;AAE5G,QAAA,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,MAAM;AAC7D,YAAA,EAAE,EAAE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB;AAC5F,SAAA,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM;YAC9B,EAAE;AACF,YAAA,MAAM,EAAE,kBAAkB,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,IAAI;AAC5E,SAAA,CAAC,CAAC;AACH,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;;AAGzB,IAAA,YAAY,CAAC,MAAS,EAAA;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QACjD,IAAI,UAAU,EAAE;YACZ;;QAGJ,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QACxC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,CAAC,GAAG,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;;AAG/D,IAAA,cAAc,CAAC,MAAS,EAAA;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE;YACb;;QAGJ,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QACxC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;;IAGjF,KAAK,GAAA;AACR,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;AACtB,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;;AAGzB,IAAA,qBAAqB,CAAC,QAAgB,EAAA;AACzC,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ,GAAG,QAAQ,GAAG,CAAC,QAAQ;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;QACpE,IAAI,CAAC,MAAM,EAAE;YACT;;AAGJ,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;;AAG3B,IAAA,eAAe,CAAC,MAAgB,EAAA;QACnC,IAAI,CAAC,MAAM,EAAE;AACT,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;YAC5B;;QAGJ,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QACxC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;;IAGnC,iBAAiB,GAAA;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE;YACT;;AAGJ,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;;IAG3B,gBAAgB,GAAA;AACnB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE;AACjC,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE;QACzC,IAAI,CAAC,YAAY,EAAE;YACf,IAAI,CAAC,iBAAiB,EAAE;YACxB;;AAGJ,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,KAAK,YAAY,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC;QAC7E,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,EAAE;YACb;;AAGJ,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC;;IAG/B,oBAAoB,GAAA;AACvB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE;AACjC,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE;QACzC,IAAI,CAAC,YAAY,EAAE;YACf,IAAI,CAAC,iBAAiB,EAAE;YACxB;;AAGJ,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,KAAK,YAAY,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC;AAC7E,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;YACb;;QAGJ,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,cAAc,EAAE;YACjB;;AAGJ,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,cAAc,CAAC;;IAGnC,gBAAgB,GAAA;AACnB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE;AACjC,QAAA,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;YACvB;;QAGJ,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QAChD,IAAI,CAAC,UAAU,EAAE;YACb;;AAGJ,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC;;AAG9B,IAAA,iBAAiB,CAAC,MAAS,EAAA;QAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;QACxC,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC;;AAGlE,IAAA,gBAAgB,CAAC,MAAS,EAAA;AAC9B,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU;AAC1C,QAAA,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;QAC7B,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;YAClD,MAAM,IAAI,KAAK,CAAC,CAAA,sDAAA,EAAyD,OAAO,EAAE,CAAA,CAAE,CAAC;;AAGzF,QAAA,OAAO,EAAE;;AAEhB;;MCpLY,qBAAqB,GAC5B,IAAI,cAAc,CAAwC,4BAA4B;AAO5E,SAAA,yBAAyB,CAAI,IAAY,EAAE,MAAoC,EAAA;IAC3F,OAAO;AACH,QAAA,OAAO,EAAE,qBAAqB;AAC9B,QAAA,QAAQ,EAAE;YACN,IAAI;YACJ,KAAK,EAAE,IAAI,uBAAuB,CAAC;AAC/B,gBAAA,UAAU,EAAE,MAAM,EAAE,UAAU,IAAI,IAAe;AACjD,gBAAA,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI;aAC7B;AACJ,SAAA;AACD,QAAA,KAAK,EAAE;KACV;AACL;AAEgB,SAAA,yBAAyB,CAAI,IAAY,EAAE,OAE1D,EAAA;AACG,IAAA,MAAM,eAAe,GAAG,OAAO,EAAE;UAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,qBAAqB;AAC5C,UAAE,MAAM,CAAC,qBAAqB,CAAC;AAEnC,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC;IAC7E,IAAI,CAAC,QAAQ,EAAE;AACX,QAAA,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAA,CAAE,CAAC;;IAG1E,OAAO,QAAQ,CAAC,KAAmC;AACvD;;MClBa,oBAAoB,GAAG,IAAI,cAAc,CAA8B,kBAAkB;MAYzF,uBAAuB,CAAA;IAChB,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAS,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;AAC9D,IAAA,iBAAiB,GAAG,KAAK,CAAU,KAAK,CAAC;IAEzC,UAAU,GAAG,eAAe,CACxC,yCAAyC,EACzC,EAAE,WAAW,EAAE,IAAI,EAAE,CACxB;AAEgB,IAAA,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC;AAC7B,IAAA,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE;AAEzC,IAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAC9B,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAEpC,IAAA,eAAe;AAEzB,IAAA,WAAA,GAAA;QACI,MAAM,CAAC,MAAK;AACR,YAAA,IAAI,CAAC,eAAe,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC9F,SAAC,CAAC;QAEF,MAAM,CAAC,MAAK;AACR,YAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;gBACtB;;AAGJ,YAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE;AAC3B,gBAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE;oBACrB,UAAU,EAAE,IAAI,CAAC,KAAK;AACtB,oBAAA,WAAW,EAAE;AACT,wBAAA,UAAU,EAAE,IAAI;AAChB,wBAAA,QAAQ,EAAE;AACb;AACJ,iBAAA,CAAC;gBACF;;AAER,SAAC,CAAC;QAEF,MAAM,CAAC,MAAK;AACR,YAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE;gBACtB;;AAGJ,YAAA,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7D,IAAI,CAAC,WAAW,EAAE;gBACd;;YAGJ,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE;YACnD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE;AAC1D,YAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE;gBACrB,UAAU,EAAE,IAAI,CAAC,KAAK;AACtB,gBAAA,WAAW,EAAE;AACT,oBAAA,UAAU,EAAE,QAAQ;AACpB,oBAAA,QAAQ,EAAE;AACb;AACJ,aAAA,CAAC;AACN,SAAC,CAAC;;IAGC,QAAQ,GAAA;QACX,IAAI,CAAC,eAAe,EAAE;;IAGlB,eAAe,GAAA;AACnB,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;YACvB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;AACtD,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;YAC3B;;QAGJ,IAAI,CAAC,MAAM,CAAC;AACP,aAAA,IAAI,CACD,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,YAAY,aAAa,CAAC,EACjD,IAAI,CAAC,CAAC,CAAC;aAEV,SAAS,CAAC,MAAK;YACZ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC;AACtD,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC;AAC/B,SAAC,CAAC;;AAGF,IAAA,gBAAgB,CAAC,MAGxB,EAAA;AACG,QAAA,IAAI,MAAM,CAAC,UAAU,EAAE;YACnB,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU;kBAC5C,MAAM,CAAC;AACT,kBAAE,CAAC,MAAM,CAAC,UAAU,CAAC;AACzB,YAAA,IAAI,CAAC,eAAe,CAAC,yBAAyB,CAAC,UAAU,CAAC;;AAG9D,QAAA,IAAI,MAAM,CAAC,QAAQ,EAAE;YACjB,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,MAAM,CAAC,QAAQ,CAAC;;;wGAhG1D,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,EAJrB,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EAAA;AACP,YAAA,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,uBAAuB,CAAC;AAC1F,SAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,YAAA,EAAA,SAAA,EAOG,yCAAyC,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FALpC,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBANnC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACP,oBAAA,QAAQ,EAAE,sBAAsB;AAChC,oBAAA,SAAS,EAAE;AACP,wBAAA,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,UAAU,CAAC,MAA6B,uBAAA,CAAC;AAC1F;AACJ,iBAAA;;;SC1Be,iCAAiC,GAAA;AAC7C,IAAA,OAAO,MAAM,CAAC,oBAAoB,CAA0B;AAChE;AAEM,SAAU,wBAAwB,CAAI,IAAa,EAAA;IACrD,IAAI,CAAC,IAAI,EAAE;AACP,QAAA,IAAI,GAAG,iCAAiC,EAAE,CAAC,IAAI,EAAE;;AAGrD,IAAA,MAAM,eAAe,GAAG,MAAM,CAAC,qBAAqB,CAAC;AACrD,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC;IAC7E,IAAI,CAAC,QAAQ,EAAE;AACX,QAAA,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAA,CAAE,CAAC;;IAG1E,OAAO,QAAQ,CAAC,KAAmC;AACvD;;MCba,yCAAyC,CAAA;AAC/B,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACjC,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAC/B,kBAAkB,GAAG,wBAAwB,EAAK;AAErD,IAAA,gBAAgB,GAAG,KAAK,CAAC,QAAQ,EAAK;AACtC,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC;AAEhH,IAAA,WAAA,GAAA;QACI,MAAM,CAAC,MAAK;AACR,YAAA,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;AAClG,SAAC,CAAC;;IAGC,QAAQ,GAAA;AACX,QAAA,IAAI,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,CAAC;QAE9C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,KAAI;YACxF,IAAI,OAAO,EAAE;gBACT,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;;iBAC1D;gBACH,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;;AAEvE,SAAC,CAAC;;IAGC,WAAW,GAAA;AACd,QAAA,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC;;IAG7C,YAAY,GAAA;AACf,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG,IAAI;AAC/B,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;;IAGtE,cAAc,GAAA;AACjB,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG,KAAK;AAChC,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;;wGArCrE,yCAAyC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAzC,yCAAyC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gDAAA,EAAA,MAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAzC,yCAAyC,EAAA,UAAA,EAAA,CAAA;kBAHrD,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACP,oBAAA,QAAQ,EAAE;AACb,iBAAA;;;MCCY,yCAAyC,CAAA;IACjC,2BAA2B,GAAG,iCAAiC,EAAK;AACpE,IAAA,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACjC,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAEhD,IAAA,WAAA,GAAA;AACI,QAAA,iBAAiB,CAAC;YACd,IAAI,EAAE,MAAK;gBACP,MAAM,UAAU,GAAG,IAAI,CAAC,2BAA2B,CAAC,UAAU,EAAE;AAChE,gBAAA,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,KAAK,CAAC;gBAErC,IAAI,CAAC,WAAW,CAAC,OAAO,GAAG,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC1F,IAAI,CAAC,WAAW,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;AAC5C,uBAAA,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;;AAElE,SAAA,CAAC;;IAGC,QAAQ,GAAA;QACX,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,KAAI;YACxF,IAAI,OAAO,EAAE;AACT,gBAAA,IAAI,CAAC,2BAA2B,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,YAAY,EAAE,CAAC;;iBACzF;AACH,gBAAA,IAAI,CAAC,2BAA2B,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,cAAc,EAAE,CAAC;;AAEtG,SAAC,CAAC;;wGAzBG,yCAAyC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAzC,yCAAyC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gDAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAAzC,yCAAyC,EAAA,UAAA,EAAA,CAAA;kBAHrD,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACP,oBAAA,QAAQ,EAAE;AACb,iBAAA;;;ACPD;;AAEG;;;;"}
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./selectable-list";
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@recursyve/nice-selectable-list",
3
+ "version": "19.0.0-beta.0",
4
+ "peerDependencies": {
5
+ "@angular/common": "^19.2.0",
6
+ "@angular/cdk": "^19.2.0",
7
+ "@angular/core": "^19.2.0",
8
+ "@angular/material": "^19.2.0"
9
+ },
10
+ "dependencies": {
11
+ "tslib": "^2.3.0"
12
+ },
13
+ "sideEffects": false,
14
+ "module": "fesm2022/recursyve-nice-selectable-list.mjs",
15
+ "typings": "index.d.ts",
16
+ "exports": {
17
+ "./package.json": {
18
+ "default": "./package.json"
19
+ },
20
+ ".": {
21
+ "types": "./index.d.ts",
22
+ "default": "./fesm2022/recursyve-nice-selectable-list.mjs"
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,17 @@
1
+ import { DestroyRef, OnDestroy, OnInit } from "@angular/core";
2
+ import { MatCheckbox } from "@angular/material/checkbox";
3
+ import * as i0 from "@angular/core";
4
+ export declare class NiceSelectableListEntityCheckboxDirective<T> implements OnInit, OnDestroy {
5
+ protected readonly matCheckbox: MatCheckbox;
6
+ protected readonly destroyRef: DestroyRef;
7
+ protected readonly niceSelectableList: import("@recursyve/nice-selectable-list").NiceSelectableListStore<T>;
8
+ readonly selectableEntity: import("@angular/core").InputSignal<T>;
9
+ readonly isSelected: import("@angular/core").Signal<boolean>;
10
+ constructor();
11
+ ngOnInit(): void;
12
+ ngOnDestroy(): void;
13
+ selectEntity(): void;
14
+ deselectEntity(): void;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<NiceSelectableListEntityCheckboxDirective<any>, never>;
16
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NiceSelectableListEntityCheckboxDirective<any>, "mat-checkbox[niceSelectableListEntityCheckbox]", never, { "selectableEntity": { "alias": "selectableEntity"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
17
+ }
@@ -0,0 +1,11 @@
1
+ import { OnInit } from "@angular/core";
2
+ import * as i0 from "@angular/core";
3
+ export declare class NiceSelectableListHeaderCheckboxDirective<T> implements OnInit {
4
+ private readonly niceSelectableListDirective;
5
+ private readonly matCheckbox;
6
+ private readonly destroyRef;
7
+ constructor();
8
+ ngOnInit(): void;
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<NiceSelectableListHeaderCheckboxDirective<any>, never>;
10
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NiceSelectableListHeaderCheckboxDirective<any>, "mat-checkbox[niceSelectableListHeaderCheckbox]", never, {}, {}, never, never, true, never>;
11
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./entity-checkbox.directive";
2
+ export * from "./header-checkbox.directive";
3
+ export * from "./selectable-list";
4
+ export * from "./injector";
5
+ export * from "./provider";
6
+ export * from "./store";
@@ -0,0 +1,4 @@
1
+ import { NiceSelectableList } from "./selectable-list";
2
+ import { NiceSelectableListStore } from "./store";
3
+ export declare function injectNiceSelectableListDirective<T>(): NiceSelectableList<T>;
4
+ export declare function injectNiceSelectableList<T>(name?: string): NiceSelectableListStore<T>;
@@ -0,0 +1,11 @@
1
+ import { InjectionToken, Injector, Provider } from "@angular/core";
2
+ import { NiceSelectableListConfig, NiceSelectableListStore } from "./store";
3
+ export declare const NICE_SELECTABLE_LISTS: InjectionToken<NiceSelectableListProvider<unknown>[]>;
4
+ export type NiceSelectableListProvider<T> = {
5
+ name: string;
6
+ store: NiceSelectableListStore<T>;
7
+ };
8
+ export declare function provideNiceSelectableList<T>(name: string, config?: NiceSelectableListConfig<T>): Provider;
9
+ export declare function resolveNiceSelectableList<T>(name: string, options?: {
10
+ injector: Injector;
11
+ }): NiceSelectableListStore<T>;
@@ -0,0 +1,27 @@
1
+ import { InjectionToken, Injector, OnInit, Signal } from "@angular/core";
2
+ import { ActivatedRoute, Router } from "@angular/router";
3
+ import { NiceSelectableListEntityCheckboxDirective } from "./entity-checkbox.directive";
4
+ import { NiceSelectableListStore } from "./store";
5
+ import * as i0 from "@angular/core";
6
+ export declare const NICE_SELECTABLE_LIST: InjectionToken<NiceSelectableList<unknown>>;
7
+ export type NiceSelectableList<T> = {
8
+ name: Signal<string>;
9
+ checkboxes: Signal<readonly NiceSelectableListEntityCheckboxDirective<T>[]>;
10
+ };
11
+ export declare class SelectableListDirective<T> implements NiceSelectableList<T>, OnInit {
12
+ readonly name: import("@angular/core").InputSignal<string>;
13
+ readonly enableQueryParams: import("@angular/core").InputSignal<boolean>;
14
+ readonly checkboxes: Signal<readonly NiceSelectableListEntityCheckboxDirective<T>[]>;
15
+ private readonly _initialized;
16
+ readonly initialized: Signal<boolean>;
17
+ protected readonly route: ActivatedRoute;
18
+ protected readonly router: Router;
19
+ protected readonly injector: Injector;
20
+ protected selectableLists: NiceSelectableListStore<T>;
21
+ constructor();
22
+ ngOnInit(): void;
23
+ private loadQueryParams;
24
+ private parseQueryParams;
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<SelectableListDirective<any>, never>;
26
+ static ɵdir: i0.ɵɵDirectiveDeclaration<SelectableListDirective<any>, "[niceSelectableList]", never, { "name": { "alias": "niceSelectableList"; "required": true; "isSignal": true; }; "enableQueryParams": { "alias": "enableQueryParams"; "required": false; "isSignal": true; }; }, {}, ["checkboxes"], never, true, never>;
27
+ }
@@ -0,0 +1,37 @@
1
+ import { Signal } from "@angular/core";
2
+ import { NiceSelectableListEntityCheckboxDirective } from "./entity-checkbox.directive";
3
+ export type NiceSelectableListConfig<T> = {
4
+ idProperty: keyof T;
5
+ idType?: "string" | "number";
6
+ };
7
+ export type NiceSelectableListEntity<T> = {
8
+ id: string | number;
9
+ entity: T | null;
10
+ };
11
+ export declare class NiceSelectableListStore<T> {
12
+ private readonly _config;
13
+ private readonly _entities;
14
+ private readonly _activeEntity;
15
+ private readonly _checkboxes;
16
+ readonly entities: Signal<NiceSelectableListEntity<T>[]>;
17
+ readonly activeEntity: Signal<NiceSelectableListEntity<T> | null>;
18
+ readonly total: Signal<number>;
19
+ readonly entitiesIds: Signal<(string | number)[]>;
20
+ readonly activeEntityId: Signal<string | number | null>;
21
+ constructor(_config: NiceSelectableListConfig<T>);
22
+ registerCheckbox(checkbox: NiceSelectableListEntityCheckboxDirective<T>): void;
23
+ unregisterCheckbox(checkbox: NiceSelectableListEntityCheckboxDirective<T>): void;
24
+ isEntitySelected(entity: T): Signal<boolean>;
25
+ setEntitiesFromSelections(selections: string[]): void;
26
+ selectEntity(entity: T): void;
27
+ deselectEntity(entity: T): void;
28
+ clear(): void;
29
+ setActiveFromSelected(selected: string): void;
30
+ setActiveEntity(entity: T | null): void;
31
+ selectFirstEntity(): void;
32
+ selectNextEntity(): void;
33
+ selectPreviousEntity(): void;
34
+ selectLastEntity(): void;
35
+ private _isEntitySelected;
36
+ private _resolveEntityId;
37
+ }