@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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, OnInit, OnDestroy, TemplateRef } from '@angular/core';
2
+ import { InjectionToken, OnInit, OnDestroy, TemplateRef, OnChanges, AfterViewInit, ElementRef, SimpleChanges } from '@angular/core';
3
3
  import { Observable } from 'rxjs';
4
4
  import * as _theseam_ui_common_data_filters from '@theseam/ui-common/data-filters';
5
5
  import { BooleanInput } from '@angular/cdk/coercion';
@@ -11,6 +11,8 @@ import * as i4 from '@angular/common';
11
11
  import * as i6 from '@theseam/ui-common/form-field';
12
12
  import * as i7 from '@fortawesome/angular-fontawesome';
13
13
  import * as i8 from '@theseam/ui-common/toggle-group';
14
+ import * as i10 from '@theseam/ui-common/menu';
15
+ import * as i11 from '@theseam/ui-common/buttons';
14
16
 
15
17
  type DataFilterFunction = <T>(data: T[]) => Observable<T[]>;
16
18
  /**
@@ -172,6 +174,7 @@ declare class DataFilterTextComponent implements OnInit, OnDestroy, IDataFilter
172
174
  static ɵcmp: i0.ɵɵComponentDeclaration<DataFilterTextComponent, "seam-data-filter-text", never, { "filterName": { "alias": "filterName"; "required": false; }; "properties": { "alias": "properties"; "required": false; }; "omitProperties": { "alias": "omitProperties"; "required": false; }; "exact": { "alias": "exact"; "required": false; }; "caseSensitive": { "alias": "caseSensitive"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "iconTpl": { "alias": "iconTpl"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, {}, never, never, false, never>;
173
175
  }
174
176
 
177
+ declare const DATA_FILTER_TOGGLE_BUTTON_DROPDOWN_TEXT = "Select Filter";
175
178
  declare const DATA_FILTER_TOGGLE_BUTTON: any;
176
179
  interface IToggleButton {
177
180
  name: string;
@@ -183,10 +186,30 @@ interface IToggleButtonsFilterOptions extends ITextFilterOptions {
183
186
  multiple: boolean;
184
187
  buttons: IToggleButton[];
185
188
  initialValue?: any;
189
+ /**
190
+ * The maximum width a button row can grow to before collapsing.
191
+ * If not set, the button row will grow until it overflows, then collapse.
192
+ * To force a button row to always be collapsed or expanded, use the `forceCollapseState` option instead.
193
+ */
194
+ maxWidth?: number;
195
+ /**
196
+ * The text shown before the button row when the button row is in the collapsed state.
197
+ * If not set, the button row will not show any text before the buttons when collapsed.
198
+ */
199
+ prependLabel?: string;
200
+ /**
201
+ * The text shown when the button row is in the collapsed state and no filter is selected.
202
+ */
203
+ filterDropdownLabel?: string;
204
+ /**
205
+ * When set, the button row will always be collapsed or expanded, regardless of the available width.
206
+ */
207
+ forceCollapseState?: 'collapsed' | 'expanded';
186
208
  }
187
209
  declare const DefaultToggleButtonsFilterOptions: IToggleButtonsFilterOptions;
188
210
  declare function toggleButtonsFilter(data: any[], values: string[], options?: IToggleButtonsFilterOptions): any[];
189
- declare class DataFilterToggleButtonsComponent implements OnInit, OnDestroy, IDataFilter {
211
+ declare class DataFilterToggleButtonsComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit, IDataFilter {
212
+ private _elementRef;
190
213
  private _filterContainer;
191
214
  private _filterOptions;
192
215
  readonly name = "toggle-buttons";
@@ -200,22 +223,45 @@ declare class DataFilterToggleButtonsComponent implements OnInit, OnDestroy, IDa
200
223
  buttons: IToggleButton[];
201
224
  exact: boolean;
202
225
  caseSensitive: boolean;
226
+ maxWidth: number | undefined;
227
+ prependLabel: string | undefined;
228
+ filterDropdownLabel: string | undefined;
229
+ forceCollapseState: "collapsed" | "expanded" | undefined;
230
+ get _collapsedClass(): boolean;
231
+ get _expandedClass(): boolean;
232
+ readonly isCollapsed: i0.WritableSignal<boolean>;
233
+ private _measureDiv;
234
+ private _resizeObserver;
235
+ /**
236
+ * Emits when the `buttons` input changes.
237
+ */
238
+ private readonly _buttonsChanged;
203
239
  set value(value: string | string[]);
204
240
  readonly filterStateChanges: Observable<DataFilterState>;
205
- constructor(_filterContainer: DataFilterContainer, _filterOptions: IToggleButtonsFilterOptions | null);
241
+ activeFilterLabel: Observable<string>;
242
+ constructor(_elementRef: ElementRef<HTMLElement>, _filterContainer: DataFilterContainer, _filterOptions: IToggleButtonsFilterOptions | null);
206
243
  ngOnInit(): void;
244
+ ngAfterViewInit(): void;
245
+ ngOnChanges(changes: SimpleChanges): void;
246
+ /**
247
+ * Observes the parent element only while the collapsed state is width driven.
248
+ * When `forceCollapseState` is set there is nothing to observe, so the
249
+ * observer is disconnected and the forced state is applied directly.
250
+ */
251
+ private _syncResizeObserver;
207
252
  ngOnDestroy(): void;
208
253
  private _optDefault;
209
254
  get options(): IToggleButtonsFilterOptions;
210
255
  filter<T>(data: T[]): Observable<T[]>;
256
+ private _updateCollapsed;
211
257
  filterState(): DataFilterState;
212
- static ɵfac: i0.ɵɵFactoryDeclaration<DataFilterToggleButtonsComponent, [null, { optional: true; }]>;
213
- static ɵcmp: i0.ɵɵComponentDeclaration<DataFilterToggleButtonsComponent, "seam-data-filter-toggle-buttons", never, { "filterName": { "alias": "filterName"; "required": false; }; "properties": { "alias": "properties"; "required": false; }; "omitProperties": { "alias": "omitProperties"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "selectionToggleable": { "alias": "selectionToggleable"; "required": false; }; "buttons": { "alias": "buttons"; "required": false; }; "exact": { "alias": "exact"; "required": false; }; "caseSensitive": { "alias": "caseSensitive"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, {}, never, never, false, never>;
258
+ static ɵfac: i0.ɵɵFactoryDeclaration<DataFilterToggleButtonsComponent, [null, null, { optional: true; }]>;
259
+ static ɵcmp: i0.ɵɵComponentDeclaration<DataFilterToggleButtonsComponent, "seam-data-filter-toggle-buttons", never, { "filterName": { "alias": "filterName"; "required": false; }; "properties": { "alias": "properties"; "required": false; }; "omitProperties": { "alias": "omitProperties"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "selectionToggleable": { "alias": "selectionToggleable"; "required": false; }; "buttons": { "alias": "buttons"; "required": false; }; "exact": { "alias": "exact"; "required": false; }; "caseSensitive": { "alias": "caseSensitive"; "required": false; }; "maxWidth": { "alias": "maxWidth"; "required": false; }; "prependLabel": { "alias": "prependLabel"; "required": false; }; "filterDropdownLabel": { "alias": "filterDropdownLabel"; "required": false; }; "forceCollapseState": { "alias": "forceCollapseState"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, {}, never, never, false, never>;
214
260
  }
215
261
 
216
262
  declare class TheSeamDataFiltersModule {
217
263
  static ɵfac: i0.ɵɵFactoryDeclaration<TheSeamDataFiltersModule, never>;
218
- static ɵmod: i0.ɵɵNgModuleDeclaration<TheSeamDataFiltersModule, [typeof DataFilterSearchComponent, typeof DataFilterTextComponent, typeof DataFilterToggleButtonsComponent], [typeof i4.CommonModule, typeof i5.ReactiveFormsModule, typeof i6.TheSeamFormFieldModule, typeof i7.FontAwesomeModule, typeof i8.TheSeamToggleGroupModule, typeof i9.TheSeamIconModule], [typeof DataFilterSearchComponent, typeof DataFilterTextComponent, typeof DataFilterToggleButtonsComponent]>;
264
+ static ɵmod: i0.ɵɵNgModuleDeclaration<TheSeamDataFiltersModule, [typeof DataFilterSearchComponent, typeof DataFilterTextComponent, typeof DataFilterToggleButtonsComponent], [typeof i4.CommonModule, typeof i5.ReactiveFormsModule, typeof i6.TheSeamFormFieldModule, typeof i7.FontAwesomeModule, typeof i8.TheSeamToggleGroupModule, typeof i9.TheSeamIconModule, typeof i10.TheSeamMenuModule, typeof i11.TheSeamButtonsModule], [typeof DataFilterSearchComponent, typeof DataFilterTextComponent, typeof DataFilterToggleButtonsComponent]>;
219
265
  static ɵinj: i0.ɵɵInjectorDeclaration<TheSeamDataFiltersModule>;
220
266
  }
221
267
 
@@ -228,5 +274,5 @@ interface IDataFilterDef<T = any> {
228
274
  }
229
275
  declare const THESEAM_DATA_FILTER_DEF: InjectionToken<IDataFilterDef<any>[]>;
230
276
 
231
- export { DATA_FILTER_SEARCH, DATA_FILTER_TEXT, DATA_FILTER_TOGGLE_BUTTON, DataFilterSearchComponent, DataFilterTextComponent, DataFilterToggleButtonsComponent, DefaultSearchFilterOptions, DefaultTextFilterOptions, DefaultToggleButtonsFilterOptions, THESEAM_DATA_FILTER, THESEAM_DATA_FILTER_CONTAINER, THESEAM_DATA_FILTER_DEF, THESEAM_DATA_FILTER_OPTIONS, TheSeamDataFiltersModule, composeDataFilterStates, composeDataFilters, filterOperator, searchDataFilter, textDataFilter, toggleButtonsFilter };
277
+ export { DATA_FILTER_SEARCH, DATA_FILTER_TEXT, DATA_FILTER_TOGGLE_BUTTON, DATA_FILTER_TOGGLE_BUTTON_DROPDOWN_TEXT, DataFilterSearchComponent, DataFilterTextComponent, DataFilterToggleButtonsComponent, DefaultSearchFilterOptions, DefaultTextFilterOptions, DefaultToggleButtonsFilterOptions, THESEAM_DATA_FILTER, THESEAM_DATA_FILTER_CONTAINER, THESEAM_DATA_FILTER_DEF, THESEAM_DATA_FILTER_OPTIONS, TheSeamDataFiltersModule, composeDataFilterStates, composeDataFilters, filterOperator, searchDataFilter, textDataFilter, toggleButtonsFilter };
232
278
  export type { DataFilter, DataFilterContainer, DataFilterFunction, DataFilterState, IDataFilter, IDataFilterDef, IDataFilterFunction, ISearchFilterOptions, ITextFilterOptions, IToggleButton, IToggleButtonsFilterOptions };
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, forwardRef, Input, Inject, Optional, Component, ChangeDetectionStrategy, NgModule } from '@angular/core';
3
- import { of, combineLatest } from 'rxjs';
2
+ import { InjectionToken, forwardRef, Input, Inject, Optional, Component, ChangeDetectionStrategy, signal, ViewChild, HostBinding, NgModule } from '@angular/core';
3
+ import { of, combineLatest, Subject, merge } from 'rxjs';
4
4
  import { switchMap, startWith, map, shareReplay } from 'rxjs/operators';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
@@ -13,10 +13,14 @@ import * as i4 from '@theseam/ui-common/icon';
13
13
  import { TheSeamIconModule } from '@theseam/ui-common/icon';
14
14
  import * as i3$1 from '@theseam/ui-common/toggle-group';
15
15
  import { TheSeamToggleGroupModule } from '@theseam/ui-common/toggle-group';
16
+ import * as i4$1 from '@theseam/ui-common/menu';
17
+ import { TheSeamMenuModule } from '@theseam/ui-common/menu';
18
+ import * as i5 from '@theseam/ui-common/buttons';
19
+ import { TheSeamButtonsModule } from '@theseam/ui-common/buttons';
16
20
  import { __decorate } from 'tslib';
17
21
  import { faSearch } from '@fortawesome/free-solid-svg-icons';
18
22
  import { InputBoolean } from '@theseam/ui-common/core';
19
- import { isNullOrUndefined, hasProperty } from '@theseam/ui-common/utils';
23
+ import { isNullOrUndefined, hasProperty, notNullOrUndefined } from '@theseam/ui-common/utils';
20
24
  import { coerceArray } from '@angular/cdk/coercion';
21
25
 
22
26
  const THESEAM_DATA_FILTER = new InjectionToken('TheSeamDataFilter');
@@ -310,6 +314,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
310
314
  type: Input
311
315
  }] } });
312
316
 
317
+ const DATA_FILTER_TOGGLE_BUTTON_DROPDOWN_TEXT = 'Select Filter';
313
318
  const DATA_FILTER_TOGGLE_BUTTON = {
314
319
  provide: THESEAM_DATA_FILTER,
315
320
  useExisting: forwardRef(() => DataFilterToggleButtonsComponent),
@@ -323,13 +328,17 @@ const DefaultToggleButtonsFilterOptions = {
323
328
  buttons: [],
324
329
  exact: false,
325
330
  caseSensitive: false,
331
+ maxWidth: undefined,
332
+ prependLabel: undefined,
333
+ filterDropdownLabel: DATA_FILTER_TOGGLE_BUTTON_DROPDOWN_TEXT,
334
+ forceCollapseState: undefined,
326
335
  };
327
336
  function toggleButtonsFilter(data, values, options = DefaultToggleButtonsFilterOptions) {
328
337
  if (!data || !values) {
329
338
  return data;
330
339
  }
331
340
  const customComparatorBtns = [];
332
- for (const btn of options.buttons) {
341
+ for (const btn of options.buttons || []) {
333
342
  if (btn.comparator) {
334
343
  customComparatorBtns.push(btn);
335
344
  }
@@ -367,6 +376,7 @@ function toggleButtonsFilter(data, values, options = DefaultToggleButtonsFilterO
367
376
  }
368
377
  let _uid = 0;
369
378
  class DataFilterToggleButtonsComponent {
379
+ _elementRef;
370
380
  _filterContainer;
371
381
  _filterOptions;
372
382
  name = 'toggle-buttons';
@@ -380,22 +390,36 @@ class DataFilterToggleButtonsComponent {
380
390
  buttons = this._optDefault('buttons');
381
391
  exact = this._optDefault('exact');
382
392
  caseSensitive = this._optDefault('caseSensitive');
393
+ maxWidth = this._optDefault('maxWidth');
394
+ prependLabel = this._optDefault('prependLabel');
395
+ filterDropdownLabel = this._optDefault('filterDropdownLabel');
396
+ forceCollapseState = this._optDefault('forceCollapseState');
397
+ get _collapsedClass() {
398
+ return this.isCollapsed();
399
+ }
400
+ get _expandedClass() {
401
+ return !this.isCollapsed();
402
+ }
403
+ isCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "isCollapsed" }] : []));
404
+ _measureDiv;
405
+ _resizeObserver;
406
+ /**
407
+ * Emits when the `buttons` input changes.
408
+ */
409
+ _buttonsChanged = new Subject();
383
410
  set value(value) {
384
411
  const _value = !isNullOrUndefined(value) ? coerceArray(value) : undefined;
385
- // console.log('_value', _value, this._control.value)
386
412
  if (this._control.value !== _value) {
387
413
  this._control.setValue(_value);
388
414
  }
389
415
  }
390
416
  filterStateChanges;
391
- constructor(_filterContainer, _filterOptions) {
417
+ activeFilterLabel;
418
+ constructor(_elementRef, _filterContainer, _filterOptions) {
419
+ this._elementRef = _elementRef;
392
420
  this._filterContainer = _filterContainer;
393
421
  this._filterOptions = _filterOptions;
394
- this.filterStateChanges = this._control.valueChanges.pipe(
395
- // tap(v => console.log('v', v)),
396
- switchMap(() => of(this.filterState())),
397
- // tap(v => console.log('v2', v)),
398
- shareReplay({ bufferSize: 1, refCount: true }));
422
+ this.filterStateChanges = this._control.valueChanges.pipe(switchMap(() => of(this.filterState())), shareReplay({ bufferSize: 1, refCount: true }));
399
423
  }
400
424
  ngOnInit() {
401
425
  this._filterContainer.addFilter(this);
@@ -403,9 +427,58 @@ class DataFilterToggleButtonsComponent {
403
427
  hasProperty(this._filterOptions, 'initialValue')) {
404
428
  this.value = this._optDefault('initialValue');
405
429
  }
430
+ this.activeFilterLabel = merge(this.filterStateChanges, this._buttonsChanged).pipe(startWith(undefined), map(() => {
431
+ const state = this.filterState();
432
+ // Depending on the timing of when this is called, the options may not be fully initialized yet.
433
+ // Cast as partial to avoid TypeError on uninitialized values.
434
+ const options = state.state
435
+ .options;
436
+ const selectedOptions = (options.buttons || [])
437
+ .filter((o) => coerceArray(state.state.value).includes(o.value))
438
+ .map((o) => o.name);
439
+ return selectedOptions.length > 0
440
+ ? selectedOptions.join(', ')
441
+ : this.filterDropdownLabel || DATA_FILTER_TOGGLE_BUTTON_DROPDOWN_TEXT;
442
+ }));
443
+ }
444
+ ngAfterViewInit() {
445
+ this._resizeObserver = new ResizeObserver(() => this._updateCollapsed());
446
+ this._syncResizeObserver();
447
+ }
448
+ ngOnChanges(changes) {
449
+ if (changes['buttons'] && !changes['buttons'].firstChange) {
450
+ this._updateCollapsed();
451
+ this._buttonsChanged.next();
452
+ }
453
+ if (changes['forceCollapseState'] &&
454
+ !changes['forceCollapseState'].firstChange) {
455
+ this._syncResizeObserver();
456
+ }
457
+ }
458
+ /**
459
+ * Observes the parent element only while the collapsed state is width driven.
460
+ * When `forceCollapseState` is set there is nothing to observe, so the
461
+ * observer is disconnected and the forced state is applied directly.
462
+ */
463
+ _syncResizeObserver() {
464
+ if (isNullOrUndefined(this._resizeObserver)) {
465
+ return;
466
+ }
467
+ this._resizeObserver.disconnect();
468
+ const parentElement = this._elementRef.nativeElement.parentElement;
469
+ if (notNullOrUndefined(parentElement) &&
470
+ isNullOrUndefined(this.forceCollapseState)) {
471
+ this._resizeObserver.observe(parentElement);
472
+ }
473
+ else {
474
+ // The observer won't fire, so apply the collapsed state directly.
475
+ this._updateCollapsed();
476
+ }
406
477
  }
407
478
  ngOnDestroy() {
408
479
  this._filterContainer.removeFilter(this);
480
+ this._resizeObserver?.disconnect();
481
+ this._buttonsChanged.complete();
409
482
  }
410
483
  _optDefault(prop) {
411
484
  if (this._filterOptions &&
@@ -423,10 +496,45 @@ class DataFilterToggleButtonsComponent {
423
496
  buttons: this.buttons,
424
497
  exact: this.exact,
425
498
  caseSensitive: this.caseSensitive,
499
+ maxWidth: this.maxWidth,
500
+ prependLabel: this.prependLabel,
501
+ filterDropdownLabel: this.filterDropdownLabel,
502
+ forceCollapseState: this.forceCollapseState,
426
503
  };
427
504
  }
428
505
  filter(data) {
429
- return this._control.valueChanges.pipe(map((v) => toggleButtonsFilter(data, coerceArray(v), this.options)), startWith(toggleButtonsFilter(data, coerceArray(this._control.value), this.options)));
506
+ // `buttons` is merged in because `toggleButtonsFilter` resolves each value's
507
+ // custom `comparator` from `options.buttons`. A `buttons` list that arrives
508
+ // after the value is set would otherwise keep filtering with the stale
509
+ // (empty) list until the next value change.
510
+ return merge(this._control.valueChanges, this._buttonsChanged).pipe(map(() => toggleButtonsFilter(data, coerceArray(this._control.value), this.options)), startWith(toggleButtonsFilter(data, coerceArray(this._control.value), this.options)));
511
+ }
512
+ _updateCollapsed() {
513
+ if (notNullOrUndefined(this.forceCollapseState)) {
514
+ if (this.isCollapsed() && this.forceCollapseState === 'expanded') {
515
+ this.isCollapsed.set(false);
516
+ }
517
+ else if (!this.isCollapsed() &&
518
+ this.forceCollapseState === 'collapsed') {
519
+ this.isCollapsed.set(true);
520
+ }
521
+ return;
522
+ }
523
+ if (!this._measureDiv) {
524
+ return;
525
+ }
526
+ const measureWidth = this._measureDiv.nativeElement.scrollWidth;
527
+ // Because of the flex layout, this element won't necessarily grow to its full
528
+ // potential width when in collapsed mode, meaning it stays collapsed even
529
+ // though there's room to expand. If this becomes a problem, we may need to use a
530
+ // different strategy to determine when it's safe to show the full filter bar.
531
+ const clientWidth = this._elementRef.nativeElement.parentElement?.clientWidth;
532
+ // Not enough information to determine collapsed state, so don't update it
533
+ if (isNullOrUndefined(clientWidth)) {
534
+ return;
535
+ }
536
+ const threshold = this.maxWidth != null ? Math.min(clientWidth, this.maxWidth) : clientWidth;
537
+ this.isCollapsed.set(measureWidth > threshold);
430
538
  }
431
539
  filterState() {
432
540
  return {
@@ -438,13 +546,13 @@ class DataFilterToggleButtonsComponent {
438
546
  },
439
547
  };
440
548
  }
441
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DataFilterToggleButtonsComponent, deps: [{ token: THESEAM_DATA_FILTER_CONTAINER }, { token: THESEAM_DATA_FILTER_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
442
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: DataFilterToggleButtonsComponent, isStandalone: false, selector: "seam-data-filter-toggle-buttons", inputs: { filterName: "filterName", properties: "properties", omitProperties: "omitProperties", multiple: "multiple", selectionToggleable: "selectionToggleable", buttons: "buttons", exact: "exact", caseSensitive: "caseSensitive", value: "value" }, providers: [DATA_FILTER_TOGGLE_BUTTON], ngImport: i0, template: "<div\n class=\"btn-group\"\n role=\"group\"\n aria-label=\"Progress Filter\"\n *ngIf=\"options as opts\"\n [formControl]=\"_control\"\n seamToggleGroup\n [multiple]=\"opts.multiple\"\n [selectionToggleable]=\"opts.selectionToggleable\"\n>\n <ng-container *ngFor=\"let btn of buttons\">\n <button\n type=\"button\"\n class=\"btn btn-sm px-4\"\n [seamToggleGroupOption]=\"btn.value\"\n #opt=\"seamToggleGroupOption\"\n [class.btn-lightgray]=\"!opt.selected\"\n [class.btn-primary]=\"opt.selected\"\n (click)=\"opt.selected = !opt.selected\"\n >\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3$1.ToggleGroupDirective, selector: "[seamToggleGroup]", inputs: ["value", "disabled", "multiple", "selectionToggleable"], outputs: ["change"], exportAs: ["seamToggleGroup"] }, { kind: "directive", type: i3$1.ToggleGroupOptionDirective, selector: "[seamToggleGroupOption]", inputs: ["seamToggleGroupOption", "selected"], outputs: ["selectionChange"], exportAs: ["seamToggleGroupOption"] }] });
549
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DataFilterToggleButtonsComponent, deps: [{ token: i0.ElementRef }, { token: THESEAM_DATA_FILTER_CONTAINER }, { token: THESEAM_DATA_FILTER_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
550
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: DataFilterToggleButtonsComponent, isStandalone: false, selector: "seam-data-filter-toggle-buttons", inputs: { filterName: "filterName", properties: "properties", omitProperties: "omitProperties", multiple: "multiple", selectionToggleable: "selectionToggleable", buttons: "buttons", exact: "exact", caseSensitive: "caseSensitive", maxWidth: "maxWidth", prependLabel: "prependLabel", filterDropdownLabel: "filterDropdownLabel", forceCollapseState: "forceCollapseState", value: "value" }, host: { properties: { "class.seam-data-filter-toggle-buttons-collapsed": "this._collapsedClass", "class.seam-data-filter-toggle-buttons-expanded": "this._expandedClass" } }, providers: [DATA_FILTER_TOGGLE_BUTTON], viewQueries: [{ propertyName: "_measureDiv", first: true, predicate: ["measureDiv"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"isCollapsed(); else buttonsTpl\">\n <div class=\"d-flex toggle-buttons-filter__collapsed\">\n <div\n *ngIf=\"prependLabel\"\n class=\"d-flex align-items-center toggle-buttons-filter__collapsed-prepend-label\"\n >\n {{ prependLabel }}\n </div>\n <button\n seamButton\n theme=\"lightgray\"\n size=\"sm\"\n class=\"dropdown-toggle toggle-buttons-filter__collapsed-button\"\n title=\"View filter options\"\n [seamMenuToggle]=\"buttonsDropdownTpl\"\n >\n {{ activeFilterLabel | async }}\n </button>\n <seam-menu #buttonsDropdownTpl>\n <div\n role=\"group\"\n aria-label=\"Toggle Filters\"\n *ngIf=\"options as opts\"\n [formControl]=\"_control\"\n seamToggleGroup\n #tg=\"seamToggleGroup\"\n [multiple]=\"opts.multiple\"\n [selectionToggleable]=\"opts.selectionToggleable\"\n >\n <ng-container *ngFor=\"let btn of buttons\">\n <button\n seamMenuItem\n [seamToggleGroupOption]=\"btn.value\"\n [class.seam-menu-item-active]=\"tg.isSelected(btn.value)\"\n (click)=\"tg.toggleOptionSelect(btn.value)\"\n title=\"Apply filter\"\n >\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n </div>\n </seam-menu>\n </div>\n</ng-container>\n\n<ng-template #buttonsTpl>\n <div\n class=\"btn-group toggle-buttons-filter__expanded\"\n role=\"group\"\n aria-label=\"Toggle Filters\"\n *ngIf=\"options as opts\"\n [formControl]=\"_control\"\n seamToggleGroup\n #tg=\"seamToggleGroup\"\n [multiple]=\"opts.multiple\"\n [selectionToggleable]=\"opts.selectionToggleable\"\n >\n <ng-container *ngFor=\"let btn of buttons\">\n <button\n type=\"button\"\n class=\"btn btn-sm px-4\"\n [seamToggleGroupOption]=\"btn.value\"\n [class.btn-lightgray]=\"!tg.isSelected(btn.value)\"\n [class.btn-primary]=\"tg.isSelected(btn.value)\"\n (click)=\"tg.toggleOptionSelect(btn.value)\"\n title=\"Apply filter\"\n >\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n </div>\n</ng-template>\n\n<!-- Hidden measurement div: always in DOM, used to read natural btn-group width -->\n<div #measureDiv class=\"btn-group btn-group--measure\" aria-hidden=\"true\">\n <ng-container *ngFor=\"let btn of buttons\">\n <button type=\"button\" class=\"btn btn-sm px-4\" tabindex=\"-1\">\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n</div>\n", styles: [":host{position:relative}.btn-group--measure{visibility:hidden;position:absolute;pointer-events:none;white-space:nowrap;top:0;left:-9999px}.seam-menu-item.seam-menu-item-active,.seam-menu-item.seam-menu-item-active.cdk-mouse-focused:not(:hover){background:#357ebd;color:#fff}.toggle-buttons-filter__collapsed{font-size:.875rem}.toggle-buttons-filter__collapsed-prepend-label{border-radius:.2rem 0 0 .2rem;padding:.25rem .75rem;background:#357ebd;color:#fff}.toggle-buttons-filter__collapsed-button{position:relative;min-width:100px;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;padding-right:1.5rem}.toggle-buttons-filter__collapsed-button:after{position:absolute;top:calc(50% - 3px);right:calc(.75rem - 3px)}.toggle-buttons-filter__collapsed-prepend-label~.toggle-buttons-filter__collapsed-button{border-radius:0 .2rem .2rem 0}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3$1.ToggleGroupDirective, selector: "[seamToggleGroup]", inputs: ["value", "disabled", "multiple", "selectionToggleable"], outputs: ["change"], exportAs: ["seamToggleGroup"] }, { kind: "directive", type: i3$1.ToggleGroupOptionDirective, selector: "[seamToggleGroupOption]", inputs: ["seamToggleGroupOption"], exportAs: ["seamToggleGroupOption"] }, { kind: "component", type: i4$1.MenuComponent, selector: "seam-menu", inputs: ["menuClass", "baseWidth", "animationType"], outputs: ["closed"], exportAs: ["seamMenu"] }, { kind: "directive", type: i4$1.MenuToggleDirective, selector: "[seamMenuToggle]", inputs: ["seamMenuToggle", "positions", "seamMenuTogglePositionsOffsetY"], outputs: ["menuToggle", "menuOpened", "menuClosed"], exportAs: ["seamMenuToggle"] }, { kind: "component", type: i4$1.MenuItemComponent, selector: "[seamMenuItem]", inputs: ["disabled", "role", "icon", "iconClass", "sublevelIcon", "subLevelIconClass", "badgeText", "badgeTheme"], exportAs: ["seamMenuItem"] }, { kind: "component", type: i5.TheSeamButtonComponent, selector: "button[seamButton]", inputs: ["disabled", "theme", "size", "type"], exportAs: ["seamButton"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
443
551
  }
444
552
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DataFilterToggleButtonsComponent, decorators: [{
445
553
  type: Component,
446
- args: [{ selector: 'seam-data-filter-toggle-buttons', providers: [DATA_FILTER_TOGGLE_BUTTON], standalone: false, template: "<div\n class=\"btn-group\"\n role=\"group\"\n aria-label=\"Progress Filter\"\n *ngIf=\"options as opts\"\n [formControl]=\"_control\"\n seamToggleGroup\n [multiple]=\"opts.multiple\"\n [selectionToggleable]=\"opts.selectionToggleable\"\n>\n <ng-container *ngFor=\"let btn of buttons\">\n <button\n type=\"button\"\n class=\"btn btn-sm px-4\"\n [seamToggleGroupOption]=\"btn.value\"\n #opt=\"seamToggleGroupOption\"\n [class.btn-lightgray]=\"!opt.selected\"\n [class.btn-primary]=\"opt.selected\"\n (click)=\"opt.selected = !opt.selected\"\n >\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n</div>\n" }]
447
- }], ctorParameters: () => [{ type: undefined, decorators: [{
554
+ args: [{ selector: 'seam-data-filter-toggle-buttons', providers: [DATA_FILTER_TOGGLE_BUTTON], standalone: false, template: "<ng-container *ngIf=\"isCollapsed(); else buttonsTpl\">\n <div class=\"d-flex toggle-buttons-filter__collapsed\">\n <div\n *ngIf=\"prependLabel\"\n class=\"d-flex align-items-center toggle-buttons-filter__collapsed-prepend-label\"\n >\n {{ prependLabel }}\n </div>\n <button\n seamButton\n theme=\"lightgray\"\n size=\"sm\"\n class=\"dropdown-toggle toggle-buttons-filter__collapsed-button\"\n title=\"View filter options\"\n [seamMenuToggle]=\"buttonsDropdownTpl\"\n >\n {{ activeFilterLabel | async }}\n </button>\n <seam-menu #buttonsDropdownTpl>\n <div\n role=\"group\"\n aria-label=\"Toggle Filters\"\n *ngIf=\"options as opts\"\n [formControl]=\"_control\"\n seamToggleGroup\n #tg=\"seamToggleGroup\"\n [multiple]=\"opts.multiple\"\n [selectionToggleable]=\"opts.selectionToggleable\"\n >\n <ng-container *ngFor=\"let btn of buttons\">\n <button\n seamMenuItem\n [seamToggleGroupOption]=\"btn.value\"\n [class.seam-menu-item-active]=\"tg.isSelected(btn.value)\"\n (click)=\"tg.toggleOptionSelect(btn.value)\"\n title=\"Apply filter\"\n >\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n </div>\n </seam-menu>\n </div>\n</ng-container>\n\n<ng-template #buttonsTpl>\n <div\n class=\"btn-group toggle-buttons-filter__expanded\"\n role=\"group\"\n aria-label=\"Toggle Filters\"\n *ngIf=\"options as opts\"\n [formControl]=\"_control\"\n seamToggleGroup\n #tg=\"seamToggleGroup\"\n [multiple]=\"opts.multiple\"\n [selectionToggleable]=\"opts.selectionToggleable\"\n >\n <ng-container *ngFor=\"let btn of buttons\">\n <button\n type=\"button\"\n class=\"btn btn-sm px-4\"\n [seamToggleGroupOption]=\"btn.value\"\n [class.btn-lightgray]=\"!tg.isSelected(btn.value)\"\n [class.btn-primary]=\"tg.isSelected(btn.value)\"\n (click)=\"tg.toggleOptionSelect(btn.value)\"\n title=\"Apply filter\"\n >\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n </div>\n</ng-template>\n\n<!-- Hidden measurement div: always in DOM, used to read natural btn-group width -->\n<div #measureDiv class=\"btn-group btn-group--measure\" aria-hidden=\"true\">\n <ng-container *ngFor=\"let btn of buttons\">\n <button type=\"button\" class=\"btn btn-sm px-4\" tabindex=\"-1\">\n {{ btn.name || btn.value }}\n </button>\n </ng-container>\n</div>\n", styles: [":host{position:relative}.btn-group--measure{visibility:hidden;position:absolute;pointer-events:none;white-space:nowrap;top:0;left:-9999px}.seam-menu-item.seam-menu-item-active,.seam-menu-item.seam-menu-item-active.cdk-mouse-focused:not(:hover){background:#357ebd;color:#fff}.toggle-buttons-filter__collapsed{font-size:.875rem}.toggle-buttons-filter__collapsed-prepend-label{border-radius:.2rem 0 0 .2rem;padding:.25rem .75rem;background:#357ebd;color:#fff}.toggle-buttons-filter__collapsed-button{position:relative;min-width:100px;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;padding-right:1.5rem}.toggle-buttons-filter__collapsed-button:after{position:absolute;top:calc(50% - 3px);right:calc(.75rem - 3px)}.toggle-buttons-filter__collapsed-prepend-label~.toggle-buttons-filter__collapsed-button{border-radius:0 .2rem .2rem 0}\n"] }]
555
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
448
556
  type: Inject,
449
557
  args: [THESEAM_DATA_FILTER_CONTAINER]
450
558
  }] }, { type: undefined, decorators: [{
@@ -468,6 +576,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
468
576
  type: Input
469
577
  }], caseSensitive: [{
470
578
  type: Input
579
+ }], maxWidth: [{
580
+ type: Input
581
+ }], prependLabel: [{
582
+ type: Input
583
+ }], filterDropdownLabel: [{
584
+ type: Input
585
+ }], forceCollapseState: [{
586
+ type: Input
587
+ }], _collapsedClass: [{
588
+ type: HostBinding,
589
+ args: ['class.seam-data-filter-toggle-buttons-collapsed']
590
+ }], _expandedClass: [{
591
+ type: HostBinding,
592
+ args: ['class.seam-data-filter-toggle-buttons-expanded']
593
+ }], _measureDiv: [{
594
+ type: ViewChild,
595
+ args: ['measureDiv']
471
596
  }], value: [{
472
597
  type: Input
473
598
  }] } });
@@ -506,7 +631,9 @@ class TheSeamDataFiltersModule {
506
631
  TheSeamFormFieldModule,
507
632
  FontAwesomeModule,
508
633
  TheSeamToggleGroupModule,
509
- TheSeamIconModule], exports: [DataFilterSearchComponent,
634
+ TheSeamIconModule,
635
+ TheSeamMenuModule,
636
+ TheSeamButtonsModule], exports: [DataFilterSearchComponent,
510
637
  DataFilterTextComponent,
511
638
  DataFilterToggleButtonsComponent] });
512
639
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TheSeamDataFiltersModule, providers: [...filterDefProviders], imports: [CommonModule,
@@ -514,7 +641,9 @@ class TheSeamDataFiltersModule {
514
641
  TheSeamFormFieldModule,
515
642
  FontAwesomeModule,
516
643
  TheSeamToggleGroupModule,
517
- TheSeamIconModule] });
644
+ TheSeamIconModule,
645
+ TheSeamMenuModule,
646
+ TheSeamButtonsModule] });
518
647
  }
519
648
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TheSeamDataFiltersModule, decorators: [{
520
649
  type: NgModule,
@@ -527,6 +656,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
527
656
  FontAwesomeModule,
528
657
  TheSeamToggleGroupModule,
529
658
  TheSeamIconModule,
659
+ TheSeamMenuModule,
660
+ TheSeamButtonsModule,
530
661
  ],
531
662
  providers: [...filterDefProviders],
532
663
  exports: [...filterComponents],
@@ -537,5 +668,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
537
668
  * Generated bundle index. Do not edit.
538
669
  */
539
670
 
540
- export { DATA_FILTER_SEARCH, DATA_FILTER_TEXT, DATA_FILTER_TOGGLE_BUTTON, DataFilterSearchComponent, DataFilterTextComponent, DataFilterToggleButtonsComponent, DefaultSearchFilterOptions, DefaultTextFilterOptions, DefaultToggleButtonsFilterOptions, THESEAM_DATA_FILTER, THESEAM_DATA_FILTER_CONTAINER, THESEAM_DATA_FILTER_DEF, THESEAM_DATA_FILTER_OPTIONS, TheSeamDataFiltersModule, composeDataFilterStates, composeDataFilters, filterOperator, searchDataFilter, textDataFilter, toggleButtonsFilter };
671
+ export { DATA_FILTER_SEARCH, DATA_FILTER_TEXT, DATA_FILTER_TOGGLE_BUTTON, DATA_FILTER_TOGGLE_BUTTON_DROPDOWN_TEXT, DataFilterSearchComponent, DataFilterTextComponent, DataFilterToggleButtonsComponent, DefaultSearchFilterOptions, DefaultTextFilterOptions, DefaultToggleButtonsFilterOptions, THESEAM_DATA_FILTER, THESEAM_DATA_FILTER_CONTAINER, THESEAM_DATA_FILTER_DEF, THESEAM_DATA_FILTER_OPTIONS, TheSeamDataFiltersModule, composeDataFilterStates, composeDataFilters, filterOperator, searchDataFilter, textDataFilter, toggleButtonsFilter };
541
672
  //# sourceMappingURL=theseam-ui-common-data-filters.mjs.map