@uxf/ui 11.21.1 → 11.21.3

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.
@@ -19,6 +19,7 @@ export interface ComboboxProps<Id = ComboboxValueId, Option = ComboboxOption<Id>
19
19
  dropdownMaxHeight?: number;
20
20
  dropdownPlacement?: Placement;
21
21
  dropdownStrategy?: Strategy;
22
+ form?: string;
22
23
  helperText?: ReactNode;
23
24
  hiddenLabel?: boolean;
24
25
  iconName?: keyof IconsSet;
@@ -27,6 +28,7 @@ export interface ComboboxProps<Id = ComboboxValueId, Option = ComboboxOption<Id>
27
28
  keyExtractor?: (option: Option) => string | number;
28
29
  label: ReactNode;
29
30
  loadOptions?: (query: string) => Promise<Option[]>;
31
+ noOptionsMessage?: string;
30
32
  noQueryMessage?: string;
31
33
  notFoundMessage?: string;
32
34
  options?: Option[];
@@ -33,6 +33,7 @@ const compose_refs_1 = require("@uxf/core-react/utils/compose-refs");
33
33
  const classes_1 = require("@uxf/core/constants/classes");
34
34
  const cx_1 = require("@uxf/core/utils/cx");
35
35
  const is_empty_1 = require("@uxf/core/utils/is-empty");
36
+ const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
36
37
  const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
37
38
  const slugify_1 = require("@uxf/core/utils/slugify");
38
39
  const use_async_loading_1 = require("@uxf/ui/hooks/use-async-loading");
@@ -41,53 +42,54 @@ const input_1 = require("@uxf/ui/input");
41
42
  const label_1 = require("@uxf/ui/label");
42
43
  const react_3 = __importStar(require("react"));
43
44
  function Option(props) {
44
- return (react_3.default.createElement(react_2.Combobox.Option, { className: (option) => (0, cx_1.cx)("uxf-dropdown__item uxf-combobox__dropdown-item", option.active && classes_1.CLASSES.IS_ACTIVE, option.disabled && classes_1.CLASSES.IS_DISABLED, option.selected && classes_1.CLASSES.IS_SELECTED), value: props.option }, (option) => { var _a, _b; return (_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option, option.selected)) !== null && _b !== void 0 ? _b : props.option.label; }));
45
+ const option = props.option;
46
+ return (react_3.default.createElement(react_2.Combobox.Option, { className: (optionState) => (0, cx_1.cx)("uxf-dropdown__item uxf-combobox__dropdown-item", optionState.active && classes_1.CLASSES.IS_ACTIVE, optionState.disabled && classes_1.CLASSES.IS_DISABLED, optionState.selected && classes_1.CLASSES.IS_SELECTED), disabled: option.disabled, value: option }, (optionState) => { var _a, _b; return react_3.default.createElement(react_3.default.Fragment, null, (_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option, optionState.selected)) !== null && _b !== void 0 ? _b : option.label); }));
45
47
  }
46
48
  Option.displayName = "UxfUiComboboxOption";
47
49
  function Options(props) {
48
50
  var _a, _b;
49
51
  (0, use_on_unmount_1.useOnUnmount)(() => { var _a; return (_a = props.onUnmount) === null || _a === void 0 ? void 0 : _a.call(props); });
50
- return (react_3.default.createElement(react_2.Combobox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-combobox__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, (0, is_empty_1.isEmpty)(props.options) ? (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage)) : (props.options.map((option) => {
52
+ return (react_3.default.createElement(react_2.Combobox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-combobox__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, (0, is_not_empty_1.isNotEmpty)(props.options) ? (props.options.map((option) => {
51
53
  var _a, _b;
52
54
  const optionKey = (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : option.id;
53
55
  return react_3.default.createElement(Option, { key: optionKey, option: option, renderOption: props.renderOption });
54
- }))));
56
+ })) : (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage))));
55
57
  }
56
58
  Options.displayName = "UxfUiComboboxOptions";
57
59
  function Combobox(props) {
58
- var _a, _b, _c, _d, _e, _f, _g;
60
+ var _a, _b, _c, _d, _e, _f, _g, _h;
59
61
  const isAsync = (0, is_not_nil_1.isNotNil)(props.loadOptions);
60
62
  const [query, setQuery] = (0, react_3.useState)("");
61
63
  const options = (0, use_async_loading_1.useAsyncLoading)(query, (_a = props.options) !== null && _a !== void 0 ? _a : [], props.loadOptions);
62
64
  const filteredData = (0, is_empty_1.isEmpty)(query) || isAsync ? options : options.filter((item) => (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query)));
63
65
  const emptyMessage = (0, is_empty_1.isEmpty)(query)
64
66
  ? (_b = props.noQueryMessage) !== null && _b !== void 0 ? _b : "Pro zobrazení možností začněte psát"
65
- : (_c = props.notFoundMessage) !== null && _c !== void 0 ? _c : "Nic nenalezeno";
67
+ : (0, is_empty_1.isEmpty)(options)
68
+ ? (_c = props.noOptionsMessage) !== null && _c !== void 0 ? _c : "Nabídka neosahuje žádné položky"
69
+ : (_d = props.notFoundMessage) !== null && _d !== void 0 ? _d : "Nic nenalezeno";
66
70
  const clearQuery = () => setQuery("");
67
71
  const onChange = (v) => props.onChange(v);
68
72
  const onInputChange = (event) => setQuery(event.target.value);
69
73
  const displayValue = (item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.label) !== null && _a !== void 0 ? _a : ""; };
70
- const selectedOption = (_d = props.value) !== null && _d !== void 0 ? _d : null;
74
+ const selectedOption = (_e = props.value) !== null && _e !== void 0 ? _e : null;
71
75
  const generatedId = (0, react_3.useId)();
72
- const id = (_e = props.id) !== null && _e !== void 0 ? _e : generatedId;
76
+ const id = (_f = props.id) !== null && _f !== void 0 ? _f : generatedId;
73
77
  const innerRef = (0, react_3.useRef)(null);
74
78
  const errorId = props.isInvalid ? `${id}--error-message` : undefined;
75
79
  const input = (0, use_input_focus_1.useInputFocus)(innerRef, props.onBlur, props.onFocus);
76
- const dropdown = (0, use_dropdown_1.useDropdown)((_f = props.dropdownPlacement) !== null && _f !== void 0 ? _f : "bottom", (_g = props.dropdownMatchesInputWidth) !== null && _g !== void 0 ? _g : true, props.dropdownMaxHeight, props.dropdownStrategy);
80
+ const dropdown = (0, use_dropdown_1.useDropdown)((_g = props.dropdownPlacement) !== null && _g !== void 0 ? _g : "bottom", (_h = props.dropdownMatchesInputWidth) !== null && _h !== void 0 ? _h : true, props.dropdownMaxHeight, props.dropdownStrategy);
77
81
  const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(innerRef, props.inputGroupRef, dropdown.refs.setReference), [dropdown.refs.setReference, props.inputGroupRef]);
