@nolwenture/formik-jsonschema-form 0.18.0 → 0.19.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.
@@ -9,11 +9,11 @@ export const SearchableSelectField = (props) => {
9
9
  useSetDefault(props);
10
10
  const { name, uiSchema } = props;
11
11
  const { props: inputProps, placeholder, clearButtonText, expandText, notFoundMessage, } = useExtractUiSchema(uiSchema);
12
- const [_, __, { setValue }] = useField(name);
12
+ const [{ value }, __, { setValue }] = useField(name);
13
13
  const enums = useMemo(() => getEnums(props), [props]);
14
14
  const options = (enums === null || enums === void 0 ? void 0 : enums.values) || [];
15
15
  const [showOptions, setShowOptions] = useState(false);
16
- const [searchTerm, setSearchTerm] = useState("");
16
+ 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
17
  const [displayedItems, setDisplayedItems] = useState([]);
18
18
  const [itemsToShow, setItemsToShow] = useState(10);
19
19
  const moreRef = useRef(null);
@@ -53,5 +53,5 @@ export const SearchableSelectField = (props) => {
53
53
  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
54
  const showMoreOption = displayedItems.length < filteredOptions.length &&
55
55
  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, { 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(SearchListOption, { 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..." }))] }))] }) })));
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(SearchListOption, { 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
57
  };
@@ -318,7 +318,7 @@ export const completeUiSchema = {
318
318
  "ui:field": "SearchableSelectField",
319
319
  "ui:options": {
320
320
  placeholder: "Search...",
321
- clearButtonText: "Clear",
321
+ clearButtonText: "X",
322
322
  expandText: "More results",
323
323
  emptySearchMessage: "...no matching results found",
324
324
  },
@@ -167,6 +167,7 @@ export declare const RadioButtonField: {
167
167
  };
168
168
  export declare const MultipleChoiceField: ({ inputProps, name, className, enums, style, }: MultipleChoiceFieldProps) => import("react/jsx-runtime").JSX.Element;
169
169
  export declare const MultiSelectContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
170
+ export declare const MultiSelectSearchContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
170
171
  export declare const MultiSelectInput: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<Omit<import("styled-components/dist/types").FastOmit<Omit<Omit<any, "as">, "ref"> & {
171
172
  ref?: unknown;
172
173
  }, never>, "ref"> & {
@@ -184,6 +185,7 @@ export declare const SearchableMultiTagSelectField: {
184
185
  ({ name, placeholder, enums, emptySearchMessage, closeElement, className, }: SelectFieldProps): import("react/jsx-runtime").JSX.Element;
185
186
  styles: {
186
187
  MultiSelectContainerStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
188
+ MultiSelectSearchContainerStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
187
189
  MultiSelectInputStyle: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<Omit<import("styled-components/dist/types").FastOmit<Omit<Omit<any, "as">, "ref"> & {
188
190
  ref?: unknown;
189
191
  }, never>, "ref"> & {
@@ -236,6 +238,6 @@ export declare const SearchInput: import("styled-components").IStyledComponent<"
236
238
  }, never>> & Omit<import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<Omit<Omit<any, "as">, "ref"> & {
237
239
  ref?: unknown;
238
240
  }, never>> & Omit<({ formikAs, ...props }: Omit<formik.FieldAttributes<any>, "as">) => import("react/jsx-runtime").JSX.Element, keyof React.Component<any, {}, any>>, keyof React.Component<any, {}, any>>;
239
- export declare const SearchClearButton: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>>;
241
+ export declare const SearchClearButton: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>>;
240
242
  export declare const SearchInputContainer: import("styled-components").IStyledComponent<"web", import("styled-components/dist/types").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>;
241
243
  export {};
@@ -293,7 +293,14 @@ export const MultiSelectContainer = styled.div `
293
293
  display: flex;
294
294
  flex-direction: column;
295
295
  `;
296
- export const MultiSelectInput = styled(FieldInput) ``;
296
+ export const MultiSelectSearchContainer = styled.div `
297
+ display: inline-block;
298
+ position: relative;
299
+ width: fit-content;
300
+ `;
301
+ export const MultiSelectInput = styled(FieldInput) `
302
+ width: 100%;
303
+ `;
297
304
  export const MultiSelectBadgeContainer = styled.div `
298
305
  margin: 0.3em 0;
299
306
  display: inline-flex;
@@ -313,13 +320,15 @@ export const MultiSelectBadgeCloseElement = styled.span `
313
320
  font-family: sans-serif;
314
321
  `;
315
322
  export const MultiSelectOptionList = styled.ul `
323
+ width: 100%;
316
324
  padding: unset;
317
325
  margin: unset;
318
326
  border: 1px solid gray;
319
327
  border-radius: 0.2em;
320
328
  position: absolute;
321
329
  background: white;
322
- margin: 1.3em 0;
330
+ top: 100%;
331
+ z-index: 1000;
323
332
  `;
324
333
  export const MultiSelectOptionListItem = styled.li `
325
334
  cursor: pointer;
@@ -345,22 +354,23 @@ export const SearchableMultiTagSelectField = ({ name, placeholder, enums, emptyS
345
354
  };
346
355
  return (_jsx(formik.Field, { className: className, name: name, multiple: true, children: ({ field, form: { setFieldValue }, meta, }) => {
347
356
  var _a;
348
- return (_jsxs(MultiSelectContainer, { className: className, children: [_jsx(FieldInput, Object.assign({ id: className, type: "hidden" }, field)), _jsx(MultiSelectInput, { id: className + "_id", className: className, type: "text", onChange: (e) => {
349
- setSearch(e.currentTarget.value);
350
- }, placeholder: placeholder, value: search }), _jsx(MultiSelectBadgeContainer, { children: ((_a = field.value) !== null && _a !== void 0 ? _a : []).map((value) => {
357
+ return (_jsxs(MultiSelectContainer, { className: className, children: [_jsx(FieldInput, Object.assign({ id: className, type: "hidden" }, field)), _jsxs(MultiSelectSearchContainer, { children: [_jsx(MultiSelectInput, { id: className + "_id", className: className, type: "text", onChange: (e) => {
358
+ setSearch(e.currentTarget.value);
359
+ }, placeholder: placeholder, value: search }), search.length > 0 && (_jsx(MultiSelectOptionList, { children: searchIncludedInEnum() ? (enums === null || enums === void 0 ? void 0 : enums.values.filter((item) => { var _a; return !((_a = field.value) !== null && _a !== void 0 ? _a : []).includes(item.const); }).filter((value) => value.title.toLowerCase().includes(search.toLowerCase())).map((option, index) => (_jsx(MultiSelectOptionListItem, { value: option.const, onClick: () => {
360
+ var _a;
361
+ setFieldValue(name, [
362
+ ...new Set([...((_a = field.value) !== null && _a !== void 0 ? _a : []), option.const]),
363
+ ]);
364
+ setSearch("");
365
+ }, children: option.title }, index)))) : (_jsx(MultiSelectOptionListWithoutItem, { children: emptySearchMessage !== null && emptySearchMessage !== void 0 ? emptySearchMessage : "No match found" })) }))] }), _jsx(MultiSelectBadgeContainer, { children: ((_a = field.value) !== null && _a !== void 0 ? _a : []).map((value) => {
351
366
  var _a;
352
367
  return (_jsxs(MultiSelectBadge, { children: [(_a = enums === null || enums === void 0 ? void 0 : enums.values.find((option) => option.const === value)) === null || _a === void 0 ? void 0 : _a.title, _jsx(MultiSelectBadgeCloseElement, { onClick: () => setFieldValue(name, field.value.filter((v) => v !== value)), children: closeElement !== null && closeElement !== void 0 ? closeElement : "x" })] }, value));
353
- }) }), search.length > 0 && (_jsx(MultiSelectOptionList, { children: searchIncludedInEnum() ? (enums === null || enums === void 0 ? void 0 : enums.values.filter((item) => { var _a; return !((_a = field.value) !== null && _a !== void 0 ? _a : []).includes(item.const); }).filter((value) => value.title.toLowerCase().includes(search.toLowerCase())).map((option, index) => (_jsx(MultiSelectOptionListItem, { value: option.const, onClick: () => {
354
- var _a;
355
- setFieldValue(name, [
356
- ...new Set([...((_a = field.value) !== null && _a !== void 0 ? _a : []), option.const]),
357
- ]);
358
- setSearch("");
359
- }, children: option.title }, index)))) : (_jsx(MultiSelectOptionListWithoutItem, { children: emptySearchMessage !== null && emptySearchMessage !== void 0 ? emptySearchMessage : "No match found" })) })), meta.touched && meta.error && (_jsx("div", { className: "error", children: meta.error }))] }));
368
+ }) }), meta.touched && meta.error && (_jsx("div", { className: "error", children: meta.error }))] }));
360
369
  } }));
361
370
  };
362
371
  SearchableMultiTagSelectField.styles = {
363
372
  MultiSelectContainerStyle: MultiSelectContainer,
373
+ MultiSelectSearchContainerStyle: MultiSelectSearchContainer,
364
374
  MultiSelectInputStyle: MultiSelectInput,
365
375
  MultiSelectBadgeContainerStyle: MultiSelectBadgeContainer,
366
376
  MultiSelectBadgeStyle: MultiSelectBadge,
@@ -402,11 +412,10 @@ export const Icon = styled.div `
402
412
  export const CollapsibleChildWrapper = styled.div ``;
403
413
  export const CollapsibleObjectFieldWrapper = ObjectFieldWrapper;
404
414
  export const CollapsibleObjectFieldTitle = ObjectFieldTitle;
405
- export const SearchableSelectContainer = styled(MultiSelectContainer) ``;
415
+ export const SearchableSelectContainer = styled(MultiSelectSearchContainer) ``;
406
416
  export const SearchDropdownContainer = styled(MultiSelectOptionList) `
407
417
  overflow-y: auto;
408
418
  overflow-x: auto;
409
- max-width: 16rem;
410
419
  max-height: 6rem;
411
420
  white-space: nowrap;
412
421
  `;
@@ -426,7 +435,24 @@ export const SearchNotFound = styled(MultiSelectOptionListItem) `
426
435
  }
427
436
  `;
428
437
  export const SearchInput = styled(FieldInput) `
438
+ width: 100%;
439
+ padding-right: 1.5em;
429
440
  text-overflow: ellipsis;
430
441
  `;
431
- export const SearchClearButton = styled.button ``;
432
- export const SearchInputContainer = styled.div ``;
442
+ export const SearchClearButton = styled.span `
443
+ cursor: pointer;
444
+ position: absolute;
445
+ right: 0.3em;
446
+ bottom: 0;
447
+ top: 0;
448
+ margin: auto;
449
+ background-color: #ccc;
450
+ border-radius: 50%;
451
+ line-height: 1em;
452
+ min-width: 1em;
453
+ height: 1em;
454
+ text-align: center;
455
+ `;
456
+ export const SearchInputContainer = styled.div `
457
+ display: flex;
458
+ `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nolwenture/formik-jsonschema-form",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Formik form generation from json schema",
5
5
  "author": "Antti Vikman <antti.vikman@nolwenture.com>",
6
6
  "contributors": [