@theseam/ui-common 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data-filters/index.d.ts +53 -7
- package/fesm2022/theseam-ui-common-data-filters.mjs +150 -19
- package/fesm2022/theseam-ui-common-data-filters.mjs.map +1 -1
- package/fesm2022/theseam-ui-common-datatable.mjs +6 -6
- package/fesm2022/theseam-ui-common-datatable.mjs.map +1 -1
- package/fesm2022/theseam-ui-common-google-maps.mjs +299 -218
- package/fesm2022/theseam-ui-common-google-maps.mjs.map +1 -1
- package/fesm2022/theseam-ui-common-toggle-group.mjs +81 -112
- package/fesm2022/theseam-ui-common-toggle-group.mjs.map +1 -1
- package/fesm2022/theseam-ui-common-utils.mjs +112 -21
- package/fesm2022/theseam-ui-common-utils.mjs.map +1 -1
- package/google-maps/index.d.ts +35 -23
- package/package.json +4 -1
- package/toggle-group/index.d.ts +42 -18
- package/utils/index.d.ts +38 -6
|
@@ -1,38 +1,25 @@
|
|
|
1
|
-
import { coerceBooleanProperty, coerceArray } from '@angular/cdk/coercion';
|
|
2
1
|
import * as i0 from '@angular/core';
|
|
3
|
-
import {
|
|
2
|
+
import { InjectionToken, inject, HostBinding, Input, Directive, forwardRef, EventEmitter, ContentChildren, Output, NgModule } from '@angular/core';
|
|
4
3
|
import { __decorate } from 'tslib';
|
|
4
|
+
import { coerceArray } from '@angular/cdk/coercion';
|
|
5
5
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
|
-
import { Subject, of, combineLatest, from } from 'rxjs';
|
|
7
|
-
import { startWith, map, takeUntil, switchMap, filter, tap } from 'rxjs/operators';
|
|
8
6
|
import { InputBoolean } from '@theseam/ui-common/core';
|
|
9
7
|
|
|
8
|
+
const THESEAM_TOGGLE_GROUP_PARENT = new InjectionToken('TheSeamToggleGroupParent');
|
|
9
|
+
|
|
10
10
|
class ToggleGroupOptionDirective {
|
|
11
|
-
|
|
11
|
+
_group = inject(THESEAM_TOGGLE_GROUP_PARENT, {
|
|
12
|
+
optional: true,
|
|
13
|
+
});
|
|
12
14
|
seamToggleGroupOption;
|
|
13
|
-
get selected() {
|
|
14
|
-
return this._selected;
|
|
15
|
-
}
|
|
16
|
-
set selected(value) {
|
|
17
|
-
if (!this._canUnselect && !value) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
this._selected = coerceBooleanProperty(value);
|
|
21
|
-
this.selectionChange.emit(this._selected);
|
|
22
|
-
this._cdr.markForCheck();
|
|
23
|
-
}
|
|
24
|
-
_selected = false;
|
|
25
|
-
/** Internal use only for now. */
|
|
26
|
-
_canUnselect = true;
|
|
27
|
-
selectionChange = new EventEmitter();
|
|
28
15
|
get _checkioSelectedClass() {
|
|
29
|
-
return this.
|
|
16
|
+
return this._group?.isSelected(this.value) || false;
|
|
30
17
|
}
|
|
31
18
|
get value() {
|
|
32
19
|
return this.seamToggleGroupOption;
|
|
33
20
|
}
|
|
34
21
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ToggleGroupOptionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
35
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: ToggleGroupOptionDirective, isStandalone: true, selector: "[seamToggleGroupOption]", inputs: { seamToggleGroupOption: "seamToggleGroupOption"
|
|
22
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: ToggleGroupOptionDirective, isStandalone: true, selector: "[seamToggleGroupOption]", inputs: { seamToggleGroupOption: "seamToggleGroupOption" }, host: { properties: { "class.lib-toggle-group-option-selected": "this._checkioSelectedClass" } }, exportAs: ["seamToggleGroupOption"], ngImport: i0 });
|
|
36
23
|
}
|
|
37
24
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ToggleGroupOptionDirective, decorators: [{
|
|
38
25
|
type: Directive,
|
|
@@ -42,10 +29,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
42
29
|
}]
|
|
43
30
|
}], propDecorators: { seamToggleGroupOption: [{
|
|
44
31
|
type: Input
|
|
45
|
-
}], selected: [{
|
|
46
|
-
type: Input
|
|
47
|
-
}], selectionChange: [{
|
|
48
|
-
type: Output
|
|
49
32
|
}], _checkioSelectedClass: [{
|
|
50
33
|
type: HostBinding,
|
|
51
34
|
args: ['class.lib-toggle-group-option-selected']
|
|
@@ -60,7 +43,6 @@ class ToggleGroupDirective {
|
|
|
60
43
|
static ngAcceptInputType_disabled;
|
|
61
44
|
static ngAcceptInputType_multiple;
|
|
62
45
|
static ngAcceptInputType_selectionToggleable;
|
|
63
|
-
_ngUnsubscribe = new Subject();
|
|
64
46
|
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
65
47
|
val;
|
|
66
48
|
disabled = false;
|
|
@@ -70,47 +52,11 @@ class ToggleGroupDirective {
|
|
|
70
52
|
// eslint-disable-next-line @angular-eslint/no-output-native
|
|
71
53
|
change = new EventEmitter();
|
|
72
54
|
optionDirectives;
|
|
73
|
-
options;
|
|
74
55
|
onChange;
|
|
75
56
|
onTouched;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
ngAfterViewInit() {
|
|
81
|
-
setTimeout(() => {
|
|
82
|
-
this._updateDirectiveStates();
|
|
83
|
-
if (this.optionDirectives) {
|
|
84
|
-
this.options = this.optionDirectives.changes.pipe(startWith(this.optionDirectives), map((v) => v.toArray()), takeUntil(this._ngUnsubscribe));
|
|
85
|
-
this.options
|
|
86
|
-
.pipe(switchMap((opts) => {
|
|
87
|
-
const _tmp = of(undefined);
|
|
88
|
-
if (opts) {
|
|
89
|
-
const _v = [];
|
|
90
|
-
for (const opt of opts) {
|
|
91
|
-
_v.push(opt.selectionChange.pipe(filter((v) => opt.selected !== this.isSelected(opt.value)), tap((v) => {
|
|
92
|
-
if (this.isSelected(opt.value)) {
|
|
93
|
-
this.unselectValue(opt.value);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
this.selectValue(opt.value);
|
|
97
|
-
}
|
|
98
|
-
})));
|
|
99
|
-
}
|
|
100
|
-
return combineLatest(_v);
|
|
101
|
-
}
|
|
102
|
-
return _tmp;
|
|
103
|
-
}), takeUntil(this._ngUnsubscribe))
|
|
104
|
-
.subscribe();
|
|
105
|
-
}
|
|
106
|
-
this.change
|
|
107
|
-
.pipe(switchMap((_) => from(this.optionDirectives?.toArray() || []).pipe(tap((opt) => {
|
|
108
|
-
this._updateDirectiveState(opt);
|
|
109
|
-
}))), takeUntil(this._ngUnsubscribe))
|
|
110
|
-
.subscribe();
|
|
111
|
-
});
|
|
112
|
-
this.optionDirectives?.changes.subscribe(() => this._updateDirectiveStates());
|
|
113
|
-
}
|
|
57
|
+
_selectedSet;
|
|
58
|
+
_selectedSetSource;
|
|
59
|
+
_selectedSetMultiple;
|
|
114
60
|
get value() {
|
|
115
61
|
return this.val;
|
|
116
62
|
}
|
|
@@ -142,17 +88,63 @@ class ToggleGroupDirective {
|
|
|
142
88
|
this.disabled = isDisabled;
|
|
143
89
|
}
|
|
144
90
|
isSelected(value) {
|
|
91
|
+
if (value === null || value === undefined) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return this._selected().has(value);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The current selection as a set, rebuilt only when the value (or `multiple`)
|
|
98
|
+
* changes.
|
|
99
|
+
*
|
|
100
|
+
* `isSelected` is called from templates and from every option's host binding,
|
|
101
|
+
* so it runs several times per option per change detection pass. Hashing the
|
|
102
|
+
* selection once keeps those lookups O(1) instead of scanning the value array
|
|
103
|
+
* on every call.
|
|
104
|
+
*
|
|
105
|
+
* Invalidation is keyed on the `val` reference rather than done in the `value`
|
|
106
|
+
* setter, because `val` is also written directly by the `[value]` input, which
|
|
107
|
+
* does not go through the setter.
|
|
108
|
+
*/
|
|
109
|
+
_selected() {
|
|
110
|
+
if (this._selectedSet === undefined ||
|
|
111
|
+
this.val !== this._selectedSetSource ||
|
|
112
|
+
this.multiple !== this._selectedSetMultiple) {
|
|
113
|
+
this._selectedSetSource = this.val;
|
|
114
|
+
this._selectedSetMultiple = this.multiple;
|
|
115
|
+
this._selectedSet = this._buildSelectedSet();
|
|
116
|
+
}
|
|
117
|
+
return this._selectedSet;
|
|
118
|
+
}
|
|
119
|
+
_buildSelectedSet() {
|
|
120
|
+
const val = this.val;
|
|
145
121
|
if (this.multiple) {
|
|
146
|
-
|
|
147
|
-
return idx !== -1;
|
|
122
|
+
return new Set(val ?? []);
|
|
148
123
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
124
|
+
// TODO: Clean this up when the directive no longer allows array value type when multiple is false
|
|
125
|
+
const v = Array.isArray(val) && val.length === 1 ? val[0] : val;
|
|
126
|
+
return typeof v === 'string' ? new Set([v]) : new Set();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Toggles an option's selected state by value.
|
|
130
|
+
*/
|
|
131
|
+
toggleOptionSelect(value) {
|
|
132
|
+
if (this.isSelected(value)) {
|
|
133
|
+
if (!this.selectionToggleable && this._selectedCount() <= 1) {
|
|
134
|
+
// Unselecting would leave nothing selected.
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
this.unselectValue(value);
|
|
138
|
+
return;
|
|
155
139
|
}
|
|
140
|
+
this.selectValue(value);
|
|
141
|
+
}
|
|
142
|
+
_selectedCount() {
|
|
143
|
+
if (this.multiple) {
|
|
144
|
+
return (this.value || []).length;
|
|
145
|
+
}
|
|
146
|
+
const v = this.value;
|
|
147
|
+
return v === null || v === undefined || v === '' ? 0 : 1;
|
|
156
148
|
}
|
|
157
149
|
unselectValue(value) {
|
|
158
150
|
if (this.multiple) {
|
|
@@ -177,43 +169,14 @@ class ToggleGroupDirective {
|
|
|
177
169
|
}
|
|
178
170
|
return this.optionDirectives.toArray().find((opt) => opt.value === value);
|
|
179
171
|
}
|
|
180
|
-
_updateDirectiveStates() {
|
|
181
|
-
if (this.optionDirectives) {
|
|
182
|
-
for (const opt of this.optionDirectives.toArray()) {
|
|
183
|
-
this._updateDirectiveState(opt);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
_updateDirectiveState(opt) {
|
|
188
|
-
const selected = this.isSelected(opt.value);
|
|
189
|
-
if (opt.selected !== selected) {
|
|
190
|
-
if (!opt._canUnselect) {
|
|
191
|
-
opt._canUnselect = true;
|
|
192
|
-
}
|
|
193
|
-
opt.selected = selected;
|
|
194
|
-
}
|
|
195
|
-
if (!this.selectionToggleable) {
|
|
196
|
-
if (!this.multiple || (this.value && this.value.length <= 1)) {
|
|
197
|
-
if (opt.selected) {
|
|
198
|
-
if (opt._canUnselect) {
|
|
199
|
-
opt._canUnselect = false;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
if (!opt._canUnselect) {
|
|
204
|
-
opt._canUnselect = true;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
if (!opt._canUnselect) {
|
|
210
|
-
opt._canUnselect = true;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
172
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ToggleGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
216
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: ToggleGroupDirective, isStandalone: true, selector: "[seamToggleGroup]", inputs: { val: ["value", "val"], disabled: "disabled", multiple: "multiple", selectionToggleable: "selectionToggleable" }, outputs: { change: "change" }, providers: [
|
|
173
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: ToggleGroupDirective, isStandalone: true, selector: "[seamToggleGroup]", inputs: { val: ["value", "val"], disabled: "disabled", multiple: "multiple", selectionToggleable: "selectionToggleable" }, outputs: { change: "change" }, providers: [
|
|
174
|
+
TOGGLE_GROUP_VALUE_ACCESSOR,
|
|
175
|
+
{
|
|
176
|
+
provide: THESEAM_TOGGLE_GROUP_PARENT,
|
|
177
|
+
useExisting: forwardRef(() => ToggleGroupDirective),
|
|
178
|
+
},
|
|
179
|
+
], queries: [{ propertyName: "optionDirectives", predicate: ToggleGroupOptionDirective }], exportAs: ["seamToggleGroup"], ngImport: i0 });
|
|
217
180
|
}
|
|
218
181
|
__decorate([
|
|
219
182
|
InputBoolean()
|
|
@@ -229,7 +192,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
229
192
|
args: [{
|
|
230
193
|
selector: '[seamToggleGroup]',
|
|
231
194
|
exportAs: 'seamToggleGroup',
|
|
232
|
-
providers: [
|
|
195
|
+
providers: [
|
|
196
|
+
TOGGLE_GROUP_VALUE_ACCESSOR,
|
|
197
|
+
{
|
|
198
|
+
provide: THESEAM_TOGGLE_GROUP_PARENT,
|
|
199
|
+
useExisting: forwardRef(() => ToggleGroupDirective),
|
|
200
|
+
},
|
|
201
|
+
],
|
|
233
202
|
}]
|
|
234
203
|
}], propDecorators: { val: [{
|
|
235
204
|
type: Input,
|
|
@@ -264,5 +233,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
264
233
|
* Generated bundle index. Do not edit.
|
|
265
234
|
*/
|
|
266
235
|
|
|
267
|
-
export { TOGGLE_GROUP_VALUE_ACCESSOR, TheSeamToggleGroupModule, ToggleGroupDirective, ToggleGroupOptionDirective };
|
|
236
|
+
export { THESEAM_TOGGLE_GROUP_PARENT, TOGGLE_GROUP_VALUE_ACCESSOR, TheSeamToggleGroupModule, ToggleGroupDirective, ToggleGroupOptionDirective };
|
|
268
237
|
//# sourceMappingURL=theseam-ui-common-toggle-group.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theseam-ui-common-toggle-group.mjs","sources":["../../../projects/ui-common/toggle-group/toggle-group-option.directive.ts","../../../projects/ui-common/toggle-group/toggle-group.directive.ts","../../../projects/ui-common/toggle-group/toggle-group.module.ts","../../../projects/ui-common/toggle-group/theseam-ui-common-toggle-group.ts"],"sourcesContent":["import { coerceBooleanProperty } from '@angular/cdk/coercion'\nimport {\n ChangeDetectorRef,\n Directive,\n EventEmitter,\n HostBinding,\n inject,\n Input,\n Output,\n} from '@angular/core'\n\n@Directive({\n selector: '[seamToggleGroupOption]',\n exportAs: 'seamToggleGroupOption',\n})\nexport class ToggleGroupOptionDirective {\n private readonly _cdr = inject(ChangeDetectorRef)\n\n @Input() seamToggleGroupOption: string | undefined | null\n\n @Input()\n get selected(): boolean {\n return this._selected\n }\n set selected(value: boolean) {\n if (!this._canUnselect && !value) {\n return\n }\n this._selected = coerceBooleanProperty(value)\n this.selectionChange.emit(this._selected)\n this._cdr.markForCheck()\n }\n private _selected = false\n\n /** Internal use only for now. */\n _canUnselect = true\n\n @Output() selectionChange = new EventEmitter<boolean>()\n\n @HostBinding('class.lib-toggle-group-option-selected')\n get _checkioSelectedClass() {\n return this._selected\n }\n\n get value(): string | undefined | null {\n return this.seamToggleGroupOption\n }\n}\n","import { BooleanInput, coerceArray } from '@angular/cdk/coercion'\nimport {\n AfterViewInit,\n ContentChildren,\n Directive,\n EventEmitter,\n forwardRef,\n Input,\n OnDestroy,\n Output,\n QueryList,\n} from '@angular/core'\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'\nimport { combineLatest, from, Observable, of, Subject } from 'rxjs'\nimport {\n filter,\n map,\n startWith,\n switchMap,\n takeUntil,\n tap,\n} from 'rxjs/operators'\n\nimport { InputBoolean } from '@theseam/ui-common/core'\n\nimport { ToggleGroupOptionDirective } from './toggle-group-option.directive'\n\nexport const TOGGLE_GROUP_VALUE_ACCESSOR: any = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => ToggleGroupDirective),\n multi: true,\n}\n\n@Directive({\n selector: '[seamToggleGroup]',\n exportAs: 'seamToggleGroup',\n providers: [TOGGLE_GROUP_VALUE_ACCESSOR],\n})\nexport class ToggleGroupDirective\n implements OnDestroy, AfterViewInit, ControlValueAccessor\n{\n static ngAcceptInputType_disabled: BooleanInput\n static ngAcceptInputType_multiple: BooleanInput\n static ngAcceptInputType_selectionToggleable: BooleanInput\n\n private readonly _ngUnsubscribe = new Subject<void>()\n\n // eslint-disable-next-line @angular-eslint/no-input-rename\n @Input('value') val: string | string[] | undefined | null\n\n @Input() @InputBoolean() disabled = false\n @Input() @InputBoolean() multiple = false\n @Input() @InputBoolean() selectionToggleable = true\n\n // TODO: Add min/max selected inputs to make toggling better for multi select\n\n // eslint-disable-next-line @angular-eslint/no-output-native\n @Output() readonly change = new EventEmitter<\n string | string[] | undefined | null\n >()\n\n @ContentChildren(ToggleGroupOptionDirective)\n optionDirectives?: QueryList<ToggleGroupOptionDirective>\n\n public options?: Observable<ToggleGroupOptionDirective[]>\n\n onChange: any\n onTouched: any\n\n ngOnDestroy() {\n this._ngUnsubscribe.next()\n this._ngUnsubscribe.complete()\n }\n\n ngAfterViewInit() {\n setTimeout(() => {\n this._updateDirectiveStates()\n\n if (this.optionDirectives) {\n this.options = this.optionDirectives.changes.pipe(\n startWith(this.optionDirectives),\n map((v) => v.toArray() as ToggleGroupOptionDirective[]),\n takeUntil(this._ngUnsubscribe),\n )\n\n this.options\n .pipe(\n switchMap((opts) => {\n const _tmp = of(undefined)\n if (opts) {\n const _v: Observable<boolean>[] = []\n for (const opt of opts) {\n _v.push(\n opt.selectionChange.pipe(\n filter(\n (v) => opt.selected !== this.isSelected(opt.value),\n ),\n tap((v) => {\n if (this.isSelected(opt.value)) {\n this.unselectValue(opt.value)\n } else {\n this.selectValue(opt.value)\n }\n }),\n ),\n )\n }\n return combineLatest(_v)\n }\n return _tmp\n }),\n takeUntil(this._ngUnsubscribe),\n )\n .subscribe()\n }\n\n this.change\n .pipe(\n switchMap((_) =>\n from(this.optionDirectives?.toArray() || []).pipe(\n tap((opt) => {\n this._updateDirectiveState(opt)\n }),\n ),\n ),\n takeUntil(this._ngUnsubscribe),\n )\n .subscribe()\n })\n\n this.optionDirectives?.changes.subscribe(() =>\n this._updateDirectiveStates(),\n )\n }\n\n get value(): string | string[] | undefined | null {\n return this.val\n }\n\n set value(value: string | string[] | undefined | null) {\n const _value = this.multiple\n ? value !== null && value !== undefined\n ? coerceArray(value)\n : value\n : value\n\n this.val = this.multiple ? [...((_value as string[]) || [])] : _value || ''\n this.change.emit(this.val)\n if (this.onChange) {\n this.onChange(_value)\n }\n if (this.onTouched) {\n this.onTouched()\n }\n }\n\n writeValue(value: any): void {\n this.value = value\n }\n\n registerOnChange(fn: any): void {\n this.onChange = fn\n }\n\n registerOnTouched(fn: any): void {\n this.onTouched = fn\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled\n }\n\n isSelected(value: string | undefined | null) {\n if (this.multiple) {\n const idx = ((this.value as string[]) || []).findIndex((v) => v === value)\n return idx !== -1\n } else {\n // TODO: Clean this up when the directive no longer allows array value type when multiple is false\n const v =\n Array.isArray(this.value) && this.value.length === 1\n ? this.value[0]\n : this.value\n return v === value\n }\n }\n\n unselectValue(value: string | undefined | null) {\n if (this.multiple) {\n this.value = ((this.value as string[]) || []).filter((v) => v !== value)\n } else {\n this.value = undefined\n }\n }\n\n selectValue(value: string | undefined | null) {\n if (this.multiple) {\n const _value = [...((this.value as string[]) || [])]\n this.value = value ? [..._value, value] : _value\n } else {\n this.value = value\n }\n }\n\n getOptionDirectiveByValue(value: string) {\n if (!this.optionDirectives || this.optionDirectives.length < 1) {\n return null\n }\n\n return this.optionDirectives.toArray().find((opt) => opt.value === value)\n }\n\n private _updateDirectiveStates(): void {\n if (this.optionDirectives) {\n for (const opt of this.optionDirectives.toArray()) {\n this._updateDirectiveState(opt)\n }\n }\n }\n\n private _updateDirectiveState(opt: ToggleGroupOptionDirective): void {\n const selected = this.isSelected(opt.value)\n if (opt.selected !== selected) {\n if (!opt._canUnselect) {\n opt._canUnselect = true\n }\n opt.selected = selected\n }\n if (!this.selectionToggleable) {\n if (!this.multiple || (this.value && this.value.length <= 1)) {\n if (opt.selected) {\n if (opt._canUnselect) {\n opt._canUnselect = false\n }\n } else {\n if (!opt._canUnselect) {\n opt._canUnselect = true\n }\n }\n } else {\n if (!opt._canUnselect) {\n opt._canUnselect = true\n }\n }\n }\n }\n}\n","import { NgModule } from '@angular/core'\n\nimport { ToggleGroupOptionDirective } from './toggle-group-option.directive'\nimport { ToggleGroupDirective } from './toggle-group.directive'\n\n@NgModule({\n imports: [ToggleGroupDirective, ToggleGroupOptionDirective],\n exports: [ToggleGroupDirective, ToggleGroupOptionDirective],\n})\nexport class TheSeamToggleGroupModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;MAea,0BAA0B,CAAA;AACpB,IAAA,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAExC,IAAA,qBAAqB;AAE9B,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS;IACvB;IACA,IAAI,QAAQ,CAAC,KAAc,EAAA;QACzB,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,EAAE;YAChC;QACF;AACA,QAAA,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,KAAK,CAAC;QAC7C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;AACzC,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;IAC1B;IACQ,SAAS,GAAG,KAAK;;IAGzB,YAAY,GAAG,IAAI;AAET,IAAA,eAAe,GAAG,IAAI,YAAY,EAAW;AAEvD,IAAA,IACI,qBAAqB,GAAA;QACvB,OAAO,IAAI,CAAC,SAAS;IACvB;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,qBAAqB;IACnC;wGA/BW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAA1B,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,MAAA,EAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,wCAAA,EAAA,4BAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAAA,uBAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAA1B,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAJtC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,yBAAyB;AACnC,oBAAA,QAAQ,EAAE,uBAAuB;AAClC,iBAAA;;sBAIE;;sBAEA;;sBAiBA;;sBAEA,WAAW;uBAAC,wCAAwC;;;ACZhD,MAAM,2BAA2B,GAAQ;AAC9C,IAAA,OAAO,EAAE,iBAAiB;AAC1B,IAAA,WAAW,EAAE,UAAU,CAAC,MAAM,oBAAoB,CAAC;AACnD,IAAA,KAAK,EAAE,IAAI;;MAQA,oBAAoB,CAAA;IAG/B,OAAO,0BAA0B;IACjC,OAAO,0BAA0B;IACjC,OAAO,qCAAqC;AAE3B,IAAA,cAAc,GAAG,IAAI,OAAO,EAAQ;;AAGrC,IAAA,GAAG;IAEM,QAAQ,GAAG,KAAK;IAChB,QAAQ,GAAG,KAAK;IAChB,mBAAmB,GAAG,IAAI;;;AAKhC,IAAA,MAAM,GAAG,IAAI,YAAY,EAEzC;AAGH,IAAA,gBAAgB;AAET,IAAA,OAAO;AAEd,IAAA,QAAQ;AACR,IAAA,SAAS;IAET,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;AAC1B,QAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;IAChC;IAEA,eAAe,GAAA;QACb,UAAU,CAAC,MAAK;YACd,IAAI,CAAC,sBAAsB,EAAE;AAE7B,YAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACzB,gBAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAC/C,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAChC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAkC,CAAC,EACvD,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAC/B;AAED,gBAAA,IAAI,CAAC;AACF,qBAAA,IAAI,CACH,SAAS,CAAC,CAAC,IAAI,KAAI;AACjB,oBAAA,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC;oBAC1B,IAAI,IAAI,EAAE;wBACR,MAAM,EAAE,GAA0B,EAAE;AACpC,wBAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACtB,4BAAA,EAAE,CAAC,IAAI,CACL,GAAG,CAAC,eAAe,CAAC,IAAI,CACtB,MAAM,CACJ,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CACnD,EACD,GAAG,CAAC,CAAC,CAAC,KAAI;gCACR,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC9B,oCAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;gCAC/B;qCAAO;AACL,oCAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;gCAC7B;4BACF,CAAC,CAAC,CACH,CACF;wBACH;AACA,wBAAA,OAAO,aAAa,CAAC,EAAE,CAAC;oBAC1B;AACA,oBAAA,OAAO,IAAI;gBACb,CAAC,CAAC,EACF,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC;AAE/B,qBAAA,SAAS,EAAE;YAChB;AAEA,YAAA,IAAI,CAAC;iBACF,IAAI,CACH,SAAS,CAAC,CAAC,CAAC,KACV,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAC/C,GAAG,CAAC,CAAC,GAAG,KAAI;AACV,gBAAA,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC;YACjC,CAAC,CAAC,CACH,CACF,EACD,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC;AAE/B,iBAAA,SAAS,EAAE;AAChB,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,SAAS,CAAC,MACvC,IAAI,CAAC,sBAAsB,EAAE,CAC9B;IACH;AAEA,IAAA,IAAI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,GAAG;IACjB;IAEA,IAAI,KAAK,CAAC,KAA2C,EAAA;AACnD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC;AAClB,cAAE,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK;AAC5B,kBAAE,WAAW,CAAC,KAAK;AACnB,kBAAE;cACF,KAAK;QAET,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAK,MAAmB,IAAI,EAAE,CAAC,CAAC,GAAG,MAAM,IAAI,EAAE;QAC3E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC1B,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QACvB;AACA,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;YAClB,IAAI,CAAC,SAAS,EAAE;QAClB;IACF;AAEA,IAAA,UAAU,CAAC,KAAU,EAAA;AACnB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;IACpB;AAEA,IAAA,gBAAgB,CAAC,EAAO,EAAA;AACtB,QAAA,IAAI,CAAC,QAAQ,GAAG,EAAE;IACpB;AAEA,IAAA,iBAAiB,CAAC,EAAO,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AAEA,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,QAAQ,GAAG,UAAU;IAC5B;AAEA,IAAA,UAAU,CAAC,KAAgC,EAAA;AACzC,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,MAAM,GAAG,GAAG,CAAE,IAAI,CAAC,KAAkB,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AAC1E,YAAA,OAAO,GAAG,KAAK,CAAC,CAAC;QACnB;aAAO;;AAEL,YAAA,MAAM,CAAC,GACL,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK;AACjD,kBAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AACd,kBAAE,IAAI,CAAC,KAAK;YAChB,OAAO,CAAC,KAAK,KAAK;QACpB;IACF;AAEA,IAAA,aAAa,CAAC,KAAgC,EAAA;AAC5C,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,IAAI,CAAC,KAAK,GAAG,CAAE,IAAI,CAAC,KAAkB,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;QAC1E;aAAO;AACL,YAAA,IAAI,CAAC,KAAK,GAAG,SAAS;QACxB;IACF;AAEA,IAAA,WAAW,CAAC,KAAgC,EAAA;AAC1C,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,YAAA,MAAM,MAAM,GAAG,CAAC,IAAK,IAAI,CAAC,KAAkB,IAAI,EAAE,CAAC,CAAC;AACpD,YAAA,IAAI,CAAC,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM;QAClD;aAAO;AACL,YAAA,IAAI,CAAC,KAAK,GAAG,KAAK;QACpB;IACF;AAEA,IAAA,yBAAyB,CAAC,KAAa,EAAA;AACrC,QAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;AAC9D,YAAA,OAAO,IAAI;QACb;QAEA,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC;IAC3E;IAEQ,sBAAsB,GAAA;AAC5B,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE;AACjD,gBAAA,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC;YACjC;QACF;IACF;AAEQ,IAAA,qBAAqB,CAAC,GAA+B,EAAA;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;AAC3C,QAAA,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE;AAC7B,YAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;AACrB,gBAAA,GAAG,CAAC,YAAY,GAAG,IAAI;YACzB;AACA,YAAA,GAAG,CAAC,QAAQ,GAAG,QAAQ;QACzB;AACA,QAAA,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE;AAC7B,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE;AAC5D,gBAAA,IAAI,GAAG,CAAC,QAAQ,EAAE;AAChB,oBAAA,IAAI,GAAG,CAAC,YAAY,EAAE;AACpB,wBAAA,GAAG,CAAC,YAAY,GAAG,KAAK;oBAC1B;gBACF;qBAAO;AACL,oBAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;AACrB,wBAAA,GAAG,CAAC,YAAY,GAAG,IAAI;oBACzB;gBACF;YACF;iBAAO;AACL,gBAAA,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE;AACrB,oBAAA,GAAG,CAAC,YAAY,GAAG,IAAI;gBACzB;YACF;QACF;IACF;wGA9MW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,CAAA,OAAA,EAAA,KAAA,CAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,qBAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,SAAA,EAFpB,CAAC,2BAA2B,CAAC,2DAyBvB,0BAA0B,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;AAXlB,UAAA,CAAA;AAAf,IAAA,YAAY;AAAmB,CAAA,EAAA,oBAAA,CAAA,SAAA,EAAA,UAAA,EAAA,KAAA,CAAA,CAAA;AAChB,UAAA,CAAA;AAAf,IAAA,YAAY;AAAmB,CAAA,EAAA,oBAAA,CAAA,SAAA,EAAA,UAAA,EAAA,KAAA,CAAA,CAAA;AAChB,UAAA,CAAA;AAAf,IAAA,YAAY;AAA6B,CAAA,EAAA,oBAAA,CAAA,SAAA,EAAA,qBAAA,EAAA,KAAA,CAAA,CAAA;4FAdxC,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBALhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,mBAAmB;AAC7B,oBAAA,QAAQ,EAAE,iBAAiB;oBAC3B,SAAS,EAAE,CAAC,2BAA2B,CAAC;AACzC,iBAAA;;sBAWE,KAAK;uBAAC,OAAO;;sBAEb;;sBACA;;sBACA;;sBAKA;;sBAIA,eAAe;uBAAC,0BAA0B;;;MCpDhC,wBAAwB,CAAA;wGAAxB,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA;AAAxB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,wBAAwB,YAHzB,oBAAoB,EAAE,0BAA0B,CAAA,EAAA,OAAA,EAAA,CAChD,oBAAoB,EAAE,0BAA0B,CAAA,EAAA,CAAA;yGAE/C,wBAAwB,EAAA,CAAA;;4FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAJpC,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,OAAO,EAAE,CAAC,oBAAoB,EAAE,0BAA0B,CAAC;AAC3D,oBAAA,OAAO,EAAE,CAAC,oBAAoB,EAAE,0BAA0B,CAAC;AAC5D,iBAAA;;;ACRD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"theseam-ui-common-toggle-group.mjs","sources":["../../../projects/ui-common/toggle-group/toggle-group-parent.ts","../../../projects/ui-common/toggle-group/toggle-group-option.directive.ts","../../../projects/ui-common/toggle-group/toggle-group.directive.ts","../../../projects/ui-common/toggle-group/toggle-group.module.ts","../../../projects/ui-common/toggle-group/theseam-ui-common-toggle-group.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core'\n\n/**\n * The part of the toggle group that an option needs in order to resolve its own\n * selected state.\n *\n * This exists as a separate token so `ToggleGroupOptionDirective` can reach its\n * parent group without importing `ToggleGroupDirective`, which would create a\n * circular import between the two directives.\n */\nexport interface TheSeamToggleGroupParent {\n isSelected(value: string | undefined | null): boolean\n}\n\nexport const THESEAM_TOGGLE_GROUP_PARENT =\n new InjectionToken<TheSeamToggleGroupParent>('TheSeamToggleGroupParent')\n","import { Directive, HostBinding, inject, Input } from '@angular/core'\n\nimport { THESEAM_TOGGLE_GROUP_PARENT } from './toggle-group-parent'\n\n@Directive({\n selector: '[seamToggleGroupOption]',\n exportAs: 'seamToggleGroupOption',\n})\nexport class ToggleGroupOptionDirective {\n private readonly _group = inject(THESEAM_TOGGLE_GROUP_PARENT, {\n optional: true,\n })\n\n @Input() seamToggleGroupOption: string | undefined | null\n\n @HostBinding('class.lib-toggle-group-option-selected')\n get _checkioSelectedClass() {\n return this._group?.isSelected(this.value) || false\n }\n\n get value(): string | undefined | null {\n return this.seamToggleGroupOption\n }\n}\n","import { BooleanInput, coerceArray } from '@angular/cdk/coercion'\nimport {\n ContentChildren,\n Directive,\n EventEmitter,\n forwardRef,\n Input,\n Output,\n QueryList,\n} from '@angular/core'\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'\n\nimport { InputBoolean } from '@theseam/ui-common/core'\n\nimport { THESEAM_TOGGLE_GROUP_PARENT } from './toggle-group-parent'\nimport { ToggleGroupOptionDirective } from './toggle-group-option.directive'\n\nexport const TOGGLE_GROUP_VALUE_ACCESSOR: any = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => ToggleGroupDirective),\n multi: true,\n}\n\n@Directive({\n selector: '[seamToggleGroup]',\n exportAs: 'seamToggleGroup',\n providers: [\n TOGGLE_GROUP_VALUE_ACCESSOR,\n {\n provide: THESEAM_TOGGLE_GROUP_PARENT,\n useExisting: forwardRef(() => ToggleGroupDirective),\n },\n ],\n})\nexport class ToggleGroupDirective implements ControlValueAccessor {\n static ngAcceptInputType_disabled: BooleanInput\n static ngAcceptInputType_multiple: BooleanInput\n static ngAcceptInputType_selectionToggleable: BooleanInput\n\n // eslint-disable-next-line @angular-eslint/no-input-rename\n @Input('value') val: string | string[] | undefined | null\n\n @Input() @InputBoolean() disabled = false\n @Input() @InputBoolean() multiple = false\n @Input() @InputBoolean() selectionToggleable = true\n\n // TODO: Add min/max selected inputs to make toggling better for multi select\n\n // eslint-disable-next-line @angular-eslint/no-output-native\n @Output() readonly change = new EventEmitter<\n string | string[] | undefined | null\n >()\n\n @ContentChildren(ToggleGroupOptionDirective)\n optionDirectives?: QueryList<ToggleGroupOptionDirective>\n\n onChange: any\n onTouched: any\n\n private _selectedSet: Set<string> | undefined\n private _selectedSetSource: string | string[] | undefined | null\n private _selectedSetMultiple: boolean | undefined\n\n get value(): string | string[] | undefined | null {\n return this.val\n }\n\n set value(value: string | string[] | undefined | null) {\n const _value = this.multiple\n ? value !== null && value !== undefined\n ? coerceArray(value)\n : value\n : value\n\n this.val = this.multiple ? [...((_value as string[]) || [])] : _value || ''\n this.change.emit(this.val)\n if (this.onChange) {\n this.onChange(_value)\n }\n if (this.onTouched) {\n this.onTouched()\n }\n }\n\n writeValue(value: any): void {\n this.value = value\n }\n\n registerOnChange(fn: any): void {\n this.onChange = fn\n }\n\n registerOnTouched(fn: any): void {\n this.onTouched = fn\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled\n }\n\n isSelected(value: string | undefined | null): boolean {\n if (value === null || value === undefined) {\n return false\n }\n return this._selected().has(value)\n }\n\n /**\n * The current selection as a set, rebuilt only when the value (or `multiple`)\n * changes.\n *\n * `isSelected` is called from templates and from every option's host binding,\n * so it runs several times per option per change detection pass. Hashing the\n * selection once keeps those lookups O(1) instead of scanning the value array\n * on every call.\n *\n * Invalidation is keyed on the `val` reference rather than done in the `value`\n * setter, because `val` is also written directly by the `[value]` input, which\n * does not go through the setter.\n */\n private _selected(): ReadonlySet<string> {\n if (\n this._selectedSet === undefined ||\n this.val !== this._selectedSetSource ||\n this.multiple !== this._selectedSetMultiple\n ) {\n this._selectedSetSource = this.val\n this._selectedSetMultiple = this.multiple\n this._selectedSet = this._buildSelectedSet()\n }\n return this._selectedSet\n }\n\n private _buildSelectedSet(): Set<string> {\n const val = this.val\n\n if (this.multiple) {\n return new Set((val as string[]) ?? [])\n }\n\n // TODO: Clean this up when the directive no longer allows array value type when multiple is false\n const v = Array.isArray(val) && val.length === 1 ? val[0] : val\n return typeof v === 'string' ? new Set([v]) : new Set()\n }\n\n /**\n * Toggles an option's selected state by value.\n */\n toggleOptionSelect(value: string | undefined | null): void {\n if (this.isSelected(value)) {\n if (!this.selectionToggleable && this._selectedCount() <= 1) {\n // Unselecting would leave nothing selected.\n return\n }\n this.unselectValue(value)\n return\n }\n\n this.selectValue(value)\n }\n\n private _selectedCount(): number {\n if (this.multiple) {\n return ((this.value as string[]) || []).length\n }\n const v = this.value\n return v === null || v === undefined || v === '' ? 0 : 1\n }\n\n unselectValue(value: string | undefined | null) {\n if (this.multiple) {\n this.value = ((this.value as string[]) || []).filter((v) => v !== value)\n } else {\n this.value = undefined\n }\n }\n\n selectValue(value: string | undefined | null) {\n if (this.multiple) {\n const _value = [...((this.value as string[]) || [])]\n this.value = value ? [..._value, value] : _value\n } else {\n this.value = value\n }\n }\n\n getOptionDirectiveByValue(\n value: string,\n ): ToggleGroupOptionDirective | null | undefined {\n if (!this.optionDirectives || this.optionDirectives.length < 1) {\n return null\n }\n\n return this.optionDirectives.toArray().find((opt) => opt.value === value)\n }\n}\n","import { NgModule } from '@angular/core'\n\nimport { ToggleGroupOptionDirective } from './toggle-group-option.directive'\nimport { ToggleGroupDirective } from './toggle-group.directive'\n\n@NgModule({\n imports: [ToggleGroupDirective, ToggleGroupOptionDirective],\n exports: [ToggleGroupDirective, ToggleGroupOptionDirective],\n})\nexport class TheSeamToggleGroupModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { switchMap, startWith, map, distinctUntilChanged, mapTo, filter, take, pairwise, toArray, tap, auditTime, share } from 'rxjs/operators';
|
|
2
2
|
import { of, merge, interval, from, combineLatest, Observable, isObservable, Subject, BehaviorSubject, EMPTY } from 'rxjs';
|
|
3
3
|
import area from '@turf/area';
|
|
4
|
-
import { convertArea } from '@turf/helpers';
|
|
4
|
+
import { convertArea, polygon } from '@turf/helpers';
|
|
5
5
|
import kinks from '@turf/kinks';
|
|
6
6
|
import { fileTypeFromBuffer } from 'file-type';
|
|
7
|
-
import
|
|
7
|
+
import { parseShp, parseZip } from 'shpjs';
|
|
8
|
+
import booleanContains from '@turf/boolean-contains';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
*
|
|
@@ -476,6 +477,18 @@ function notNullOrUndefined(value) {
|
|
|
476
477
|
return value !== null && value !== undefined;
|
|
477
478
|
}
|
|
478
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Checks if a single polygon ring's coordinate count violates the given
|
|
482
|
+
* min/max point bounds. `max` is only applied when it is greater than `min`.
|
|
483
|
+
*/
|
|
484
|
+
function polygonViolatesMinMax(coordinateLength, min, max) {
|
|
485
|
+
if (coordinateLength < min ||
|
|
486
|
+
(notNullOrUndefined(max) && max > min && coordinateLength > max)) {
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
return false;
|
|
490
|
+
}
|
|
491
|
+
|
|
479
492
|
const MIN_MAX_POINTS_VALIDATOR_NAME = 'min-max-points';
|
|
480
493
|
function minMaxPointsValidator(min = 3, max) {
|
|
481
494
|
return (control) => {
|
|
@@ -522,13 +535,6 @@ function collectionViolatesMinMax(featureCollection, min, max) {
|
|
|
522
535
|
}
|
|
523
536
|
return false;
|
|
524
537
|
}
|
|
525
|
-
function polygonViolatesMinMax(coordinateLength, min, max) {
|
|
526
|
-
if (coordinateLength < min ||
|
|
527
|
-
(notNullOrUndefined(max) && max > min && coordinateLength > max)) {
|
|
528
|
-
return true;
|
|
529
|
-
}
|
|
530
|
-
return false;
|
|
531
|
-
}
|
|
532
538
|
|
|
533
539
|
const NO_EMPTY_FEATURE_COLLECTION_VALIDATOR_NAME = 'no-empty-feature-collection';
|
|
534
540
|
function noEmptyFeatureCollectionValidator() {
|
|
@@ -757,7 +763,7 @@ async function coerceToArrayBuffer(fileOrBuffer) {
|
|
|
757
763
|
return fileOrBuffer;
|
|
758
764
|
}
|
|
759
765
|
async function parseShpFile(buffer) {
|
|
760
|
-
const geometries =
|
|
766
|
+
const geometries = parseShp(buffer);
|
|
761
767
|
const featCollection = {
|
|
762
768
|
type: 'FeatureCollection',
|
|
763
769
|
features: geometries.map((geom) => ({
|
|
@@ -769,7 +775,7 @@ async function parseShpFile(buffer) {
|
|
|
769
775
|
return featCollection;
|
|
770
776
|
}
|
|
771
777
|
async function parseShpZip(buffer) {
|
|
772
|
-
let featCollection = await
|
|
778
|
+
let featCollection = await parseZip(buffer);
|
|
773
779
|
if (Array.isArray(featCollection)) {
|
|
774
780
|
if (featCollection.length === 0) {
|
|
775
781
|
throw Error(`Shape data not found.`);
|
|
@@ -819,11 +825,11 @@ function splitMultPolygon(multiPolygon) {
|
|
|
819
825
|
}
|
|
820
826
|
|
|
821
827
|
/**
|
|
822
|
-
* Close all polygons in the GeoJSON
|
|
828
|
+
* Close all polygons in the GeoJSON so the first and last position of every
|
|
829
|
+
* ring are identical.
|
|
823
830
|
*
|
|
824
|
-
* Google Maps requires
|
|
825
|
-
*
|
|
826
|
-
* that the GeoJSON is valid for Google Maps.
|
|
831
|
+
* Google Maps requires closed polygon rings, but not all libraries produce
|
|
832
|
+
* them. This is idempotent: rings that are already closed are left unchanged.
|
|
827
833
|
*/
|
|
828
834
|
function closePolygons(geoJson) {
|
|
829
835
|
if (geoJson.type === 'FeatureCollection') {
|
|
@@ -834,6 +840,12 @@ function closePolygons(geoJson) {
|
|
|
834
840
|
else if (geoJson.type === 'Feature') {
|
|
835
841
|
closePolygonsFeature(geoJson);
|
|
836
842
|
}
|
|
843
|
+
else if (geoJson.type === 'Polygon') {
|
|
844
|
+
closePolygon(geoJson);
|
|
845
|
+
}
|
|
846
|
+
else if (geoJson.type === 'MultiPolygon') {
|
|
847
|
+
closeMultiPolygon(geoJson);
|
|
848
|
+
}
|
|
837
849
|
}
|
|
838
850
|
function closePolygonsFeature(feature) {
|
|
839
851
|
if (feature.geometry.type === 'Polygon') {
|
|
@@ -844,17 +856,96 @@ function closePolygonsFeature(feature) {
|
|
|
844
856
|
}
|
|
845
857
|
}
|
|
846
858
|
function closePolygon(polygon) {
|
|
847
|
-
for (const
|
|
848
|
-
|
|
859
|
+
for (const ring of polygon.coordinates) {
|
|
860
|
+
closeRing(ring);
|
|
849
861
|
}
|
|
850
862
|
}
|
|
851
863
|
function closeMultiPolygon(multiPolygon) {
|
|
852
|
-
for (const
|
|
853
|
-
for (const
|
|
854
|
-
|
|
864
|
+
for (const polygon of multiPolygon.coordinates) {
|
|
865
|
+
for (const ring of polygon) {
|
|
866
|
+
closeRing(ring);
|
|
855
867
|
}
|
|
856
868
|
}
|
|
857
869
|
}
|
|
870
|
+
/**
|
|
871
|
+
* Appends the first position to the end of a ring only when it is not already
|
|
872
|
+
* closed. Exact equality is correct here: the closing point is a copy of the
|
|
873
|
+
* first point, so we compare a value against its own copy.
|
|
874
|
+
*/
|
|
875
|
+
function closeRing(ring) {
|
|
876
|
+
if (ring.length < 1) {
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
const first = ring[0];
|
|
880
|
+
const last = ring[ring.length - 1];
|
|
881
|
+
if (first[0] === last[0] && first[1] === last[1]) {
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
ring.push([...first]);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/** Count distinct vertices in a ring, ignoring an explicit closing point. */
|
|
888
|
+
function distinctVertexCount(ring) {
|
|
889
|
+
if (ring.length === 0) {
|
|
890
|
+
return 0;
|
|
891
|
+
}
|
|
892
|
+
const first = ring[0];
|
|
893
|
+
const last = ring[ring.length - 1];
|
|
894
|
+
const isClosed = ring.length > 1 && first[0] === last[0] && first[1] === last[1];
|
|
895
|
+
return isClosed ? ring.length - 1 : ring.length;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Whether a polygon's outer ring has at least `min` distinct vertices.
|
|
899
|
+
* Ring closure (a repeated first/last point) does not count toward the total,
|
|
900
|
+
* so this behaves the same for closed and unclosed rings.
|
|
901
|
+
*/
|
|
902
|
+
function polygonHasMinDistinctVertices(polygon, min = 3) {
|
|
903
|
+
const outer = polygon.coordinates[0] ?? [];
|
|
904
|
+
return !polygonViolatesMinMax(distinctVertexCount(outer), min, undefined);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Whether `outer` fully contains `inner`, using turf's boolean-contains on the
|
|
909
|
+
* GeoJSON geometries directly (no Google Maps dependency).
|
|
910
|
+
*/
|
|
911
|
+
function polygonContains(outer, inner) {
|
|
912
|
+
return booleanContains(polygon(outer.coordinates), polygon(inner.coordinates));
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Whether a ring is wound clockwise, via the shoelace signed-area sign.
|
|
917
|
+
* Sum of (x2 - x1) * (y2 + y1) is positive for clockwise rings in standard
|
|
918
|
+
* (x = lng, y = lat) orientation.
|
|
919
|
+
*/
|
|
920
|
+
function ringIsClockwise(ring) {
|
|
921
|
+
let sum = 0;
|
|
922
|
+
for (let i = 0; i < ring.length - 1; i++) {
|
|
923
|
+
const [x1, y1] = ring[i];
|
|
924
|
+
const [x2, y2] = ring[i + 1];
|
|
925
|
+
sum += (x2 - x1) * (y2 + y1);
|
|
926
|
+
}
|
|
927
|
+
return sum > 0;
|
|
928
|
+
}
|
|
929
|
+
/** Return `ring` wound opposite to `reference`, reversing a copy if needed. */
|
|
930
|
+
function ringWoundOpposite(reference, ring) {
|
|
931
|
+
if (ringIsClockwise(reference) === ringIsClockwise(ring)) {
|
|
932
|
+
return [...ring].reverse();
|
|
933
|
+
}
|
|
934
|
+
return [...ring];
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Append the outer ring of `hole` to `exterior` as an interior ring (a
|
|
938
|
+
* cutout), wound opposite the exterior ring so it renders as a hole. Returns a
|
|
939
|
+
* new Polygon; inputs are not mutated.
|
|
940
|
+
*/
|
|
941
|
+
function addHoleToPolygon(exterior, hole) {
|
|
942
|
+
const exteriorRing = exterior.coordinates[0];
|
|
943
|
+
const holeRing = ringWoundOpposite(exteriorRing, hole.coordinates[0]);
|
|
944
|
+
return {
|
|
945
|
+
type: 'Polygon',
|
|
946
|
+
coordinates: [...exterior.coordinates, holeRing],
|
|
947
|
+
};
|
|
948
|
+
}
|
|
858
949
|
|
|
859
950
|
// Based on source: https://github.com/sindresorhus/array-move/blob/main/index.js
|
|
860
951
|
/**
|
|
@@ -1403,5 +1494,5 @@ function sanitizeFilename(filename, options) {
|
|
|
1403
1494
|
* Generated bundle index. Do not edit.
|
|
1404
1495
|
*/
|
|
1405
1496
|
|
|
1406
|
-
export { IS_FEATURE_COLLECTION_VALIDATOR_NAME, IS_ONLY_GEOMETRY_TYPES_VALIDATOR_NAME, MIN_MAX_POINTS_VALIDATOR_NAME, NO_EMPTY_FEATURE_COLLECTION_VALIDATOR_NAME, NO_INNER_RINGS_VALIDATOR_NAME, NO_KINKS_VALIDATOR_NAME, PollingTickerOptions, Refreshable, activatedRoutesWithDataProperty, arrayMoveImmutable, arrayMoveMutable, calcPercentage, closePolygons, coerceFeatureCollection, createPadding, deleteProperties, deleteProperty, fileBufferToBlob, fileBufferToObjectUrl, fileDataFromBuffer, fractionalDigitsCount, geoJsonToArea, getAttribute, getClosestWidgetCdkDrag, getControlName, getControlPath, hasAttribute, hasProperty, hasRequiredControl, isAbsoluteUrl, isEmptyInputValue, isEmptyUrlRoute, isFeatureCollectionValidator, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumeric, isOnlyGeometryTypes, isOnlyGeometryTypesValidator, leafChildRoute, loadStyle, loadStyleSheet, mapEach, mergePolygons, minMaxPointsValidator, noEmptyFeatureCollectionValidator, noInnerRingsValidator, noKinksValidator, notNullOrUndefined, notNullOrUndefinedOrEmpty, observeControlIsDifferent, observeControlStatus, observeControlValid, observeControlValue, observeControlValueChange, observeQueryList, openBlob, padEnd, padStart, phoneNumberMask, pollingTicker, readFileAsDataUrlAsync, readFileAsync, readGeoFile, routeSnapshotPathFull, routeSnapshotPathRelative, sanitizeFilename, splitMultiPolygons, stripOuter, subscriberCount, tapFirst, toggleAttribute, trimRepeated, waitOnConditionAsync, waitOnNonPendingStatus, willHaveDataProp, withoutProperties, withoutProperty, wrapIntoObservable };
|
|
1497
|
+
export { IS_FEATURE_COLLECTION_VALIDATOR_NAME, IS_ONLY_GEOMETRY_TYPES_VALIDATOR_NAME, MIN_MAX_POINTS_VALIDATOR_NAME, NO_EMPTY_FEATURE_COLLECTION_VALIDATOR_NAME, NO_INNER_RINGS_VALIDATOR_NAME, NO_KINKS_VALIDATOR_NAME, PollingTickerOptions, Refreshable, activatedRoutesWithDataProperty, addHoleToPolygon, arrayMoveImmutable, arrayMoveMutable, calcPercentage, closePolygons, coerceFeatureCollection, createPadding, deleteProperties, deleteProperty, fileBufferToBlob, fileBufferToObjectUrl, fileDataFromBuffer, fractionalDigitsCount, geoJsonToArea, getAttribute, getClosestWidgetCdkDrag, getControlName, getControlPath, hasAttribute, hasProperty, hasRequiredControl, isAbsoluteUrl, isEmptyInputValue, isEmptyUrlRoute, isFeatureCollectionValidator, isNullOrUndefined, isNullOrUndefinedOrEmpty, isNumeric, isOnlyGeometryTypes, isOnlyGeometryTypesValidator, leafChildRoute, loadStyle, loadStyleSheet, mapEach, mergePolygons, minMaxPointsValidator, noEmptyFeatureCollectionValidator, noInnerRingsValidator, noKinksValidator, notNullOrUndefined, notNullOrUndefinedOrEmpty, observeControlIsDifferent, observeControlStatus, observeControlValid, observeControlValue, observeControlValueChange, observeQueryList, openBlob, padEnd, padStart, phoneNumberMask, pollingTicker, polygonContains, polygonHasMinDistinctVertices, polygonViolatesMinMax, readFileAsDataUrlAsync, readFileAsync, readGeoFile, ringIsClockwise, routeSnapshotPathFull, routeSnapshotPathRelative, sanitizeFilename, splitMultiPolygons, stripOuter, subscriberCount, tapFirst, toggleAttribute, trimRepeated, waitOnConditionAsync, waitOnNonPendingStatus, willHaveDataProp, withoutProperties, withoutProperty, wrapIntoObservable };
|
|
1407
1498
|
//# sourceMappingURL=theseam-ui-common-utils.mjs.map
|