@xui/suggest 2.0.0-alpha.20 → 2.0.0-alpha.21

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.
@@ -14,19 +14,29 @@ import { XuiSelectOption } from '@xui/select';
14
14
  * `xui-select`, there is no separate trigger. `[(value)]` two-way binding.
15
15
  */
16
16
  class XuiSuggest {
17
+ /** Extra classes, merged into the component's own rather than replacing them. */
17
18
  class = input('', /* @ts-ignore */
18
19
  ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
20
+ /** The options to search over. */
19
21
  items = input([], /* @ts-ignore */
20
22
  ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
23
+ /**
24
+ * How an item is labelled, in both the list and the field once chosen. Also what the default filter matches against.
25
+ */
21
26
  itemText = input((item) => (item == null ? '' : String(item)), /* @ts-ignore */
22
27
  ...(ngDevMode ? [{ debugName: "itemText" }] : /* istanbul ignore next */ []));
28
+ /** Custom filter for one item against the query. Defaults to a case-insensitive substring match on `itemText`. */
23
29
  itemPredicate = input(/* @ts-ignore */
24
30
  ...(ngDevMode ? [undefined, { debugName: "itemPredicate" }] : /* istanbul ignore next */ []));
31
+ /** Which items cannot be chosen. They stay in the list, greyed out. */
25
32
  itemDisabled = input(() => false, /* @ts-ignore */
26
33
  ...(ngDevMode ? [{ debugName: "itemDisabled" }] : /* istanbul ignore next */ []));
34
+ /** Block interaction and dim the field. */
27
35
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
36
+ /** Text shown in the empty field. */
28
37
  placeholder = input('Search…', /* @ts-ignore */
29
38
  ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
39
+ /** Shown in place of the list when the query matches nothing. */
30
40
  noResultsText = input('No results.', /* @ts-ignore */
31
41
  ...(ngDevMode ? [{ debugName: "noResultsText" }] : /* istanbul ignore next */ []));
32
42
  /** The chosen item. Two-way bindable with `[(value)]`, or via `formControl`/`ngModel`. */
@@ -1 +1 @@
1
- {"version":3,"file":"xui-suggest.mjs","sources":["../../../../../../libs/ui/suggest/xui/src/lib/suggest.ts","../../../../../../libs/ui/suggest/xui/src/index.ts","../../../../../../libs/ui/suggest/xui/src/xui-suggest.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n input,\n model,\n signal,\n untracked,\n ViewEncapsulation\n} from '@angular/core';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { xui } from '@xui/core';\nimport { createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { createXActiveOption, createXItemListPredicate, createXQueryList, trackXItem } from '@xui/core/query';\nimport { XuiPopoverImports } from '@xui/popover';\nimport { XuiSelectOption } from '@xui/select';\nimport type { ClassValue } from 'clsx';\n\n/**\n * A typeahead autocomplete: the text input itself is the target. Typing filters a\n * popover list; choosing an item fills the input with its text. Unlike\n * `xui-select`, there is no separate trigger. `[(value)]` two-way binding.\n */\n@Component({\n selector: 'xui-suggest',\n imports: [NgTemplateOutlet, XuiPopoverImports],\n template: `\n <input\n #input\n type=\"text\"\n [attr.role]=\"'combobox'\"\n [class]=\"inputClass()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.disabled]=\"isDisabled() ? '' : null\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-autocomplete]=\"'list'\"\n [xuiPopover]=\"panel\"\n [(open)]=\"open\"\n [role]=\"'listbox'\"\n [matchTargetWidth]=\"true\"\n [minimal]=\"true\"\n [disabled]=\"isDisabled()\"\n interactionKind=\"click-target\"\n placement=\"bottom-start\"\n (input)=\"onInput($event)\"\n (focus)=\"open.set(true)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <ng-template #panel>\n <ul role=\"listbox\" class=\"m-0 max-h-60 list-none overflow-y-auto p-1 text-sm\">\n @for (item of list.filteredItems(); track trackItem($index, item)) {\n <!-- Keyboard navigation runs through the input, so options are pointer\n targets rather than individual tab stops. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n role=\"option\"\n [class]=\"optionClass(item)\"\n [attr.aria-selected]=\"item === value()\"\n (click)=\"choose(item)\"\n (mouseenter)=\"list.setActiveItem(item)\"\n >\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n item: item,\n active: list.isActive(item),\n selected: item === value(),\n index: $index\n }\"\n />\n } @else {\n {{ displayText(item) }}\n }\n </li>\n } @empty {\n <li class=\"text-foreground-muted px-2 py-2\">{{ noResultsText() }}</li>\n }\n </ul>\n </ng-template>\n `,\n host: {\n '[class]': 'computedClass()'\n },\n providers: [provideXValueAccessor(() => XuiSuggest)],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class XuiSuggest<T> implements ControlValueAccessor {\n readonly class = input<ClassValue>('');\n\n readonly items = input<readonly T[]>([]);\n readonly itemText = input<(item: T) => string>((item: T) => (item == null ? '' : String(item)));\n readonly itemPredicate = input<(query: string, item: T) => boolean>();\n readonly itemDisabled = input<(item: T) => boolean>(() => false);\n\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n readonly placeholder = input<string>('Search…');\n readonly noResultsText = input<string>('No results.');\n\n /** The chosen item. Two-way bindable with `[(value)]`, or via `formControl`/`ngModel`. */\n readonly value = model<T | null>(null);\n\n protected readonly cva = createXValueAccessor<T | null>({\n onWrite: value => this.value.set(value ?? null),\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n /** Whether the popover has ever been open — so the initial closed state is not \"touched\". */\n private hasOpened = false;\n\n protected readonly open = model(false);\n protected readonly query = signal('');\n /** Whether the user is actively editing (so the input shows the query). */\n private readonly editing = signal(false);\n\n protected readonly optionTemplate = contentChild(XuiSelectOption<T>);\n\n protected readonly list = createXQueryList<T>({\n items: this.items,\n query: this.query,\n itemText: item => this.itemText()(item),\n itemDisabled: item => this.itemDisabled()(item),\n itemListPredicate: createXItemListPredicate({\n itemText: this.itemText,\n itemPredicate: this.itemPredicate\n })\n });\n\n // Keyboard navigation over the filtered list (ArrowDown re-opens the popover).\n private readonly nav = createXActiveOption<T>({\n list: this.list,\n select: item => this.choose(item),\n close: () => this.open.set(false),\n open: () => this.open.set(true)\n });\n\n /** The input shows the live query while editing, else the selected item's text. */\n protected readonly displayValue = computed(() => {\n if (this.editing()) {\n return this.query();\n }\n\n const selected = this.value();\n return selected == null ? '' : this.itemText()(selected);\n });\n\n protected readonly computedClass = computed(() => xui('inline-block', this.class()));\n\n protected readonly inputClass = computed(() =>\n xui(\n 'border-border bg-surface-inset text-foreground placeholder:text-foreground-subtle h-(--control-height-md) w-full min-w-44 rounded-lg border px-(--control-padding-md) text-sm',\n 'focus-visible:border-focus transition-colors focus:outline-none',\n this.isDisabled() && 'cursor-not-allowed opacity-50'\n )\n );\n\n constructor() {\n // Stop editing (revert to the selected item's text) and mark the control\n // touched once the popover closes.\n effect(() => {\n if (this.open()) {\n this.hasOpened = true;\n } else {\n untracked(() => {\n this.editing.set(false);\n this.query.set('');\n if (this.hasOpened) {\n this.cva.markTouched();\n }\n });\n }\n });\n }\n\n protected displayText(item: T): string {\n return this.itemText()(item);\n }\n\n protected readonly trackItem = trackXItem;\n\n protected optionClass(item: T): string {\n return xui(\n 'flex cursor-pointer items-center gap-2 rounded px-2 py-1.5',\n this.list.isActive(item) && 'bg-primary/10',\n item === this.value() && 'text-primary font-medium',\n this.list.isDisabled(item) && 'pointer-events-none opacity-50'\n );\n }\n\n protected onInput(event: Event): void {\n this.editing.set(true);\n this.open.set(true);\n this.query.set((event.target as HTMLInputElement).value);\n this.list.activateFirst();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n this.nav.onKeydown(event);\n }\n\n protected choose(item: T): void {\n if (this.list.isDisabled(item)) {\n return;\n }\n\n this.value.set(item);\n this.cva.notifyChange(item);\n this.open.set(false);\n }\n\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n","import { XuiSuggest } from './lib/suggest';\n\nexport * from './lib/suggest';\n\nexport const XuiSuggestImports = [XuiSuggest] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xui-suggest.mjs","sources":["../../../../../../libs/ui/suggest/xui/src/lib/suggest.ts","../../../../../../libs/ui/suggest/xui/src/index.ts","../../../../../../libs/ui/suggest/xui/src/xui-suggest.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n effect,\n input,\n model,\n signal,\n untracked,\n ViewEncapsulation\n} from '@angular/core';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { xui } from '@xui/core';\nimport { createXValueAccessor, provideXValueAccessor } from '@xui/core/forms';\nimport { createXActiveOption, createXItemListPredicate, createXQueryList, trackXItem } from '@xui/core/query';\nimport { XuiPopoverImports } from '@xui/popover';\nimport { XuiSelectOption } from '@xui/select';\nimport type { ClassValue } from 'clsx';\n\n/**\n * A typeahead autocomplete: the text input itself is the target. Typing filters a\n * popover list; choosing an item fills the input with its text. Unlike\n * `xui-select`, there is no separate trigger. `[(value)]` two-way binding.\n */\n@Component({\n selector: 'xui-suggest',\n imports: [NgTemplateOutlet, XuiPopoverImports],\n template: `\n <input\n #input\n type=\"text\"\n [attr.role]=\"'combobox'\"\n [class]=\"inputClass()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.disabled]=\"isDisabled() ? '' : null\"\n [attr.aria-expanded]=\"open()\"\n [attr.aria-autocomplete]=\"'list'\"\n [xuiPopover]=\"panel\"\n [(open)]=\"open\"\n [role]=\"'listbox'\"\n [matchTargetWidth]=\"true\"\n [minimal]=\"true\"\n [disabled]=\"isDisabled()\"\n interactionKind=\"click-target\"\n placement=\"bottom-start\"\n (input)=\"onInput($event)\"\n (focus)=\"open.set(true)\"\n (keydown)=\"onKeydown($event)\"\n />\n\n <ng-template #panel>\n <ul role=\"listbox\" class=\"m-0 max-h-60 list-none overflow-y-auto p-1 text-sm\">\n @for (item of list.filteredItems(); track trackItem($index, item)) {\n <!-- Keyboard navigation runs through the input, so options are pointer\n targets rather than individual tab stops. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <li\n role=\"option\"\n [class]=\"optionClass(item)\"\n [attr.aria-selected]=\"item === value()\"\n (click)=\"choose(item)\"\n (mouseenter)=\"list.setActiveItem(item)\"\n >\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n item: item,\n active: list.isActive(item),\n selected: item === value(),\n index: $index\n }\"\n />\n } @else {\n {{ displayText(item) }}\n }\n </li>\n } @empty {\n <li class=\"text-foreground-muted px-2 py-2\">{{ noResultsText() }}</li>\n }\n </ul>\n </ng-template>\n `,\n host: {\n '[class]': 'computedClass()'\n },\n providers: [provideXValueAccessor(() => XuiSuggest)],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class XuiSuggest<T> implements ControlValueAccessor {\n /** Extra classes, merged into the component's own rather than replacing them. */\n readonly class = input<ClassValue>('');\n\n /** The options to search over. */\n readonly items = input<readonly T[]>([]);\n /**\n * How an item is labelled, in both the list and the field once chosen. Also what the default filter matches against.\n */\n readonly itemText = input<(item: T) => string>((item: T) => (item == null ? '' : String(item)));\n /** Custom filter for one item against the query. Defaults to a case-insensitive substring match on `itemText`. */\n readonly itemPredicate = input<(query: string, item: T) => boolean>();\n /** Which items cannot be chosen. They stay in the list, greyed out. */\n readonly itemDisabled = input<(item: T) => boolean>(() => false);\n\n /** Block interaction and dim the field. */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n /** Text shown in the empty field. */\n readonly placeholder = input<string>('Search…');\n /** Shown in place of the list when the query matches nothing. */\n readonly noResultsText = input<string>('No results.');\n\n /** The chosen item. Two-way bindable with `[(value)]`, or via `formControl`/`ngModel`. */\n readonly value = model<T | null>(null);\n\n protected readonly cva = createXValueAccessor<T | null>({\n onWrite: value => this.value.set(value ?? null),\n disabled: this.disabled\n });\n protected readonly isDisabled = this.cva.disabled;\n\n /** Whether the popover has ever been open — so the initial closed state is not \"touched\". */\n private hasOpened = false;\n\n protected readonly open = model(false);\n protected readonly query = signal('');\n /** Whether the user is actively editing (so the input shows the query). */\n private readonly editing = signal(false);\n\n protected readonly optionTemplate = contentChild(XuiSelectOption<T>);\n\n protected readonly list = createXQueryList<T>({\n items: this.items,\n query: this.query,\n itemText: item => this.itemText()(item),\n itemDisabled: item => this.itemDisabled()(item),\n itemListPredicate: createXItemListPredicate({\n itemText: this.itemText,\n itemPredicate: this.itemPredicate\n })\n });\n\n // Keyboard navigation over the filtered list (ArrowDown re-opens the popover).\n private readonly nav = createXActiveOption<T>({\n list: this.list,\n select: item => this.choose(item),\n close: () => this.open.set(false),\n open: () => this.open.set(true)\n });\n\n /** The input shows the live query while editing, else the selected item's text. */\n protected readonly displayValue = computed(() => {\n if (this.editing()) {\n return this.query();\n }\n\n const selected = this.value();\n return selected == null ? '' : this.itemText()(selected);\n });\n\n protected readonly computedClass = computed(() => xui('inline-block', this.class()));\n\n protected readonly inputClass = computed(() =>\n xui(\n 'border-border bg-surface-inset text-foreground placeholder:text-foreground-subtle h-(--control-height-md) w-full min-w-44 rounded-lg border px-(--control-padding-md) text-sm',\n 'focus-visible:border-focus transition-colors focus:outline-none',\n this.isDisabled() && 'cursor-not-allowed opacity-50'\n )\n );\n\n constructor() {\n // Stop editing (revert to the selected item's text) and mark the control\n // touched once the popover closes.\n effect(() => {\n if (this.open()) {\n this.hasOpened = true;\n } else {\n untracked(() => {\n this.editing.set(false);\n this.query.set('');\n if (this.hasOpened) {\n this.cva.markTouched();\n }\n });\n }\n });\n }\n\n protected displayText(item: T): string {\n return this.itemText()(item);\n }\n\n protected readonly trackItem = trackXItem;\n\n protected optionClass(item: T): string {\n return xui(\n 'flex cursor-pointer items-center gap-2 rounded px-2 py-1.5',\n this.list.isActive(item) && 'bg-primary/10',\n item === this.value() && 'text-primary font-medium',\n this.list.isDisabled(item) && 'pointer-events-none opacity-50'\n );\n }\n\n protected onInput(event: Event): void {\n this.editing.set(true);\n this.open.set(true);\n this.query.set((event.target as HTMLInputElement).value);\n this.list.activateFirst();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n this.nav.onKeydown(event);\n }\n\n protected choose(item: T): void {\n if (this.list.isDisabled(item)) {\n return;\n }\n\n this.value.set(item);\n this.cva.notifyChange(item);\n this.open.set(false);\n }\n\n readonly writeValue = this.cva.writeValue;\n readonly registerOnChange = this.cva.registerOnChange;\n readonly registerOnTouched = this.cva.registerOnTouched;\n readonly setDisabledState = this.cva.setDisabledState;\n}\n","import { XuiSuggest } from './lib/suggest';\n\nexport * from './lib/suggest';\n\nexport const XuiSuggestImports = [XuiSuggest] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xui/suggest",
3
- "version": "2.0.0-alpha.20",
3
+ "version": "2.0.0-alpha.21",
4
4
  "description": "Modern Angular 22 UI Library based on TailwindCSS",
5
5
  "keywords": [
6
6
  "angular",
@@ -40,9 +40,9 @@
40
40
  "@angular/common": "22",
41
41
  "@angular/core": "22",
42
42
  "@angular/forms": "22",
43
- "@xui/core": "2.0.0-alpha.20",
44
- "@xui/popover": "2.0.0-alpha.20",
45
- "@xui/select": "2.0.0-alpha.20",
43
+ "@xui/core": "2.0.0-alpha.21",
44
+ "@xui/popover": "2.0.0-alpha.21",
45
+ "@xui/select": "2.0.0-alpha.21",
46
46
  "clsx": "^2.1.1"
47
47
  },
48
48
  "publishConfig": {
@@ -12,13 +12,23 @@ import { ClassValue } from 'clsx';
12
12
  * `xui-select`, there is no separate trigger. `[(value)]` two-way binding.
13
13
  */
14
14
  declare class XuiSuggest<T> implements ControlValueAccessor {
15
+ /** Extra classes, merged into the component's own rather than replacing them. */
15
16
  readonly class: _angular_core.InputSignal<ClassValue>;
17
+ /** The options to search over. */
16
18
  readonly items: _angular_core.InputSignal<readonly T[]>;
19
+ /**
20
+ * How an item is labelled, in both the list and the field once chosen. Also what the default filter matches against.
21
+ */
17
22
  readonly itemText: _angular_core.InputSignal<(item: T) => string>;
23
+ /** Custom filter for one item against the query. Defaults to a case-insensitive substring match on `itemText`. */
18
24
  readonly itemPredicate: _angular_core.InputSignal<((query: string, item: T) => boolean) | undefined>;
25
+ /** Which items cannot be chosen. They stay in the list, greyed out. */
19
26
  readonly itemDisabled: _angular_core.InputSignal<(item: T) => boolean>;
27
+ /** Block interaction and dim the field. */
20
28
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
29
+ /** Text shown in the empty field. */
21
30
  readonly placeholder: _angular_core.InputSignal<string>;
31
+ /** Shown in place of the list when the query matches nothing. */
22
32
  readonly noResultsText: _angular_core.InputSignal<string>;
23
33
  /** The chosen item. Two-way bindable with `[(value)]`, or via `formControl`/`ngModel`. */
24
34
  readonly value: _angular_core.ModelSignal<T | null>;