78
- return (react_3.default.createElement(react_2.Combobox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-combobox", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: props.isDisabled || props.isReadOnly, onChange: onChange, style: props.style, value: selectedOption }, (renderProps) => (react_3.default.createElement(react_3.default.Fragment, null,
82
+ const isNotInteractive = props.isDisabled || props.isReadOnly;
83
+ return (react_3.default.createElement(react_2.Combobox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-combobox", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: isNotInteractive, form: props.form, name: props.name, onChange: onChange, style: props.style, value: selectedOption }, (renderProps) => (react_3.default.createElement(react_3.default.Fragment, null,
79
84
  react_3.default.createElement("div", { className: "uxf-form-component__label" },
80
- react_3.default.createElement(react_2.Combobox.Label, { as: label_1.Label, isHidden: props.hiddenLabel, onClick: props.isDisabled || props.isReadOnly ? undefined : input.focus }, props.label)),
85
+ react_3.default.createElement(react_2.Combobox.Label, { as: label_1.Label, isHidden: props.hiddenLabel, onClick: isNotInteractive ? undefined : input.focus }, props.label)),
81
86
  react_3.default.createElement("div", { className: "uxf-form-component__input" },
82
87
  react_3.default.createElement(react_2.Combobox.Button, { as: input_1.Input, "aria-invalid": props.isInvalid, "aria-describedby": errorId, className: (0, cx_1.cx)("uxf-combobox__button", dropdown.placement === "bottom" && `${classes_1.CLASSES.IS_OPEN}--bottom`, dropdown.placement === "top" && `${classes_1.CLASSES.IS_OPEN}--top`, renderProps.open && classes_1.CLASSES.IS_OPEN), customInputElementDisplayName: react_2.Combobox.Input.displayName, inputFocus: input, inputGroupRef: stableRef, inputWrapperRef: props.inputWrapperRef, isDisabled: props.isDisabled, isFocused: renderProps.open, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, ref: props.inputRef, size: props.size, variant: props.variant },
83
88
  props.leftAddon && react_3.default.createElement(input_1.Input.LeftAddon, null, props.leftAddon),
84
89
  props.leftElement && react_3.default.createElement(input_1.Input.LeftElement, null, props.leftElement),
85
90
  react_3.default.createElement(react_2.Combobox.Input, { autoComplete: "off", className: "uxf-input__element", displayValue: displayValue, onBlur: props.onBlur, onChange: onInputChange, placeholder: props.placeholder, type: "text" }),
86
91
  react_3.default.createElement(input_1.Input.RightElement, null,
87
- react_3.default.createElement(show_1.Show, { when: Boolean(props.isClearable) &&
88
- (0, is_not_nil_1.isNotNil)(selectedOption) &&
89
- !props.isDisabled &&
90
- !props.isReadOnly },
92
+ react_3.default.createElement(show_1.Show, { when: Boolean(props.isClearable) && (0, is_not_nil_1.isNotNil)(selectedOption) && !isNotInteractive },
91
93
  react_3.default.createElement(input_1.Input.RemoveButton, { onChange: onChange })),
92
94
  props.inputArrow ? (react_3.default.createElement(react_2.Combobox.Button, null, props.inputArrow(renderProps.open))) : (react_3.default.createElement(input_1.Input.ArrowIcon, { iconName: props.iconName, isOpen: renderProps.open }))),
93
95
  props.rightAddon && react_3.default.createElement(input_1.Input.RightAddon, null, props.rightAddon)),
@@ -123,7 +123,7 @@
123
123
 
124
124
  &__dropdown-item {
125
125
  .uxf-checkbox {
126
- margin-top: theme("spacing.[0.5]");
126
+ margin-top: theme("spacing.1");
127
127
  }
128
128
 
129
129
  &.is-active {
@@ -109,4 +109,16 @@
109
109
  }
110
110
  }
111
111
  }
112
+
113
+ &__dropdown-item {
114
+ .uxf-checkbox {
115
+ margin-top: theme("spacing.1");
116
+ }
117
+
118
+ &.is-active {
119
+ .uxf-checkbox-input__label {
120
+ color: theme("colors.white");
121
+ }
122
+ }
123
+ }
112
124
  }
@@ -66,7 +66,7 @@ function Default() {
66
66
  react_1.default.createElement(index_1.Dropzone, { isDisabled: true, label: "Disabled dropzone", onChange: onChange, onUploadFile: upload_file_mock_1.uploadFile, value: files, name: "dropzone-disabled" }),
67
67
  react_1.default.createElement(index_1.Dropzone.List, { errorText: "Chyba p\u0159i nahr\u00E1v\u00E1n\u00ED souboru", onChange: onChange, onRemoveConfirm: onRemoveConfirm, value: files, name: "dropzone-error-message" }),
68
68
  react_1.default.createElement(index_1.Dropzone.List, { onChange: onChange, onRemoveConfirm: onRemoveConfirm, renderItem: (file) => (react_1.default.createElement("li", { key: file.id },
69
- react_1.default.createElement("pre", null, JSON.stringify(file, null, 4)))), value: files, name: "dropzone-list" })));
69
+ react_1.default.createElement("pre", { className: "text-wrap" }, JSON.stringify(file, null, 4)))), value: files, name: "dropzone-list" })));
70
70
  }
71
71
  exports.Default = Default;
72
72
  function ComponentStructure() {
@@ -33,6 +33,7 @@ const classes_1 = require("@uxf/core/constants/classes");
33
33
  const cx_1 = require("@uxf/core/utils/cx");
34
34
  const is_empty_1 = require("@uxf/core/utils/is-empty");
35
35
  const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
36
+ const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
36
37
  const last_1 = require("@uxf/core/utils/last");
37
38
  const slugify_1 = require("@uxf/core/utils/slugify");
38
39
  const checkbox_input_1 = require("@uxf/ui/checkbox-input");
@@ -56,55 +57,69 @@ function handleInputKeyDownRecursion(selectedOptions, onRemove) {
56
57
  }
57
58
  function Option(props) {
58
59
  const option = props.option;
59
- return (react_3.default.createElement(react_2.Combobox.Option, { className: (optionState) => (0, cx_1.cx)("uxf-dropdown__item uxf-multi-combobox__dropdown-item", optionState.active && classes_1.CLASSES.IS_ACTIVE, optionState.disabled && classes_1.CLASSES.IS_DISABLED, optionState.selected && classes_1.CLASSES.IS_SELECTED), disabled: option.disabled, value: option }, (optionState) => (react_3.default.createElement(react_3.default.Fragment, null, props.withCheckboxes ? (react_3.default.createElement(checkbox_input_1.CheckboxInput, { isDisabled: optionState.disabled, isFocused: optionState.active, label: props.label, onChange: props.handleCheckboxChange, value: optionState.selected, name: option.id.toString() })) : (props.label)))));
60
+ return (react_3.default.createElement(react_2.Combobox.Option, { className: (optionState) => (0, cx_1.cx)("uxf-dropdown__item uxf-multi-combobox__dropdown-item", optionState.active && classes_1.CLASSES.IS_ACTIVE, optionState.disabled && classes_1.CLASSES.IS_DISABLED, optionState.selected && classes_1.CLASSES.IS_SELECTED), disabled: option.disabled, value: option }, (optionState) => {
61
+ var _a, _b;
62
+ return (react_3.default.createElement(react_3.default.Fragment, null, props.withCheckboxes ? (react_3.default.createElement(checkbox_input_1.CheckboxInput, { isDisabled: optionState.disabled, isFocused: optionState.active, label: option.label, name: option.id.toString(), onChange: props.handleCheckboxChange, value: optionState.selected })) : ((_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option)) !== null && _b !== void 0 ? _b : option.label)));
63
+ }));
60
64
  }
