@uxf/ui 11.21.2 → 11.21.4
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 +1 -0
- package/combobox/combobox.js +10 -7
- package/css/multi-combobox.css +1 -1
- package/css/multi-select.css +12 -0
- package/css/radio-group.css +21 -9
- package/multi-combobox/multi-combobox.js +44 -27
- 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 +1 -0
- package/select/select.js +6 -4
package/combobox/combobox.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export interface ComboboxProps<Id = ComboboxValueId, Option = ComboboxOption<Id>
|
|
|
28
28
|
keyExtractor?: (option: Option) => string | number;
|
|
29
29
|
label: ReactNode;
|
|
30
30
|
loadOptions?: (query: string) => Promise<Option[]>;
|
|
31
|
+
noOptionsMessage?: string;
|
|
31
32
|
noQueryMessage?: string;
|
|
32
33
|
notFoundMessage?: string;
|
|
33
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");
|
|
@@ -48,33 +49,35 @@ Option.displayName = "UxfUiComboboxOption";
|
|
|
48
49
|
function Options(props) {
|
|
49
50
|
var _a, _b;
|
|
50
51
|
(0, use_on_unmount_1.useOnUnmount)(() => { var _a; return (_a = props.onUnmount) === null || _a === void 0 ? void 0 : _a.call(props); });
|
|
51
|
-
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) => {
|
|
52
53
|
var _a, _b;
|
|
53
54
|
const optionKey = (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : option.id;
|
|
54
55
|
return react_3.default.createElement(Option, { key: optionKey, option: option, renderOption: props.renderOption });
|
|
55
|
-
}))));
|
|
56
|
+
})) : (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage))));
|
|
56
57
|
}
|
|
57
58
|
Options.displayName = "UxfUiComboboxOptions";
|
|
58
59
|
function Combobox(props) {
|
|
59
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
60
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
60
61
|
const isAsync = (0, is_not_nil_1.isNotNil)(props.loadOptions);
|
|
61
62
|
const [query, setQuery] = (0, react_3.useState)("");
|
|
62
63
|
const options = (0, use_async_loading_1.useAsyncLoading)(query, (_a = props.options) !== null && _a !== void 0 ? _a : [], props.loadOptions);
|
|
63
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)));
|
|
64
65
|
const emptyMessage = (0, is_empty_1.isEmpty)(query)
|
|
65
66
|
? (_b = props.noQueryMessage) !== null && _b !== void 0 ? _b : "Pro zobrazení možností začněte psát"
|
|
66
|
-
: (
|
|
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";
|
|
67
70
|
const clearQuery = () => setQuery("");
|
|
68
71
|
const onChange = (v) => props.onChange(v);
|
|
69
72
|
const onInputChange = (event) => setQuery(event.target.value);
|
|
70
73
|
const displayValue = (item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.label) !== null && _a !== void 0 ? _a : ""; };
|
|
71
|
-
const selectedOption = (
|
|
74
|
+
const selectedOption = (_e = props.value) !== null && _e !== void 0 ? _e : null;
|
|
72
75
|
const generatedId = (0, react_3.useId)();
|
|
73
|
-
const id = (
|
|
76
|
+
const id = (_f = props.id) !== null && _f !== void 0 ? _f : generatedId;
|
|
74
77
|
const innerRef = (0, react_3.useRef)(null);
|
|
75
78
|
const errorId = props.isInvalid ? `${id}--error-message` : undefined;
|
|
76
79
|
const input = (0, use_input_focus_1.useInputFocus)(innerRef, props.onBlur, props.onFocus);
|
|
77
|
-
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);
|
|
78
81
|
const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(innerRef, props.inputGroupRef, dropdown.refs.setReference), [dropdown.refs.setReference, props.inputGroupRef]);
|
|
79
82
|
const isNotInteractive = props.isDisabled || props.isReadOnly;
|
|
80
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,
|
package/css/multi-combobox.css
CHANGED
package/css/multi-select.css
CHANGED
package/css/radio-group.css
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
&__option-wrapper {
|
|
12
|
-
|
|
12
|
+
display: flex;
|
|
13
|
+
justify-content: space-between;
|
|
13
14
|
|
|
14
15
|
&.is-selected {
|
|
15
16
|
.uxf-radio-group__option-label {
|
|
@@ -31,7 +32,7 @@
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
&__label {
|
|
34
|
-
|
|
35
|
+
margin-bottom: theme("spacing.2");
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -57,7 +58,7 @@
|
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
.uxf-radio-group__option-label {
|
|
60
|
-
|
|
61
|
+
padding-right: theme("spacing.4");
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
@@ -71,7 +72,9 @@
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
.uxf-radio-group__options-wrapper {
|
|
74
|
-
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-wrap: wrap;
|
|
77
|
+
gap: theme("spacing.2");
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
.uxf-radio-group__option-wrapper {
|
|
@@ -92,7 +95,9 @@
|
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
.uxf-radio-group__option-label {
|
|
95
|
-
@apply
|
|
98
|
+
@apply text-sm;
|
|
99
|
+
|
|
100
|
+
padding-top: theme("spacing.4");
|
|
96
101
|
}
|
|
97
102
|
}
|
|
98
103
|
|
|
@@ -107,22 +112,29 @@
|
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
.uxf-radio-group__option-wrapper {
|
|
110
|
-
@apply flex-row-reverse
|
|
115
|
+
@apply flex-row-reverse;
|
|
116
|
+
|
|
117
|
+
align-items: center;
|
|
111
118
|
}
|
|
112
119
|
|
|
113
120
|
.uxf-radio-group__option-label {
|
|
114
|
-
|
|
121
|
+
padding-left: theme("spacing.2");
|
|
115
122
|
}
|
|
116
123
|
}
|
|
117
124
|
|
|
118
125
|
.uxf-radio-group--column {
|
|
119
126
|
.uxf-radio-group__options-wrapper {
|
|
120
|
-
|
|
127
|
+
align-items: start;
|
|
128
|
+
display: flex;
|
|
129
|
+
flex-direction: column;
|
|
130
|
+
gap: theme("spacing.2");
|
|
121
131
|
}
|
|
122
132
|
}
|
|
123
133
|
|
|
124
134
|
.uxf-radio-group--row {
|
|
125
135
|
.uxf-radio-group__options-wrapper {
|
|
126
|
-
|
|
136
|
+
align-items: center;
|
|
137
|
+
display: flex;
|
|
138
|
+
gap: theme("spacing.10");
|
|
127
139
|
}
|
|
128
140
|
}
|
|
@@ -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
|
|
69
|
+
var _a, _b;
|
|
66
70
|
const optionTyped = option;
|
|
67
|
-
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,
|
|
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("");
|
|
@@ -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), disabled: option.disabled, value: 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), 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, form: props.form, multiple: true, name: props.name, 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
|
@@ -25,6 +25,7 @@ export interface SelectProps<Value = SelectValue, Option = SelectOption<Value>>
|
|
|
25
25
|
inputArrow?: (open: boolean) => ReactNode;
|
|
26
26
|
keyExtractor?: (option: Option) => string | number;
|
|
27
27
|
label: ReactNode;
|
|
28
|
+
noOptionsMessage?: string;
|
|
28
29
|
options: Option[];
|
|
29
30
|
placeholder?: string;
|
|
30
31
|
renderOption?: (option: Option, isSelected: boolean) => ReactNode;
|
package/select/select.js
CHANGED
|
@@ -32,6 +32,7 @@ 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");
|
|
@@ -44,11 +45,11 @@ function Option(props) {
|
|
|
44
45
|
Option.displayName = "UxfUiSelectOption";
|
|
45
46
|
function Options(props) {
|
|
46
47
|
var _a, _b;
|
|
47
|
-
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) => {
|
|
48
49
|
var _a, _b;
|
|
49
50
|
const optionKey = (_b = (_a = props.keyExtractor) === null || _a === void 0 ? void 0 : _a.call(props, option)) !== null && _b !== void 0 ? _b : option.id;
|
|
50
51
|
return react_3.default.createElement(Option, { key: optionKey, option: option, renderOption: props.renderOption });
|
|
51
|
-
})));
|
|
52
|
+
})) : (react_3.default.createElement("div", { className: "uxf-dropdown__empty-wrapper" }, props.emptyMessage))));
|
|
52
53
|
}
|
|
53
54
|
Options.displayName = "UxfUiSelectOptions";
|
|
54
55
|
const SelectedValue = (0, react_3.forwardRef)((props, ref) => {
|
|
@@ -59,7 +60,7 @@ const SelectedValue = (0, react_3.forwardRef)((props, ref) => {
|
|
|
59
60
|
});
|
|
60
61
|
SelectedValue.displayName = "UxUiSelectSelectedValue";
|
|
61
62
|
function Select(props) {
|
|
62
|
-
var _a, _b, _c, _d;
|
|
63
|
+
var _a, _b, _c, _d, _e;
|
|
63
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); };
|
|
64
65
|
const selectedOption = (_a = props.options.find((option) => option.id === props.value)) !== null && _a !== void 0 ? _a : null;
|
|
65
66
|
const generatedId = (0, react_3.useId)();
|
|
@@ -70,6 +71,7 @@ function Select(props) {
|
|
|
70
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);
|
|
71
72
|
const stableRef = (0, react_3.useMemo)(() => (0, compose_refs_1.composeRefs)(innerRef, props.inputGroupRef, dropdown.refs.setReference), [dropdown.refs.setReference, props.inputGroupRef]);
|
|
72
73
|
const value = selectedOption;
|
|
74
|
+
const emptyMessage = (_e = props.noOptionsMessage) !== null && _e !== void 0 ? _e : "Nabídka neosahuje žádné položky";
|
|
73
75
|
const isNotInteractive = props.isDisabled || props.isReadOnly;
|
|
74
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) => {
|
|
75
77
|
var _a, _b, _c;
|
|
@@ -90,7 +92,7 @@ function Select(props) {
|
|
|
90
92
|
props.rightAddon && react_3.default.createElement(input_1.Input.RightAddon, null, props.rightAddon)),
|
|
91
93
|
react_3.default.createElement(show_1.Show, { when: renderProps.open },
|
|
92
94
|
react_3.default.createElement(react_1.FloatingPortal, null,
|
|
93
|
-
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 }))),
|
|
94
96
|
react_3.default.createElement(show_1.Show, { when: Boolean(props.helperText) },
|
|
95
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)))));
|
|
96
98
|
}));
|