@luomus/laji-form 15.1.53 → 15.1.55
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/laji-form.js +1 -1
- package/dist/styles.css +7 -1
- package/lib/components/LajiForm.d.ts +2 -0
- package/lib/components/LajiForm.js +2 -0
- package/lib/components/fields/CondensedObjectField.d.ts +38 -0
- package/lib/components/fields/CondensedObjectField.js +146 -0
- package/lib/components/fields/ConditionalUiSchemaField.js +2 -2
- package/lib/components/fields/HiddenWithTextField.d.ts +18 -0
- package/lib/components/fields/HiddenWithTextField.js +20 -0
- package/lib/components/fields/MapField.d.ts +6 -1
- package/lib/components/fields/MapField.js +69 -29
- package/lib/components/widgets/AutosuggestWidget.js +6 -7
- package/lib/components/widgets/InputGroupWidget.d.ts +1 -1
- package/lib/components/widgets/InputGroupWidget.js +1 -1
- package/lib/components/widgets/SelectWidget.js +44 -43
- package/lib/translations.json +5 -0
- package/lib/utils.js +3 -0
- package/package.json +1 -1
- package/test-export/test-utils.js +10 -3
|
@@ -56,6 +56,7 @@ exports.default = SelectWidget;
|
|
|
56
56
|
function SearchableDrowndown(props) {
|
|
57
57
|
const { id, disabled, readonly, value, uiSchema, options, onChange, includeEmpty = true } = props;
|
|
58
58
|
const { theme } = react_1.useContext(ReactContext_1.default);
|
|
59
|
+
const { FormControl } = theme;
|
|
59
60
|
const containerRef = react_1.useRef(null);
|
|
60
61
|
const inputRef = react_1.useRef(null);
|
|
61
62
|
const dropdownRef = react_1.useRef(null);
|
|
@@ -66,35 +67,28 @@ function SearchableDrowndown(props) {
|
|
|
66
67
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
67
68
|
? enumOptions.find(item => item.value === value).label
|
|
68
69
|
: "", [enumOptions]);
|
|
69
|
-
const [
|
|
70
|
-
const [
|
|
71
|
-
const [filterTerm, setFilterTerm] = react_1.useState("");
|
|
72
|
-
const onInputChange = react_1.useCallback((e) => {
|
|
73
|
-
const { value } = e.target;
|
|
74
|
-
setInputValue(value);
|
|
75
|
-
setInputTouched(true);
|
|
76
|
-
}, []);
|
|
77
|
-
react_1.useEffect(() => {
|
|
78
|
-
inputTouched && setFilterTerm(inputValue);
|
|
79
|
-
}, [inputTouched, inputValue]);
|
|
80
|
-
// Sync inputValue if value changes.
|
|
81
|
-
react_1.useEffect(() => {
|
|
82
|
-
if (inputTouched) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
setInputValue(getLabelFromValue(value));
|
|
86
|
-
}, [inputTouched, value, enumOptions, getLabelFromValue]);
|
|
70
|
+
const [filterTerm, setFilterTerm] = react_1.useState(undefined);
|
|
71
|
+
const [isOpen, show, hide] = utils_1.useBooleanSetter(false);
|
|
87
72
|
const displayedEnums = react_1.useMemo(() => {
|
|
88
|
-
return filterTerm !== ""
|
|
73
|
+
return filterTerm !== undefined && filterTerm !== ""
|
|
89
74
|
? enumOptions.filter(({ label }) => label.toLowerCase().match(filterTerm.toLowerCase()))
|
|
90
75
|
: enumOptions;
|
|
91
76
|
}, [filterTerm, enumOptions]);
|
|
92
|
-
const [isOpen, show, hide] = utils_1.useBooleanSetter(false);
|
|
93
|
-
const { FormControl } = theme;
|
|
94
77
|
const [activeIdx, activeIdxUp, activeIdxDown, setActiveIdx] = useRangeIncrementor((displayedEnums || []).length, getDefaultActiveIdx(displayedEnums, value));
|
|
78
|
+
const inputValue = filterTerm !== null && filterTerm !== void 0 ? filterTerm : getLabelFromValue(value);
|
|
79
|
+
const showAndSelectText = react_1.useCallback(() => {
|
|
80
|
+
var _a;
|
|
81
|
+
show();
|
|
82
|
+
(_a = react_dom_1.findDOMNode(inputRef.current)) === null || _a === void 0 ? void 0 : _a.setSelectionRange(0, inputValue.length);
|
|
83
|
+
}, [show, inputValue.length]);
|
|
84
|
+
const onInputChange = react_1.useCallback((e) => {
|
|
85
|
+
const { value } = e.target;
|
|
86
|
+
setFilterTerm(value);
|
|
87
|
+
setActiveIdx(0);
|
|
88
|
+
}, [setActiveIdx]);
|
|
95
89
|
const onItemSelected = react_1.useCallback((item) => {
|
|
96
90
|
onChange(item.value);
|
|
97
|
-
|
|
91
|
+
setFilterTerm(undefined);
|
|
98
92
|
setActiveIdx(displayedEnums.findIndex(enu => enu.value === item.value));
|
|
99
93
|
hide();
|
|
100
94
|
}, [displayedEnums, hide, onChange, setActiveIdx]);
|
|
@@ -109,39 +103,46 @@ function SearchableDrowndown(props) {
|
|
|
109
103
|
onItemSelected(displayedEnums[activeIdx]);
|
|
110
104
|
}
|
|
111
105
|
else {
|
|
112
|
-
|
|
106
|
+
setFilterTerm(undefined);
|
|
113
107
|
}
|
|
114
108
|
hide();
|
|
115
109
|
}, [activeIdx, displayedEnums, hide, onItemSelected]);
|
|
116
110
|
const onKeyDown = react_1.useCallback((e) => {
|
|
117
111
|
switch (e.key) {
|
|
118
112
|
case "ArrowDown":
|
|
119
|
-
|
|
113
|
+
if (!isOpen) {
|
|
114
|
+
showAndSelectText();
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
activeIdxDown();
|
|
118
|
+
}
|
|
120
119
|
e.preventDefault();
|
|
121
120
|
break;
|
|
122
121
|
case "ArrowUp":
|
|
123
|
-
|
|
122
|
+
if (!isOpen) {
|
|
123
|
+
showAndSelectText();
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
activeIdxUp();
|
|
127
|
+
}
|
|
124
128
|
e.preventDefault();
|
|
125
129
|
break;
|
|
126
130
|
case "Enter":
|
|
127
|
-
activeIdx !== undefined && displayedEnums
|
|
131
|
+
if (activeIdx !== undefined && displayedEnums) {
|
|
132
|
+
onItemSelected(displayedEnums[activeIdx]);
|
|
133
|
+
}
|
|
128
134
|
e.preventDefault();
|
|
129
135
|
break;
|
|
130
136
|
case "Escape":
|
|
131
|
-
|
|
137
|
+
setFilterTerm(undefined);
|
|
132
138
|
setActiveIdx(getDefaultActiveIdx(displayedEnums, value));
|
|
133
139
|
e.preventDefault();
|
|
134
140
|
break;
|
|
135
141
|
}
|
|
136
|
-
}, [activeIdx, activeIdxDown, activeIdxUp, displayedEnums, onItemSelected, setActiveIdx, value]);
|
|
137
|
-
const onFocus = react_1.useCallback(() => {
|
|
138
|
-
var _a;
|
|
139
|
-
show();
|
|
140
|
-
(_a = react_dom_1.findDOMNode(inputRef.current)) === null || _a === void 0 ? void 0 : _a.setSelectionRange(0, inputValue.length);
|
|
141
|
-
}, [inputValue.length, show]);
|
|
142
|
+
}, [activeIdx, activeIdxDown, activeIdxUp, displayedEnums, isOpen, onItemSelected, setActiveIdx, showAndSelectText, value]);
|
|
142
143
|
return (React.createElement("div", { onBlur: onBlur, onKeyDown: onKeyDown, ref: containerRef, style: { position: "relative" }, className: "laji-form-dropdown-container" },
|
|
143
|
-
React.createElement(FormControl, { disabled: disabled || readonly, id: id, onFocus:
|
|
144
|
-
React.createElement(Caret,
|
|
144
|
+
React.createElement(FormControl, { disabled: disabled || readonly, id: id, onClick: showAndSelectText, onFocus: showAndSelectText, value: inputValue, onChange: onInputChange, autoComplete: "off", ref: inputRef }),
|
|
145
|
+
React.createElement(Caret, null),
|
|
145
146
|
React.createElement("div", { className: `laji-form-dropdown laji-form-dropdown-${isOpen ? "open" : "closed"}`, style: { position: "absolute" }, tabIndex: -1, ref: dropdownRef }, displayedEnums.map((oneOf, idx) => {
|
|
146
147
|
var _a;
|
|
147
148
|
return (React.createElement(ListItem, { key: (_a = oneOf.value) !== null && _a !== void 0 ? _a : "", onSelected: onItemSelected, active: idx === activeIdx }, oneOf));
|
|
@@ -153,7 +154,7 @@ function SearchableMultiDrowndown(props) {
|
|
|
153
154
|
? undefined
|
|
154
155
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
155
156
|
: getEnumOptions(options.enumOptions, uiSchema, false));
|
|
156
|
-
const [inputValue,
|
|
157
|
+
const [inputValue, setUserTypedInputValue] = react_1.useState("");
|
|
157
158
|
const [filterTerm, setFilterTerm] = react_1.useState("");
|
|
158
159
|
const [loading, setLoading] = react_1.useState(undefined);
|
|
159
160
|
const [isOpen, show, hide] = utils_1.useBooleanSetter(false);
|
|
@@ -161,7 +162,7 @@ function SearchableMultiDrowndown(props) {
|
|
|
161
162
|
const inputRef = React.useRef(null);
|
|
162
163
|
const onInputChange = react_1.useCallback((e) => {
|
|
163
164
|
const { value } = e.target;
|
|
164
|
-
|
|
165
|
+
setUserTypedInputValue(value);
|
|
165
166
|
}, []);
|
|
166
167
|
React.useEffect(() => {
|
|
167
168
|
setFilterTerm(inputValue);
|
|
@@ -244,7 +245,7 @@ function SearchableMultiDrowndown(props) {
|
|
|
244
245
|
onItemSelectedByBlur(displayedEnums[activeIdx]);
|
|
245
246
|
}
|
|
246
247
|
else {
|
|
247
|
-
|
|
248
|
+
setUserTypedInputValue("");
|
|
248
249
|
}
|
|
249
250
|
}, [activeIdx, displayedEnums, hide, onItemSelectedByBlur, setBlurred]);
|
|
250
251
|
const onKeyDown = react_1.useCallback((e) => {
|
|
@@ -262,7 +263,7 @@ function SearchableMultiDrowndown(props) {
|
|
|
262
263
|
e.preventDefault();
|
|
263
264
|
break;
|
|
264
265
|
case "Escape":
|
|
265
|
-
|
|
266
|
+
setUserTypedInputValue("");
|
|
266
267
|
setActiveIdx(undefined);
|
|
267
268
|
e.preventDefault();
|
|
268
269
|
break;
|
|
@@ -296,7 +297,7 @@ function SearchableMultiDrowndown(props) {
|
|
|
296
297
|
.map(enu => React.createElement(SelectedMultiValue, { key: enu.value, onDelete: onDelete, readonly: readonly || disabled }, enu))),
|
|
297
298
|
React.createElement("input", { disabled: disabled || readonly, id: id, onFocus: onFocus, value: inputValue, onChange: onInputChange, autoComplete: "off", ref: inputRef }),
|
|
298
299
|
loading && React.createElement(Spinner, null)),
|
|
299
|
-
React.createElement(Caret,
|
|
300
|
+
React.createElement(Caret, null),
|
|
300
301
|
React.createElement("div", { className: `laji-form-dropdown laji-form-dropdown-${isOpen ? "open" : "closed"}`, style: { position: "absolute", zIndex: 99999 }, tabIndex: -1 }, displayedEnums.map((oneOf, idx) => {
|
|
301
302
|
var _a;
|
|
302
303
|
return (React.createElement(ListItem, { key: (_a = oneOf.value) !== null && _a !== void 0 ? _a : "", onSelected: onItemSelected, active: idx === activeIdx }, oneOf));
|
|
@@ -308,9 +309,9 @@ const SelectedMultiValue = ({ children: enu, onDelete, readonly }) => {
|
|
|
308
309
|
enu.label,
|
|
309
310
|
React.createElement("span", { tabIndex: readonly ? undefined : 0, role: readonly ? undefined : "button", onClick: onDeleteClick }, "\u00D7")));
|
|
310
311
|
};
|
|
311
|
-
const Caret = (
|
|
312
|
-
React.createElement("span", {
|
|
313
|
-
React.createElement("img", { src: "https://cdn.laji.fi/images/icons/caret-down.svg" })));
|
|
312
|
+
const Caret = () => (React.createElement("div", { className: "laji-form-dropdown-caret-container", style: { position: "absolute", pointerEvents: "none" } },
|
|
313
|
+
React.createElement("span", { className: "laji-form-dropdown-caret" },
|
|
314
|
+
React.createElement("img", { src: "https://cdn.laji.fi/images/icons/caret-down.svg" }))));
|
|
314
315
|
function ListItem({ onSelected, active, children }) {
|
|
315
316
|
const onClick = react_1.useCallback(() => {
|
|
316
317
|
onSelected(children);
|
package/lib/translations.json
CHANGED
package/lib/utils.js
CHANGED
|
@@ -784,6 +784,9 @@ function checkRules(rules, props, cache, prop = "formData") {
|
|
|
784
784
|
if (_rule === "isAdmin") {
|
|
785
785
|
passes = props.formContext.uiSchemaContext.isAdmin;
|
|
786
786
|
}
|
|
787
|
+
else if (_rule === "isLoggedIn") {
|
|
788
|
+
passes = props.formContext.uiSchemaContext.creator;
|
|
789
|
+
}
|
|
787
790
|
else if (_rule === "isEdit") {
|
|
788
791
|
passes = props.formContext.uiSchemaContext.isEdit;
|
|
789
792
|
}
|
package/package.json
CHANGED
|
@@ -292,9 +292,16 @@ class DemoPageForm extends Form {
|
|
|
292
292
|
return this.page.evaluate(`window.lajiForm.${path}`);
|
|
293
293
|
}
|
|
294
294
|
setState(state) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
295
|
+
return this.page.evaluate((state) => {
|
|
296
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
297
|
+
// @ts-ignore
|
|
298
|
+
const onSubmit = function (data) { window.submittedData = data.formData; };
|
|
299
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
300
|
+
// @ts-ignore
|
|
301
|
+
const onChange = function (formData) { window.changedData = formData; };
|
|
302
|
+
return window.lajiForm.setState(Object.assign({ onSubmit,
|
|
303
|
+
onChange }, (state || {})));
|
|
304
|
+
}, state);
|
|
298
305
|
}
|
|
299
306
|
getState() {
|
|
300
307
|
return this.page.evaluate(() => {
|