61
65
  Option.displayName = "UxfUiMultiComboboxOption";
62
66
  function Options(props) {
63
67
  var _a, _b;
64
68
  return (react_3.default.createElement(react_2.Combobox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-multi-combobox__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, (0, is_not_empty_1.isNotEmpty)(props.options) ? (props.options.map((option) => {
65
- var _a, _b, _c, _d;
66
- const _option = option;
67
- return (react_3.default.createElement(Option, { option: option, key: (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : _option.id, label: (_d = (_c = props.renderOption) === null || _c === void 0 ? void 0 : _c.call(props, option)) !== null && _d !== void 0 ? _d : _option.label, handleCheckboxChange: props.onCheckboxChange(_option.id), withCheckboxes: props.withCheckboxes }));
69
+ var _a, _b;
70
+ const optionTyped = option;
71
+ return (react_3.default.createElement(Option, { handleCheckboxChange: props.onCheckboxChange(optionTyped.id), key: (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : optionTyped.id, option: optionTyped, withCheckboxes: props.withCheckboxes }));
68
72
  })) : (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage))));
69
73
  }
70
74
  Options.displayName = "UxfUiMultiComboboxOptions";
75
+ function useMultiComboboxOptions(query, props) {
76
+ var _a, _b;
77
+ const isAsync = (0, is_not_nil_1.isNotNil)(props.loadOptions);
78
+ const options = (0, use_async_loading_1.useAsyncLoading)(query, (_a = props.options) !== null && _a !== void 0 ? _a : [], props.loadOptions);
79
+ const selectedOptions = (_b = props.value) !== null && _b !== void 0 ? _b : [];
80
+ const filteredOptions = isAsync
81
+ ? options
82
+ : options.filter((item) => (!selectedOptions.some((v) => v.id === item.id) || props.withCheckboxes) &&
83
+ ((0, is_empty_1.isEmpty)(query) || (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query))));
84
+ return {
85
+ options,
86
+ selectedOptions,
87
+ filteredOptions,
88
+ };
89
+ }
71
90
  exports.MultiCombobox = (0, react_3.forwardRef)((props, ref) => {
72
- var _a, _b, _c, _d, _e, _f, _g, _h;
91
+ var _a, _b, _c, _d, _e, _f, _g;
73
92
  const generatedId = (0, react_3.useId)();
74
93
  const id = (_a = props.id) !== null && _a !== void 0 ? _a : generatedId;
75
94
  const errorId = props.isInvalid ? `${id}--error-message` : undefined;
76
- const isAsync = !!props.loadOptions;
77
95
  const [query, setQuery] = (0, react_3.useState)("");
78
- const options = (0, use_async_loading_1.useAsyncLoading)(query, (_b = props.options) !== null && _b !== void 0 ? _b : [], props.loadOptions);
79
- const selectedOptions = (_c = props.value) !== null && _c !== void 0 ? _c : [];
80
- const filteredData = isAsync
81
- ? options
82
- : options.filter((item) => {
83
- var _a;
84
- return (!((_a = props.value) === null || _a === void 0 ? void 0 : _a.some((v) => v.id === item.id)) || props.withCheckboxes) &&
85
- ((0, is_empty_1.isEmpty)(query) || (0, slugify_1.slugify)(item.label).includes((0, slugify_1.slugify)(query)));
86
- });
87
- const iconName = (_d = props.iconName) !== null && _d !== void 0 ? _d : "caretDown";
88
- const dropdown = (0, use_dropdown_1.useDropdown)((_e = props.dropdownPlacement) !== null && _e !== void 0 ? _e : "bottom", true, props.dropdownMaxHeight, props.dropdownStrategy);
96
+ const { filteredOptions, selectedOptions, options } = useMultiComboboxOptions(query, {
97
+ loadOptions: props.loadOptions,
98
+ options: props.options,
99
+ value: props.value,
100
+ withCheckboxes: props.withCheckboxes,
101
+ });
102
+ const iconName = (_b = props.iconName) !== null && _b !== void 0 ? _b : "caretDown";
103
+ const dropdown = (0, use_dropdown_1.useDropdown)((_c = props.dropdownPlacement) !== null && _c !== void 0 ? _c : "bottom", true, props.dropdownMaxHeight, props.dropdownStrategy);
89
104
  const inputRef = (0, react_3.useRef)(null);
90
105
  const input = (0, use_input_focus_1.useInputFocus)(inputRef, props.onBlur, props.onFocus);
91
106
  const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(inputRef, dropdown.refs.setReference), [dropdown.refs.setReference]);
92
- const optionRemoveHandler = (valueId) => { var _a; return props.onChange(((_a = props.value) !== null && _a !== void 0 ? _a : []).filter((v) => v.id !== valueId)); };
107
+ const optionRemoveHandler = (valueId) => props.onChange(selectedOptions.filter((v) => v.id !== valueId));
93
108
  const chipCloseHandler = (valueId) => (e) => {
94
109
  e.preventDefault();
95
110
  e.stopPropagation();
96
111
  optionRemoveHandler(valueId);
97
112
  };
98
113
  const checkboxChangeHandler = (valueId) => (checked) => {
99
- var _a, _b, _c;
100
- if (((_a = props.value) === null || _a === void 0 ? void 0 : _a.some((v) => v.id === valueId)) && !checked) {
114
+ const isAlreadySelected = selectedOptions.find((v) => v.id === valueId);
115
+ if (isAlreadySelected && !checked) {
101
116
  optionRemoveHandler(valueId);
102
117
  return;
103
118
  }
104
119
  const newOption = options.find((o) => o.id === valueId);
105
120
  // adding new option if not in value
106
- if (!((_b = props.value) === null || _b === void 0 ? void 0 : _b.some((v) => v.id === valueId)) && checked && newOption) {
107
- props.onChange([...((_c = props.value) !== null && _c !== void 0 ? _c : []), newOption]);
121
+ if (!isAlreadySelected && checked && newOption) {
122
+ props.onChange([...selectedOptions, newOption]);
108
123
  }
109
124
  };
110
125
  const inputKeyDownHandler = (e) => {
@@ -114,14 +129,16 @@ exports.MultiCombobox = (0, react_3.forwardRef)((props, ref) => {
114
129
  };
115
130
  const inputChangeHandler = (e) => setQuery(e.target.value);
116
131
  const changeHandler = (v) => {
117
- props.onChange(v.map((option) => option));
132
+ props.onChange(v);
118
133
  setQuery("");
119
134
  };
120
135
  const emptyMessage = (0, is_empty_1.isEmpty)(query)
121
- ? (_f = props.noQueryMessage) !== null && _f !== void 0 ? _f : "Pro zobrazení možností začněte psát"
136
+ ? (_d = props.noQueryMessage) !== null && _d !== void 0 ? _d : "Pro zobrazení možností začněte psát"
122
137
  : selectedOptions.length === options.length && (0, is_not_empty_1.isNotEmpty)(selectedOptions)
123
- ? (_g = props.allOptionsSelectedMessage) !== null && _g !== void 0 ? _g : "Všechny možnosti jsou již vybrány"
124
- : (_h = props.notFoundMessage) !== null && _h !== void 0 ? _h : "Nic nenalezeno";
138
+ ? (_e = props.allOptionsSelectedMessage) !== null && _e !== void 0 ? _e : "Všechny možnosti jsou již vybrány"
139
+ : (0, is_empty_1.isEmpty)(options)
140
+ ? (_f = props.noOptionsMessage) !== null && _f !== void 0 ? _f : "Nabídka neosahuje žádné položky"
141
+ : (_g = props.notFoundMessage) !== null && _g !== void 0 ? _g : "Nic nenalezeno";
125
142
  const onBlur = (e) => {
126
143
  /* TODO: refactor component to enable this */
127
144
  // setQuery("");
@@ -129,7 +146,7 @@ exports.MultiCombobox = (0, react_3.forwardRef)((props, ref) => {
129
146
  (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
130
147
  };
131
148
  const isNotInteractive = props.isDisabled || props.isReadOnly;
132
- return (react_3.default.createElement(react_2.Combobox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-multi-combobox", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: isNotInteractive, multiple: true, onChange: changeHandler, style: props.style, value: selectedOptions }, (renderProps) => {
149
+ return (react_3.default.createElement(react_2.Combobox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-multi-combobox", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: isNotInteractive, form: props.form, multiple: true, name: props.name, onChange: changeHandler, style: props.style, value: selectedOptions }, (renderProps) => {
133
150
  var _a, _b;
134
151
  return (react_3.default.createElement(react_3.default.Fragment, null,
135
152
  react_3.default.createElement("div", { className: "uxf-form-component__label" },
@@ -140,12 +157,12 @@ exports.MultiCombobox = (0, react_3.forwardRef)((props, ref) => {
140
157
  props.leftElement && react_3.default.createElement(input_1.Input.LeftElement, null, props.leftElement),
141
158
  react_3.default.createElement("div", { className: "uxf-multi-combobox__selected-options" },
142
159
  selectedOptions.map((item) => (react_3.default.createElement(chip_1.Chip, { className: "uxf-multi-combobox__input-chip", color: item.color, key: item.id, onClose: props.isDisabled || item.disabled ? undefined : chipCloseHandler(item.id), size: "large", suppressFocus: true }, item.label))),
143
- react_3.default.createElement(react_2.Combobox.Input, { autoComplete: "off", className: "uxf-input__element uxf-multi-combobox__input", onBlur: onBlur, onChange: inputChangeHandler, onKeyDown: inputKeyDownHandler, id: id, ref: ref, placeholder: props.placeholder, type: "text", value: query })),
160
+ react_3.default.createElement(react_2.Combobox.Input, { autoComplete: "off", className: "uxf-input__element uxf-multi-combobox__input", id: id, onBlur: onBlur, onChange: inputChangeHandler, onKeyDown: inputKeyDownHandler, placeholder: props.placeholder, ref: ref, type: "text", value: query })),
144
161
  props.rightAddon && react_3.default.createElement(input_1.Input.RightAddon, null, props.rightAddon),
145
162
  props.rightElement && react_3.default.createElement(input_1.Input.RightElement, null, props.rightElement), (_b = (_a = props.inputArrow) === null || _a === void 0 ? void 0 : _a.call(props, renderProps.open)) !== null && _b !== void 0 ? _b : (react_3.default.createElement(input_1.Input.ArrowIcon, { iconName: iconName, isOpen: renderProps.open }))),
146
163
  react_3.default.createElement(show_1.Show, { when: renderProps.open },
147
164
  react_3.default.createElement(react_1.FloatingPortal, null,
148
- react_3.default.createElement(Options, { className: props.dropdownClassName, emptyMessage: emptyMessage, forwardRef: dropdown.refs.setFloating, keyExtractor: props.keyExtractor, matchWidth: props.dropdownMatchesInputWidth, onCheckboxChange: checkboxChangeHandler, options: filteredData, placement: dropdown.placement, renderOption: props.renderOption, size: props.size, style: dropdown.floatingStyles, variant: props.variant, withCheckboxes: props.withCheckboxes }))),
165
+ react_3.default.createElement(Options, { className: props.dropdownClassName, emptyMessage: emptyMessage, forwardRef: dropdown.refs.setFloating, keyExtractor: props.keyExtractor, matchWidth: props.dropdownMatchesInputWidth, onCheckboxChange: checkboxChangeHandler, options: filteredOptions, placement: dropdown.placement, renderOption: props.renderOption, size: props.size, style: dropdown.floatingStyles, variant: props.variant, withCheckboxes: props.withCheckboxes }))),
149
166
  react_3.default.createElement(show_1.Show, { when: Boolean(props.helperText) },
150
167
  react_3.default.createElement("div", { className: (0, cx_1.cx)("uxf-helper-text", props.isInvalid && classes_1.CLASSES.IS_INVALID), id: errorId }, props.helperText)))));
151
168
  }));
@@ -89,6 +89,6 @@ exports.Async = Async;
89
89
  function ComponentStructure() {
90
90
  const [value, onChange] = (0, react_1.useState)(null);
91
91
  return (react_1.default.createElement(component_structure_analyzer_1.default, null,
92
- react_1.default.createElement(multi_combobox_1.MultiCombobox, { id: "multi-combobox-structure", name: "multi-combobox", label: "MultiCombobox with helper text", options: options, onChange: onChange, value: value, helperText: "Start typing to see options..." })));
92
+ react_1.default.createElement(multi_combobox_1.MultiCombobox, { helperText: "Start typing to see options...", id: "multi-combobox-structure", label: "MultiCombobox with helper text", name: "multi-combobox", onChange: onChange, options: options, value: value })));
93
93
  }
94
94
  exports.ComponentStructure = ComponentStructure;
@@ -32,6 +32,7 @@ export interface MultiComboboxProps<ValueId = MultiComboboxValueId, Option = Mul
32
32
  leftAddon?: ReactNode;
33
33
  leftElement?: ReactNode;
34
34
  loadOptions?: (query: string) => Promise<Option[]>;
35
+ noOptionsMessage?: string;
35
36
  noQueryMessage?: string;
36
37
  notFoundMessage?: string;
37
38
  options?: Option[];
@@ -34,6 +34,7 @@ const cx_1 = require("@uxf/core/utils/cx");
34
34
  const is_empty_1 = require("@uxf/core/utils/is-empty");
35
35
  const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
36
36
  const last_1 = require("@uxf/core/utils/last");
37
+ const checkbox_input_1 = require("@uxf/ui/checkbox-input");
37
38
  const chip_1 = require("@uxf/ui/chip");
38
39
  const use_dropdown_1 = require("@uxf/ui/hooks/use-dropdown");
39
40
  const input_1 = require("@uxf/ui/input");
@@ -52,58 +53,80 @@ function handleInputKeyDownRecursion(selectedOptions, onRemove) {
52
53
  }
53
54
  }
54
55
  function Option(props) {
55
- var _a, _b;
56
56
  const option = props.option;
57
- return (react_3.default.createElement(react_2.Listbox.Option, { className: (optionState) => (0, cx_1.cx)("uxf-dropdown__item uxf-multi-select__dropdown-item", optionState.active && classes_1.CLASSES.IS_ACTIVE, optionState.disabled && classes_1.CLASSES.IS_DISABLED, optionState.selected && classes_1.CLASSES.IS_SELECTED), value: option, disabled: option.disabled }, (_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option)) !== null && _b !== void 0 ? _b : option.label));
57
+ return (react_3.default.createElement(react_2.Listbox.Option, { className: (optionState) => (0, cx_1.cx)("uxf-dropdown__item uxf-multi-select__dropdown-item", optionState.active && classes_1.CLASSES.IS_ACTIVE, optionState.disabled && classes_1.CLASSES.IS_DISABLED, optionState.selected && classes_1.CLASSES.IS_SELECTED), disabled: option.disabled, value: option }, (optionState) => {
58
+ var _a, _b;
59
+ return (react_3.default.createElement(react_3.default.Fragment, null, props.withCheckboxes ? (react_3.default.createElement(checkbox_input_1.CheckboxInput, { isDisabled: optionState.disabled, isFocused: optionState.active, label: option.label, name: option.id.toString(), onChange: props.handleCheckboxChange, value: optionState.selected })) : ((_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option)) !== null && _b !== void 0 ? _b : option.label)));
60
+ }));
58
61
  }
59
62
  Option.displayName = "UxfUiMultiSelectOption";
60
63
  function Options(props) {
61
64
  var _a, _b;
62
- return (react_3.default.createElement(react_2.Listbox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-multi-select__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, props.options.map((option) => {
65
+ return (react_3.default.createElement(react_2.Listbox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-multi-select__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, (0, is_not_empty_1.isNotEmpty)(props.options) ? (props.options.map((option) => {
63
66
  var _a, _b;
64
- const optionKey = (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : option.id;
65
- return react_3.default.createElement(Option, { key: optionKey, option: option, renderOption: props.renderOption });
66
- })));
67
+ const optionTyped = option;
68
+ return (react_3.default.createElement(Option, { handleCheckboxChange: props.onCheckboxChange(optionTyped.id), key: (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : optionTyped.id, option: optionTyped, withCheckboxes: props.withCheckboxes }));
69
+ })) : (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage))));
67
70
  }
68
71
  Options.displayName = "UxfUiMultiSelectOptions";
69
72
  exports.MultiSelect = (0, react_3.forwardRef)((props, ref) => {
70
- var _a, _b, _c, _d;
73
+ var _a, _b, _c, _d, _e, _f;
71
74
  const generatedId = (0, react_3.useId)();
72
75
  const id = (_a = props.id) !== null && _a !== void 0 ? _a : generatedId;
73
76
  const errorId = props.isInvalid ? `${id}--error-message` : undefined;
77
+ const dropdown = (0, use_dropdown_1.useDropdown)((_b = props.dropdownPlacement) !== null && _b !== void 0 ? _b : "bottom", true, props.dropdownMaxHeight, props.dropdownStrategy);
74
78
  const innerRef = (0, react_3.useRef)(null);
75
79
  const input = (0, use_input_focus_1.useInputFocus)(innerRef, props.onBlur, props.onFocus);
76
- const dropdown = (0, use_dropdown_1.useDropdown)((_b = props.dropdownPlacement) !== null && _b !== void 0 ? _b : "bottom", true, props.dropdownMaxHeight, props.dropdownStrategy);
77
80
  const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(innerRef, ref, dropdown.refs.setReference), [ref, dropdown.refs.setReference]);
78
81
  const iconName = (_c = props.iconName) !== null && _c !== void 0 ? _c : "caretDown";
79
82
  const selectedOptions = (_d = props.value) !== null && _d !== void 0 ? _d : [];
80
- const filteredOptions = props.options.filter((option) => !selectedOptions.map((i) => i.id).includes(option.id));
81
- const changeHandler = (v) => props.onChange(v.map((option) => option));
83
+ const filteredOptions = props.options.filter((option) => !selectedOptions.some((v) => v.id === option.id) || props.withCheckboxes);
82
84
  const inputKeyDownHandler = (e) => {
83
85
  if (e.key === "Backspace" && (0, is_not_empty_1.isNotEmpty)(selectedOptions)) {
84
86
  handleInputKeyDownRecursion(selectedOptions, (v) => props.onChange(selectedOptions.filter((option) => option.id !== v)));
85
87
  }
86
88
  };
89
+ const optionRemoveHandler = (valueId) => props.onChange(selectedOptions.filter((v) => v.id !== valueId));
87
90
  const chipCloseHandler = (valueId) => (e) => {
88
- var _a, _b;
89
91
  e.preventDefault();
90
92
  e.stopPropagation();
91
- props.onChange((_b = (_a = props.value) === null || _a === void 0 ? void 0 : _a.filter((v) => v.id !== valueId)) !== null && _b !== void 0 ? _b : []);
93
+ optionRemoveHandler(valueId);
94
+ };
95
+ const checkboxChangeHandler = (valueId) => (checked) => {
96
+ const isAlreadySelected = selectedOptions.some((v) => v.id === valueId);
97
+ if (isAlreadySelected && !checked) {
98
+ optionRemoveHandler(valueId);
99
+ return;
100
+ }
101
+ const newOption = props.options.find((o) => o.id === valueId);
102
+ // adding new option if not in value
103
+ if (!isAlreadySelected && checked && newOption) {
104
+ props.onChange([...selectedOptions, newOption]);
105
+ }
92
106
  };
107
+ const emptyMessage = (0, is_empty_1.isEmpty)(filteredOptions) && (0, is_not_empty_1.isNotEmpty)(selectedOptions)
108
+ ? (_e = props.allOptionsSelectedMessage) !== null && _e !== void 0 ? _e : "Všechny možnosti jsou již vybrány"
109
+ : (_f = props.noOptionsMessage) !== null && _f !== void 0 ? _f : "Nabídka neosahuje žádné položky";
93
110
  const isNotInteractive = props.isDisabled || props.isReadOnly;
94
- return (react_3.default.createElement(react_2.Listbox, { as: "div", className: (0, cx_1.cx)("uxf-form-component uxf-multi-select", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: isNotInteractive, multiple: true, onChange: changeHandler, value: selectedOptions }, (renderProps) => {
111
+ return (react_3.default.createElement(react_2.Listbox, { as: "div", className: (0, cx_1.cx)("uxf-form-component uxf-multi-select", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: isNotInteractive, form: props.form, multiple: true, name: props.name, onChange: props.onChange, value: selectedOptions }, (renderProps) => {
95
112
  var _a, _b;
96
113
  return (react_3.default.createElement(react_3.default.Fragment, null,
97
114
  react_3.default.createElement("div", { className: "uxf-form-component__label" },
98
115
  react_3.default.createElement(react_2.Listbox.Label, { as: label_1.Label, isHidden: props.hiddenLabel, onClick: isNotInteractive ? undefined : input.focus }, props.label)),
99
116
  react_3.default.createElement("div", { className: "uxf-form-component__input" },
100
- react_3.default.createElement(react_2.Listbox.Button, { "aria-invalid": props.isInvalid, "aria-describedby": errorId, as: "div", className: (0, cx_1.cx)("uxf-multi-select__button", (renderProps.open || input.focused) && classes_1.CLASSES.IS_FOCUSED, renderProps.disabled && classes_1.CLASSES.IS_DISABLED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isInvalid && classes_1.CLASSES.IS_INVALID, dropdown.placement === "bottom" && `${classes_1.CLASSES.IS_OPEN}--bottom`, dropdown.placement === "top" && `${classes_1.CLASSES.IS_OPEN}--top`, renderProps.open && classes_1.CLASSES.IS_OPEN), id: id, onBlur: input.onBlur, onFocus: input.onFocus, onKeyDown: inputKeyDownHandler, tabIndex: isNotInteractive ? undefined : 0, ref: stableRef },
117
+ react_3.default.createElement(react_2.Listbox.Button, { "aria-invalid": props.isInvalid, "aria-describedby": errorId, as: "div", className: (0, cx_1.cx)("uxf-input uxf-multi-select__button", (renderProps.open || input.focused) && classes_1.CLASSES.IS_FOCUSED, renderProps.disabled && classes_1.CLASSES.IS_DISABLED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isInvalid && classes_1.CLASSES.IS_INVALID, dropdown.placement === "bottom" && `${classes_1.CLASSES.IS_OPEN}--bottom`, dropdown.placement === "top" && `${classes_1.CLASSES.IS_OPEN}--top`, renderProps.open && classes_1.CLASSES.IS_OPEN), id: id, onBlur: input.onBlur, onFocus: input.onFocus, onKeyDown: inputKeyDownHandler, tabIndex: isNotInteractive ? undefined : 0, ref: stableRef },
118
+ props.leftAddon && react_3.default.createElement(input_1.Input.LeftAddon, null, props.leftAddon),
119
+ props.leftElement && react_3.default.createElement(input_1.Input.LeftElement, null, props.leftElement),
101
120
  react_3.default.createElement("div", { className: (0, cx_1.cx)("uxf-input__element uxf-multi-select__input", (0, is_empty_1.isEmpty)(selectedOptions) && `${classes_1.CLASSES.IS_EMPTY} uxf-multi-select__input--is-empty`) }, (0, is_empty_1.isEmpty)(selectedOptions)
102
121
  ? props.placeholder
103
- : selectedOptions.map((item) => (react_3.default.createElement(chip_1.Chip, { className: "uxf-multi-select__input-chip", color: item.color, key: item.id, onClose: item.disabled ? undefined : chipCloseHandler(item.id), size: "large", suppressFocus: true }, item.label)))), (_b = (_a = props.inputArrow) === null || _a === void 0 ? void 0 : _a.call(props, renderProps.open)) !== null && _b !== void 0 ? _b : (react_3.default.createElement(input_1.Input.ArrowIcon, { iconName: iconName, isOpen: renderProps.open }))),
122
+ : selectedOptions.map((item) => (react_3.default.createElement(chip_1.Chip, { className: "uxf-multi-select__input-chip", color: item.color, key: item.id, onClose: props.isDisabled || item.disabled
123
+ ? undefined
124
+ : chipCloseHandler(item.id), size: "large", suppressFocus: true }, item.label)))),
125
+ props.rightAddon && react_3.default.createElement(input_1.Input.RightAddon, null, props.rightAddon),
126
+ props.rightElement && react_3.default.createElement(input_1.Input.RightElement, null, props.rightElement), (_b = (_a = props.inputArrow) === null || _a === void 0 ? void 0 : _a.call(props, renderProps.open)) !== null && _b !== void 0 ? _b : (react_3.default.createElement(input_1.Input.ArrowIcon, { iconName: iconName, isOpen: renderProps.open }))),
104
127
  react_3.default.createElement(show_1.Show, { when: renderProps.open },
105
128
  react_3.default.createElement(react_1.FloatingPortal, null,
106
- react_3.default.createElement(Options, { className: props.dropdownClassName, forwardRef: dropdown.refs.setFloating, keyExtractor: props.keyExtractor, matchWidth: props.dropdownMatchesInputWidth, options: filteredOptions, placement: dropdown.placement, renderOption: props.renderOption, size: props.size, style: dropdown.floatingStyles, variant: props.variant }))),
129
+ react_3.default.createElement(Options, { className: props.dropdownClassName, emptyMessage: emptyMessage, forwardRef: dropdown.refs.setFloating, keyExtractor: props.keyExtractor, matchWidth: props.dropdownMatchesInputWidth, onCheckboxChange: checkboxChangeHandler, options: filteredOptions, placement: dropdown.placement, renderOption: props.renderOption, size: props.size, style: dropdown.floatingStyles, variant: props.variant, withCheckboxes: props.withCheckboxes }))),
107
130
  react_3.default.createElement(show_1.Show, { when: Boolean(props.helperText) },
108
131
  react_3.default.createElement("div", { className: (0, cx_1.cx)("uxf-helper-text", props.isInvalid && classes_1.CLASSES.IS_INVALID), id: errorId }, props.helperText)))));
109
132
  }));
@@ -30,10 +30,10 @@ exports.ComponentStructure = exports.Default = void 0;
30
30
  const component_structure_analyzer_1 = __importDefault(require("@uxf/ui/utils/component-structure-analyzer"));
31
31
  const react_1 = __importStar(require("react"));
32
32
  const action_1 = require("../utils/action");
33
- const index_1 = require("./index");
33
+ const multi_select_1 = require("./multi-select");
34
34
  exports.default = {
35
35
  title: "UI/MultiSelect",
36
- component: index_1.MultiSelect,
36
+ component: multi_select_1.MultiSelect,
37
37
  };
38
38
  const options = [
39
39
  { id: "one", label: "Option red", color: "red" },
@@ -56,11 +56,18 @@ const Default = () => {
56
56
  console.log("Select values: ", v);
57
57
  setValue(v);
58
58
  });
59
- const component = (react_1.default.createElement(react_1.default.Fragment, null,
60
- react_1.default.createElement(index_1.MultiSelect, { dropdownMaxHeight: 350, id: "multi-select-1", label: "MultiSelect", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte pros\u00EDm jednu nebo v\u00EDce mo\u017Enost\u00ED", value: value }),
61
- react_1.default.createElement(index_1.MultiSelect, { id: "multi-select-2", label: "MultiSelect with renderOption", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte...", value: value, renderOption: (option) => react_1.default.createElement(react_1.default.Fragment, null,
59
+ const component = (react_1.default.createElement("div", { className: "space-y-8" },
60
+ react_1.default.createElement(multi_select_1.MultiSelect, { dropdownMaxHeight: 350, id: "multi-select-1", label: "MultiSelect", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte pros\u00EDm jednu nebo v\u00EDce mo\u017Enost\u00ED", value: value }),
61
+ react_1.default.createElement(multi_select_1.MultiSelect, { id: "multi-select-2", label: "MultiSelect with checkboxes", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte...", value: value, withCheckboxes: true }),
62
+ react_1.default.createElement(multi_select_1.MultiSelect, { helperText: "Start typing to see options...", id: "multi-select-3", label: "MultiSelect with helper text", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte...", value: value }),
63
+ react_1.default.createElement(multi_select_1.MultiSelect, { helperText: "Error message", id: "multi-select-4", isInvalid: true, isRequired: true, label: "MultiSelect invalid", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte...", value: value }),
64
+ react_1.default.createElement(multi_select_1.MultiSelect, { dropdownPlacement: "top", id: "multi-select-5", label: "MultiSelect with dropdown top", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte...", value: value }),
65
+ react_1.default.createElement(multi_select_1.MultiSelect, { id: "multi-select-6", label: "MultiSelect with renderOption", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte...", value: value, renderOption: (option) => react_1.default.createElement(react_1.default.Fragment, null,
62
66
  "Option: ",
63
- option.label) })));
67
+ option.label) }),
68
+ react_1.default.createElement(multi_select_1.MultiSelect, { id: "multi-select-disabled", label: "MultiSelect disabled", name: "multi-select", onChange: onChange, options: options, placeholder: "Vyberte...", value: value, renderOption: (option) => react_1.default.createElement(react_1.default.Fragment, null,
69
+ "Option: ",
70
+ option.label), isDisabled: true })));
64
71
  return (react_1.default.createElement("div", { className: "flex flex-col lg:flex-row" },
65
72
  react_1.default.createElement("div", { className: "space-y-2 p-20 lg:w-1/2" }, component)));
66
73
  };
@@ -68,6 +75,6 @@ exports.Default = Default;
68
75
  function ComponentStructure() {
69
76
  const [value, onChange] = (0, react_1.useState)(null);
70
77
  return (react_1.default.createElement(component_structure_analyzer_1.default, null,
71
- react_1.default.createElement(index_1.MultiSelect, { options: options, onChange: onChange, value: value, name: "multi-select-component-structure" })));
78
+ react_1.default.createElement(multi_select_1.MultiSelect, { helperText: "Start typing to see options...", label: "MultiSelect with helper text", id: "multi-select-structure", name: "multi-select-structure", onChange: onChange, options: options, value: value })));
72
79
  }
73
80
  exports.ComponentStructure = ComponentStructure;
@@ -12,6 +12,7 @@ export type MultiSelectOption<T = MultiSelectValueId> = {
12
12
  label: ReactNode;
13
13
  };
14
14
  export interface MultiSelectProps<ValueId = MultiSelectValueId, Option = MultiSelectOption<ValueId>> extends FormControlProps<Option[] | null> {
15
+ allOptionsSelectedMessage?: string;
15
16
  className?: string;
16
17
  dropdownClassName?: string;
17
18
  dropdownMatchesInputWidth?: boolean;
@@ -25,12 +26,18 @@ export interface MultiSelectProps<ValueId = MultiSelectValueId, Option = MultiSe
25
26
  id?: string;
26
27
  inputArrow?: (open: boolean) => ReactNode;
27
28
  keyExtractor?: (option: Option) => string | number;
28
- label?: ReactNode;
29
+ label: ReactNode;
30
+ leftAddon?: ReactNode;
31
+ leftElement?: ReactNode;
32
+ noOptionsMessage?: string;
29
33
  options: Option[];
30
34
  placeholder?: string;
31
35
  renderOption?: (option: Option) => ReactNode;
36
+ rightAddon?: ReactNode;
37
+ rightElement?: ReactNode;
32
38
  size?: keyof InputGroupSizes;
33
39
  style?: CSSProperties;
34
40
  variant?: keyof InputGroupVariants;
41
+ withCheckboxes?: boolean;
35
42
  }
36
43
  export type MultiSelectTypeRef = HTMLDivElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxf/ui",
3
- "version": "11.21.1",
3
+ "version": "11.21.3",
4
4
  "description": "",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -17,6 +17,7 @@ export interface SelectProps<Value = SelectValue, Option = SelectOption<Value>>
17
17
  dropdownMaxHeight?: number;
18
18
  dropdownPlacement?: Placement;
19
19
  dropdownStrategy?: Strategy;
20
+ form?: string;
20
21
  helperText?: ReactNode;
21
22
  hiddenLabel?: boolean;
22
23
  iconName?: keyof IconsSet;
@@ -24,6 +25,7 @@ export interface SelectProps<Value = SelectValue, Option = SelectOption<Value>>
24
25
  inputArrow?: (open: boolean) => ReactNode;
25
26
  keyExtractor?: (option: Option) => string | number;
26
27
  label: ReactNode;
28
+ noOptionsMessage?: string;
27
29
  options: Option[];
28
30
  placeholder?: string;
29
31
  renderOption?: (option: Option, isSelected: boolean) => ReactNode;
package/select/select.js CHANGED
@@ -32,22 +32,24 @@ const compose_refs_1 = require("@uxf/core-react/utils/compose-refs");
32
32
  const classes_1 = require("@uxf/core/constants/classes");
33
33
  const cx_1 = require("@uxf/core/utils/cx");
34
34
  const is_nil_1 = require("@uxf/core/utils/is-nil");
35
+ const is_not_empty_1 = require("@uxf/core/utils/is-not-empty");
35
36
  const is_not_nil_1 = require("@uxf/core/utils/is-not-nil");
36
37
  const use_dropdown_1 = require("@uxf/ui/hooks/use-dropdown");
37
38
  const input_1 = require("@uxf/ui/input");
38
39
  const label_1 = require("@uxf/ui/label");
39
40
  const react_3 = __importStar(require("react"));
40
41
  function Option(props) {
41
- return (react_3.default.createElement(react_2.Listbox.Option, { className: (option) => (0, cx_1.cx)("uxf-dropdown__item uxf-select__dropdown-item", option.active && classes_1.CLASSES.IS_ACTIVE, option.disabled && classes_1.CLASSES.IS_DISABLED, option.selected && classes_1.CLASSES.IS_SELECTED), value: props.option }, (option) => { var _a, _b; return (_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option, option.selected)) !== null && _b !== void 0 ? _b : props.option.label; }));
42
+ const option = props.option;
43
+ return (react_3.default.createElement(react_2.Listbox.Option, { className: (optionState) => (0, cx_1.cx)("uxf-dropdown__item uxf-select__dropdown-item", optionState.active && classes_1.CLASSES.IS_ACTIVE, optionState.disabled && classes_1.CLASSES.IS_DISABLED, optionState.selected && classes_1.CLASSES.IS_SELECTED), disabled: option.disabled, value: option }, (optionState) => { var _a, _b; return react_3.default.createElement(react_3.default.Fragment, null, (_b = (_a = props.renderOption) === null || _a === void 0 ? void 0 : _a.call(props, props.option, optionState.selected)) !== null && _b !== void 0 ? _b : option.label); }));
42
44
  }
43
45
  Option.displayName = "UxfUiSelectOption";
44
46
  function Options(props) {
45
47
  var _a, _b;
46
- return (react_3.default.createElement(react_2.Listbox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-select__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, props.options.map((option) => {
48
+ return (react_3.default.createElement(react_2.Listbox.Options, { className: (0, cx_1.cx)("uxf-dropdown uxf-select__dropdown", `uxf-dropdown--size-${(_a = props.size) !== null && _a !== void 0 ? _a : "default"}`, `uxf-dropdown--variant-${(_b = props.variant) !== null && _b !== void 0 ? _b : "default"}`, props.matchWidth ? "uxf-dropdown--match-width" : "uxf-dropdown--not-match-width", props.placement === "bottom" && "uxf-dropdown--bottom", props.placement === "top" && "uxf-dropdown--top", props.className), ref: props.forwardRef, static: true, style: props.style }, (0, is_not_empty_1.isNotEmpty)(props.options) ? (props.options.map((option) => {
47
49
  var _a, _b;
48
50
  const optionKey = (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : option.id;
49
51
  return react_3.default.createElement(Option, { key: optionKey, option: option, renderOption: props.renderOption });
50
- })));
52
+ })) : (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage))));
51
53
  }
52
54
  Options.displayName = "UxfUiSelectOptions";
53
55
  const SelectedValue = (0, react_3.forwardRef)((props, ref) => {
@@ -58,7 +60,7 @@ const SelectedValue = (0, react_3.forwardRef)((props, ref) => {
58
60
  });
59
61
  SelectedValue.displayName = "UxUiSelectSelectedValue";
60
62
  function Select(props) {
61
- var _a, _b, _c, _d;
63
+ var _a, _b, _c, _d, _e;
62
64
  const onChange = (v) => { var _a; return props.onChange((_a = v === null || v === void 0 ? void 0 : v.id) !== null && _a !== void 0 ? _a : null); };
63
65
  const selectedOption = (_a = props.options.find((option) => option.id === props.value)) !== null && _a !== void 0 ? _a : null;
64
66
  const generatedId = (0, react_3.useId)();
@@ -69,11 +71,13 @@ function Select(props) {
69
71
  const dropdown = (0, use_dropdown_1.useDropdown)((_c = props.dropdownPlacement) !== null && _c !== void 0 ? _c : "bottom", (_d = props.dropdownMatchesInputWidth) !== null && _d !== void 0 ? _d : true, props.dropdownMaxHeight, props.dropdownStrategy);
70
72
  const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(innerRef, props.inputGroupRef, dropdown.refs.setReference), [dropdown.refs.setReference, props.inputGroupRef]);
71
73
  const value = selectedOption;
72
- return (react_3.default.createElement(react_2.Listbox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-select", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: props.isDisabled || props.isReadOnly, onChange: onChange, style: props.style, value: value }, (renderProps) => {
74
+ const emptyMessage = (_e = props.noOptionsMessage) !== null && _e !== void 0 ? _e : "Nabídka neosahuje žádné položky";
75
+ const isNotInteractive = props.isDisabled || props.isReadOnly;
76
+ return (react_3.default.createElement(react_2.Listbox, { as: "div", by: "id", className: (0, cx_1.cx)("uxf-form-component uxf-select", props.isInvalid && classes_1.CLASSES.IS_INVALID, props.isRequired && classes_1.CLASSES.IS_REQUIRED, props.isReadOnly && classes_1.CLASSES.IS_READONLY, props.isDisabled && classes_1.CLASSES.IS_DISABLED, props.className), "data-name": props.name, disabled: isNotInteractive, form: props.form, name: props.name, onChange: onChange, style: props.style, value: value }, (renderProps) => {
73
77
  var _a, _b, _c;
74
78
  return (react_3.default.createElement(react_3.default.Fragment, null,
75
79
  react_3.default.createElement("div", { className: "uxf-form-component__label" },
76
- react_3.default.createElement(react_2.Listbox.Label, { as: label_1.Label, isHidden: props.hiddenLabel, onClick: props.isDisabled || props.isReadOnly ? undefined : input.focus }, props.label)),
80
+ react_3.default.createElement(react_2.Listbox.Label, { as: label_1.Label, isHidden: props.hiddenLabel, onClick: isNotInteractive ? undefined : input.focus }, props.label)),
77
81
  react_3.default.createElement("div", { className: "uxf-form-component__input" },
78
82
  react_3.default.createElement(react_2.Listbox.Button, { as: input_1.Input, "aria-invalid": props.isInvalid, "aria-describedby": errorId, className: (0, cx_1.cx)("uxf-select__button", dropdown.placement === "bottom" && `${classes_1.CLASSES.IS_OPEN}--bottom`, dropdown.placement === "top" && `${classes_1.CLASSES.IS_OPEN}--top`, renderProps.open && classes_1.CLASSES.IS_OPEN), customInputElementDisplayName: (_a = SelectedValue.displayName) !== null && _a !== void 0 ? _a : "", inputFocus: input, inputGroupRef: stableRef, inputWrapperRef: props.inputWrapperRef, isDisabled: props.isDisabled, isFocused: renderProps.open, isInvalid: props.isInvalid, isReadOnly: props.isReadOnly, ref: props.inputRef, size: props.size, variant: props.variant },
79
83
  props.leftAddon && react_3.default.createElement(input_1.Input.LeftAddon, null, props.leftAddon),
@@ -82,16 +86,13 @@ function Select(props) {
82
86
  ? (_c = (_b = props.renderSelectedOption) === null || _b === void 0 ? void 0 : _b.call(props, selectedOption)) !== null && _c !== void 0 ? _c : selectedOption.label
83
87
  : props.placeholder),
84
88
  react_3.default.createElement(input_1.Input.RightElement, null,
85
- react_3.default.createElement(show_1.Show, { when: Boolean(props.isClearable) &&
86
- (0, is_not_nil_1.isNotNil)(value) &&
87
- !props.isDisabled &&
88
- !props.isReadOnly },
89
+ react_3.default.createElement(show_1.Show, { when: Boolean(props.isClearable) && (0, is_not_nil_1.isNotNil)(value) && !isNotInteractive },
89
90
  react_3.default.createElement(input_1.Input.RemoveButton, { onChange: onChange })),
90
91
  props.inputArrow ? (props.inputArrow(renderProps.open)) : (react_3.default.createElement(input_1.Input.ArrowIcon, { iconName: props.iconName, isOpen: renderProps.open }))),
91
92
  props.rightAddon && react_3.default.createElement(input_1.Input.RightAddon, null, props.rightAddon)),
92
93
  react_3.default.createElement(show_1.Show, { when: renderProps.open },
93
94
  react_3.default.createElement(react_1.FloatingPortal, null,
94
- react_3.default.createElement(Options, { className: props.dropdownClassName, forwardRef: dropdown.refs.setFloating, keyExtractor: props.keyExtractor, matchWidth: props.dropdownMatchesInputWidth, options: props.options, placement: dropdown.placement, renderOption: props.renderOption, size: props.size, style: dropdown.floatingStyles, variant: props.variant }))),
95
+ react_3.default.createElement(Options, { className: props.dropdownClassName, emptyMessage: emptyMessage, forwardRef: dropdown.refs.setFloating, keyExtractor: props.keyExtractor, matchWidth: props.dropdownMatchesInputWidth, options: props.options, placement: dropdown.placement, renderOption: props.renderOption, size: props.size, style: dropdown.floatingStyles, variant: props.variant }))),
95
96
  react_3.default.createElement(show_1.Show, { when: Boolean(props.helperText) },
96
97
  react_3.default.createElement("div", { className: (0, cx_1.cx)("uxf-helper-text", props.isInvalid && classes_1.CLASSES.IS_INVALID), id: errorId }, props.helperText)))));
97
98
  }));