forge-select 0.1.0 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -10,6 +10,11 @@ interface Option {
10
10
  description?: string;
11
11
  /** Arbitrary payload for custom templates; ForgeSelect never reads it. */
12
12
  meta?: Record<string, unknown>;
13
+ /**
14
+ * Nested options, making this a tree node. Purely additive: lists where
15
+ * no option has `children` render and behave exactly as a flat list.
16
+ */
17
+ children?: Option[];
13
18
  }
14
19
  interface OptionGroup {
15
20
  label: string;
@@ -17,11 +22,24 @@ interface OptionGroup {
17
22
  }
18
23
  type DataItem = Option | OptionGroup;
19
24
  interface AjaxConfig {
20
- url: string | ((query: string) => string);
21
- params?: (query: string) => Record<string, unknown>;
25
+ url: string | ((query: string, page: number) => string);
26
+ params?: (query: string, page: number) => Record<string, unknown>;
22
27
  /** Debounce in milliseconds. Default 250. */
23
28
  debounce?: number;
24
- transform?: (response: unknown) => Option[];
29
+ /**
30
+ * Opt in to loading additional pages as the user scrolls near the bottom
31
+ * of the dropdown, instead of only reloading on search. Default false.
32
+ */
33
+ pagination?: boolean;
34
+ /**
35
+ * Return a plain array (page-replace behavior, unchanged from before
36
+ * `pagination` existed) or `{ options, hasMore }` so ForgeSelect knows
37
+ * whether to keep requesting further pages when `pagination` is true.
38
+ */
39
+ transform?: (response: unknown) => Option[] | {
40
+ options: Option[];
41
+ hasMore: boolean;
42
+ };
25
43
  }
26
44
  interface ForgeSelectPlugin {
27
45
  name: string;
@@ -37,6 +55,13 @@ interface ForgeSelectOptions {
37
55
  multiple?: boolean;
38
56
  clearable?: boolean;
39
57
  allowCreate?: boolean;
58
+ /**
59
+ * Let the user reorder selected tags by dragging them (mouse/touch/pen via
60
+ * Pointer Events), or via Alt+Left/Alt+Right when a tag has focus. Only
61
+ * meaningful when `multiple` is true. Default false — existing multi-select
62
+ * behavior and tag markup are unchanged when this is left off.
63
+ */
64
+ sortable?: boolean;
40
65
  theme?: string;
41
66
  disabled?: boolean;
42
67
  data?: DataItem[];
@@ -54,7 +79,11 @@ interface ForgeSelectOptions {
54
79
  plugins?: ForgeSelectPlugin[];
55
80
  }
56
81
  type ForgeSelectValue = string | string[] | null;
57
- type ForgeSelectEvent = "change" | "open" | "close" | "search" | "clear";
82
+ interface SetValueOptions {
83
+ /** Emit Forge Select's `change` event after updating. Default true. */
84
+ emitChange?: boolean;
85
+ }
86
+ type ForgeSelectEvent = "change" | "open" | "close" | "search" | "clear" | "error";
58
87
 
59
88
  declare class ForgeSelect {
60
89
  /** The original element ForgeSelect was mounted on. */
@@ -64,6 +93,7 @@ declare class ForgeSelect {
64
93
  private data;
65
94
  private selected;
66
95
  private selectedOptions;
96
+ private suppressNextTagClick;
67
97
  private emitter;
68
98
  private plugins;
69
99
  private uid;
@@ -74,6 +104,7 @@ declare class ForgeSelect {
74
104
  private dropdown;
75
105
  private searchInput;
76
106
  private list;
107
+ private liveRegion;
77
108
  private isOpen;
78
109
  private isDisabled;
79
110
  private destroyed;
@@ -82,26 +113,56 @@ declare class ForgeSelect {
82
113
  private navItems;
83
114
  private highlightedIndex;
84
115
  private rowContentCache;
116
+ private expandedValues;
85
117
  private loading;
118
+ private loadingMore;
119
+ private page;
120
+ private hasMore;
86
121
  private ajaxTimer;
87
122
  private ajaxRequestId;
123
+ private ajaxController;
88
124
  private remoteLoaded;
125
+ private loadError;
126
+ private originalDisplay;
127
+ private originalDisabled;
128
+ private nativeSelect;
129
+ private nativeForm;
130
+ private syncingNative;
89
131
  private onDocumentMouseDown;
132
+ private onNativeChange;
133
+ private applyNativeValues;
134
+ private onFormReset;
90
135
  constructor(target: string | HTMLElement, options?: ForgeSelectOptions);
91
136
  open(): void;
92
137
  close(): void;
93
138
  destroy(): void;
94
139
  getValue(): ForgeSelectValue;
95
- setValue(value: ForgeSelectValue): void;
140
+ setValue(value: ForgeSelectValue, options?: SetValueOptions): void;
96
141
  enable(): void;
97
142
  disable(): void;
98
143
  on(event: ForgeSelectEvent, handler: Handler): void;
99
144
  off(event: ForgeSelectEvent, handler: Handler): void;
145
+ /**
146
+ * The original target (a hidden native <select> or a plain mount div) can
147
+ * carry an accessible name via aria-label/aria-labelledby, or via a
148
+ * <label for> pointing at its id — but once `this.el` is display:none it
149
+ * drops out of the accessibility tree, so any such association silently
150
+ * stops reaching assistive tech unless we forward it onto the visible,
151
+ * interactive `this.control` ourselves.
152
+ */
153
+ private applyAccessibleName;
100
154
  private buildDom;
101
155
  private bindEvents;
102
156
  private handleKeydown;
103
157
  private selectValue;
104
158
  private deselectValue;
159
+ /**
160
+ * Keeps every tree parent's own membership in `selected` consistent with
161
+ * its descendants (post-order, so parents see already-corrected children):
162
+ * a parent counts as selected only when `computeCheckState` says "all".
163
+ * No-op for data with no `children` anywhere.
164
+ */
165
+ private syncTreeAncestors;
105
166
  private clearSelection;
106
167
  private afterSelectionChange;
107
168
  private syncNativeSelect;
@@ -109,11 +170,25 @@ declare class ForgeSelect {
109
170
  private createFromQuery;
110
171
  private activateNavItem;
111
172
  private renderValue;
112
- private renderTemplate;
173
+ /**
174
+ * Pointer-based (mouse/touch/pen) reorder for a single tag. Only the real
175
+ * dragged DOM node is moved during the gesture — a full renderValue()
176
+ * mid-drag would destroy it — so the reordered `this.selected` is only
177
+ * committed on release. The move/up listeners and pointer capture live on
178
+ * the stable `this.valueEl` container rather than the tag itself: `tag`
179
+ * gets repositioned via `insertBefore` during the drag, and browsers treat
180
+ * that reparenting as detaching the node, which silently drops pointer
181
+ * capture (and further move events) if it were captured on `tag`.
182
+ */
183
+ private bindTagDrag;
184
+ /** Alt+Left/Alt+Right on a focused tag: the keyboard-operable equivalent of dragging. */
185
+ private handleTagKeydown;
186
+ private focusTagByValue;
113
187
  private buildRows;
114
188
  private hasExactMatch;
115
189
  private usesVirtualScroll;
116
190
  private renderList;
191
+ private announceStatus;
117
192
  private renderRows;
118
193
  private renderRow;
119
194
  /**
@@ -124,9 +199,17 @@ declare class ForgeSelect {
124
199
  */
125
200
  private optionContent;
126
201
  private moveHighlight;
202
+ private focusNavIndex;
203
+ private navigateTree;
127
204
  private updateActiveDescendant;
128
205
  private scheduleRemoteLoad;
206
+ /**
207
+ * Fires on every list scroll. Only acts when pagination is opted into via
208
+ * `ajax.pagination`; reads real scroll geometry rather than row counts so
209
+ * it works whether or not virtual scrolling is active for this list.
210
+ */
211
+ private maybeLoadNextPage;
129
212
  private loadRemote;
130
213
  }
131
214
 
132
- export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type Option, type OptionGroup, type TemplateFn, ForgeSelect as default };
215
+ export { type AjaxConfig, type DataItem, ForgeSelect, type ForgeSelectEvent, type ForgeSelectOptions, type ForgeSelectPlugin, type ForgeSelectValue, type Option, type OptionGroup, type SetValueOptions, type TemplateFn, ForgeSelect as default };