@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.
@@ -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 [inputValue, setInputValue] = react_1.useState(getLabelFromValue(value));
70
- const [inputTouched, setInputTouched] = react_1.useState(false);
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
- setInputTouched(false);
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
- setInputValue("");
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
- activeIdxDown();
113
+ if (!isOpen) {
114
+ showAndSelectText();
115
+ }
116
+ else {
117
+ activeIdxDown();
118
+ }
120
119
  e.preventDefault();
121
120
  break;
122
121
  case "ArrowUp":
123
- activeIdxUp();
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 && onItemSelected(displayedEnums[activeIdx]);
131
+ if (activeIdx !== undefined && displayedEnums) {
132
+ onItemSelected(displayedEnums[activeIdx]);
133
+ }
128
134
  e.preventDefault();
129
135
  break;
130
136
  case "Escape":
131
- setInputValue("");
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: onFocus, value: inputValue, onChange: onInputChange, autoComplete: "off", ref: inputRef }),
144
- React.createElement(Caret, { onFocus: onFocus }),
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, setInputValue] = react_1.useState("");
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
- setInputValue(value);
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
- setInputValue("");
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
- setInputValue("");
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, { onFocus: onFocus }),
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 = ({ onFocus }) => React.createElement("div", { className: "laji-form-dropdown-caret-container", style: { position: "absolute", pointerEvents: "none" } },
312
- React.createElement("span", { onFocus: onFocus, className: "laji-form-dropdown-caret" },
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);
@@ -873,5 +873,10 @@
873
873
  "fi": "Klikkaa järjestääksesi",
874
874
  "en": "Click to sort",
875
875
  "sv": "Klicka för att sortera"
876
+ },
877
+ "addField": {
878
+ "fi": "Lisää kenttä",
879
+ "en": "Add field",
880
+ "sv": "Lägg till fält"
876
881
  }
877
882
  }
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luomus/laji-form",
3
- "version": "15.1.53",
3
+ "version": "15.1.55",
4
4
  "description": "React module capable of building dynamic forms from Laji form json schemas",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -292,9 +292,16 @@ class DemoPageForm extends Form {
292
292
  return this.page.evaluate(`window.lajiForm.${path}`);
293
293
  }
294
294
  setState(state) {
295
- const onSubmit = "function(data) {window.submittedData = data.formData;}";
296
- const onChange = "function(formData) {window.changedData = formData;}";
297
- return this.e(`setState({onSubmit: ${onSubmit}, onChange: ${onChange}, ...${JSON.stringify(state)}})`);
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(() => {