ng-primitives 0.46.0 → 0.48.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.
Files changed (51) hide show
  1. package/a11y/active-descendant/active-descendant.d.ts +5 -1
  2. package/combobox/combobox/combobox-state.d.ts +1 -1
  3. package/combobox/combobox/combobox.d.ts +1 -1
  4. package/combobox/combobox-button/combobox-button.d.ts +2 -2
  5. package/combobox/combobox-dropdown/combobox-dropdown.d.ts +2 -3
  6. package/combobox/combobox-input/combobox-input.d.ts +2 -6
  7. package/combobox/combobox-option/combobox-option.d.ts +1 -1
  8. package/example-theme/index.css +1 -1
  9. package/fesm2022/ng-primitives-a11y.mjs +32 -10
  10. package/fesm2022/ng-primitives-a11y.mjs.map +1 -1
  11. package/fesm2022/ng-primitives-combobox.mjs +26 -23
  12. package/fesm2022/ng-primitives-combobox.mjs.map +1 -1
  13. package/fesm2022/ng-primitives-file-upload.mjs +6 -1
  14. package/fesm2022/ng-primitives-file-upload.mjs.map +1 -1
  15. package/fesm2022/ng-primitives-input.mjs +4 -1
  16. package/fesm2022/ng-primitives-input.mjs.map +1 -1
  17. package/fesm2022/ng-primitives-internal.mjs +61 -41
  18. package/fesm2022/ng-primitives-internal.mjs.map +1 -1
  19. package/fesm2022/ng-primitives-menu.mjs +39 -42
  20. package/fesm2022/ng-primitives-menu.mjs.map +1 -1
  21. package/fesm2022/ng-primitives-popover.mjs +5 -6
  22. package/fesm2022/ng-primitives-popover.mjs.map +1 -1
  23. package/fesm2022/ng-primitives-portal.mjs +145 -12
  24. package/fesm2022/ng-primitives-portal.mjs.map +1 -1
  25. package/fesm2022/ng-primitives-switch.mjs +7 -6
  26. package/fesm2022/ng-primitives-switch.mjs.map +1 -1
  27. package/fesm2022/ng-primitives-tooltip.mjs +3 -6
  28. package/fesm2022/ng-primitives-tooltip.mjs.map +1 -1
  29. package/file-upload/file-upload/file-upload-state.d.ts +1 -0
  30. package/file-upload/file-upload/file-upload.d.ts +4 -0
  31. package/internal/exit-animation/exit-animation.d.ts +14 -5
  32. package/internal/index.d.ts +1 -1
  33. package/internal/style-injector/style-injector.d.ts +4 -0
  34. package/menu/menu/menu.d.ts +5 -7
  35. package/menu/submenu-trigger/submenu-trigger-state.d.ts +1 -23
  36. package/menu/submenu-trigger/submenu-trigger.d.ts +2 -4
  37. package/package.json +5 -5
  38. package/popover/popover/popover.d.ts +1 -2
  39. package/portal/index.d.ts +1 -0
  40. package/portal/portal.d.ts +2 -0
  41. package/portal/scroll-strategy.d.ts +23 -0
  42. package/schematics/ng-generate/schema.d.ts +1 -0
  43. package/schematics/ng-generate/schema.json +1 -0
  44. package/schematics/ng-generate/templates/combobox/combobox.__fileSuffix@dasherize__.ts.template +16 -20
  45. package/schematics/ng-generate/templates/listbox/listbox.__fileSuffix@dasherize__.ts.template +1 -0
  46. package/schematics/ng-generate/templates/menu/menu-item.__fileSuffix@dasherize__.ts.template +40 -0
  47. package/schematics/ng-generate/templates/menu/menu.__fileSuffix@dasherize__.ts.template +53 -0
  48. package/switch/switch/switch-state.d.ts +1 -1
  49. package/switch/switch/switch.d.ts +2 -3
  50. package/switch/switch-thumb/switch-thumb.d.ts +1 -1
  51. package/tooltip/tooltip/tooltip.d.ts +1 -2
@@ -1,4 +1,4 @@
1
- import { Signal } from '@angular/core';
1
+ import { ElementRef, Signal } from '@angular/core';
2
2
  interface ActiveDescendantManagerOptions<T extends NgpActivatable> {
3
3
  /**
4
4
  * The disabled state of the active descendant group.
@@ -24,6 +24,10 @@ export interface NgpActivatable {
24
24
  * Whether the item is disabled.
25
25
  */
26
26
  disabled?: Signal<boolean>;
27
+ /**
28
+ * The element that represents the item.
29
+ */
30
+ elementRef: ElementRef<HTMLElement>;
27
31
  }
