@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.
- package/combobox/combobox.d.ts +2 -0
- package/combobox/combobox.js +16 -14
- package/css/multi-combobox.css +1 -1
- package/css/multi-select.css +12 -0
- package/dropzone/dropzone.stories.js +1 -1
- package/multi-combobox/multi-combobox.js +46 -29
- package/multi-combobox/multi-combobox.stories.js +1 -1
- package/multi-combobox/types.d.ts +1 -0
- package/multi-select/multi-select.js +39 -16
- package/multi-select/multi-select.stories.js +14 -7
- package/multi-select/types.d.ts +8 -1
- package/package.json +1 -1
- package/select/select.d.ts +2 -0
- package/select/select.js +12 -11
package/combobox/combobox.d.ts
CHANGED
|
@@ -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[];
|
package/combobox/combobox.js
CHANGED
|
@@ -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
|
-
|
|
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,
|
|
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
|
-
: (
|
|
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 = (
|
|
74
|
+
const selectedOption = (_e = props.value) !== null && _e !== void 0 ? _e : null;
|
|
71
75
|
const generatedId = (0, react_3.useId)();
|
|
72
|
-
const id = (
|
|
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)((
|
|
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
|
-
|
|
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:
|
|
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)),
|
package/css/multi-combobox.css
CHANGED
package/css/multi-select.css
CHANGED
|
@@ -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",
|
|
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) =>
|
|
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
|
|
66
|
-
const
|
|
67
|
-
return (react_3.default.createElement(Option, {
|
|
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
|
|
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
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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) =>
|
|
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
|
-
|
|
100
|
-
if (
|
|
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 (!
|
|
107
|
-
props.onChange([...
|
|
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
|
|
132
|
+
props.onChange(v);
|
|
118
133
|
setQuery("");
|
|
119
134
|
};
|
|
120
135
|
const emptyMessage = (0, is_empty_1.isEmpty)(query)
|
|
121
|
-
? (
|
|
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
|
-
? (
|
|
124
|
-
: (
|
|
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,
|
|
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:
|
|
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, {
|
|
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),
|
|
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
|
|
65
|
-
return react_3.default.createElement(Option, { key:
|
|
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.
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
|
33
|
+
const multi_select_1 = require("./multi-select");
|
|
34
34
|
exports.default = {
|
|
35
35
|
title: "UI/MultiSelect",
|
|
36
|
-
component:
|
|
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(
|
|
60
|
-
react_1.default.createElement(
|
|
61
|
-
react_1.default.createElement(
|
|
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(
|
|
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;
|
package/multi-select/types.d.ts
CHANGED
|
@@ -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
|
|
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
package/select/select.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
}));
|