@gravionlabs/helix-ui 22.2.2 → 22.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4890,6 +4890,13 @@ var HxSelect = class HxSelect {
4890
4890
  optionDisabled = input("disabled", ...ngDevMode ? [{ debugName: "optionDisabled" }] : /* istanbul ignore next */ []);
4891
4891
  placeholder = input("", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
4892
4892
  emptyMessage = input("No options", ...ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []);
4893
+ filter = input(false, {
4894
+ ...ngDevMode ? { debugName: "filter" } : /* istanbul ignore next */ {},
4895
+ transform: booleanAttribute
4896
+ });
4897
+ filterPlaceholder = input("Search", ...ngDevMode ? [{ debugName: "filterPlaceholder" }] : /* istanbul ignore next */ []);
4898
+ filterBy = input(...ngDevMode ? [void 0, { debugName: "filterBy" }] : /* istanbul ignore next */ []);
4899
+ emptyFilterMessage = input("No results", ...ngDevMode ? [{ debugName: "emptyFilterMessage" }] : /* istanbul ignore next */ []);
4893
4900
  size = input("medium", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
4894
4901
  variant = input("outlined", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
4895
4902
  fluid = input(false, {
@@ -4932,9 +4939,25 @@ var HxSelect = class HxSelect {
4932
4939
  }];
4933
4940
  trigger = viewChild.required("trigger", ...ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []);
4934
4941
  listbox = viewChild(CdkListbox, ...ngDevMode ? [{ debugName: "listbox" }] : /* istanbul ignore next */ []);
4942
+ filterField = viewChild("filterField", ...ngDevMode ? [{ debugName: "filterField" }] : /* istanbul ignore next */ []);
4943
+ query = signal("", ...ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []);
4935
4944
  #cvaDisabled = signal(false, ...ngDevMode ? [{ debugName: "#cvaDisabled" }] : /* istanbul ignore next */ []);
4936
4945
  isDisabled = computed(() => this.disabled() || this.#cvaDisabled(), ...ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []);
4937
4946
  items = computed(() => resolveOptions(this.options(), this.optionLabel(), this.optionValue(), this.optionDisabled()), ...ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []);
4947
+ visibleItems = computed(() => {
4948
+ const query = this.query().trim().toLowerCase();
4949
+ const items = this.items();
4950
+ if (!this.filter() || !query) return items;
4951
+ const by = this.filterBy();
4952
+ const options = this.options();
4953
+ return items.filter((item, i) => {
4954
+ return (by === void 0 ? item.label : this.#filterText(options[i], by, item.label)).toLowerCase().includes(query);
4955
+ });
4956
+ }, ...ngDevMode ? [{ debugName: "visibleItems" }] : /* istanbul ignore next */ []);
4957
+ resultsLabel = computed(() => {
4958
+ const n = this.visibleItems().length;
4959
+ return n === 1 ? "1 result" : `${n} results`;
4960
+ }, ...ngDevMode ? [{ debugName: "resultsLabel" }] : /* istanbul ignore next */ []);
4938
4961
  selected = computed(() => {
4939
4962
  const compare = this.compareWith();
4940
4963
  const current = this.value();
@@ -4974,10 +4997,26 @@ var HxSelect = class HxSelect {
4974
4997
  close(refocus = false) {
4975
4998
  if (!this.open()) return;
4976
4999
  this.open.set(false);
5000
+ this.query.set("");
4977
5001
  if (refocus) this.focus();
4978
5002
  }
4979
5003
  onAttach() {
4980
- afterNextRender(() => this.listbox()?.focus(), { injector: this.#injector });
5004
+ afterNextRender(() => {
5005
+ const field = this.filterField();
5006
+ if (field) field.nativeElement.focus();
5007
+ else this.listbox()?.focus();
5008
+ }, { injector: this.#injector });
5009
+ }
5010
+ onFilterKeydown(event) {
5011
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
5012
+ event.preventDefault();
5013
+ this.listbox()?.focus();
5014
+ }
5015
+ }
5016
+ #filterText(option, by, fallback) {
5017
+ if (option === null || typeof option !== "object") return fallback;
5018
+ if (typeof by === "function") return String(by(option) ?? "");
5019
+ return by in option ? String(option[by] ?? "") : "";
4981
5020
  }
4982
5021
  onTriggerKeydown(event) {
4983
5022
  if (event.key === "ArrowDown" || event.key === "ArrowUp") {
@@ -5074,6 +5113,34 @@ var HxSelect = class HxSelect {
5074
5113
  isRequired: false,
5075
5114
  transformFunction: null
5076
5115
  },
5116
+ filter: {
5117
+ classPropertyName: "filter",
5118
+ publicName: "filter",
5119
+ isSignal: true,
5120
+ isRequired: false,
5121
+ transformFunction: null
5122
+ },
5123
+ filterPlaceholder: {
5124
+ classPropertyName: "filterPlaceholder",
5125
+ publicName: "filterPlaceholder",
5126
+ isSignal: true,
5127
+ isRequired: false,
5128
+ transformFunction: null
5129
+ },
5130
+ filterBy: {
5131
+ classPropertyName: "filterBy",
5132
+ publicName: "filterBy",
5133
+ isSignal: true,
5134
+ isRequired: false,
5135
+ transformFunction: null
5136
+ },
5137
+ emptyFilterMessage: {
5138
+ classPropertyName: "emptyFilterMessage",
5139
+ publicName: "emptyFilterMessage",
5140
+ isSignal: true,
5141
+ isRequired: false,
5142
+ transformFunction: null
5143
+ },
5077
5144
  size: {
5078
5145
  classPropertyName: "size",
5079
5146
  publicName: "size",
@@ -5176,21 +5243,31 @@ var HxSelect = class HxSelect {
5176
5243
  useExisting: forwardRef(() => HxSelect),
5177
5244
  multi: true
5178
5245
  }],
5179
- viewQueries: [{
5180
- propertyName: "trigger",
5181
- first: true,
5182
- predicate: ["trigger"],
5183
- descendants: true,
5184
- isSignal: true
5185
- }, {
5186
- propertyName: "listbox",
5187
- first: true,
5188
- predicate: CdkListbox,
5189
- descendants: true,
5190
- isSignal: true
5191
- }],
5246
+ viewQueries: [
5247
+ {
5248
+ propertyName: "trigger",
5249
+ first: true,
5250
+ predicate: ["trigger"],
5251
+ descendants: true,
5252
+ isSignal: true
5253
+ },
5254
+ {
5255
+ propertyName: "listbox",
5256
+ first: true,
5257
+ predicate: CdkListbox,
5258
+ descendants: true,
5259
+ isSignal: true
5260
+ },
5261
+ {
5262
+ propertyName: "filterField",
5263
+ first: true,
5264
+ predicate: ["filterField"],
5265
+ descendants: true,
5266
+ isSignal: true
5267
+ }
5268
+ ],
5192
5269
  ngImport: i0,
5193
- template: "<button\n #trigger\n type=\"button\"\n class=\"hx-select-trigger\"\n role=\"combobox\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n aria-haspopup=\"listbox\"\n [attr.id]=\"inputId() ?? null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? panelId : null\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n <span class=\"hx-select-label\" [class.hx-select-placeholder]=\"!selected()\">{{\n selected()?.label ?? placeholder()\n }}</span>\n <span class=\"hx-select-chevron\" aria-hidden=\"true\"></span>\n</button>\n@if (canClear()) {\n <button type=\"button\" class=\"hx-select-clear\" aria-label=\"Clear selection\" (click)=\"clear($event)\">\n <span class=\"hx-select-clear-icon\" aria-hidden=\"true\"></span>\n </button>\n}\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayPanelClass=\"hx-select-overlay\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayMinWidth]=\"panelWidth()\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n (overlayKeydown)=\"onOverlayKeydown($event)\"\n (attach)=\"onAttach()\"\n (detach)=\"close()\"\n>\n <div class=\"hx-select-panel\">\n <div\n cdkListbox\n class=\"hx-select-list\"\n [id]=\"panelId\"\n [cdkListboxValue]=\"selectedValues()\"\n [cdkListboxUseActiveDescendant]=\"true\"\n [cdkListboxCompareWith]=\"compareWith()\"\n [attr.aria-label]=\"ariaLabel() ?? placeholder() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (cdkListboxValueChange)=\"onSelect($event)\"\n >\n @for (item of items(); track $index) {\n <div\n class=\"hx-select-option\"\n [cdkOption]=\"item.value\"\n [cdkOptionDisabled]=\"item.disabled\"\n [cdkOptionTypeaheadLabel]=\"item.label\"\n >\n <span class=\"hx-select-check\" aria-hidden=\"true\"></span>\n <span>{{ item.label }}</span>\n </div>\n } @empty {\n <div class=\"hx-select-empty\">{{ emptyMessage() }}</div>\n }\n </div>\n </div>\n</ng-template>\n",
5270
+ template: "<button\n #trigger\n type=\"button\"\n class=\"hx-select-trigger\"\n role=\"combobox\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n aria-haspopup=\"listbox\"\n [attr.id]=\"inputId() ?? null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? panelId : null\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n <span class=\"hx-select-label\" [class.hx-select-placeholder]=\"!selected()\">{{\n selected()?.label ?? placeholder()\n }}</span>\n <span class=\"hx-select-chevron\" aria-hidden=\"true\"></span>\n</button>\n@if (canClear()) {\n <button type=\"button\" class=\"hx-select-clear\" aria-label=\"Clear selection\" (click)=\"clear($event)\">\n <span class=\"hx-select-clear-icon\" aria-hidden=\"true\"></span>\n </button>\n}\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayPanelClass=\"hx-select-overlay\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayMinWidth]=\"panelWidth()\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n (overlayKeydown)=\"onOverlayKeydown($event)\"\n (attach)=\"onAttach()\"\n (detach)=\"close()\"\n>\n <div class=\"hx-select-panel\">\n @if (filter()) {\n <div class=\"hx-select-header\">\n <input\n #filterField\n type=\"text\"\n class=\"hx-select-filter\"\n autocomplete=\"off\"\n [attr.aria-label]=\"filterPlaceholder()\"\n [attr.aria-controls]=\"panelId\"\n [placeholder]=\"filterPlaceholder()\"\n [value]=\"query()\"\n (input)=\"query.set($any($event.target).value)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n }\n <div\n cdkListbox\n class=\"hx-select-list\"\n [id]=\"panelId\"\n [cdkListboxValue]=\"selectedValues()\"\n [cdkListboxUseActiveDescendant]=\"true\"\n [cdkListboxCompareWith]=\"compareWith()\"\n [attr.aria-label]=\"ariaLabel() ?? placeholder() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (cdkListboxValueChange)=\"onSelect($event)\"\n >\n @for (item of visibleItems(); track item) {\n <div\n class=\"hx-select-option\"\n [cdkOption]=\"item.value\"\n [cdkOptionDisabled]=\"item.disabled\"\n [cdkOptionTypeaheadLabel]=\"item.label\"\n >\n <span class=\"hx-select-check\" aria-hidden=\"true\"></span>\n <span>{{ item.label }}</span>\n </div>\n } @empty {\n <div class=\"hx-select-empty\">{{ query().trim() ? emptyFilterMessage() : emptyMessage() }}</div>\n }\n </div>\n @if (filter()) {\n <span class=\"hx-select-sr-only\" aria-live=\"polite\">{{ resultsLabel() }}</span>\n }\n </div>\n</ng-template>\n",
5194
5271
  dependencies: [
5195
5272
  {
5196
5273
  kind: "directive",
@@ -5309,7 +5386,7 @@ i0.ɵɵngDeclareClassMetadata({
5309
5386
  "[class.hx-filled]": "!!selected()",
5310
5387
  "(focusout)": "onFocusOut($event)"
5311
5388
  },
5312
- template: "<button\n #trigger\n type=\"button\"\n class=\"hx-select-trigger\"\n role=\"combobox\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n aria-haspopup=\"listbox\"\n [attr.id]=\"inputId() ?? null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? panelId : null\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n <span class=\"hx-select-label\" [class.hx-select-placeholder]=\"!selected()\">{{\n selected()?.label ?? placeholder()\n }}</span>\n <span class=\"hx-select-chevron\" aria-hidden=\"true\"></span>\n</button>\n@if (canClear()) {\n <button type=\"button\" class=\"hx-select-clear\" aria-label=\"Clear selection\" (click)=\"clear($event)\">\n <span class=\"hx-select-clear-icon\" aria-hidden=\"true\"></span>\n </button>\n}\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayPanelClass=\"hx-select-overlay\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayMinWidth]=\"panelWidth()\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n (overlayKeydown)=\"onOverlayKeydown($event)\"\n (attach)=\"onAttach()\"\n (detach)=\"close()\"\n>\n <div class=\"hx-select-panel\">\n <div\n cdkListbox\n class=\"hx-select-list\"\n [id]=\"panelId\"\n [cdkListboxValue]=\"selectedValues()\"\n [cdkListboxUseActiveDescendant]=\"true\"\n [cdkListboxCompareWith]=\"compareWith()\"\n [attr.aria-label]=\"ariaLabel() ?? placeholder() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (cdkListboxValueChange)=\"onSelect($event)\"\n >\n @for (item of items(); track $index) {\n <div\n class=\"hx-select-option\"\n [cdkOption]=\"item.value\"\n [cdkOptionDisabled]=\"item.disabled\"\n [cdkOptionTypeaheadLabel]=\"item.label\"\n >\n <span class=\"hx-select-check\" aria-hidden=\"true\"></span>\n <span>{{ item.label }}</span>\n </div>\n } @empty {\n <div class=\"hx-select-empty\">{{ emptyMessage() }}</div>\n }\n </div>\n </div>\n</ng-template>\n"
5389
+ template: "<button\n #trigger\n type=\"button\"\n class=\"hx-select-trigger\"\n role=\"combobox\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n aria-haspopup=\"listbox\"\n [attr.id]=\"inputId() ?? null\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-controls]=\"open() ? panelId : null\"\n [attr.aria-label]=\"ariaLabel() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n [attr.aria-invalid]=\"invalid() ? 'true' : null\"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\"\n>\n <span class=\"hx-select-label\" [class.hx-select-placeholder]=\"!selected()\">{{\n selected()?.label ?? placeholder()\n }}</span>\n <span class=\"hx-select-chevron\" aria-hidden=\"true\"></span>\n</button>\n@if (canClear()) {\n <button type=\"button\" class=\"hx-select-clear\" aria-label=\"Clear selection\" (click)=\"clear($event)\">\n <span class=\"hx-select-clear-icon\" aria-hidden=\"true\"></span>\n </button>\n}\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayPanelClass=\"hx-select-overlay\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"open()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayMinWidth]=\"panelWidth()\"\n (overlayOutsideClick)=\"onOutsideClick($event)\"\n (overlayKeydown)=\"onOverlayKeydown($event)\"\n (attach)=\"onAttach()\"\n (detach)=\"close()\"\n>\n <div class=\"hx-select-panel\">\n @if (filter()) {\n <div class=\"hx-select-header\">\n <input\n #filterField\n type=\"text\"\n class=\"hx-select-filter\"\n autocomplete=\"off\"\n [attr.aria-label]=\"filterPlaceholder()\"\n [attr.aria-controls]=\"panelId\"\n [placeholder]=\"filterPlaceholder()\"\n [value]=\"query()\"\n (input)=\"query.set($any($event.target).value)\"\n (keydown)=\"onFilterKeydown($event)\"\n />\n </div>\n }\n <div\n cdkListbox\n class=\"hx-select-list\"\n [id]=\"panelId\"\n [cdkListboxValue]=\"selectedValues()\"\n [cdkListboxUseActiveDescendant]=\"true\"\n [cdkListboxCompareWith]=\"compareWith()\"\n [attr.aria-label]=\"ariaLabel() ?? placeholder() ?? null\"\n [attr.aria-labelledby]=\"ariaLabelledby() ?? null\"\n (cdkListboxValueChange)=\"onSelect($event)\"\n >\n @for (item of visibleItems(); track item) {\n <div\n class=\"hx-select-option\"\n [cdkOption]=\"item.value\"\n [cdkOptionDisabled]=\"item.disabled\"\n [cdkOptionTypeaheadLabel]=\"item.label\"\n >\n <span class=\"hx-select-check\" aria-hidden=\"true\"></span>\n <span>{{ item.label }}</span>\n </div>\n } @empty {\n <div class=\"hx-select-empty\">{{ query().trim() ? emptyFilterMessage() : emptyMessage() }}</div>\n }\n </div>\n @if (filter()) {\n <span class=\"hx-select-sr-only\" aria-live=\"polite\">{{ resultsLabel() }}</span>\n }\n </div>\n</ng-template>\n"
5313
5390
  }]
5314
5391
  }],
5315
5392
  propDecorators: {
@@ -5361,6 +5438,38 @@ i0.ɵɵngDeclareClassMetadata({
5361
5438
  required: false
5362
5439
  }]
5363
5440
  }],
5441
+ filter: [{
5442
+ type: i0.Input,
5443
+ args: [{
5444
+ isSignal: true,
5445
+ alias: "filter",
5446
+ required: false
5447
+ }]
5448
+ }],
5449
+ filterPlaceholder: [{
5450
+ type: i0.Input,
5451
+ args: [{
5452
+ isSignal: true,
5453
+ alias: "filterPlaceholder",
5454
+ required: false
5455
+ }]
5456
+ }],
5457
+ filterBy: [{
5458
+ type: i0.Input,
5459
+ args: [{
5460
+ isSignal: true,
5461
+ alias: "filterBy",
5462
+ required: false
5463
+ }]
5464
+ }],
5465
+ emptyFilterMessage: [{
5466
+ type: i0.Input,
5467
+ args: [{
5468
+ isSignal: true,
5469
+ alias: "emptyFilterMessage",
5470
+ required: false
5471
+ }]
5472
+ }],
5364
5473
  size: [{
5365
5474
  type: i0.Input,
5366
5475
  args: [{
@@ -5463,6 +5572,10 @@ i0.ɵɵngDeclareClassMetadata({
5463
5572
  listbox: [{
5464
5573
  type: i0.ViewChild,
5465
5574
  args: [i0.forwardRef(() => CdkListbox), { isSignal: true }]
5575
+ }],
5576
+ filterField: [{
5577
+ type: i0.ViewChild,
5578
+ args: ["filterField", { isSignal: true }]
5466
5579
  }]
5467
5580
  }
5468
5581
  });
@@ -5680,6 +5793,10 @@ var HxPaginator = class HxPaginator {
5680
5793
  "optionDisabled",
5681
5794
  "placeholder",
5682
5795
  "emptyMessage",
5796
+ "filter",
5797
+ "filterPlaceholder",
5798
+ "filterBy",
5799
+ "emptyFilterMessage",
5683
5800
  "size",
5684
5801
  "variant",
5685
5802
  "fluid",