28
32
  export declare function activeDescendantManager<T extends NgpActivatable>(options: ActiveDescendantManagerOptions<T>): {
29
33
  activeDescendant: Signal<string | undefined>;
@@ -40,7 +40,7 @@ export declare const injectComboboxState: <U = {
40
40
  readonly state: import("ng-primitives/state").CreatedState<NgpCombobox>;
41
41
  openDropdown: () => Promise<void>;
42
42
  closeDropdown: () => void;
43
- toggleDropdown: () => void;
43
+ toggleDropdown: () => Promise<void>;
44
44
  selectOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
45
45
  deselectOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
46
46
  toggleOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
@@ -104,7 +104,7 @@ export declare class NgpCombobox {
104
104
  * Toggle the dropdown.
105
105
  * @internal
106
106
  */
107
- toggleDropdown(): void;
107
+ toggleDropdown(): Promise<void>;
108
108
  /**
109
109
  * Select an option.
110
110
  * @param option The option to select.
@@ -31,7 +31,7 @@ export declare class NgpComboboxButton {
31
31
  readonly state: import("ng-primitives/state").CreatedState<import("ng-primitives/combobox").NgpCombobox>;
32
32
  openDropdown: () => Promise<void>;
33
33
  closeDropdown: () => void;
34
- toggleDropdown: () => void;
34
+ toggleDropdown: () => Promise<void>;
35
35
  selectOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
36
36
  deselectOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
37
37
  toggleOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
@@ -55,7 +55,7 @@ export declare class NgpComboboxButton {
55
55
  /** The id of the dropdown. */
56
56
  readonly dropdownId: import("@angular/core").Signal<string | undefined>;
57
57
  constructor();
58
- protected toggleDropdown(): void;
58
+ protected toggleDropdown(): Promise<void>;
59
59
  static ɵfac: i0.ɵɵFactoryDeclaration<NgpComboboxButton, never>;
60
60
  static ɵdir: i0.ɵɵDirectiveDeclaration<NgpComboboxButton, "[ngpComboboxButton]", ["ngpComboboxButton"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
61
61
  }
@@ -1,5 +1,4 @@
1
1
  import * as i0 from "@angular/core";
2
- import * as i1 from "ng-primitives/internal";
3
2
  export declare class NgpComboboxDropdown {
4
3
  /** Access the combobox state. */
5
4
  protected readonly state: import("@angular/core").Signal<import("ng-primitives/state").State<{
@@ -32,7 +31,7 @@ export declare class NgpComboboxDropdown {
32
31
  readonly state: import("ng-primitives/state").CreatedState<import("ng-primitives/combobox").NgpCombobox>;
33
32
  openDropdown: () => Promise<void>;
34
33
  closeDropdown: () => void;
35
- toggleDropdown: () => void;
34
+ toggleDropdown: () => Promise<void>;
36
35
  selectOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
37
36
  deselectOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
38
37
  toggleOption: (option: import("ng-primitives/combobox").NgpComboboxOption) => void;
@@ -61,5 +60,5 @@ export declare class NgpComboboxDropdown {
61
60
  readonly id: import("@angular/core").InputSignal<string>;
62
61
  constructor();
63
62
  static ɵfac: i0.ɵɵFactoryDeclaration<NgpComboboxDropdown, never>;
64
- static ɵdir: i0.ɵɵDirectiveDeclaration<NgpComboboxDropdown, "[ngpComboboxDropdown]", ["ngpComboboxDropdown"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.NgpExitAnimation; inputs: {}; outputs: {}; }]>;
63
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NgpComboboxDropdown, "[ngpComboboxDropdown]", ["ngpComboboxDropdown"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
65
64
  }
@@ -32,7 +32,7 @@ export declare class NgpComboboxInput {
32
32
  readonly state: import("ng-primitives/state").CreatedState<import("ng-primitives/combobox").NgpCombobox>;
33
33
  openDropdown: () => Promise<void>;
34
34
  closeDropdown: () => void;
35
- toggleDropdown: () => void;
35
+ toggleDropdown: () => Promise<void>;
36
36
  selectOption: (option: NgpComboboxOption) => void;
37
37
  deselectOption: (option: NgpComboboxOption) => void;
38
38
  toggleOption: (option: NgpComboboxOption) => void;
@@ -53,10 +53,6 @@ export declare class NgpComboboxInput {
53
53
  readonly elementRef: import("@angular/core").ElementRef<HTMLInputElement>;
54
54
  /** The id of the input. */
55
55
  readonly id: import("@angular/core").InputSignal<string>;
56
- /**
57
- * Extract the string representation of the value.
58
- */
59
- readonly displayWith: import("@angular/core").InputSignal<(value: any) => string>;
60
56
  /** The id of the dropdown. */
61
57
  readonly dropdownId: import("@angular/core").Signal<string | undefined>;
62
58
  /** The id of the active descendant. */
@@ -75,5 +71,5 @@ export declare class NgpComboboxInput {
75
71
  protected highlightText(): void;
76
72
  protected handlePointerDown(): void;
77
73
  static ɵfac: i0.ɵɵFactoryDeclaration<NgpComboboxInput, never>;
78
- static ɵdir: i0.ɵɵDirectiveDeclaration<NgpComboboxInput, "input[ngpComboboxInput]", ["ngpComboboxInput"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
74
+ static ɵdir: i0.ɵɵDirectiveDeclaration<NgpComboboxInput, "input[ngpComboboxInput]", ["ngpComboboxInput"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
79
75
  }
@@ -34,7 +34,7 @@ export declare class NgpComboboxOption implements OnInit, OnDestroy, NgpActivata
34
34
  readonly state: import("ng-primitives/state").CreatedState<import("ng-primitives/combobox").NgpCombobox>;
35
35
  openDropdown: () => Promise<void>;
36
36
  closeDropdown: () => void;
37
- toggleDropdown: () => void;
37
+ toggleDropdown: () => Promise<void>;
38
38
  selectOption: (option: NgpComboboxOption) => void;
39
39
  deselectOption: (option: NgpComboboxOption) => void;
40
40
  toggleOption: (option: NgpComboboxOption) => void;
@@ -26,7 +26,7 @@
26
26
  --ngp-background-blue: #dbeafe;
27
27
  --ngp-background-success: oklch(84.1% 0.238 128.85);
28
28
 
29
- --ngp-border: var(--ngp-gray-200);
29
+ --ngp-border: rgba(0, 0, 0, 0.1);
30
30
  --ngp-border-secondary: var(--ngp-gray-300);
31
31
  --ngp-border-blue: #3b82f6;
32
32
  --ngp-border-inverse: var(--ngp-black);
@@ -1,11 +1,34 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, Directive } from '@angular/core';
2
+ import { signal, computed, effect, Directive } from '@angular/core';
3
3
  import { createStateToken, createStateProvider, createStateInjector, createState } from 'ng-primitives/state';
4
4
 
5
5
  function activeDescendantManager(options) {
6
+ const sortedOptions = () => options
7
+ .items()
8
+ .slice()
9
+ .sort((a, b) => {
10
+ const aElement = a.elementRef.nativeElement;
11
+ const bElement = b.elementRef.nativeElement;
12
+ return aElement.compareDocumentPosition(bElement) & Node.DOCUMENT_POSITION_FOLLOWING
13
+ ? -1
14
+ : 1;
15
+ });
6
16
  const activeIndex = signal(0);
7
- const activeItem = computed(() => options.items()?.[activeIndex()]);
17
+ const activeItem = computed(() => sortedOptions()?.[activeIndex()]);
8
18
  const disabled = computed(() => options.disabled?.() || options.items().every(item => item.disabled?.()));
19
+ // any time the item list changes, check if the active index is still valid
20
+ effect(() => {
21
+ const items = sortedOptions();
22
+ if (activeIndex() >= items.length || activeIndex() < 0) {
23
+ activeIndex.set(items.findIndex(item => !item.disabled?.()));
24
+ }
25
+ if (activeIndex() === -1 && items.length > 0) {
26
+ activeIndex.set(0);
27
+ }
28
+ if (disabled() || items.length === 0) {
29
+ activeIndex.set(-1);
30
+ }
31
+ });
9
32
  const activeDescendant = computed(() => {
10
33
  const item = activeItem();
11
34
  if (disabled() || !item) {
@@ -18,20 +41,20 @@ function activeDescendantManager(options) {
18
41
  * @param item The item to activate.
19
42
  */
20
43
  const activate = (item) => {
21
- if (!item) {
44
+ if (item === undefined) {
22
45
  activeIndex.set(-1);
23
46
  return;
24
47
  }
25
48
  if (disabled() || item.disabled?.()) {
26
49
  return;
27
50
  }
28
- activeIndex.set(options.items().indexOf(item));
51
+ activeIndex.set(sortedOptions().indexOf(item));
29
52
  };
30
53
  /**
31
54
  * Activate the first enabled item in the active descendant group.
32
55
  */
33
56
  const first = () => {
34
- const item = options.items().findIndex(item => !item.disabled?.());
57
+ const item = sortedOptions().findIndex(item => !item.disabled?.());
35
58
  if (item) {
36
59
  activeIndex.set(item);
37
60
  }
@@ -40,12 +63,11 @@ function activeDescendantManager(options) {
40
63
  * Activate the last enabled item in the active descendant group.
41
64
  */
42
65
  const last = () => {
43
- const item = options
44
- .items()
66
+ const item = sortedOptions()
45
67
  .reverse()
46
68
  .findIndex(item => !item.disabled?.());
47
69
  if (item !== -1) {
48
- activeIndex.set(options.items().length - 1 - item);
70
+ activeIndex.set(sortedOptions().length - 1 - item);
49
71
  }
50
72
  };
51
73
  const findNextIndex = (items, currentIndex, direction, wrap) => {
@@ -67,7 +89,7 @@ function activeDescendantManager(options) {
67
89
  * Activate the next enabled item in the active descendant group.
68
90
  */
69
91
  const next = () => {
70
- const items = options.items();
92
+ const items = sortedOptions();
71
93
  const nextIndex = findNextIndex(items, activeIndex(), 1, options.wrap?.() ?? false);
72
94
  if (nextIndex !== undefined) {
73
95
  activeIndex.set(nextIndex);
@@ -77,7 +99,7 @@ function activeDescendantManager(options) {
77
99
  * Activate the previous enabled item in the active descendant group.
78
100
  */
79
101
  const previous = () => {
80
- const items = options.items();
102
+ const items = sortedOptions();
81
103
  const prevIndex = findNextIndex(items, activeIndex(), -1, options.wrap?.() ?? false);
82
104
  if (prevIndex !== undefined) {
83
105
  activeIndex.set(prevIndex);
@@ -1 +1 @@
1
- {"version":3,"file":"ng-primitives-a11y.mjs","sources":["../../../../packages/ng-primitives/a11y/src/active-descendant/active-descendant.ts","../../../../packages/ng-primitives/a11y/src/visually-hidden/visually-hidden-state.ts","../../../../packages/ng-primitives/a11y/src/visually-hidden/visually-hidden.ts","../../../../packages/ng-primitives/a11y/src/ng-primitives-a11y.ts"],"sourcesContent":["import { computed, Signal, signal } from '@angular/core';\n\ninterface ActiveDescendantManagerOptions<T extends NgpActivatable> {\n /**\n * The disabled state of the active descendant group.\n * @default false\n */\n disabled?: Signal<boolean>;\n /**\n * The items in the active descendant group.\n */\n items: Signal<T[]>;\n /**\n * Whether active descendant should wrap around.\n * @default false\n */\n wrap?: Signal<boolean>;\n}\n\nexport interface NgpActivatable {\n /**\n * The id of the item.\n */\n id: Signal<string>;\n /**\n * Whether the item is disabled.\n */\n disabled?: Signal<boolean>;\n}\n\nexport function activeDescendantManager<T extends NgpActivatable>(\n options: ActiveDescendantManagerOptions<T>,\n) {\n const activeIndex = signal<number>(0);\n const activeItem = computed<T | undefined>(() => options.items()?.[activeIndex()]);\n const disabled = computed(\n () => options.disabled?.() || options.items().every(item => item.disabled?.()),\n );\n\n const activeDescendant = computed(() => {\n const item = activeItem();\n\n if (disabled() || !item) {\n return undefined;\n }\n\n return item.id();\n });\n\n /**\n * Activate an item in the active descendant group.\n * @param item The item to activate.\n */\n const activate = (item: T | undefined) => {\n if (!item) {\n activeIndex.set(-1);\n return;\n }\n\n if (disabled() || item.disabled?.()) {\n return;\n }\n\n activeIndex.set(options.items().indexOf(item));\n };\n\n /**\n * Activate the first enabled item in the active descendant group.\n */\n const first = () => {\n const item = options.items().findIndex(item => !item.disabled?.());\n\n if (item) {\n activeIndex.set(item);\n }\n };\n\n /**\n * Activate the last enabled item in the active descendant group.\n */\n const last = () => {\n const item = options\n .items()\n .reverse()\n .findIndex(item => !item.disabled?.());\n\n if (item !== -1) {\n activeIndex.set(options.items().length - 1 - item);\n }\n };\n\n const findNextIndex = (\n items: NgpActivatable[],\n currentIndex: number,\n direction: 1 | -1,\n wrap: boolean,\n ): number | undefined => {\n let index = (currentIndex + direction + items.length) % items.length;\n\n while (index !== currentIndex) {\n const item = items[index];\n if (item && !item.disabled?.()) {\n return index;\n }\n index = (index + direction + items.length) % items.length;\n\n if (\n !wrap &&\n ((direction === 1 && index === 0) || (direction === -1 && index === items.length - 1))\n ) {\n break;\n }\n }\n\n return undefined;\n };\n\n /**\n * Activate the next enabled item in the active descendant group.\n */\n const next = () => {\n const items = options.items();\n const nextIndex = findNextIndex(items, activeIndex(), 1, options.wrap?.() ?? false);\n\n if (nextIndex !== undefined) {\n activeIndex.set(nextIndex);\n }\n };\n\n /**\n * Activate the previous enabled item in the active descendant group.\n */\n const previous = () => {\n const items = options.items();\n const prevIndex = findNextIndex(items, activeIndex(), -1, options.wrap?.() ?? false);\n\n if (prevIndex !== undefined) {\n activeIndex.set(prevIndex);\n }\n };\n\n /**\n * Reset the active descendant group, clearing the active index.\n */\n const reset = () => {\n activeIndex.set(-1);\n };\n\n return {\n activeDescendant,\n activeItem,\n activate,\n first,\n last,\n next,\n previous,\n reset,\n };\n}\n","import {\n createState,\n createStateInjector,\n createStateProvider,\n createStateToken,\n} from 'ng-primitives/state';\nimport type { NgpVisuallyHidden } from './visually-hidden';\n\n/**\n * The state token for the VisuallyHidden primitive.\n */\nexport const NgpVisuallyHiddenStateToken = createStateToken<NgpVisuallyHidden>('VisuallyHidden');\n\n/**\n * Provides the VisuallyHidden state.\n */\nexport const provideVisuallyHiddenState = createStateProvider(NgpVisuallyHiddenStateToken);\n\n/**\n * Injects the VisuallyHidden state.\n */\nexport const injectVisuallyHiddenState = createStateInjector(NgpVisuallyHiddenStateToken);\n\n/**\n * The VisuallyHidden state registration function.\n */\nexport const visuallyHiddenState = createState(NgpVisuallyHiddenStateToken);\n","import { Directive, computed, signal } from '@angular/core';\nimport { provideVisuallyHiddenState, visuallyHiddenState } from './visually-hidden-state';\n\n/**\n * Hide an element visually while keeping it present in the DOM.\n */\n@Directive({\n selector: '[ngpVisuallyHidden]',\n exportAs: 'ngpVisuallyHidden',\n providers: [provideVisuallyHiddenState()],\n host: {\n '[style]': 'style()',\n },\n})\nexport class NgpVisuallyHidden {\n /**\n * Whether the element is hidden.\n */\n protected readonly hidden = signal<boolean>(true);\n\n protected readonly style = computed(() => {\n if (!this.hidden()) {\n return {};\n }\n\n return {\n position: 'absolute',\n width: '1px',\n height: '1px',\n margin: '-1px',\n padding: '0',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: '0',\n wordWrap: 'normal',\n outline: '0',\n '-webkit-appearance': 'none',\n '-moz-appearance': 'none',\n 'inset-inline-start': '0',\n };\n });\n\n protected readonly state = visuallyHiddenState<NgpVisuallyHidden>(this);\n\n /**\n * Set the element visibility.\n * @param visible\n */\n setVisibility(visible: boolean): void {\n this.hidden.set(!visible);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-primitives-a11y.mjs","sources":["../../../../packages/ng-primitives/a11y/src/active-descendant/active-descendant.ts","../../../../packages/ng-primitives/a11y/src/visually-hidden/visually-hidden-state.ts","../../../../packages/ng-primitives/a11y/src/visually-hidden/visually-hidden.ts","../../../../packages/ng-primitives/a11y/src/ng-primitives-a11y.ts"],"sourcesContent":["import { computed, effect, ElementRef, Signal, signal } from '@angular/core';\n\ninterface ActiveDescendantManagerOptions<T extends NgpActivatable> {\n /**\n * The disabled state of the active descendant group.\n * @default false\n */\n disabled?: Signal<boolean>;\n /**\n * The items in the active descendant group.\n */\n items: Signal<T[]>;\n /**\n * Whether active descendant should wrap around.\n * @default false\n */\n wrap?: Signal<boolean>;\n}\n\nexport interface NgpActivatable {\n /**\n * The id of the item.\n */\n id: Signal<string>;\n /**\n * Whether the item is disabled.\n */\n disabled?: Signal<boolean>;\n /**\n * The element that represents the item.\n */\n elementRef: ElementRef<HTMLElement>;\n}\n\nexport function activeDescendantManager<T extends NgpActivatable>(\n options: ActiveDescendantManagerOptions<T>,\n) {\n const sortedOptions = () =>\n options\n .items()\n .slice()\n .sort((a, b) => {\n const aElement = a.elementRef.nativeElement;\n const bElement = b.elementRef.nativeElement;\n return aElement.compareDocumentPosition(bElement) & Node.DOCUMENT_POSITION_FOLLOWING\n ? -1\n : 1;\n });\n\n const activeIndex = signal<number>(0);\n const activeItem = computed<T | undefined>(() => sortedOptions()?.[activeIndex()]);\n const disabled = computed(\n () => options.disabled?.() || options.items().every(item => item.disabled?.()),\n );\n\n // any time the item list changes, check if the active index is still valid\n effect(() => {\n const items = sortedOptions();\n if (activeIndex() >= items.length || activeIndex() < 0) {\n activeIndex.set(items.findIndex(item => !item.disabled?.()));\n }\n if (activeIndex() === -1 && items.length > 0) {\n activeIndex.set(0);\n }\n if (disabled() || items.length === 0) {\n activeIndex.set(-1);\n }\n });\n\n const activeDescendant = computed(() => {\n const item = activeItem();\n\n if (disabled() || !item) {\n return undefined;\n }\n\n return item.id();\n });\n\n /**\n * Activate an item in the active descendant group.\n * @param item The item to activate.\n */\n const activate = (item: T | undefined) => {\n if (item === undefined) {\n activeIndex.set(-1);\n return;\n }\n\n if (disabled() || item.disabled?.()) {\n return;\n }\n\n activeIndex.set(sortedOptions().indexOf(item));\n };\n\n /**\n * Activate the first enabled item in the active descendant group.\n */\n const first = () => {\n const item = sortedOptions().findIndex(item => !item.disabled?.());\n\n if (item) {\n activeIndex.set(item);\n }\n };\n\n /**\n * Activate the last enabled item in the active descendant group.\n */\n const last = () => {\n const item = sortedOptions()\n .reverse()\n .findIndex(item => !item.disabled?.());\n\n if (item !== -1) {\n activeIndex.set(sortedOptions().length - 1 - item);\n }\n };\n\n const findNextIndex = (\n items: NgpActivatable[],\n currentIndex: number,\n direction: 1 | -1,\n wrap: boolean,\n ): number | undefined => {\n let index = (currentIndex + direction + items.length) % items.length;\n\n while (index !== currentIndex) {\n const item = items[index];\n if (item && !item.disabled?.()) {\n return index;\n }\n index = (index + direction + items.length) % items.length;\n\n if (\n !wrap &&\n ((direction === 1 && index === 0) || (direction === -1 && index === items.length - 1))\n ) {\n break;\n }\n }\n\n return undefined;\n };\n\n /**\n * Activate the next enabled item in the active descendant group.\n */\n const next = () => {\n const items = sortedOptions();\n const nextIndex = findNextIndex(items, activeIndex(), 1, options.wrap?.() ?? false);\n\n if (nextIndex !== undefined) {\n activeIndex.set(nextIndex);\n }\n };\n\n /**\n * Activate the previous enabled item in the active descendant group.\n */\n const previous = () => {\n const items = sortedOptions();\n const prevIndex = findNextIndex(items, activeIndex(), -1, options.wrap?.() ?? false);\n\n if (prevIndex !== undefined) {\n activeIndex.set(prevIndex);\n }\n };\n\n /**\n * Reset the active descendant group, clearing the active index.\n */\n const reset = () => {\n activeIndex.set(-1);\n };\n\n return {\n activeDescendant,\n activeItem,\n activate,\n first,\n last,\n next,\n previous,\n reset,\n };\n}\n","import {\n createState,\n createStateInjector,\n createStateProvider,\n createStateToken,\n} from 'ng-primitives/state';\nimport type { NgpVisuallyHidden } from './visually-hidden';\n\n/**\n * The state token for the VisuallyHidden primitive.\n */\nexport const NgpVisuallyHiddenStateToken = createStateToken<NgpVisuallyHidden>('VisuallyHidden');\n\n/**\n * Provides the VisuallyHidden state.\n */\nexport const provideVisuallyHiddenState = createStateProvider(NgpVisuallyHiddenStateToken);\n\n/**\n * Injects the VisuallyHidden state.\n */\nexport const injectVisuallyHiddenState = createStateInjector(NgpVisuallyHiddenStateToken);\n\n/**\n * The VisuallyHidden state registration function.\n */\nexport const visuallyHiddenState = createState(NgpVisuallyHiddenStateToken);\n","import { Directive, computed, signal } from '@angular/core';\nimport { provideVisuallyHiddenState, visuallyHiddenState } from './visually-hidden-state';\n\n/**\n * Hide an element visually while keeping it present in the DOM.\n */\n@Directive({\n selector: '[ngpVisuallyHidden]',\n exportAs: 'ngpVisuallyHidden',\n providers: [provideVisuallyHiddenState()],\n host: {\n '[style]': 'style()',\n },\n})\nexport class NgpVisuallyHidden {\n /**\n * Whether the element is hidden.\n */\n protected readonly hidden = signal<boolean>(true);\n\n protected readonly style = computed(() => {\n if (!this.hidden()) {\n return {};\n }\n\n return {\n position: 'absolute',\n width: '1px',\n height: '1px',\n margin: '-1px',\n padding: '0',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: '0',\n wordWrap: 'normal',\n outline: '0',\n '-webkit-appearance': 'none',\n '-moz-appearance': 'none',\n 'inset-inline-start': '0',\n };\n });\n\n protected readonly state = visuallyHiddenState<NgpVisuallyHidden>(this);\n\n /**\n * Set the element visibility.\n * @param visible\n */\n setVisibility(visible: boolean): void {\n this.hidden.set(!visible);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, Directive, computed, HostListener, booleanAttribute, inject, ViewContainerRef, TemplateRef, Injector, signal, output, afterNextRender } from '@angular/core';
3
- import * as i1 from 'ng-primitives/internal';
4
- import { injectElementRef, NgpExitAnimation, setupInteractions, explicitEffect, provideExitAnimationManager } from 'ng-primitives/internal';
2
+ import { input, Directive, computed, HostListener, booleanAttribute, inject, ViewContainerRef, TemplateRef, Injector, signal, output, afterRenderEffect } from '@angular/core';
3
+ import { injectElementRef, setupInteractions } from 'ng-primitives/internal';
5
4
  import { observeResize } from 'ng-primitives/resize';
6
5
  import { uniqueId } from 'ng-primitives/utils';
7
6
  import { createStateToken, createStateProvider, createStateInjector, createState } from 'ng-primitives/state';
@@ -45,14 +44,13 @@ class NgpComboboxDropdown {
45
44
  this.state().registerDropdown(this);
46
45
  }
47
46
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpComboboxDropdown, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
48
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpComboboxDropdown, isStandalone: true, selector: "[ngpComboboxDropdown]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "listbox" }, properties: { "id": "id()", "style.left.px": "state().overlay()?.position()?.x", "style.top.px": "state().overlay()?.position()?.y", "style.--ngp-combobox-transform-origin": "state().overlay()?.transformOrigin()", "style.--ngp-combobox-width.px": "comboboxDimensions().width", "style.--ngp-combobox-input-width.px": "inputDimensions().width", "style.--ngp-combobox-button-width.px": "buttonDimensions().width" } }, exportAs: ["ngpComboboxDropdown"], hostDirectives: [{ directive: i1.NgpExitAnimation }], ngImport: i0 }); }
47
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpComboboxDropdown, isStandalone: true, selector: "[ngpComboboxDropdown]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "listbox" }, properties: { "id": "id()", "style.left.px": "state().overlay()?.position()?.x", "style.top.px": "state().overlay()?.position()?.y", "style.--ngp-combobox-transform-origin": "state().overlay()?.transformOrigin()", "style.--ngp-combobox-width.px": "comboboxDimensions().width", "style.--ngp-combobox-input-width.px": "inputDimensions().width", "style.--ngp-combobox-button-width.px": "buttonDimensions().width" } }, exportAs: ["ngpComboboxDropdown"], ngImport: i0 }); }
49
48
  }
50
49
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpComboboxDropdown, decorators: [{
51
50
  type: Directive,
52
51
  args: [{
53
52
  selector: '[ngpComboboxDropdown]',
54
53
  exportAs: 'ngpComboboxDropdown',
55
- hostDirectives: [NgpExitAnimation],
56
54
  host: {
57
55
  role: 'listbox',
58
56
  '[id]': 'id()',
@@ -77,15 +75,6 @@ class NgpComboboxInput {
77
75
  this.elementRef = injectElementRef();
78
76
  /** The id of the input. */
79
77
  this.id = input(uniqueId('ngp-combobox-input'));
80
- /**
81
- * Extract the string representation of the value.
82
- */
83
- this.displayWith = input((value) => {
84
- if (typeof value === 'string') {
85
- return value;
86
- }
87
- throw new Error('You must provide a displayWith function for non-string values');
88
- });
89
78
  /** The id of the dropdown. */
90
79
  this.dropdownId = computed(() => this.state().dropdown()?.id());
91
80
  /** The id of the active descendant. */
@@ -144,6 +133,12 @@ class NgpComboboxInput {
144
133
  this.state().closeDropdown();
145
134
  event.preventDefault();
146
135
  break;
136
+ case 'Backspace':
137
+ // if the input is not empty then open the dropdown
138
+ if (this.elementRef.nativeElement.value.length > 0) {
139
+ this.state().openDropdown();
140
+ }
141
+ break;
147
142
  default:
148
143
  // Ignore keys with length > 1 (e.g., 'Shift', 'ArrowLeft', 'Enter', etc.)
149
144
  // Filter out control/meta key combos (e.g., Ctrl+C)
@@ -187,7 +182,7 @@ class NgpComboboxInput {
187
182
  this.pointerFocused = true;
188
183
  }
189
184
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpComboboxInput, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
190
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpComboboxInput, isStandalone: true, selector: "input[ngpComboboxInput]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "combobox", "type": "text", "autocomplete": "off", "autocorrect": "off", "spellcheck": "false", "aria-haspopup": "listbox", "aria-autocomplete": "list" }, listeners: { "keydown": "handleKeydown($event)", "blur": "closeDropdown($event)", "focus": "highlightText($event)", "pointerdown": "handlePointerDown($event)" }, properties: { "id": "id()", "attr.aria-controls": "state().open() ? dropdownId() : undefined", "attr.aria-expanded": "state().open()", "attr.data-open": "state().open() ? \"\" : undefined", "attr.data-disabled": "state().disabled() ? \"\" : undefined", "attr.data-multiple": "state().multiple() ? \"\" : undefined", "attr.aria-activedescendant": "activeDescendant()", "disabled": "state().disabled()" } }, exportAs: ["ngpComboboxInput"], ngImport: i0 }); }
185
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpComboboxInput, isStandalone: true, selector: "input[ngpComboboxInput]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "combobox", "type": "text", "autocomplete": "off", "autocorrect": "off", "spellcheck": "false", "aria-haspopup": "listbox", "aria-autocomplete": "list" }, listeners: { "keydown": "handleKeydown($event)", "blur": "closeDropdown($event)", "focus": "highlightText($event)", "pointerdown": "handlePointerDown($event)" }, properties: { "id": "id()", "attr.aria-controls": "state().open() ? dropdownId() : undefined", "attr.aria-expanded": "state().open()", "attr.data-open": "state().open() ? \"\" : undefined", "attr.data-disabled": "state().disabled() ? \"\" : undefined", "attr.data-multiple": "state().multiple() ? \"\" : undefined", "attr.aria-activedescendant": "activeDescendant()", "disabled": "state().disabled()" } }, exportAs: ["ngpComboboxInput"], ngImport: i0 }); }
191
186
  }
192
187
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpComboboxInput, decorators: [{
193
188
  type: Directive,
@@ -487,10 +482,11 @@ class NgpCombobox {
487
482
  /** The state of the combobox. */
488
483
  this.state = comboboxState(this);
489
484
  // any time the active descendant changes, ensure we scroll it into view
490
- explicitEffect([this.activeDescendantManager.activeItem], ([option]) =>
491
485
  // perform after next render to ensure the DOM is updated
492
486
  // e.g. the dropdown is open before the option is scrolled into view
493
- afterNextRender({ write: () => option?.scrollIntoView?.() }, { injector: this.injector }));
487
+ afterRenderEffect({
488
+ write: () => this.activeDescendantManager.activeItem()?.scrollIntoView?.(),
489
+ });
494
490
  }
495
491
  /**
496
492
  * Open the dropdown.
@@ -529,12 +525,12 @@ class NgpCombobox {
529
525
  * Toggle the dropdown.
530
526
  * @internal
531
527
  */
532
- toggleDropdown() {
528
+ async toggleDropdown() {
533
529
  if (this.open()) {
534
530
  this.closeDropdown();
535
531
  }
536
532
  else {
537
- this.openDropdown();
533
+ await this.openDropdown();
538
534
  }
539
535
  }
540
536
  /**
@@ -589,6 +585,13 @@ class NgpCombobox {
589
585
  if (this.state.disabled()) {
590
586
  return;
591
587
  }
588
+ // if the state is single selection, we don't allow toggling
589
+ if (!this.state.multiple()) {
590
+ // always select the option in single selection mode even if it is already selected so that we update the input
591
+ this.selectOption(option);
592
+ return;
593
+ }
594
+ // otherwise toggle the option
592
595
  if (this.isOptionSelected(option)) {
593
596
  this.deselectOption(option);
594
597
  }
@@ -712,14 +715,14 @@ class NgpCombobox {
712
715
  this.options.update(options => options.filter(o => o !== option));
713
716
  }
714
717
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpCombobox, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
715
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpCombobox, isStandalone: true, selector: "[ngpCombobox]", inputs: { value: { classPropertyName: "value", publicName: "ngpComboboxValue", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "ngpComboboxMultiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpComboboxDisabled", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "ngpComboboxCompareWith", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "ngpComboboxDropdownPlacement", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "ngpComboboxValueChange", openChange: "ngpComboboxOpenChange" }, host: { properties: { "attr.data-open": "state.open() ? \"\" : undefined", "attr.data-disabled": "state.disabled() ? \"\" : undefined", "attr.data-multiple": "state.multiple() ? \"\" : undefined" } }, providers: [provideComboboxState(), provideExitAnimationManager()], exportAs: ["ngpCombobox"], ngImport: i0 }); }
718
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.11", type: NgpCombobox, isStandalone: true, selector: "[ngpCombobox]", inputs: { value: { classPropertyName: "value", publicName: "ngpComboboxValue", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "ngpComboboxMultiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpComboboxDisabled", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "ngpComboboxCompareWith", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "ngpComboboxDropdownPlacement", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "ngpComboboxValueChange", openChange: "ngpComboboxOpenChange" }, host: { properties: { "attr.data-open": "state.open() ? \"\" : undefined", "attr.data-disabled": "state.disabled() ? \"\" : undefined", "attr.data-multiple": "state.multiple() ? \"\" : undefined" } }, providers: [provideComboboxState()], exportAs: ["ngpCombobox"], ngImport: i0 }); }
716
719
  }
717
720
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpCombobox, decorators: [{
718
721
  type: Directive,
719
722
  args: [{
720
723
  selector: '[ngpCombobox]',
721
724
  exportAs: 'ngpCombobox',
722
- providers: [provideComboboxState(), provideExitAnimationManager()],
725
+ providers: [provideComboboxState()],
723
726
  host: {
724
727
  '[attr.data-open]': 'state.open() ? "" : undefined',
725
728
  '[attr.data-disabled]': 'state.disabled() ? "" : undefined',
@@ -748,8 +751,8 @@ class NgpComboboxButton {
748
751
  });
749
752
  this.state().registerButton(this);
750
753
  }
751
- toggleDropdown() {
752
- this.state().toggleDropdown();
754
+ async toggleDropdown() {
755
+ await this.state().toggleDropdown();
753
756
  this.state().input()?.focus();
754
757
  }
755
758
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.11", ngImport: i0, type: NgpComboboxButton, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }