matsuri-ui-base 0.0.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/README.md +1 -0
- package/SelectField/index.d.ts +96 -0
- package/SelectField/index.js +353 -0
- package/SelectField/index.js.map +1 -0
- package/cjs/SelectField/index.js +348 -0
- package/cjs/SelectField/index.js.map +1 -0
- package/cjs/index.js +7 -0
- package/cjs/index.js.map +1 -0
- package/esm/SelectField/index.js +353 -0
- package/esm/SelectField/index.js.map +1 -0
- package/esm/index.js +2 -0
- package/esm/index.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.js +2 -0
- package/index.js.map +1 -0
- package/package.json +42 -0
- package/types/SelectField/index.d.ts +96 -0
- package/types/index.d.ts +1 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# matsuri-ui-base
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const filterSelectOptionsByQuery: <T extends SelectOptionValue = SelectOptionValue>(options: T[], query: string) => any[];
|
|
3
|
+
export type SelectLoadOptions<T extends SelectOptionValue = SelectOptionValue> = (args: {
|
|
4
|
+
query: string;
|
|
5
|
+
options?: T[];
|
|
6
|
+
selectedOptions?: T[];
|
|
7
|
+
}) => Promise<T[] | undefined>;
|
|
8
|
+
export interface SelectOptionValue {
|
|
9
|
+
value: string | undefined;
|
|
10
|
+
label: string;
|
|
11
|
+
keys?: string[];
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
interface UseSelectFieldArgs<T extends SelectOptionValue> {
|
|
15
|
+
/**
|
|
16
|
+
* 選択肢の初期値を指定する。
|
|
17
|
+
*/
|
|
18
|
+
defaultValue?: string;
|
|
19
|
+
/**
|
|
20
|
+
* 選択肢の選択が可能かどうか指定する。
|
|
21
|
+
* @default false
|
|
22
|
+
*/
|
|
23
|
+
readOnly?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* 選択肢の選択が必須かどうか指定する。
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
required?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* input要素に渡したいname属性を指定する。
|
|
31
|
+
*/
|
|
32
|
+
name?: string;
|
|
33
|
+
/**
|
|
34
|
+
* queryに応じて選択肢をロードする関数を指定する。
|
|
35
|
+
* この関数で返された選択肢が、選択肢として表示される。
|
|
36
|
+
*/
|
|
37
|
+
loadOptions?: SelectLoadOptions<T>;
|
|
38
|
+
/**
|
|
39
|
+
* 選択肢を指定する。
|
|
40
|
+
* 各選択肢は、valueとlabel及び任意のプロパティを持つオブジェクトである必要がある。
|
|
41
|
+
*/
|
|
42
|
+
options?: T[];
|
|
43
|
+
/**
|
|
44
|
+
* このフラグがtrueの場合、queryもvalueとして扱えるようになる
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
treatQueryAsValue?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* 選択肢が変更された時に呼ばれるコールバック関数を指定する。
|
|
50
|
+
*/
|
|
51
|
+
onChangeOption?: (option: T) => void;
|
|
52
|
+
}
|
|
53
|
+
interface UseSelectFieldResult<T extends SelectOptionValue> {
|
|
54
|
+
/**
|
|
55
|
+
* 表示用の文字列。
|
|
56
|
+
*/
|
|
57
|
+
displayValue: string | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* 検索用に入力された文字列。
|
|
60
|
+
*/
|
|
61
|
+
query: string;
|
|
62
|
+
/**
|
|
63
|
+
* input要素に渡される値。
|
|
64
|
+
*/
|
|
65
|
+
value: string | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* 選択肢のリストを開くかどうか。
|
|
68
|
+
*/
|
|
69
|
+
openList: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* 実態となるinput要素に渡すprops
|
|
72
|
+
*/
|
|
73
|
+
inputProps: React.ComponentPropsWithRef<"input">;
|
|
74
|
+
/**
|
|
75
|
+
* 擬似的なinput要素つまり検索用のinput要素に渡すprops
|
|
76
|
+
*/
|
|
77
|
+
pseudoInputProps: React.ComponentPropsWithRef<"input">;
|
|
78
|
+
/**
|
|
79
|
+
* 選択肢のリストに渡すprops
|
|
80
|
+
*/
|
|
81
|
+
listProps: React.ComponentPropsWithRef<"ul">;
|
|
82
|
+
/**
|
|
83
|
+
* 選択肢のリストの各要素に渡すpropsと、各選択肢、及びkeyを持つオブジェクトの配列。
|
|
84
|
+
*/
|
|
85
|
+
listItems?: {
|
|
86
|
+
key: string;
|
|
87
|
+
option: T;
|
|
88
|
+
props: React.ComponentPropsWithoutRef<"li">;
|
|
89
|
+
}[];
|
|
90
|
+
/**
|
|
91
|
+
* 全ての要素の親となる要素に渡すprops
|
|
92
|
+
*/
|
|
93
|
+
rootProps: React.ComponentPropsWithRef<"div">;
|
|
94
|
+
}
|
|
95
|
+
export declare const useSelectField: <T extends SelectOptionValue>(args: UseSelectFieldArgs<T>) => UseSelectFieldResult<T>;
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
2
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
3
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
var useOnClickOutside = (ref, handler) => {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!handler) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
var listener = event => {
|
|
11
|
+
if (Array.isArray(ref)) {
|
|
12
|
+
for (var i = 0; i < ref.length; i++) {
|
|
13
|
+
var element = ref[i].current;
|
|
14
|
+
// 1つ目の要素がないからといって、2つ目の要素もなくクリック範囲に含まれていないとは言えない。
|
|
15
|
+
if (element && element.contains(event.composedPath()[0])) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
if (!ref.current || ref.current.contains(event.composedPath()[0])) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
handler(event);
|
|
25
|
+
};
|
|
26
|
+
document.addEventListener("mousedown", listener);
|
|
27
|
+
document.addEventListener("touchstart", listener);
|
|
28
|
+
return () => {
|
|
29
|
+
document.removeEventListener("mousedown", listener);
|
|
30
|
+
document.removeEventListener("touchstart", listener);
|
|
31
|
+
};
|
|
32
|
+
}, [ref, handler]);
|
|
33
|
+
};
|
|
34
|
+
var getSearch = (items, query) => {
|
|
35
|
+
var copy = items.slice();
|
|
36
|
+
var len = items.length;
|
|
37
|
+
var key = query.toLowerCase();
|
|
38
|
+
var i = -1;
|
|
39
|
+
var c = 0;
|
|
40
|
+
var tmp;
|
|
41
|
+
var res = new Array(len);
|
|
42
|
+
while (++i !== len) {
|
|
43
|
+
tmp = copy[i];
|
|
44
|
+
/**
|
|
45
|
+
* Caluculate Minimum Index
|
|
46
|
+
*/
|
|
47
|
+
var j = -1;
|
|
48
|
+
var index = -1;
|
|
49
|
+
var keylen = tmp.keys.length;
|
|
50
|
+
var current = void 0;
|
|
51
|
+
while (++j !== keylen) {
|
|
52
|
+
current = tmp.keys[j].toLowerCase().indexOf(key);
|
|
53
|
+
if (index === -1 || current !== -1 && current < index) {
|
|
54
|
+
index = current;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Caluculate Score
|
|
59
|
+
*/
|
|
60
|
+
var score = index > -1 ? 1 / (index + 1) : 0;
|
|
61
|
+
if (score > 0) {
|
|
62
|
+
res[c++] = _extends({}, tmp, {
|
|
63
|
+
score
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
res.length = c;
|
|
68
|
+
res.sort((a, b) => {
|
|
69
|
+
if (a.score <= b.score) {
|
|
70
|
+
return 1;
|
|
71
|
+
} else {
|
|
72
|
+
return -1;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return res;
|
|
76
|
+
};
|
|
77
|
+
var dispatchChangeEvent = (element, value) => {
|
|
78
|
+
var _Object$getOwnPropert;
|
|
79
|
+
var nativeInputValueSetter = (_Object$getOwnPropert = Object.getOwnPropertyDescriptor(element.tagName.toLowerCase() === "input" ? HTMLInputElement.prototype : HTMLTextAreaElement.prototype, "value")) == null ? void 0 : _Object$getOwnPropert.set;
|
|
80
|
+
nativeInputValueSetter == null ? void 0 : nativeInputValueSetter.call(element, value);
|
|
81
|
+
element.dispatchEvent(new Event("change", {
|
|
82
|
+
bubbles: true
|
|
83
|
+
}));
|
|
84
|
+
};
|
|
85
|
+
function ownerDocument(node) {
|
|
86
|
+
return node && node.ownerDocument || document;
|
|
87
|
+
}
|
|
88
|
+
var nextItem = (list, item) => {
|
|
89
|
+
if (list === item) {
|
|
90
|
+
return list.firstChild;
|
|
91
|
+
}
|
|
92
|
+
if (item && item.nextElementSibling) {
|
|
93
|
+
return item.nextElementSibling;
|
|
94
|
+
}
|
|
95
|
+
return list.firstChild;
|
|
96
|
+
};
|
|
97
|
+
var previousItem = (list, item) => {
|
|
98
|
+
if (list === item) {
|
|
99
|
+
return list.lastChild;
|
|
100
|
+
}
|
|
101
|
+
if (item && item.previousElementSibling) {
|
|
102
|
+
return item.previousElementSibling;
|
|
103
|
+
}
|
|
104
|
+
return list.lastChild;
|
|
105
|
+
};
|
|
106
|
+
var moveFocus = (list, currentFocus, traversalFunction) => {
|
|
107
|
+
var nextFocus = traversalFunction(list, currentFocus);
|
|
108
|
+
while (nextFocus) {
|
|
109
|
+
if (currentFocus === null ? nextFocus === list.lastChild : nextFocus === currentFocus) {
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
var disabledFocus = nextFocus.disabled || nextFocus.getAttribute("aria-disabled") === "true";
|
|
113
|
+
if (disabledFocus) {
|
|
114
|
+
nextFocus = traversalFunction(list, nextFocus);
|
|
115
|
+
} else {
|
|
116
|
+
nextFocus.focus();
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
export var filterSelectOptionsByQuery = (options, query) => {
|
|
122
|
+
var result = getSearch(options.map(option => {
|
|
123
|
+
return _extends({}, option, {
|
|
124
|
+
keys: option.keys || [option.label],
|
|
125
|
+
content: option.value
|
|
126
|
+
});
|
|
127
|
+
}), query);
|
|
128
|
+
return result;
|
|
129
|
+
};
|
|
130
|
+
var defaultLoadOptions = /*#__PURE__*/function () {
|
|
131
|
+
var _ref2 = _asyncToGenerator(function* (_ref) {
|
|
132
|
+
var {
|
|
133
|
+
query,
|
|
134
|
+
options
|
|
135
|
+
} = _ref;
|
|
136
|
+
if (options === undefined) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
if (query === undefined) {
|
|
140
|
+
return options;
|
|
141
|
+
}
|
|
142
|
+
var result = filterSelectOptionsByQuery(options, query);
|
|
143
|
+
return result.length ? result : options;
|
|
144
|
+
});
|
|
145
|
+
return function defaultLoadOptions(_x) {
|
|
146
|
+
return _ref2.apply(this, arguments);
|
|
147
|
+
};
|
|
148
|
+
}();
|
|
149
|
+
export var useSelectField = args => {
|
|
150
|
+
var {
|
|
151
|
+
readOnly = false,
|
|
152
|
+
name,
|
|
153
|
+
required = false,
|
|
154
|
+
options: propsOptions,
|
|
155
|
+
loadOptions = defaultLoadOptions,
|
|
156
|
+
treatQueryAsValue = false,
|
|
157
|
+
defaultValue = undefined,
|
|
158
|
+
onChangeOption
|
|
159
|
+
} = args;
|
|
160
|
+
var [open, setOpen] = useState(false);
|
|
161
|
+
var [query, setQuery] = useState("");
|
|
162
|
+
var [value, setValue] = useState(defaultValue);
|
|
163
|
+
var selectedOptionsCache = useRef(propsOptions);
|
|
164
|
+
var [options, setOptions] = useState(propsOptions);
|
|
165
|
+
var rootRef = useRef(null);
|
|
166
|
+
var originalInputRef = useRef(null);
|
|
167
|
+
var listRef = useRef(null);
|
|
168
|
+
var pseudoInputRef = useRef(null);
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
void loadOptions({
|
|
171
|
+
query,
|
|
172
|
+
options: propsOptions,
|
|
173
|
+
selectedOptions: selectedOptionsCache.current
|
|
174
|
+
}).then(result => {
|
|
175
|
+
setOptions(result);
|
|
176
|
+
});
|
|
177
|
+
}, [propsOptions, loadOptions, query]);
|
|
178
|
+
var inputProps = useMemo(() => {
|
|
179
|
+
return {
|
|
180
|
+
ref: originalInputRef,
|
|
181
|
+
required: required,
|
|
182
|
+
name: name,
|
|
183
|
+
defaultValue: value,
|
|
184
|
+
key: value,
|
|
185
|
+
tabIndex: -1,
|
|
186
|
+
autoComplete: "off",
|
|
187
|
+
autoCorrect: "off",
|
|
188
|
+
autoCapitalize: "none",
|
|
189
|
+
spellCheck: false,
|
|
190
|
+
onFocus: event => {
|
|
191
|
+
var _pseudoInputRef$curre;
|
|
192
|
+
event.currentTarget.blur();
|
|
193
|
+
(_pseudoInputRef$curre = pseudoInputRef.current) == null ? void 0 : _pseudoInputRef$curre.focus();
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}, [name, required, value]);
|
|
197
|
+
var displayValue = useMemo(() => {
|
|
198
|
+
var _ref3, _selectedOptionsCache;
|
|
199
|
+
return (_ref3 = ((_selectedOptionsCache = selectedOptionsCache.current) == null ? void 0 : _selectedOptionsCache.find(option => option.value === value)) || (options == null ? void 0 : options.find(option => option.value === value))) == null ? void 0 : _ref3.label;
|
|
200
|
+
}, [options, value]);
|
|
201
|
+
var rootProps = useMemo(() => {
|
|
202
|
+
return {
|
|
203
|
+
ref: rootRef
|
|
204
|
+
};
|
|
205
|
+
}, []);
|
|
206
|
+
useOnClickOutside([rootRef, listRef], () => {
|
|
207
|
+
setOpen(false);
|
|
208
|
+
setQuery("");
|
|
209
|
+
});
|
|
210
|
+
var updateValue = useCallback(option => {
|
|
211
|
+
var value = option.value;
|
|
212
|
+
setValue(value);
|
|
213
|
+
if (onChangeOption) {
|
|
214
|
+
onChangeOption(option);
|
|
215
|
+
}
|
|
216
|
+
selectedOptionsCache.current = options;
|
|
217
|
+
if (originalInputRef.current) {
|
|
218
|
+
dispatchChangeEvent(originalInputRef.current, value);
|
|
219
|
+
}
|
|
220
|
+
}, [onChangeOption, options]);
|
|
221
|
+
var pseudoInputProps = useMemo(() => {
|
|
222
|
+
return {
|
|
223
|
+
ref: pseudoInputRef,
|
|
224
|
+
value: query,
|
|
225
|
+
autoComplete: "off",
|
|
226
|
+
autoCorrect: "off",
|
|
227
|
+
autoCapitalize: "none",
|
|
228
|
+
spellCheck: false,
|
|
229
|
+
tabIndex: 0,
|
|
230
|
+
onChange: event => {
|
|
231
|
+
var query = event.currentTarget.value;
|
|
232
|
+
setQuery(query);
|
|
233
|
+
if (treatQueryAsValue) {
|
|
234
|
+
updateValue({
|
|
235
|
+
label: query,
|
|
236
|
+
value: query
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
onClick: event => {
|
|
241
|
+
/**
|
|
242
|
+
* ユーザーがフォーカスされている状態で入力要素をクリックするのは、
|
|
243
|
+
* ユーザーが選択肢を一度選択してから再度選択したいケースと想定されるため、リストを再度開く。
|
|
244
|
+
*/
|
|
245
|
+
if (event.currentTarget === document.activeElement) {
|
|
246
|
+
setOpen(true);
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
onFocus: () => {
|
|
250
|
+
if (readOnly !== true) {
|
|
251
|
+
setOpen(true);
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
onKeyDown: event => {
|
|
255
|
+
var {
|
|
256
|
+
key
|
|
257
|
+
} = event;
|
|
258
|
+
if (key === "Delete" || key === "Backspace") {
|
|
259
|
+
setQuery(prev => {
|
|
260
|
+
if (prev === "") {
|
|
261
|
+
setValue(undefined);
|
|
262
|
+
}
|
|
263
|
+
return prev;
|
|
264
|
+
});
|
|
265
|
+
} else if (key === "ArrowDown") {
|
|
266
|
+
event.preventDefault();
|
|
267
|
+
var _list = listRef.current;
|
|
268
|
+
if (_list) {
|
|
269
|
+
moveFocus(_list, null, nextItem);
|
|
270
|
+
}
|
|
271
|
+
} else if (treatQueryAsValue && event.nativeEvent.isComposing === false && key === "Enter") {
|
|
272
|
+
if (treatQueryAsValue) {
|
|
273
|
+
selectedOptionsCache.current = [{
|
|
274
|
+
value: query,
|
|
275
|
+
label: query
|
|
276
|
+
}];
|
|
277
|
+
}
|
|
278
|
+
setOpen(false);
|
|
279
|
+
} else if (event.key.length === 1) {
|
|
280
|
+
setOpen(true);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}, [query, treatQueryAsValue, updateValue, readOnly]);
|
|
285
|
+
var listProps = useMemo(() => {
|
|
286
|
+
return {
|
|
287
|
+
ref: listRef,
|
|
288
|
+
role: "listbox",
|
|
289
|
+
tabIndex: -1,
|
|
290
|
+
onKeyDown: event => {
|
|
291
|
+
var key = event.key;
|
|
292
|
+
var list = listRef.current;
|
|
293
|
+
if (list === null) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
var currentFocus = ownerDocument(list).activeElement;
|
|
297
|
+
if (key === "ArrowDown") {
|
|
298
|
+
event.preventDefault();
|
|
299
|
+
moveFocus(list, currentFocus, nextItem);
|
|
300
|
+
} else if (key === "ArrowUp") {
|
|
301
|
+
event.preventDefault();
|
|
302
|
+
moveFocus(list, currentFocus, previousItem);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}, []);
|
|
307
|
+
var listItems = useMemo(() => {
|
|
308
|
+
return options == null ? void 0 : options.map((option, index) => {
|
|
309
|
+
var selected = option.value === value;
|
|
310
|
+
return {
|
|
311
|
+
key: option.value + "-" + index,
|
|
312
|
+
option,
|
|
313
|
+
props: {
|
|
314
|
+
role: "option",
|
|
315
|
+
"aria-selected": selected,
|
|
316
|
+
/**
|
|
317
|
+
* 何も選択されていないときは、先頭のオプションに飛べるようにする
|
|
318
|
+
*/
|
|
319
|
+
tabIndex: (value === undefined ? index === 0 : selected) ? -1 : -1,
|
|
320
|
+
onClick: () => {
|
|
321
|
+
var _pseudoInputRef$curre2;
|
|
322
|
+
updateValue(option);
|
|
323
|
+
setQuery("");
|
|
324
|
+
pseudoInputRef == null ? void 0 : (_pseudoInputRef$curre2 = pseudoInputRef.current) == null ? void 0 : _pseudoInputRef$curre2.focus();
|
|
325
|
+
setOpen(false);
|
|
326
|
+
},
|
|
327
|
+
onKeyDown: event => {
|
|
328
|
+
var key = event.key;
|
|
329
|
+
if (key === "Enter" || key === " ") {
|
|
330
|
+
event.preventDefault();
|
|
331
|
+
event.currentTarget.click();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
});
|
|
337
|
+
}, [options, updateValue, value]);
|
|
338
|
+
var result = useMemo(() => {
|
|
339
|
+
return {
|
|
340
|
+
displayValue,
|
|
341
|
+
query,
|
|
342
|
+
value,
|
|
343
|
+
openList: open,
|
|
344
|
+
inputProps,
|
|
345
|
+
pseudoInputProps,
|
|
346
|
+
listProps,
|
|
347
|
+
listItems,
|
|
348
|
+
rootProps
|
|
349
|
+
};
|
|
350
|
+
}, [displayValue, inputProps, listItems, listProps, open, pseudoInputProps, query, rootProps, value]);
|
|
351
|
+
return result;
|
|
352
|
+
};
|
|
353
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["useCallback","useEffect","useMemo","useRef","useState","useOnClickOutside","ref","handler","undefined","listener","event","Array","isArray","i","length","element","current","contains","composedPath","document","addEventListener","removeEventListener","getSearch","items","query","copy","slice","len","key","toLowerCase","c","tmp","res","j","index","keylen","keys","indexOf","score","_extends","sort","a","b","dispatchChangeEvent","value","_Object$getOwnPropert","nativeInputValueSetter","Object","getOwnPropertyDescriptor","tagName","HTMLInputElement","prototype","HTMLTextAreaElement","set","call","dispatchEvent","Event","bubbles","ownerDocument","node","nextItem","list","item","firstChild","nextElementSibling","previousItem","lastChild","previousElementSibling","moveFocus","currentFocus","traversalFunction","nextFocus","disabledFocus","disabled","getAttribute","focus","filterSelectOptionsByQuery","options","result","map","option","label","content","defaultLoadOptions","_ref2","_asyncToGenerator","_ref","_x","apply","arguments","useSelectField","args","readOnly","name","required","propsOptions","loadOptions","treatQueryAsValue","defaultValue","onChangeOption","open","setOpen","setQuery","setValue","selectedOptionsCache","setOptions","rootRef","originalInputRef","listRef","pseudoInputRef","selectedOptions","then","inputProps","tabIndex","autoComplete","autoCorrect","autoCapitalize","spellCheck","onFocus","_pseudoInputRef$curre","currentTarget","blur","displayValue","_ref3","_selectedOptionsCache","find","rootProps","updateValue","pseudoInputProps","onChange","onClick","activeElement","onKeyDown","prev","preventDefault","nativeEvent","isComposing","listProps","role","listItems","selected","props","_pseudoInputRef$curre2","click","openList"],"sources":["../../../src/SelectField/index.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nconst useOnClickOutside = (\n ref: React.RefObject<HTMLElement> | React.RefObject<HTMLElement>[],\n handler?: (event: MouseEvent | TouchEvent) => void\n) => {\n useEffect(() => {\n if (!handler) {\n return undefined;\n }\n const listener = (event: MouseEvent | TouchEvent) => {\n if (Array.isArray(ref)) {\n for (let i = 0; i < ref.length; i++) {\n const element = ref[i].current;\n // 1つ目の要素がないからといって、2つ目の要素もなくクリック範囲に含まれていないとは言えない。\n if (element && element.contains(event.composedPath()[0] as Node)) {\n return;\n }\n }\n } else {\n if (\n !ref.current ||\n ref.current.contains(event.composedPath()[0] as Node)\n ) {\n return;\n }\n }\n\n handler(event);\n };\n\n document.addEventListener(\"mousedown\", listener);\n document.addEventListener(\"touchstart\", listener);\n\n return () => {\n document.removeEventListener(\"mousedown\", listener);\n document.removeEventListener(\"touchstart\", listener);\n };\n }, [ref, handler]);\n};\n\nconst getSearch = <\n T extends {\n keys: string[];\n }\n>(\n items: T[],\n query: string\n) => {\n const copy = items.slice();\n const len = items.length;\n const key = query.toLowerCase();\n let i = -1;\n let c = 0;\n let tmp: {\n keys: string[];\n };\n const res = new Array(len);\n while (++i !== len) {\n tmp = copy[i];\n /**\n * Caluculate Minimum Index\n */\n let j = -1;\n let index = -1;\n const keylen = tmp.keys.length;\n let current;\n while (++j !== keylen) {\n current = tmp.keys[j].toLowerCase().indexOf(key);\n if (index === -1 || (current !== -1 && current < index)) {\n index = current;\n }\n }\n /**\n * Caluculate Score\n */\n const score = index > -1 ? 1 / (index + 1) : 0;\n if (score > 0) {\n res[c++] = { ...tmp, score };\n }\n }\n\n res.length = c;\n res.sort((a, b) => {\n if (a.score <= b.score) {\n return 1;\n } else {\n return -1;\n }\n });\n return res;\n};\n\nconst dispatchChangeEvent = (\n element: HTMLInputElement | HTMLTextAreaElement,\n value?: string | number\n) => {\n const nativeInputValueSetter = Object.getOwnPropertyDescriptor(\n element.tagName.toLowerCase() === \"input\"\n ? HTMLInputElement.prototype\n : HTMLTextAreaElement.prototype,\n \"value\"\n )?.set;\n\n nativeInputValueSetter?.call(element, value);\n\n element.dispatchEvent(new Event(\"change\", { bubbles: true }));\n};\n\nfunction ownerDocument(node: Node | null | undefined): Document {\n return (node && node.ownerDocument) || document;\n}\n\ntype TraversalFunction = (\n list: HTMLUListElement,\n item?: Element | null\n) => ChildNode | null;\n\nconst nextItem: TraversalFunction = (list, item) => {\n if (list === item) {\n return list.firstChild;\n }\n if (item && item.nextElementSibling) {\n return item.nextElementSibling;\n }\n return list.firstChild;\n};\n\nconst previousItem: TraversalFunction = (list, item) => {\n if (list === item) {\n return list.lastChild;\n }\n if (item && item.previousElementSibling) {\n return item.previousElementSibling;\n }\n return list.lastChild;\n};\n\nconst moveFocus = (\n list: HTMLUListElement,\n currentFocus: Element | null,\n traversalFunction: TraversalFunction\n) => {\n let nextFocus = traversalFunction(list, currentFocus) as HTMLElement | null;\n while (nextFocus) {\n if (\n currentFocus === null\n ? nextFocus === list.lastChild\n : nextFocus === currentFocus\n ) {\n break;\n }\n const disabledFocus =\n (nextFocus as HTMLInputElement).disabled ||\n nextFocus.getAttribute(\"aria-disabled\") === \"true\";\n if (disabledFocus) {\n nextFocus = traversalFunction(list, nextFocus) as HTMLElement;\n } else {\n nextFocus.focus();\n break;\n }\n }\n};\n\nexport const filterSelectOptionsByQuery = <\n T extends SelectOptionValue = SelectOptionValue\n>(\n options: T[],\n query: string\n) => {\n const result = getSearch(\n options.map((option) => {\n return {\n ...option,\n keys: option.keys || [option.label],\n content: option.value,\n };\n }),\n query\n );\n return result;\n};\n\nconst defaultLoadOptions = async <\n T extends SelectOptionValue = SelectOptionValue\n>({\n query,\n options,\n}: {\n query: string;\n options?: T[];\n}): Promise<T[] | undefined> => {\n if (options === undefined) {\n return undefined;\n }\n if (query === undefined) {\n return options;\n }\n const result = filterSelectOptionsByQuery(options, query);\n return result.length ? result : options;\n};\n\nexport type SelectLoadOptions<T extends SelectOptionValue = SelectOptionValue> =\n (args: {\n query: string;\n options?: T[];\n selectedOptions?: T[];\n }) => Promise<T[] | undefined>;\n\nexport interface SelectOptionValue {\n value: string | undefined;\n label: string;\n keys?: string[];\n [key: string]: unknown;\n}\n\ninterface UseSelectFieldArgs<T extends SelectOptionValue> {\n /**\n * 選択肢の初期値を指定する。\n */\n defaultValue?: string;\n /**\n * 選択肢の選択が可能かどうか指定する。\n * @default false\n */\n readOnly?: boolean;\n /**\n * 選択肢の選択が必須かどうか指定する。\n * @default false\n */\n required?: boolean;\n /**\n * input要素に渡したいname属性を指定する。\n */\n name?: string;\n /**\n * queryに応じて選択肢をロードする関数を指定する。\n * この関数で返された選択肢が、選択肢として表示される。\n */\n loadOptions?: SelectLoadOptions<T>;\n /**\n * 選択肢を指定する。\n * 各選択肢は、valueとlabel及び任意のプロパティを持つオブジェクトである必要がある。\n */\n options?: T[];\n /**\n * このフラグがtrueの場合、queryもvalueとして扱えるようになる\n * @default false\n */\n treatQueryAsValue?: boolean;\n /**\n * 選択肢が変更された時に呼ばれるコールバック関数を指定する。\n */\n onChangeOption?: (option: T) => void;\n}\n\ninterface UseSelectFieldResult<T extends SelectOptionValue> {\n /**\n * 表示用の文字列。\n */\n displayValue: string | undefined;\n /**\n * 検索用に入力された文字列。\n */\n query: string;\n /**\n * input要素に渡される値。\n */\n value: string | undefined;\n /**\n * 選択肢のリストを開くかどうか。\n */\n openList: boolean;\n /**\n * 実態となるinput要素に渡すprops\n */\n inputProps: React.ComponentPropsWithRef<\"input\">;\n /**\n * 擬似的なinput要素つまり検索用のinput要素に渡すprops\n */\n pseudoInputProps: React.ComponentPropsWithRef<\"input\">;\n /**\n * 選択肢のリストに渡すprops\n */\n listProps: React.ComponentPropsWithRef<\"ul\">;\n /**\n * 選択肢のリストの各要素に渡すpropsと、各選択肢、及びkeyを持つオブジェクトの配列。\n */\n listItems?: {\n key: string;\n option: T;\n props: React.ComponentPropsWithoutRef<\"li\">;\n }[];\n /**\n * 全ての要素の親となる要素に渡すprops\n */\n rootProps: React.ComponentPropsWithRef<\"div\">;\n}\n\nexport const useSelectField = <T extends SelectOptionValue>(\n args: UseSelectFieldArgs<T>\n): UseSelectFieldResult<T> => {\n const {\n readOnly = false,\n name,\n required = false,\n options: propsOptions,\n loadOptions = defaultLoadOptions,\n treatQueryAsValue = false,\n defaultValue = undefined,\n onChangeOption,\n } = args;\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const [value, setValue] = useState<string | undefined>(defaultValue);\n\n const selectedOptionsCache = useRef<T[] | undefined>(propsOptions);\n const [options, setOptions] = useState(propsOptions);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const originalInputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n const pseudoInputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n void loadOptions({\n query,\n options: propsOptions,\n selectedOptions: selectedOptionsCache.current,\n }).then((result) => {\n setOptions(result);\n });\n }, [propsOptions, loadOptions, query]);\n\n const inputProps = useMemo((): React.ComponentPropsWithRef<\"input\"> => {\n return {\n ref: originalInputRef,\n required: required,\n name: name,\n defaultValue: value,\n key: value,\n tabIndex: -1,\n autoComplete: \"off\",\n autoCorrect: \"off\",\n autoCapitalize: \"none\",\n spellCheck: false,\n onFocus: (event) => {\n event.currentTarget.blur();\n pseudoInputRef.current?.focus();\n },\n };\n }, [name, required, value]);\n\n const displayValue = useMemo(() => {\n return (\n selectedOptionsCache.current?.find((option) => option.value === value) ||\n options?.find((option) => option.value === value)\n )?.label;\n }, [options, value]);\n\n const rootProps = useMemo(() => {\n return {\n ref: rootRef,\n };\n }, []);\n\n useOnClickOutside([rootRef, listRef], () => {\n setOpen(false);\n setQuery(\"\");\n });\n\n const updateValue = useCallback(\n (option: T) => {\n const value = option.value;\n setValue(value);\n if (onChangeOption) {\n onChangeOption(option);\n }\n selectedOptionsCache.current = options;\n if (originalInputRef.current) {\n dispatchChangeEvent(originalInputRef.current, value);\n }\n },\n [onChangeOption, options]\n );\n\n const pseudoInputProps = useMemo((): React.ComponentPropsWithRef<\"input\"> => {\n return {\n ref: pseudoInputRef,\n value: query,\n autoComplete: \"off\",\n autoCorrect: \"off\",\n autoCapitalize: \"none\",\n spellCheck: false,\n tabIndex: 0,\n onChange: (event: React.ChangeEvent<HTMLInputElement>) => {\n const query = event.currentTarget.value;\n setQuery(query);\n if (treatQueryAsValue) {\n updateValue({\n label: query,\n value: query,\n } as T);\n }\n },\n onClick: (event) => {\n /**\n * ユーザーがフォーカスされている状態で入力要素をクリックするのは、\n * ユーザーが選択肢を一度選択してから再度選択したいケースと想定されるため、リストを再度開く。\n */\n if (event.currentTarget === document.activeElement) {\n setOpen(true);\n }\n },\n onFocus: () => {\n if (readOnly !== true) {\n setOpen(true);\n }\n },\n onKeyDown: (event: React.KeyboardEvent<HTMLInputElement>) => {\n const { key } = event;\n if (key === \"Delete\" || key === \"Backspace\") {\n setQuery((prev) => {\n if (prev === \"\") {\n setValue(undefined);\n }\n return prev;\n });\n } else if (key === \"ArrowDown\") {\n event.preventDefault();\n const list = listRef.current;\n if (list) {\n moveFocus(list, null, nextItem);\n }\n } else if (\n treatQueryAsValue &&\n event.nativeEvent.isComposing === false &&\n key === \"Enter\"\n ) {\n if (treatQueryAsValue) {\n selectedOptionsCache.current = [\n {\n value: query,\n label: query,\n } as T,\n ];\n }\n setOpen(false);\n } else if (event.key.length === 1) {\n setOpen(true);\n }\n },\n };\n }, [query, treatQueryAsValue, updateValue, readOnly]);\n\n const listProps = useMemo(() => {\n return {\n ref: listRef,\n role: \"listbox\",\n tabIndex: -1,\n onKeyDown: (event: React.KeyboardEvent<HTMLUListElement>) => {\n const key = event.key;\n const list = listRef.current;\n if (list === null) {\n return;\n }\n const currentFocus = ownerDocument(list).activeElement;\n if (key === \"ArrowDown\") {\n event.preventDefault();\n moveFocus(list, currentFocus, nextItem);\n } else if (key === \"ArrowUp\") {\n event.preventDefault();\n moveFocus(list, currentFocus, previousItem);\n }\n },\n };\n }, []);\n\n const listItems = useMemo(() => {\n return options?.map((option, index) => {\n const selected = option.value === value;\n return {\n key: `${option.value}-${index}`,\n option,\n props: {\n role: \"option\",\n \"aria-selected\": selected,\n /**\n * 何も選択されていないときは、先頭のオプションに飛べるようにする\n */\n tabIndex: (value === undefined ? index === 0 : selected) ? -1 : -1,\n onClick: () => {\n updateValue(option);\n setQuery(\"\");\n pseudoInputRef?.current?.focus();\n setOpen(false);\n },\n onKeyDown: (event: React.KeyboardEvent<HTMLLIElement>) => {\n const key = event.key;\n if (key === \"Enter\" || key === \" \") {\n event.preventDefault();\n event.currentTarget.click();\n }\n },\n },\n };\n });\n }, [options, updateValue, value]);\n\n const result = useMemo(() => {\n return {\n displayValue,\n query,\n value,\n openList: open,\n inputProps,\n pseudoInputProps,\n listProps,\n listItems,\n rootProps,\n };\n }, [\n displayValue,\n inputProps,\n listItems,\n listProps,\n open,\n pseudoInputProps,\n query,\n rootProps,\n value,\n ]);\n return result;\n};\n"],"mappings":"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"}
|