@nolwenture/formik-jsonschema-form 0.20.0 → 0.21.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.
|
@@ -1,21 +1,48 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
1
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { useExtractUiSchema, useSetDefault } from "../hooks";
|
|
4
|
-
import { FormRegistry } from "../Form";
|
|
13
|
+
import { useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
5
14
|
import { useField } from "formik";
|
|
15
|
+
import { FormRegistry } from "../Form";
|
|
16
|
+
import { useExtractUiSchema, useSetDefault } from "../hooks";
|
|
6
17
|
import { getEnums } from "../utils";
|
|
7
18
|
export const SearchableSelectField = (props) => {
|
|
8
19
|
const { templates: { FieldTemplate }, components: { SearchableSelectContainer, SearchDropdownContainer, SearchListOption, SearchListExpand, SearchNotFound, SearchInput, SearchClearButton, SearchInputContainer, }, } = useContext(FormRegistry);
|
|
9
20
|
useSetDefault(props);
|
|
10
|
-
const
|
|
11
|
-
|
|
21
|
+
const ListOption = (props) => {
|
|
22
|
+
const { isActive, children } = props, rest = __rest(props, ["isActive", "children"]);
|
|
23
|
+
const ref = useRef();
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (isActive) {
|
|
26
|
+
ref.current.scrollIntoView({
|
|
27
|
+
behavior: "smooth",
|
|
28
|
+
block: "center",
|
|
29
|
+
inline: "center",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}, [isActive]);
|
|
33
|
+
return (_jsx(SearchListOption, Object.assign({ ref: ref }, rest, { children: children })));
|
|
34
|
+
};
|
|
35
|
+
const { name, uiSchema, onChange } = props;
|
|
36
|
+
const { props: inputProps, placeholder, clearButtonText, expandText, notFoundMessage, hoverColors = {}, hideClearButton = false, showOptionsMenu = false, // makes CSS styling easier
|
|
37
|
+
} = useExtractUiSchema(uiSchema);
|
|
12
38
|
const [{ value }, __, { setValue }] = useField(name);
|
|
13
39
|
const enums = useMemo(() => getEnums(props), [props]);
|
|
14
40
|
const options = (enums === null || enums === void 0 ? void 0 : enums.values) || [];
|
|
15
|
-
const [showOptions, setShowOptions] = useState(
|
|
41
|
+
const [showOptions, setShowOptions] = useState(showOptionsMenu);
|
|
16
42
|
const [searchTerm, setSearchTerm] = useState(() => { var _a, _b; return (_b = (_a = options.find((option) => option.const === value)) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : ""; });
|
|
17
43
|
const [displayedItems, setDisplayedItems] = useState([]);
|
|
18
44
|
const [itemsToShow, setItemsToShow] = useState(10);
|
|
45
|
+
const [selectedItem, setSelectedItem] = useState(-1);
|
|
19
46
|
const moreRef = useRef(null);
|
|
20
47
|
const containerRef = useRef(null);
|
|
21
48
|
const loadMoreItems = () => {
|
|
@@ -26,10 +53,48 @@ export const SearchableSelectField = (props) => {
|
|
|
26
53
|
.filter((option) => { var _a, _b; return ((_b = (_a = option.title) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : "").includes(searchTerm.toLowerCase()); })
|
|
27
54
|
.slice(0, itemsToShow));
|
|
28
55
|
}, [itemsToShow, options, searchTerm]);
|
|
56
|
+
const handleKeyPress = (event) => {
|
|
57
|
+
if (showOptions) {
|
|
58
|
+
switch (event.key) {
|
|
59
|
+
case "ArrowUp": {
|
|
60
|
+
const calcValue = selectedItem - 1;
|
|
61
|
+
const newValue = calcValue < -1 ? -1 : calcValue;
|
|
62
|
+
return setSelectedItem(newValue);
|
|
63
|
+
}
|
|
64
|
+
case "ArrowDown": {
|
|
65
|
+
const calcValue = selectedItem + 1;
|
|
66
|
+
const newValue = calcValue >= displayedItems.length - 1
|
|
67
|
+
? displayedItems.length - 1
|
|
68
|
+
: calcValue;
|
|
69
|
+
return setSelectedItem(newValue);
|
|
70
|
+
}
|
|
71
|
+
case "Escape": {
|
|
72
|
+
return setShowOptions(false);
|
|
73
|
+
}
|
|
74
|
+
case "Enter": {
|
|
75
|
+
const item = displayedItems[selectedItem];
|
|
76
|
+
if (item) {
|
|
77
|
+
return handleSelect(item);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
// attach the event listener
|
|
86
|
+
document.addEventListener("keydown", handleKeyPress);
|
|
87
|
+
// remove the event listener
|
|
88
|
+
return () => {
|
|
89
|
+
document.removeEventListener("keydown", handleKeyPress);
|
|
90
|
+
};
|
|
91
|
+
}, [handleKeyPress]);
|
|
29
92
|
const handleSearchChange = (event) => {
|
|
30
93
|
setSearchTerm(event.target.value);
|
|
31
94
|
setItemsToShow(10);
|
|
32
95
|
setShowOptions(true);
|
|
96
|
+
setSelectedItem(-1);
|
|
97
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(event);
|
|
33
98
|
};
|
|
34
99
|
const handleSelect = (item) => {
|
|
35
100
|
var _a;
|
|
@@ -53,5 +118,10 @@ export const SearchableSelectField = (props) => {
|
|
|
53
118
|
const filteredOptions = options.filter((option) => { var _a, _b; return ((_b = (_a = option.title) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== null && _b !== void 0 ? _b : "").includes(searchTerm.toLowerCase()); });
|
|
54
119
|
const showMoreOption = displayedItems.length < filteredOptions.length &&
|
|
55
120
|
displayedItems.length >= 10;
|
|
56
|
-
return (_jsx(FieldTemplate, Object.assign({}, props, { children: _jsxs(SearchableSelectContainer, { ref: containerRef, onBlur: handleBlur, children: [_jsxs(SearchInputContainer, { children: [_jsx(SearchInput, Object.assign({}, inputProps, { name: name, type: "text", placeholder: placeholder, value: searchTerm, onChange: handleSearchChange, onFocus: handleFocus })), searchTerm && (_jsx(SearchClearButton, { onClick: handleClear, children: clearButtonText !== null && clearButtonText !== void 0 ? clearButtonText : "x" }))] }), showOptions && (_jsxs(SearchDropdownContainer, { role: "dropdown-list", ref: moreRef, children: [displayedItems.length > 0 ? (displayedItems.map((item, index) => (_jsx(
|
|
121
|
+
return (_jsx(FieldTemplate, Object.assign({}, props, { children: _jsxs(SearchableSelectContainer, { ref: containerRef, onBlur: handleBlur, children: [_jsxs(SearchInputContainer, { children: [_jsx(SearchInput, Object.assign({}, inputProps, { name: name, type: "text", placeholder: placeholder, value: searchTerm, onChange: handleSearchChange, onFocus: handleFocus })), searchTerm && !hideClearButton && (_jsx(SearchClearButton, { onClick: handleClear, children: clearButtonText !== null && clearButtonText !== void 0 ? clearButtonText : "x" }))] }), showOptions && (_jsxs(SearchDropdownContainer, { role: "dropdown-list", ref: moreRef, children: [displayedItems.length > 0 ? (displayedItems.map((item, index) => (_jsx(ListOption, { isActive: index === selectedItem, style: index === selectedItem
|
|
122
|
+
? {
|
|
123
|
+
backgroundColor: hoverColors.backgroundColor,
|
|
124
|
+
color: hoverColors.color,
|
|
125
|
+
}
|
|
126
|
+
: {}, role: "filtered-list", onClick: () => handleSelect(item), onMouseDown: (e) => e.preventDefault(), children: item.title }, index)))) : (_jsx(SearchNotFound, { onMouseDown: (e) => e.preventDefault(), children: notFoundMessage !== null && notFoundMessage !== void 0 ? notFoundMessage : "No match found" })), showMoreOption && (_jsx(SearchListExpand, { ref: moreRef, onMouseDown: (e) => e.preventDefault(), onClick: loadMoreItems, children: expandText !== null && expandText !== void 0 ? expandText : "More..." }))] }))] }) })));
|
|
57
127
|
};
|
|
@@ -123,10 +123,11 @@ export function createValidationSchema(schema, definitions = {}, condition) {
|
|
|
123
123
|
const schemaDefinitions = Object.assign(Object.assign({}, definitions), ((_a = schema.definitions) !== null && _a !== void 0 ? _a : {}));
|
|
124
124
|
const requiredFields = schema.required;
|
|
125
125
|
function getValue(schema, key) {
|
|
126
|
-
|
|
126
|
+
let type = schema.type;
|
|
127
127
|
let yupSchema;
|
|
128
128
|
if (schema.properties) {
|
|
129
129
|
yupSchema = createValidationSchema(schema, schemaDefinitions);
|
|
130
|
+
type = type !== null && type !== void 0 ? type : "object";
|
|
130
131
|
}
|
|
131
132
|
else {
|
|
132
133
|
yupSchema = getYupType(type);
|