@koobiq/react-components 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/DateInput/types.d.ts +3 -3
- package/dist/components/DateInput/types.js +2 -1
- package/dist/components/FieldComponents/FieldContentGroup/FieldContentGroup.d.ts +2 -2
- package/dist/components/FieldComponents/FieldContentGroup/FieldContentGroup.js +5 -6
- package/dist/components/FieldComponents/FieldContentGroup/FieldContentGroupContext.d.ts +3 -2
- package/dist/components/FieldComponents/FieldContentGroup/FieldContentGroupContext.js +2 -2
- package/dist/components/FieldComponents/FieldContentGroup/types.d.ts +4 -4
- package/dist/components/FieldComponents/FieldContentGroup/types.js +4 -0
- package/dist/components/FieldComponents/FieldInput/FieldInput.d.ts +2 -2
- package/dist/components/FieldComponents/FieldInputDate/FieldInputDate.d.ts +2 -2
- package/dist/components/FieldComponents/FieldSelect/types.d.ts +2 -2
- package/dist/components/Input/Input.d.ts +3 -3
- package/dist/components/Input/types.d.ts +4 -4
- package/dist/components/Input/types.js +2 -1
- package/dist/components/InputNumber/InputNumber.d.ts +2 -2
- package/dist/components/InputNumber/components/InputNumberCounterControls.js +2 -2
- package/dist/components/InputNumber/types.d.ts +3 -3
- package/dist/components/InputNumber/types.js +2 -1
- package/dist/components/List/List.d.ts +2 -1
- package/dist/components/List/List.js +16 -3
- package/dist/components/List/List.module.css.js +4 -1
- package/dist/components/Menu/Menu.js +1 -1
- package/dist/components/Menu/components/MenuInner/MenuInner.js +1 -1
- package/dist/components/SearchInput/SearchInput.d.ts +21 -0
- package/dist/components/SearchInput/SearchInput.js +119 -0
- package/dist/components/SearchInput/SearchInput.module.css.js +17 -0
- package/dist/components/SearchInput/index.d.ts +2 -0
- package/dist/components/SearchInput/types.d.ts +47 -0
- package/dist/components/SearchInput/types.js +5 -0
- package/dist/components/Select/Select.d.ts +3 -2
- package/dist/components/Select/Select.js +83 -101
- package/dist/components/Select/Select.module.css.js +8 -2
- package/dist/components/Select/components/SelectList/SelectList.d.ts +8 -0
- package/dist/components/Select/components/SelectList/SelectList.js +51 -0
- package/dist/components/Select/components/SelectList/SelectList.module.css.js +11 -0
- package/dist/components/Select/components/SelectList/index.d.ts +1 -0
- package/dist/components/Select/components/SelectOption/SelectOption.d.ts +7 -0
- package/dist/components/Select/components/SelectOption/SelectOption.js +42 -0
- package/dist/components/Select/components/SelectOption/index.d.ts +1 -0
- package/dist/components/Select/components/Tag/Tag.d.ts +17 -0
- package/dist/components/Select/components/Tag/Tag.js +64 -0
- package/dist/components/Select/components/Tag/index.d.ts +1 -0
- package/dist/components/Select/components/Tag/intl.json.js +7 -0
- package/dist/components/Select/components/Tag/utils.d.ts +3 -0
- package/dist/components/Select/components/Tag/utils.js +9 -0
- package/dist/components/Select/components/TagGroup/TagGroup.d.ts +13 -0
- package/dist/components/Select/components/TagGroup/TagGroup.js +24 -0
- package/dist/components/Select/components/TagGroup/TagGroup.module.css.js +23 -0
- package/dist/components/Select/components/TagGroup/TagGroupMultiline.d.ts +3 -0
- package/dist/components/Select/components/TagGroup/TagGroupMultiline.js +47 -0
- package/dist/components/Select/components/TagGroup/TagGroupResponsive.d.ts +3 -0
- package/dist/components/Select/components/TagGroup/TagGroupResponsive.js +66 -0
- package/dist/components/Select/components/TagGroup/index.d.ts +1 -0
- package/dist/components/Select/components/TagGroup/utils.d.ts +1 -0
- package/dist/components/Select/components/TagGroup/utils.js +4 -0
- package/dist/components/Select/components/index.d.ts +3 -0
- package/dist/components/Select/intl.d.ts +2 -0
- package/dist/components/Select/intl.js +15 -0
- package/dist/components/Select/types.d.ts +36 -43
- package/dist/components/Select/types.js +7 -0
- package/dist/components/Textarea/types.d.ts +2 -2
- package/dist/components/Textarea/types.js +2 -1
- package/dist/components/TimePicker/types.d.ts +2 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/style.css +257 -130
- package/package.json +5 -5
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef } from "react";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { useSelectState, removeDataAttributes, useSelect, HiddenSelect } from "@koobiq/react-primitives";
|
|
2
|
+
import { forwardRef, useCallback } from "react";
|
|
3
|
+
import { useLocalizedStringFormatter, useDOMRef, useElementSize, mergeProps, clsx } from "@koobiq/react-core";
|
|
4
|
+
import { IconXmarkCircle16, IconChevronDownS16 } from "@koobiq/react-icons";
|
|
5
|
+
import { useMultiSelectState, removeDataAttributes, useMultiSelect } from "@koobiq/react-primitives";
|
|
7
6
|
import { PopoverInner } from "../Popover/PopoverInner.js";
|
|
7
|
+
import intlMessages from "./intl.js";
|
|
8
8
|
import s from "./Select.module.css.js";
|
|
9
9
|
import { FieldSelect } from "../FieldComponents/FieldSelect/FieldSelect.js";
|
|
10
|
-
import {
|
|
10
|
+
import { SelectList } from "./components/SelectList/SelectList.js";
|
|
11
|
+
import { TagGroup } from "./components/TagGroup/TagGroup.js";
|
|
12
|
+
import { List } from "../List/List.js";
|
|
13
|
+
import { IconButton } from "../IconButton/IconButton.js";
|
|
11
14
|
import { FieldControl } from "../FieldComponents/FieldControl/FieldControl.js";
|
|
12
15
|
import { FieldLabel } from "../FieldComponents/FieldLabel/FieldLabel.js";
|
|
13
16
|
import { FieldContentGroup } from "../FieldComponents/FieldContentGroup/FieldContentGroup.js";
|
|
@@ -15,97 +18,63 @@ import { FieldCaption } from "../FieldComponents/FieldCaption/FieldCaption.js";
|
|
|
15
18
|
import { FieldError } from "../FieldComponents/FieldError/FieldError.js";
|
|
16
19
|
import { Item } from "../Collections/Item.js";
|
|
17
20
|
import { Section } from "../Collections/Section.js";
|
|
18
|
-
import {
|
|
21
|
+
import { Divider } from "../Collections/Divider.js";
|
|
19
22
|
function SelectRender(props, ref) {
|
|
20
23
|
const {
|
|
21
24
|
fullWidth = false,
|
|
25
|
+
isClearable = false,
|
|
22
26
|
"data-testid": testId,
|
|
27
|
+
selectionMode = "single",
|
|
28
|
+
selectedTagsOverflow = "responsive",
|
|
29
|
+
isRequired,
|
|
30
|
+
isDisabled,
|
|
31
|
+
caption,
|
|
32
|
+
errorMessage,
|
|
23
33
|
className,
|
|
24
34
|
style,
|
|
25
|
-
|
|
26
|
-
isOpen: isOpenProp,
|
|
27
|
-
hiddenLabel,
|
|
28
|
-
isLabelHidden: isLabelHiddenProp,
|
|
29
|
-
disabled,
|
|
30
|
-
isDisabled: isDisabledProp,
|
|
31
|
-
error,
|
|
32
|
-
isInvalid: isInvalidProp,
|
|
33
|
-
required,
|
|
34
|
-
isRequired: isRequiredProp,
|
|
35
|
-
caption,
|
|
35
|
+
isLabelHidden,
|
|
36
36
|
placeholder,
|
|
37
37
|
endAddon,
|
|
38
38
|
slotProps,
|
|
39
39
|
startAddon,
|
|
40
|
+
onClear,
|
|
40
41
|
label,
|
|
41
|
-
name,
|
|
42
|
-
errorMessage,
|
|
43
42
|
renderValue: renderValueProp
|
|
44
43
|
} = props;
|
|
45
|
-
const
|
|
46
|
-
const isInvalid = isInvalidProp ?? error ?? false;
|
|
47
|
-
const isDisabled = isDisabledProp ?? disabled ?? false;
|
|
48
|
-
const isRequired = isRequiredProp ?? required ?? false;
|
|
49
|
-
const isLabelHidden = isLabelHiddenProp ?? hiddenLabel ?? false;
|
|
50
|
-
if (process.env.NODE_ENV !== "production" && "disabled" in props) {
|
|
51
|
-
deprecate(
|
|
52
|
-
'Select: the "disabled" prop is deprecated. Use "isDisabled" prop to replace it.'
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
if (process.env.NODE_ENV !== "production" && "required" in props) {
|
|
56
|
-
deprecate(
|
|
57
|
-
'Select: the "required" prop is deprecated. Use "isRequired" prop to replace it.'
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
if (process.env.NODE_ENV !== "production" && "error" in props) {
|
|
61
|
-
deprecate(
|
|
62
|
-
'Select: the "error" prop is deprecated. Use "isInvalid" prop to replace it.'
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
if (process.env.NODE_ENV !== "production" && "open" in props) {
|
|
66
|
-
deprecate(
|
|
67
|
-
'Select: the "open" prop is deprecated. Use "isOpen" prop to replace it.'
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
if (process.env.NODE_ENV !== "production" && "hiddenLabel" in props) {
|
|
71
|
-
deprecate(
|
|
72
|
-
'Select: the "hiddenLabel" prop is deprecated. Use "isLabelHidden" prop to replace it.'
|
|
73
|
-
);
|
|
74
|
-
}
|
|
44
|
+
const t = useLocalizedStringFormatter(intlMessages);
|
|
75
45
|
const domRef = useDOMRef(ref);
|
|
76
|
-
const state =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
46
|
+
const state = useMultiSelectState(
|
|
47
|
+
removeDataAttributes({ ...props, selectionMode })
|
|
48
|
+
);
|
|
49
|
+
const hasClearButton = isClearable && !isDisabled && state.selectedItems;
|
|
50
|
+
const handleClear = useCallback(() => {
|
|
51
|
+
state.selectionManager.clearSelection();
|
|
52
|
+
onClear?.();
|
|
53
|
+
}, [onClear, state]);
|
|
84
54
|
const {
|
|
55
|
+
isInvalid,
|
|
85
56
|
menuProps,
|
|
86
57
|
valueProps,
|
|
87
58
|
triggerProps,
|
|
88
59
|
labelProps: labelPropsAria,
|
|
89
60
|
descriptionProps,
|
|
90
61
|
errorMessageProps
|
|
91
|
-
} =
|
|
92
|
-
{
|
|
93
|
-
...
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
},
|
|
99
|
-
{ ...state, isOpen: state.isOpen || opened },
|
|
62
|
+
} = useMultiSelect(
|
|
63
|
+
removeDataAttributes({
|
|
64
|
+
...props,
|
|
65
|
+
selectionMode,
|
|
66
|
+
disallowEmptySelection: true
|
|
67
|
+
}),
|
|
68
|
+
state,
|
|
100
69
|
domRef
|
|
101
70
|
);
|
|
102
71
|
const { ref: containerRef, width } = useElementSize();
|
|
103
72
|
const rootProps = mergeProps({
|
|
104
73
|
"data-testid": testId,
|
|
105
|
-
"data-invalid": isInvalid,
|
|
106
74
|
"data-fullwidth": fullWidth,
|
|
107
|
-
"data-
|
|
108
|
-
"data-
|
|
75
|
+
"data-invalid": isInvalid,
|
|
76
|
+
"data-disabled": props.isDisabled,
|
|
77
|
+
"data-required": props.isRequired,
|
|
109
78
|
className: clsx(s.base, fullWidth && s.fullWidth, className),
|
|
110
79
|
style
|
|
111
80
|
});
|
|
@@ -119,16 +88,28 @@ function SelectRender(props, ref) {
|
|
|
119
88
|
slotProps?.label,
|
|
120
89
|
labelPropsAria
|
|
121
90
|
);
|
|
91
|
+
const clearButtonProps = mergeProps(
|
|
92
|
+
{
|
|
93
|
+
"aria-label": t.format("clear"),
|
|
94
|
+
onPress: handleClear,
|
|
95
|
+
className: s.clearButton,
|
|
96
|
+
variant: isInvalid ? "error" : "fade-contrast",
|
|
97
|
+
preventFocusOnPress: true
|
|
98
|
+
},
|
|
99
|
+
slotProps?.clearButton
|
|
100
|
+
);
|
|
122
101
|
const groupProps = mergeProps(
|
|
123
102
|
{
|
|
124
103
|
slotProps: {
|
|
125
104
|
endAddon: { className: s.addon },
|
|
126
105
|
startAddon: { className: s.addon }
|
|
127
106
|
},
|
|
107
|
+
className: clsx(isClearable && s.clearable),
|
|
128
108
|
startAddon,
|
|
129
109
|
endAddon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
130
110
|
endAddon,
|
|
131
|
-
/* @__PURE__ */ jsx(
|
|
111
|
+
hasClearButton && /* @__PURE__ */ jsx(IconButton, { ...clearButtonProps, children: /* @__PURE__ */ jsx(IconXmarkCircle16, {}) }),
|
|
112
|
+
/* @__PURE__ */ jsx("span", { className: s.chevron, children: /* @__PURE__ */ jsx(IconChevronDownS16, {}) })
|
|
132
113
|
] }),
|
|
133
114
|
isInvalid,
|
|
134
115
|
isDisabled,
|
|
@@ -138,21 +119,15 @@ function SelectRender(props, ref) {
|
|
|
138
119
|
);
|
|
139
120
|
const controlProps = mergeProps(
|
|
140
121
|
{
|
|
141
|
-
isInvalid,
|
|
142
|
-
isDisabled,
|
|
143
122
|
ref: domRef,
|
|
144
|
-
placeholder
|
|
123
|
+
placeholder,
|
|
124
|
+
isInvalid,
|
|
125
|
+
isDisabled
|
|
145
126
|
},
|
|
146
127
|
slotProps?.control,
|
|
147
128
|
valueProps,
|
|
148
129
|
triggerProps
|
|
149
130
|
);
|
|
150
|
-
const captionProps = mergeProps({ children: caption }, slotProps?.caption, descriptionProps);
|
|
151
|
-
const errorProps = mergeProps(
|
|
152
|
-
{ isInvalid, children: errorMessage },
|
|
153
|
-
slotProps?.errorMessage,
|
|
154
|
-
errorMessageProps
|
|
155
|
-
);
|
|
156
131
|
const popoverProps = mergeProps(
|
|
157
132
|
{
|
|
158
133
|
state,
|
|
@@ -162,43 +137,50 @@ function SelectRender(props, ref) {
|
|
|
162
137
|
anchorRef: domRef,
|
|
163
138
|
className: s.popover,
|
|
164
139
|
placement: "bottom start",
|
|
165
|
-
type: "listbox"
|
|
166
|
-
slotProps: {
|
|
167
|
-
transition: {
|
|
168
|
-
onEnter: on,
|
|
169
|
-
onExited: off
|
|
170
|
-
}
|
|
171
|
-
}
|
|
140
|
+
type: "listbox"
|
|
172
141
|
},
|
|
173
142
|
slotProps?.popover
|
|
174
143
|
);
|
|
175
|
-
const
|
|
144
|
+
const captionProps = mergeProps({ children: caption }, slotProps?.caption, descriptionProps);
|
|
145
|
+
const errorProps = mergeProps(
|
|
146
|
+
{ isInvalid, children: errorMessage },
|
|
147
|
+
slotProps?.errorMessage,
|
|
148
|
+
errorMessageProps
|
|
149
|
+
);
|
|
150
|
+
const renderDefaultValue = (state2, states) => {
|
|
151
|
+
if (!state2.selectedItems) return null;
|
|
152
|
+
if (selectionMode === "multiple")
|
|
153
|
+
return /* @__PURE__ */ jsx(
|
|
154
|
+
TagGroup,
|
|
155
|
+
{
|
|
156
|
+
state: state2,
|
|
157
|
+
states,
|
|
158
|
+
selectedTagsOverflow
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
return state2.selectedItems[0].textValue;
|
|
162
|
+
};
|
|
176
163
|
const renderValue = renderValueProp || renderDefaultValue;
|
|
177
164
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
178
165
|
/* @__PURE__ */ jsxs(FieldControl, { ...rootProps, children: [
|
|
179
166
|
/* @__PURE__ */ jsx(FieldLabel, { ...labelProps }),
|
|
180
|
-
/* @__PURE__ */ jsx(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
state,
|
|
186
|
-
triggerRef: domRef,
|
|
187
|
-
isDisabled
|
|
188
|
-
}
|
|
189
|
-
),
|
|
190
|
-
/* @__PURE__ */ jsx(FieldContentGroup, { ...groupProps, children: /* @__PURE__ */ jsx(FieldSelect, { ...controlProps, children: renderValue(state?.selectedItem) }) }),
|
|
167
|
+
/* @__PURE__ */ jsx(FieldContentGroup, { ...groupProps, children: /* @__PURE__ */ jsx(FieldSelect, { ...controlProps, children: renderValue(state, {
|
|
168
|
+
isInvalid,
|
|
169
|
+
isDisabled: props.isDisabled,
|
|
170
|
+
isRequired: props.isRequired
|
|
171
|
+
}) }) }),
|
|
191
172
|
/* @__PURE__ */ jsx(FieldCaption, { ...captionProps }),
|
|
192
173
|
/* @__PURE__ */ jsx(FieldError, { ...errorProps })
|
|
193
174
|
] }),
|
|
194
|
-
/* @__PURE__ */ jsx(PopoverInner, { ...popoverProps, children: /* @__PURE__ */ jsx(
|
|
175
|
+
/* @__PURE__ */ jsx(PopoverInner, { ...popoverProps, children: /* @__PURE__ */ jsx(SelectList, { ...listProps }) })
|
|
195
176
|
] });
|
|
196
177
|
}
|
|
197
178
|
const SelectComponent = forwardRef(SelectRender);
|
|
198
179
|
const Select = SelectComponent;
|
|
199
180
|
Select.Item = Item;
|
|
200
181
|
Select.Section = Section;
|
|
201
|
-
Select.
|
|
182
|
+
Select.Divider = Divider;
|
|
183
|
+
Select.ItemText = List.ItemText;
|
|
202
184
|
export {
|
|
203
185
|
Select
|
|
204
186
|
};
|
|
@@ -2,20 +2,26 @@ const base = "kbq-select-6d31ad";
|
|
|
2
2
|
const fullWidth = "kbq-select-fullWidth-1dfc13";
|
|
3
3
|
const addon = "kbq-select-addon-cbc524";
|
|
4
4
|
const chevron = "kbq-select-chevron-0b4fa3";
|
|
5
|
-
const popover = "kbq-select-popover-79fc05";
|
|
6
5
|
const list = "kbq-select-list-8ffac0";
|
|
6
|
+
const popover = "kbq-select-popover-79fc05";
|
|
7
|
+
const clearButton = "kbq-select-clearButton-8031a1";
|
|
8
|
+
const clearable = "kbq-select-clearable-2f5092";
|
|
7
9
|
const s = {
|
|
8
10
|
base,
|
|
9
11
|
fullWidth,
|
|
10
12
|
addon,
|
|
11
13
|
chevron,
|
|
14
|
+
list,
|
|
12
15
|
popover,
|
|
13
|
-
|
|
16
|
+
clearButton,
|
|
17
|
+
clearable
|
|
14
18
|
};
|
|
15
19
|
export {
|
|
16
20
|
addon,
|
|
17
21
|
base,
|
|
18
22
|
chevron,
|
|
23
|
+
clearButton,
|
|
24
|
+
clearable,
|
|
19
25
|
s as default,
|
|
20
26
|
fullWidth,
|
|
21
27
|
list,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Ref } from 'react';
|
|
2
|
+
import { type MultiSelectState } from '@koobiq/react-primitives';
|
|
3
|
+
import type { ListProps } from '../../../List';
|
|
4
|
+
export type SelectListProps<T extends object> = {
|
|
5
|
+
state: MultiSelectState<T>;
|
|
6
|
+
listRef?: Ref<HTMLUListElement>;
|
|
7
|
+
} & Omit<ListProps<T>, 'ref'>;
|
|
8
|
+
export declare function SelectList<T extends object>(props: SelectListProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useDOMRef, mergeProps, clsx, isNotNil } from "@koobiq/react-core";
|
|
3
|
+
import { useListBox } from "@koobiq/react-primitives";
|
|
4
|
+
import { utilClasses } from "../../../../styles/utility.js";
|
|
5
|
+
import s from "./SelectList.module.css.js";
|
|
6
|
+
import { SelectOption } from "../SelectOption/SelectOption.js";
|
|
7
|
+
import { Typography } from "../../../Typography/Typography.js";
|
|
8
|
+
import { ListSection } from "../../../List/components/ListSection/ListSection.js";
|
|
9
|
+
import { Divider } from "../../../Divider/Divider.js";
|
|
10
|
+
const { list } = utilClasses;
|
|
11
|
+
function SelectList(props) {
|
|
12
|
+
const { label, className, style, slotProps, state, listRef } = props;
|
|
13
|
+
const domRef = useDOMRef(listRef);
|
|
14
|
+
const { listBoxProps, labelProps } = useListBox(props, state, domRef);
|
|
15
|
+
const titleProps = mergeProps(
|
|
16
|
+
{
|
|
17
|
+
className: s.label,
|
|
18
|
+
variant: "text-normal-strong"
|
|
19
|
+
},
|
|
20
|
+
slotProps?.label,
|
|
21
|
+
labelProps
|
|
22
|
+
);
|
|
23
|
+
const listProps = mergeProps(
|
|
24
|
+
{
|
|
25
|
+
style,
|
|
26
|
+
ref: domRef,
|
|
27
|
+
className: clsx(list, className)
|
|
28
|
+
},
|
|
29
|
+
slotProps?.list,
|
|
30
|
+
listBoxProps
|
|
31
|
+
);
|
|
32
|
+
const renderItems = (treeState) => [...treeState.collection].map((item) => {
|
|
33
|
+
switch (item.type) {
|
|
34
|
+
case "divider":
|
|
35
|
+
return /* @__PURE__ */ jsx(Divider, { className: s.divider }, item.key);
|
|
36
|
+
case "item":
|
|
37
|
+
return /* @__PURE__ */ jsx(SelectOption, { item, state }, item.key);
|
|
38
|
+
case "section":
|
|
39
|
+
return /* @__PURE__ */ jsx(ListSection, { section: item, state }, item.key);
|
|
40
|
+
default:
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
45
|
+
isNotNil(label) && /* @__PURE__ */ jsx(Typography, { ...titleProps, children: label }),
|
|
46
|
+
/* @__PURE__ */ jsx("ul", { ...listProps, children: renderItems(state) })
|
|
47
|
+
] });
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
SelectList
|
|
51
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SelectList';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Node } from '@koobiq/react-core';
|
|
2
|
+
import { type MultiSelectState } from '@koobiq/react-primitives';
|
|
3
|
+
export type SelectOptionProps<T> = {
|
|
4
|
+
item: Node<T>;
|
|
5
|
+
state: MultiSelectState<T>;
|
|
6
|
+
};
|
|
7
|
+
export declare function SelectOption<T>({ item, state }: SelectOptionProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useRef } from "react";
|
|
4
|
+
import { useHover, usePress, clsx, mergeProps } from "@koobiq/react-core";
|
|
5
|
+
import { useOption } from "@koobiq/react-primitives";
|
|
6
|
+
import { utilClasses } from "../../../../styles/utility.js";
|
|
7
|
+
import { Checkbox } from "../../../Checkbox/Checkbox.js";
|
|
8
|
+
const textVariant = utilClasses.typography;
|
|
9
|
+
const { listItem } = utilClasses;
|
|
10
|
+
function SelectOption({ item, state }) {
|
|
11
|
+
const { href, className, style } = item.props;
|
|
12
|
+
const ref = useRef(null);
|
|
13
|
+
const { optionProps, isSelected, isDisabled, isFocusVisible } = useOption(
|
|
14
|
+
{ key: item.key },
|
|
15
|
+
state,
|
|
16
|
+
ref
|
|
17
|
+
);
|
|
18
|
+
const { hoverProps, isHovered } = useHover({ isDisabled });
|
|
19
|
+
const { isPressed, pressProps } = usePress({ isDisabled });
|
|
20
|
+
const Tag = href ? "a" : "li";
|
|
21
|
+
return /* @__PURE__ */ jsxs(
|
|
22
|
+
Tag,
|
|
23
|
+
{
|
|
24
|
+
...mergeProps(optionProps, hoverProps, pressProps),
|
|
25
|
+
className: clsx(listItem, textVariant["text-normal"], className),
|
|
26
|
+
style,
|
|
27
|
+
ref,
|
|
28
|
+
"data-hovered": isHovered,
|
|
29
|
+
"data-pressed": isPressed,
|
|
30
|
+
"data-disabled": isDisabled,
|
|
31
|
+
"data-selected": isSelected,
|
|
32
|
+
"data-focus-visible": isFocusVisible,
|
|
33
|
+
children: [
|
|
34
|
+
state.selectionMode === "multiple" && /* @__PURE__ */ jsx(Checkbox, { isDisabled, isSelected, isReadOnly: true }),
|
|
35
|
+
item.rendered
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
SelectOption
|
|
42
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SelectOption';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
import type { TagGroupPropVariant } from '../../../TagGroup';
|
|
3
|
+
type TagProps = {
|
|
4
|
+
/**
|
|
5
|
+
* The variant to use.
|
|
6
|
+
* @default 'theme-fade'
|
|
7
|
+
*/
|
|
8
|
+
variant?: TagGroupPropVariant;
|
|
9
|
+
className?: string;
|
|
10
|
+
style?: CSSProperties;
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
icon?: ReactNode;
|
|
13
|
+
isDisabled?: boolean;
|
|
14
|
+
onRemove?: () => void;
|
|
15
|
+
};
|
|
16
|
+
export declare const Tag: import("react").ForwardRefExoticComponent<TagProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { useLocalizedStringFormatter, mergeProps, clsx, isNotNil } from "@koobiq/react-core";
|
|
4
|
+
import { IconXmarkS16 } from "@koobiq/react-icons";
|
|
5
|
+
import { utilClasses } from "../../../../styles/utility.js";
|
|
6
|
+
import s from "../../../TagGroup/components/Tag/Tag.module.css.js";
|
|
7
|
+
import intlMessages from "./intl.json.js";
|
|
8
|
+
import { matchVariantToCloseButton } from "./utils.js";
|
|
9
|
+
import { IconButton } from "../../../IconButton/IconButton.js";
|
|
10
|
+
const textNormalMedium = utilClasses.typography["text-normal-medium"];
|
|
11
|
+
const Tag = forwardRef((props, ref) => {
|
|
12
|
+
const {
|
|
13
|
+
variant = "theme-fade",
|
|
14
|
+
icon,
|
|
15
|
+
className,
|
|
16
|
+
style,
|
|
17
|
+
isDisabled,
|
|
18
|
+
children,
|
|
19
|
+
onRemove
|
|
20
|
+
} = props;
|
|
21
|
+
const stringFormatter = useLocalizedStringFormatter(intlMessages);
|
|
22
|
+
const rootProps = mergeProps({
|
|
23
|
+
className: clsx(
|
|
24
|
+
s.base,
|
|
25
|
+
s[variant],
|
|
26
|
+
isDisabled && s.disabled,
|
|
27
|
+
textNormalMedium,
|
|
28
|
+
className
|
|
29
|
+
),
|
|
30
|
+
style
|
|
31
|
+
});
|
|
32
|
+
const removeButtonProps = {
|
|
33
|
+
isCompact: true,
|
|
34
|
+
isDisabled,
|
|
35
|
+
className: s.cancelIcon,
|
|
36
|
+
variant: matchVariantToCloseButton[variant],
|
|
37
|
+
"aria-label": stringFormatter.format("remove")
|
|
38
|
+
};
|
|
39
|
+
const contentProps = mergeProps({
|
|
40
|
+
className: s.content
|
|
41
|
+
});
|
|
42
|
+
const iconProps = mergeProps({
|
|
43
|
+
className: s.icon
|
|
44
|
+
});
|
|
45
|
+
return /* @__PURE__ */ jsxs("div", { ref, ...rootProps, children: [
|
|
46
|
+
isNotNil(icon) && /* @__PURE__ */ jsx("span", { ...iconProps, children: icon }),
|
|
47
|
+
isNotNil(children) && /* @__PURE__ */ jsx("span", { ...contentProps, children }),
|
|
48
|
+
/* @__PURE__ */ jsx(
|
|
49
|
+
IconButton,
|
|
50
|
+
{
|
|
51
|
+
as: "div",
|
|
52
|
+
size: "l",
|
|
53
|
+
...removeButtonProps,
|
|
54
|
+
tabIndex: void 0,
|
|
55
|
+
onPress: onRemove,
|
|
56
|
+
children: /* @__PURE__ */ jsx(IconXmarkS16, {})
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
] });
|
|
60
|
+
});
|
|
61
|
+
Tag.displayName = "SelectTag";
|
|
62
|
+
export {
|
|
63
|
+
Tag
|
|
64
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Tag';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import type { MultiSelectState } from '@koobiq/react-primitives';
|
|
3
|
+
import type { SelectPropSelectedTagsOverflow } from '../../types';
|
|
4
|
+
export type TagGroupProps<T> = {
|
|
5
|
+
state: MultiSelectState<T>;
|
|
6
|
+
states: {
|
|
7
|
+
isInvalid?: boolean;
|
|
8
|
+
isDisabled?: boolean;
|
|
9
|
+
isRequired?: boolean;
|
|
10
|
+
};
|
|
11
|
+
selectedTagsOverflow?: SelectPropSelectedTagsOverflow;
|
|
12
|
+
};
|
|
13
|
+
export declare const TagGroup: FC<TagGroupProps<unknown>>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { logger } from "@koobiq/logger";
|
|
3
|
+
import { TagGroupMultiline } from "./TagGroupMultiline.js";
|
|
4
|
+
import { TagGroupResponsive } from "./TagGroupResponsive.js";
|
|
5
|
+
function assertNever(x) {
|
|
6
|
+
logger.error(`Unhandled selectedTagsOverflow variant: ${x}`);
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const TagGroup = ({
|
|
10
|
+
selectedTagsOverflow = "responsive",
|
|
11
|
+
...rest
|
|
12
|
+
}) => {
|
|
13
|
+
switch (selectedTagsOverflow) {
|
|
14
|
+
case "responsive":
|
|
15
|
+
return /* @__PURE__ */ jsx(TagGroupResponsive, { ...rest });
|
|
16
|
+
case "multiline":
|
|
17
|
+
return /* @__PURE__ */ jsx(TagGroupMultiline, { ...rest });
|
|
18
|
+
default:
|
|
19
|
+
return assertNever(selectedTagsOverflow);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
TagGroup
|
|
24
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const container = "kbq-taggroup-container-c4d544";
|
|
2
|
+
const hasStartAddon = "kbq-taggroup-hasStartAddon-40d1f9";
|
|
3
|
+
const base = "kbq-taggroup-8253a5";
|
|
4
|
+
const tag = "kbq-taggroup-tag-b9306f";
|
|
5
|
+
const more = "kbq-taggroup-more-b2d6b9";
|
|
6
|
+
const hidden = "kbq-taggroup-hidden-eadb46";
|
|
7
|
+
const s = {
|
|
8
|
+
container,
|
|
9
|
+
hasStartAddon,
|
|
10
|
+
base,
|
|
11
|
+
tag,
|
|
12
|
+
more,
|
|
13
|
+
hidden
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
base,
|
|
17
|
+
container,
|
|
18
|
+
s as default,
|
|
19
|
+
hasStartAddon,
|
|
20
|
+
hidden,
|
|
21
|
+
more,
|
|
22
|
+
tag
|
|
23
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLocalizedStringFormatter, clsx } from "@koobiq/react-core";
|
|
3
|
+
import intlMessages from "../../intl.js";
|
|
4
|
+
import s from "./TagGroup.module.css.js";
|
|
5
|
+
import { Tag } from "../Tag/Tag.js";
|
|
6
|
+
import { useFieldContentGroup } from "../../../FieldComponents/FieldContentGroup/FieldContentGroupContext.js";
|
|
7
|
+
const TagGroupMultiline = ({
|
|
8
|
+
state,
|
|
9
|
+
states
|
|
10
|
+
}) => {
|
|
11
|
+
const { isDisabled, isInvalid } = states;
|
|
12
|
+
const t = useLocalizedStringFormatter(intlMessages);
|
|
13
|
+
const { hasStartAddon } = useFieldContentGroup();
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
className: clsx(s.container, hasStartAddon && s.hasStartAddon),
|
|
18
|
+
"aria-hidden": true,
|
|
19
|
+
children: /* @__PURE__ */ jsx(
|
|
20
|
+
"div",
|
|
21
|
+
{
|
|
22
|
+
className: s.base,
|
|
23
|
+
"data-limit-tags": "multiline",
|
|
24
|
+
"aria-label": t.format("selected items"),
|
|
25
|
+
children: state.selectedItems?.map((item) => /* @__PURE__ */ jsx(
|
|
26
|
+
Tag,
|
|
27
|
+
{
|
|
28
|
+
className: s.tag,
|
|
29
|
+
isDisabled,
|
|
30
|
+
variant: isInvalid ? "error-fade" : "contrast-fade",
|
|
31
|
+
onRemove: () => {
|
|
32
|
+
if (state.selectionManager.isSelected(item.key)) {
|
|
33
|
+
state.selectionManager.toggleSelection(item.key);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
children: item.textValue
|
|
37
|
+
},
|
|
38
|
+
item.key
|
|
39
|
+
))
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
TagGroupMultiline
|
|
47
|
+
};
|