@inspark/inspark-components 14.0.59 → 14.0.60

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.
@@ -2105,38 +2105,48 @@ class SelectButtonComponent {
2105
2105
  this.error = '';
2106
2106
  this.iconPos = 'left';
2107
2107
  this.options = [];
2108
+ this.disabled = false;
2108
2109
  this.required = false;
2109
2110
  this.multiple = false;
2110
2111
  this.focus = new EventEmitter();
2111
2112
  this.blur = new EventEmitter();
2112
2113
  this.click = new EventEmitter();
2113
2114
  this.change = new EventEmitter();
2115
+ // хранит выбранные ЗНАЧЕНИЯ, а не объекты
2114
2116
  this.selected = [];
2115
- this.propagateChange = (_) => {
2116
- };
2117
- }
2118
- ngOnInit() {
2117
+ // то, что отдаем наружу в форму
2118
+ this.value = null;
2119
+ this.propagateChange = () => { };
2120
+ this.propagateTouched = () => { };
2119
2121
  }
2120
- ngOnChanges() {
2121
- if (this.initial) {
2122
- this.selected = this.initial;
2122
+ ngOnInit() { }
2123
+ ngOnChanges(changes) {
2124
+ // применяем initial только когда он реально поменялся
2125
+ if (changes['initial'] && this.initial) {
2126
+ this.selected = [...this.initial];
2127
+ this.value = this.multiple ? [...this.initial] : this.initial[0] ?? null;
2128
+ this.cdRef.detectChanges();
2123
2129
  }
2124
- else {
2125
- this.selected = [];
2130
+ // если меняется список опций, надо попытаться восстановить выделение
2131
+ if (changes['options'] && this.options && this.options.length > 0) {
2132
+ this.syncSelectedWithOptions();
2126
2133
  }
2127
2134
  }
2128
2135
  clickButton(option) {
2129
- if (option.readonly) {
2130
- return false;
2136
+ if (option.readonly || this.disabled) {
2137
+ return;
2131
2138
  }
2139
+ this.click.emit(option);
2132
2140
  if (this.multiple) {
2133
- if (this.selected.indexOf(option.value) !== -1) {
2134
- this.selected = this.selected.filter(item => item !== option.value);
2141
+ if (this.selected.includes(option.value)) {
2142
+ // убираем
2143
+ this.selected = this.selected.filter(v => v !== option.value);
2135
2144
  }
2136
2145
  else {
2137
- this.selected.push(option.value);
2146
+ // добавляем
2147
+ this.selected = [...this.selected, option.value];
2138
2148
  }
2139
- this.value = this.options.filter(item => this.selected.indexOf(item.value) !== -1).map(val => val.value);
2149
+ this.value = [...this.selected];
2140
2150
  }
2141
2151
  else {
2142
2152
  this.selected = [option.value];
@@ -2145,46 +2155,79 @@ class SelectButtonComponent {
2145
2155
  this.cdRef.detectChanges();
2146
2156
  this.onChange();
2147
2157
  }
2148
- /**
2149
- * Write form value to the DOM element (model => view)
2150
- */
2158
+ // ControlValueAccessor: model -> view
2151
2159
  writeValue(value) {
2152
2160
  this.value = value;
2153
- if (value !== null && value !== undefined) {
2154
- if (Array.isArray(value)) {
2155
- this.selected = value.map(val => val);
2156
- }
2157
- else {
2158
- this.selected = [value];
2159
- }
2161
+ if (value === null || value === undefined) {
2162
+ this.selected = [];
2160
2163
  }
2164
+ else if (Array.isArray(value)) {
2165
+ // multiple
2166
+ this.selected = [...value];
2167
+ }
2168
+ else {
2169
+ // single
2170
+ this.selected = [value];
2171
+ }
2172
+ // когда значение пришло извне, надо убедиться что такие опции есть
2173
+ this.syncSelectedWithOptions();
2161
2174
  this.cdRef.detectChanges();
2162
2175
  }
2163
- /**
2164
- * Write form disabled state to the DOM element (model => view)
2165
- */
2166
- setDisabledState(isDisabled) {
2167
- this.disabled = isDisabled;
2168
- }
2169
- /**
2170
- * Update form when DOM element value changes (view => model)
2171
- */
2176
+ // ControlValueAccessor
2172
2177
  registerOnChange(fn) {
2173
- // Store the provided function as an internal method.
2174
2178
  this.propagateChange = fn;
2175
2179
  }
2176
- /**
2177
- * Update form when DOM element is blurred (view => model)
2178
- */
2180
+ // ControlValueAccessor
2179
2181
  registerOnTouched(fn) {
2180
- // Store the provided function as an internal method.
2181
- this.onTouched = fn;
2182
+ this.propagateTouched = fn;
2183
+ }
2184
+ // ControlValueAccessor: disabled
2185
+ setDisabledState(isDisabled) {
2186
+ this.disabled = isDisabled;
2187
+ this.cdRef.detectChanges();
2182
2188
  }
2189
+ // пробросить наружу
2183
2190
  onChange() {
2184
2191
  this.propagateChange(this.value);
2185
2192
  this.change.emit(this.value);
2186
2193
  }
2187
- onTouched() {
2194
+ onBlur() {
2195
+ this.propagateTouched();
2196
+ this.blur.emit();
2197
+ }
2198
+ onFocus() {
2199
+ this.focus.emit();
2200
+ }
2201
+ // синхронизируем текущее выбранное со свежими options
2202
+ syncSelectedWithOptions() {
2203
+ if (!this.options || this.options.length === 0) {
2204
+ return;
2205
+ }
2206
+ if (this.multiple) {
2207
+ // оставляем только те выбранные, которые реально есть в новых options
2208
+ const optionValues = this.options.map(o => o.value);
2209
+ this.selected = this.selected.filter(v => optionValues.includes(v));
2210
+ this.value = [...this.selected];
2211
+ }
2212
+ else {
2213
+ if (this.selected.length > 0) {
2214
+ const current = this.selected[0];
2215
+ const found = this.options.find(o => o.value === current);
2216
+ if (!found) {
2217
+ // выбранного больше нет в списке
2218
+ this.selected = [];
2219
+ this.value = null;
2220
+ }
2221
+ else {
2222
+ this.selected = [found.value];
2223
+ this.value = found.value;
2224
+ }
2225
+ }
2226
+ }
2227
+ }
2228
+ // для *ngFor trackBy
2229
+ trackByValue(index, item) {
2230
+ return item.value;
2188
2231
  }
2189
2232
  }
2190
2233
  SelectButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectButtonComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
@@ -2193,8 +2236,8 @@ SelectButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
2193
2236
  provide: NG_VALUE_ACCESSOR,
2194
2237
  useExisting: forwardRef(() => SelectButtonComponent),
2195
2238
  multi: true,
2196
- }
2197
- ], usesOnChanges: true, ngImport: i0, template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{label}}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{error}}</span>\n </span>\n<div class=\"container\">\n <in-button class=\"button-none\"></in-button>\n <in-button (click)=\"clickButton(option)\"\n *ngFor=\"let option of options\"\n [color]=\"selected.indexOf(option.value) === -1 ? 'normal': 'primary' \"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name] = option.label\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "in-button", inputs: ["size", "color", "type", "name", "testId", "label", "icon", "className", "notify", "svg", "width", "link", "isLoading", "shadow", "isIconOnly", "linkType", "linkTarget", "pressed", "disabled", "iconPos", "selectedItem", "menuPlacement", "menuItems"], outputs: ["focus", "blur", "click"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] });
2239
+ },
2240
+ ], usesOnChanges: true, ngImport: i0, template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{ label }}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{ error }}</span>\n</span>\n\n<div class=\"container\">\n <!-- \u0444\u0438\u043A\u0442\u0438\u0432\u043D\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0430 \u0435\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 -->\n <in-button class=\"button-none\"></in-button>\n\n <in-button\n *ngFor=\"let option of options; trackBy: trackByValue\"\n (click)=\"clickButton(option)\"\n [color]=\"selected.includes(option.value) ? 'primary' : 'normal'\"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name]=\"option.label\"\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "in-button", inputs: ["size", "color", "type", "name", "testId", "label", "icon", "className", "notify", "svg", "width", "link", "isLoading", "shadow", "isIconOnly", "linkType", "linkTarget", "pressed", "disabled", "iconPos", "selectedItem", "menuPlacement", "menuItems"], outputs: ["focus", "blur", "click"] }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] });
2198
2241
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectButtonComponent, decorators: [{
2199
2242
  type: Component,
2200
2243
  args: [{ selector: 'in-select-button', providers: [
@@ -2202,8 +2245,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2202
2245
  provide: NG_VALUE_ACCESSOR,
2203
2246
  useExisting: forwardRef(() => SelectButtonComponent),
2204
2247
  multi: true,
2205
- }
2206
- ], template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{label}}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{error}}</span>\n </span>\n<div class=\"container\">\n <in-button class=\"button-none\"></in-button>\n <in-button (click)=\"clickButton(option)\"\n *ngFor=\"let option of options\"\n [color]=\"selected.indexOf(option.value) === -1 ? 'normal': 'primary' \"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name] = option.label\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"] }]
2248
+ },
2249
+ ], template: "<span *ngIf=\"label\" class=\"c-label__content\">\n {{ label }}\n <span *ngIf=\"required\" class=\"c-label__req\">*</span>\n <span *ngIf=\"error\" class=\"c-label__sub_is-error\">{{ error }}</span>\n</span>\n\n<div class=\"container\">\n <!-- \u0444\u0438\u043A\u0442\u0438\u0432\u043D\u0430\u044F \u043A\u043D\u043E\u043F\u043A\u0430 \u0435\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0430 -->\n <in-button class=\"button-none\"></in-button>\n\n <in-button\n *ngFor=\"let option of options; trackBy: trackByValue\"\n (click)=\"clickButton(option)\"\n [color]=\"selected.includes(option.value) ? 'primary' : 'normal'\"\n [icon]=\"option.icon\"\n [label]=\"option.label | translate\"\n [testId]=\"'filter-buttons-' + option.value\"\n [title]=\"option.title ? (option.title | translate) : ''\"\n [name]=\"option.label\"\n [disabled]=\"option.readonly || disabled\"\n >\n </in-button>\n</div>\n", styles: [".container{white-space:nowrap}in-button ::ng-deep button{outline:none}in-button:first-child ::ng-deep button{border-bottom-right-radius:0;border-top-right-radius:0;border-right:1px solid #000}in-button:not(:first-child):not(:last-child) ::ng-deep button{border-radius:0;border-right:1px solid #000}in-button:last-child ::ng-deep button{border-bottom-left-radius:0;border-top-left-radius:0}.button-none{display:none}\n"] }]
2207
2250
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { name: [{
2208
2251
  type: Input
2209
2252
  }], testId: [{