@destyler/combobox 0.2.6 → 0.2.7
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.mts +49 -39
- package/dist/index.mjs +47 -9
- package/package.json +10 -10
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as _destyler_anatomy0 from "@destyler/anatomy";
|
|
2
1
|
import { CollectionItem, CollectionItem as CollectionItem$1, CollectionOptions, CollectionOptions as CollectionOptions$1, ListCollection } from "@destyler/collection";
|
|
3
2
|
import * as _destyler_xstate0 from "@destyler/xstate";
|
|
4
3
|
import { AnyEventObject, Machine, XSend, XState } from "@destyler/xstate";
|
|
@@ -7,7 +6,7 @@ import { FocusOutsideEvent, InteractOutsideEvent, InteractOutsideHandlers, Point
|
|
|
7
6
|
import { CommonProperties, DirectionProperty, NormalizeProps, PropTypes, RequiredBy } from "@destyler/types";
|
|
8
7
|
|
|
9
8
|
//#region src/anatomy.d.ts
|
|
10
|
-
declare const anatomy:
|
|
9
|
+
declare const anatomy: any;
|
|
11
10
|
//#endregion
|
|
12
11
|
//#region src/collection.d.ts
|
|
13
12
|
declare function collection<T extends CollectionItem$1>(options: CollectionOptions$1<T>): ListCollection<T>;
|
|
@@ -59,56 +58,67 @@ interface PublicContext<T extends CollectionItem = CollectionItem> extends Direc
|
|
|
59
58
|
/**
|
|
60
59
|
* Whether the combobox is open
|
|
61
60
|
*/
|
|
62
|
-
|
|
61
|
+
open?: boolean | undefined;
|
|
63
62
|
/**
|
|
64
|
-
*
|
|
63
|
+
* The initial open state of the combobox when it is not controlled.
|
|
64
|
+
* Prefer this over seeding with `open` for uncontrolled usage.
|
|
65
65
|
*/
|
|
66
|
-
|
|
66
|
+
defaultOpen?: boolean | undefined;
|
|
67
67
|
/**
|
|
68
68
|
* The ids of the elements in the combobox. Useful for composition.
|
|
69
69
|
*/
|
|
70
|
-
|
|
70
|
+
ids?: ElementIds | undefined;
|
|
71
71
|
/**
|
|
72
|
-
* The
|
|
72
|
+
* The controlled value of the combobox's input
|
|
73
73
|
*/
|
|
74
|
-
|
|
74
|
+
inputValue?: string | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* The initial value of the combobox's input when it is not controlled.
|
|
77
|
+
* Prefer this over seeding with `inputValue` for uncontrolled usage.
|
|
78
|
+
*/
|
|
79
|
+
defaultInputValue?: string | undefined;
|
|
75
80
|
/**
|
|
76
81
|
* The `name` attribute of the combobox's input. Useful for form submission
|
|
77
82
|
*/
|
|
78
|
-
|
|
83
|
+
name?: string | undefined;
|
|
79
84
|
/**
|
|
80
85
|
* The associate form of the combobox.
|
|
81
86
|
*/
|
|
82
|
-
|
|
87
|
+
form?: string | undefined;
|
|
83
88
|
/**
|
|
84
89
|
* Whether the combobox is disabled
|
|
85
90
|
*/
|
|
86
|
-
|
|
91
|
+
disabled?: boolean | undefined;
|
|
87
92
|
/**
|
|
88
93
|
* Whether the combobox is readonly. This puts the combobox in a "non-editable" mode
|
|
89
94
|
* but the user can still interact with it
|
|
90
95
|
*/
|
|
91
|
-
|
|
96
|
+
readOnly?: boolean | undefined;
|
|
92
97
|
/**
|
|
93
98
|
* Whether the combobox is invalid
|
|
94
99
|
*/
|
|
95
|
-
|
|
100
|
+
invalid?: boolean | undefined;
|
|
96
101
|
/**
|
|
97
102
|
* Whether the combobox is required
|
|
98
103
|
*/
|
|
99
|
-
|
|
104
|
+
required?: boolean | undefined;
|
|
100
105
|
/**
|
|
101
106
|
* The placeholder text of the combobox's input
|
|
102
107
|
*/
|
|
103
|
-
|
|
108
|
+
placeholder?: string | undefined;
|
|
104
109
|
/**
|
|
105
110
|
* The active item's id. Used to set the `aria-activedescendant` attribute
|
|
106
111
|
*/
|
|
107
|
-
|
|
112
|
+
highlightedValue: string | null;
|
|
113
|
+
/**
|
|
114
|
+
* The controlled keys of the selected items
|
|
115
|
+
*/
|
|
116
|
+
value?: string[] | undefined;
|
|
108
117
|
/**
|
|
109
|
-
* The keys of the selected items
|
|
118
|
+
* The initial keys of the selected items when it is not controlled.
|
|
119
|
+
* Prefer this over seeding with `value` for uncontrolled usage.
|
|
110
120
|
*/
|
|
111
|
-
|
|
121
|
+
defaultValue?: string[] | undefined;
|
|
112
122
|
/**
|
|
113
123
|
* Defines the auto-completion behavior of the combobox.
|
|
114
124
|
*
|
|
@@ -117,7 +127,7 @@ interface PublicContext<T extends CollectionItem = CollectionItem> extends Direc
|
|
|
117
127
|
*
|
|
118
128
|
* @default "none"
|
|
119
129
|
*/
|
|
120
|
-
|
|
130
|
+
inputBehavior: 'autohighlight' | 'autocomplete' | 'none';
|
|
121
131
|
/**
|
|
122
132
|
* The behavior of the combobox input when an item is selected
|
|
123
133
|
*
|
|
@@ -127,92 +137,92 @@ interface PublicContext<T extends CollectionItem = CollectionItem> extends Direc
|
|
|
127
137
|
*
|
|
128
138
|
* @default "replace"
|
|
129
139
|
*/
|
|
130
|
-
|
|
140
|
+
selectionBehavior: 'clear' | 'replace' | 'preserve';
|
|
131
141
|
/**
|
|
132
142
|
* Whether to autofocus the input on mount
|
|
133
143
|
*/
|
|
134
|
-
|
|
144
|
+
autoFocus?: boolean | undefined;
|
|
135
145
|
/**
|
|
136
146
|
* Whether to open the combobox popup on initial click on the input
|
|
137
147
|
* @default false
|
|
138
148
|
*/
|
|
139
|
-
|
|
149
|
+
openOnClick?: boolean | undefined;
|
|
140
150
|
/**
|
|
141
151
|
* Whether to show the combobox when the input value changes
|
|
142
152
|
* @default true
|
|
143
153
|
*/
|
|
144
|
-
|
|
154
|
+
openOnChange?: boolean | ((details: InputValueChangeDetails) => boolean) | undefined;
|
|
145
155
|
/**
|
|
146
156
|
* Whether to allow typing custom values in the input
|
|
147
157
|
*/
|
|
148
|
-
|
|
158
|
+
allowCustomValue?: boolean | undefined;
|
|
149
159
|
/**
|
|
150
160
|
* Whether to loop the keyboard navigation through the items
|
|
151
161
|
* @default true
|
|
152
162
|
*/
|
|
153
|
-
|
|
163
|
+
loopFocus?: boolean | undefined;
|
|
154
164
|
/**
|
|
155
165
|
* The positioning options to dynamically position the menu
|
|
156
166
|
*/
|
|
157
|
-
|
|
167
|
+
positioning: PositioningOptions;
|
|
158
168
|
/**
|
|
159
169
|
* Function called when the input's value changes
|
|
160
170
|
*/
|
|
161
|
-
|
|
171
|
+
onInputValueChange?: ((details: InputValueChangeDetails) => void) | undefined;
|
|
162
172
|
/**
|
|
163
173
|
* Function called when a new item is selected
|
|
164
174
|
*/
|
|
165
|
-
|
|
175
|
+
onValueChange?: ((details: ValueChangeDetails<T>) => void) | undefined;
|
|
166
176
|
/**
|
|
167
177
|
* Function called when an item is highlighted using the pointer
|
|
168
178
|
* or keyboard navigation.
|
|
169
179
|
*/
|
|
170
|
-
|
|
180
|
+
onHighlightChange?: ((details: HighlightChangeDetails<T>) => void) | undefined;
|
|
171
181
|
/**
|
|
172
182
|
* Function called when the popup is opened
|
|
173
183
|
*/
|
|
174
|
-
|
|
184
|
+
onOpenChange?: ((details: OpenChangeDetails) => void) | undefined;
|
|
175
185
|
/**
|
|
176
186
|
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
177
187
|
*/
|
|
178
|
-
|
|
188
|
+
translations: IntlTranslations;
|
|
179
189
|
/**
|
|
180
190
|
* The collection of items
|
|
181
191
|
*/
|
|
182
|
-
|
|
192
|
+
collection: ListCollection<any>;
|
|
183
193
|
/**
|
|
184
194
|
* Whether to allow multiple selection.
|
|
185
195
|
*
|
|
186
196
|
* **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`.
|
|
187
197
|
* It is recommended to render the selected items in a separate container.
|
|
188
198
|
*/
|
|
189
|
-
|
|
199
|
+
multiple?: boolean | undefined;
|
|
190
200
|
/**
|
|
191
201
|
* Whether to close the combobox when an item is selected.
|
|
192
202
|
*/
|
|
193
|
-
|
|
203
|
+
closeOnSelect?: boolean | undefined;
|
|
194
204
|
/**
|
|
195
205
|
* Whether to open the combobox on arrow key press
|
|
196
206
|
* @default true
|
|
197
207
|
*/
|
|
198
|
-
|
|
208
|
+
openOnKeyPress: boolean;
|
|
199
209
|
/**
|
|
200
210
|
* Function to scroll to a specific index
|
|
201
211
|
*/
|
|
202
|
-
|
|
212
|
+
scrollToIndexFn?: ((details: ScrollToIndexDetails) => void) | undefined;
|
|
203
213
|
/**
|
|
204
214
|
* Whether the combobox is a composed with other composite widgets like tabs
|
|
205
215
|
* @default true
|
|
206
216
|
*/
|
|
207
|
-
|
|
217
|
+
composite: boolean;
|
|
208
218
|
/**
|
|
209
219
|
* Whether to disable registering this a dismissable layer
|
|
210
220
|
*/
|
|
211
|
-
|
|
221
|
+
disableLayer?: boolean | undefined;
|
|
212
222
|
/**
|
|
213
223
|
* Function to navigate to the selected item
|
|
214
224
|
*/
|
|
215
|
-
|
|
225
|
+
navigate: (details: NavigateDetails) => void;
|
|
216
226
|
}
|
|
217
227
|
type UserDefinedContext<T extends CollectionItem = CollectionItem> = RequiredBy<PublicContext<T>, 'id' | 'collection'>;
|
|
218
228
|
type ComputedContext = Readonly<{
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { ariaAttr, clickIfLink, createScope, dataAttr, getEventKey, isAnchorElem
|
|
|
5
5
|
import { getPlacement, getPlacementStyles } from "@destyler/popper";
|
|
6
6
|
import { ariaHidden } from "@destyler/aria-hidden";
|
|
7
7
|
import { trackDismissableElement } from "@destyler/dismissable";
|
|
8
|
-
import { addOrRemove, compact, isArray, isBoolean, isEqual, match } from "@destyler/utils";
|
|
8
|
+
import { addOrRemove, compact, isArray, isBoolean, isControlled, isEqual, isPropUserProvided, match, resolveControllableOpen, resolveControllableProp, withControllableProvided } from "@destyler/utils";
|
|
9
9
|
|
|
10
10
|
//#region src/anatomy.ts
|
|
11
11
|
const anatomy = createAnatomy("combobox").parts("root", "clearTrigger", "content", "control", "input", "item", "itemGroup", "itemGroupLabel", "itemIndicator", "itemText", "label", "list", "positioner", "trigger");
|
|
@@ -548,17 +548,32 @@ const invoke = {
|
|
|
548
548
|
ctx.onInputValueChange?.({ inputValue: ctx.inputValue });
|
|
549
549
|
}
|
|
550
550
|
};
|
|
551
|
+
function proposeValueChange(ctx, value) {
|
|
552
|
+
const prevSelectedItems = ctx.selectedItems;
|
|
553
|
+
const items = value.map((v) => {
|
|
554
|
+
const foundItem = prevSelectedItems.find((item) => ctx.collection.getItemValue(item) === v);
|
|
555
|
+
if (foundItem) return foundItem;
|
|
556
|
+
return ctx.collection.find(v);
|
|
557
|
+
});
|
|
558
|
+
ctx.onValueChange?.({
|
|
559
|
+
value: Array.from(value),
|
|
560
|
+
items: Array.from(items)
|
|
561
|
+
});
|
|
562
|
+
}
|
|
551
563
|
const set = {
|
|
552
564
|
value: (ctx, value, force = false) => {
|
|
553
565
|
if (isEqual(ctx.value, value)) return;
|
|
554
566
|
if (value == null && !force) return;
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
567
|
+
let next;
|
|
568
|
+
if (value == null) next = [];
|
|
569
|
+
else if (isArray(value)) next = value;
|
|
570
|
+
else next = ctx.multiple ? addOrRemove(ctx.value, value) : [value];
|
|
571
|
+
if (isEqual(ctx.value, next)) return;
|
|
572
|
+
if (isControlled(ctx, "value")) {
|
|
573
|
+
proposeValueChange(ctx, next);
|
|
558
574
|
return;
|
|
559
575
|
}
|
|
560
|
-
|
|
561
|
-
else if (value != null) ctx.value = ctx.multiple ? addOrRemove(ctx.value, value) : [value];
|
|
576
|
+
ctx.value = next;
|
|
562
577
|
invoke.valueChange(ctx);
|
|
563
578
|
},
|
|
564
579
|
highlightedValue: (ctx, value, force = false) => {
|
|
@@ -569,15 +584,36 @@ const set = {
|
|
|
569
584
|
},
|
|
570
585
|
inputValue: (ctx, value) => {
|
|
571
586
|
if (isEqual(ctx.inputValue, value)) return;
|
|
587
|
+
if (isControlled(ctx, "inputValue")) {
|
|
588
|
+
ctx.onInputValueChange?.({ inputValue: value });
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
572
591
|
ctx.inputValue = value;
|
|
573
592
|
invoke.inputChange(ctx);
|
|
574
593
|
}
|
|
575
594
|
};
|
|
576
595
|
function machine(userContext) {
|
|
577
|
-
const ctx = compact(userContext
|
|
596
|
+
const ctx = compact(withControllableProvided(userContext, [
|
|
597
|
+
"open",
|
|
598
|
+
"value",
|
|
599
|
+
"inputValue"
|
|
600
|
+
]));
|
|
601
|
+
const { initialOpen } = resolveControllableOpen(ctx);
|
|
602
|
+
const { initial: initialValue } = resolveControllableProp({
|
|
603
|
+
value: ctx.value,
|
|
604
|
+
defaultValue: ctx.defaultValue,
|
|
605
|
+
valueProvided: isPropUserProvided(ctx, "value"),
|
|
606
|
+
fallback: []
|
|
607
|
+
});
|
|
608
|
+
const { initial: initialInputValue } = resolveControllableProp({
|
|
609
|
+
value: ctx.inputValue,
|
|
610
|
+
defaultValue: ctx.defaultInputValue,
|
|
611
|
+
valueProvided: isPropUserProvided(ctx, "inputValue"),
|
|
612
|
+
fallback: ""
|
|
613
|
+
});
|
|
578
614
|
return createMachine({
|
|
579
615
|
id: "combobox",
|
|
580
|
-
initial:
|
|
616
|
+
initial: initialOpen ? "suggesting" : "idle",
|
|
581
617
|
context: {
|
|
582
618
|
loopFocus: true,
|
|
583
619
|
openOnClick: false,
|
|
@@ -597,6 +633,8 @@ function machine(userContext) {
|
|
|
597
633
|
clickIfLink(node);
|
|
598
634
|
},
|
|
599
635
|
...ctx,
|
|
636
|
+
value: initialValue,
|
|
637
|
+
inputValue: initialInputValue,
|
|
600
638
|
highlightedItem: null,
|
|
601
639
|
selectedItems: [],
|
|
602
640
|
valueAsString: "",
|
|
@@ -1091,7 +1129,7 @@ function machine(userContext) {
|
|
|
1091
1129
|
allowCustomValue: (ctx$1) => !!ctx$1.allowCustomValue,
|
|
1092
1130
|
hasHighlightedItem: (ctx$1) => ctx$1.highlightedValue != null,
|
|
1093
1131
|
closeOnSelect: (ctx$1) => !!ctx$1.closeOnSelect,
|
|
1094
|
-
isOpenControlled: (ctx$1) =>
|
|
1132
|
+
isOpenControlled: (ctx$1) => isControlled(ctx$1, "open"),
|
|
1095
1133
|
openOnChange: (ctx$1, evt) => {
|
|
1096
1134
|
if (isBoolean(ctx$1.openOnChange)) return ctx$1.openOnChange;
|
|
1097
1135
|
return !!ctx$1.openOnChange?.({ inputValue: evt.value });
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@destyler/combobox",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.7",
|
|
5
5
|
"description": "autocomplete input and command palette with a list of suggestions.",
|
|
6
6
|
"author": "Elone Hoo <elonehoo@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@destyler/anatomy": "0.2.
|
|
26
|
-
"@destyler/aria-hidden": "0.2.
|
|
27
|
-
"@destyler/collection": "0.2.
|
|
28
|
-
"@destyler/
|
|
29
|
-
"@destyler/
|
|
30
|
-
"@destyler/popper": "0.2.
|
|
31
|
-
"@destyler/
|
|
32
|
-
"@destyler/
|
|
33
|
-
"@destyler/utils": "0.2.
|
|
25
|
+
"@destyler/anatomy": "0.2.7",
|
|
26
|
+
"@destyler/aria-hidden": "0.2.7",
|
|
27
|
+
"@destyler/collection": "0.2.7",
|
|
28
|
+
"@destyler/dom": "0.2.7",
|
|
29
|
+
"@destyler/dismissable": "0.2.7",
|
|
30
|
+
"@destyler/popper": "0.2.7",
|
|
31
|
+
"@destyler/types": "0.2.7",
|
|
32
|
+
"@destyler/xstate": "0.2.7",
|
|
33
|
+
"@destyler/utils": "0.2.7"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|