@rovula/ui 0.0.30 → 0.0.32
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/cjs/bundle.css +1173 -243
- package/dist/cjs/bundle.js +2 -2
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +12 -2
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +12 -2
- package/dist/cjs/types/components/InputFilter/InputFilter.d.ts +63 -4
- package/dist/cjs/types/components/InputFilter/InputFilter.stories.d.ts +54 -18
- package/dist/cjs/types/components/InputFilter/InputFilter.styles.d.ts +1 -0
- package/dist/cjs/types/components/Search/Search.stories.d.ts +7 -1
- package/dist/cjs/types/stories/ColorPreview.d.ts +9 -5
- package/dist/cjs/types/utils/colors.d.ts +1 -0
- package/dist/components/ActionButton/ActionButton.stories.js +1 -1
- package/dist/components/Checkbox/Checkbox.js +3 -3
- package/dist/components/Checkbox/Checkbox.stories.js +1 -1
- package/dist/components/Dropdown/Dropdown.js +12 -8
- package/dist/components/Dropdown/Dropdown.styles.js +1 -1
- package/dist/components/InputFilter/InputFilter.js +118 -12
- package/dist/components/InputFilter/InputFilter.stories.js +5 -4
- package/dist/components/InputFilter/InputFilter.styles.js +9 -4
- package/dist/components/RadioGroup/RadioGroup.js +5 -2
- package/dist/components/RadioGroup/RadioGroup.stories.js +1 -1
- package/dist/components/Search/Search.stories.js +2 -1
- package/dist/components/Text/Text.stories.js +5 -1
- package/dist/components/TextInput/TextInput.js +2 -1
- package/dist/components/TextInput/TextInput.styles.js +10 -9
- package/dist/esm/bundle.css +1173 -243
- package/dist/esm/bundle.js +2 -2
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Dropdown/Dropdown.d.ts +12 -2
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +12 -2
- package/dist/esm/types/components/InputFilter/InputFilter.d.ts +63 -4
- package/dist/esm/types/components/InputFilter/InputFilter.stories.d.ts +54 -18
- package/dist/esm/types/components/InputFilter/InputFilter.styles.d.ts +1 -0
- package/dist/esm/types/components/Search/Search.stories.d.ts +7 -1
- package/dist/esm/types/stories/ColorPreview.d.ts +9 -5
- package/dist/esm/types/utils/colors.d.ts +1 -0
- package/dist/index.d.ts +83 -14
- package/dist/src/theme/global.css +1526 -348
- package/dist/stories/ColorGroupPreview.js +282 -472
- package/dist/stories/ColorPreview.js +76 -6
- package/dist/theme/main-preset.js +8 -0
- package/dist/theme/plugins/utilities/typography.js +3 -0
- package/dist/theme/presets/colors.js +18 -0
- package/dist/theme/themes/xspector/color.css +13 -0
- package/dist/theme/themes/xspector/components/action-button.css +44 -42
- package/dist/theme/themes/xspector/state.css +1 -1
- package/dist/theme/tokens/color.css +13 -0
- package/dist/theme/tokens/components/action-button.css +42 -55
- package/dist/utils/colors.js +31 -0
- package/package.json +1 -1
- package/src/components/ActionButton/ActionButton.stories.tsx +1 -1
- package/src/components/Checkbox/Checkbox.stories.tsx +1 -1
- package/src/components/Checkbox/Checkbox.tsx +4 -4
- package/src/components/Dropdown/Dropdown.styles.ts +1 -1
- package/src/components/Dropdown/Dropdown.tsx +22 -8
- package/src/components/InputFilter/InputFilter.stories.tsx +9 -8
- package/src/components/InputFilter/InputFilter.styles.ts +9 -4
- package/src/components/InputFilter/InputFilter.tsx +301 -42
- package/src/components/RadioGroup/RadioGroup.stories.tsx +1 -1
- package/src/components/RadioGroup/RadioGroup.tsx +7 -9
- package/src/components/Search/Search.stories.tsx +2 -1
- package/src/components/Text/Text.stories.tsx +5 -1
- package/src/components/TextInput/TextInput.styles.ts +10 -9
- package/src/components/TextInput/TextInput.tsx +11 -10
- package/src/stories/ColorGroupPreview.tsx +394 -486
- package/src/stories/ColorPreview.tsx +122 -33
- package/src/theme/main-preset.js +8 -0
- package/src/theme/plugins/utilities/typography.js +3 -0
- package/src/theme/presets/colors.js +18 -0
- package/src/theme/themes/xspector/color.css +13 -0
- package/src/theme/themes/xspector/components/action-button.css +44 -42
- package/src/theme/themes/xspector/state.css +1 -1
- package/src/theme/tokens/color.css +13 -0
- package/src/theme/tokens/components/action-button.css +42 -55
- package/src/utils/colors.ts +33 -0
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from "./Dropdown.styles";
|
|
18
18
|
|
|
19
19
|
import { ChevronDownIcon } from "@heroicons/react/16/solid";
|
|
20
|
+
import { cn } from "@/utils/cn";
|
|
20
21
|
|
|
21
22
|
type RenderLabelCallbackArg = {
|
|
22
23
|
value: string;
|
|
@@ -45,11 +46,16 @@ export type DropdownProps = {
|
|
|
45
46
|
error?: boolean;
|
|
46
47
|
required?: boolean;
|
|
47
48
|
className?: string;
|
|
49
|
+
optionContainerClassName?: string;
|
|
48
50
|
options: Options[];
|
|
49
51
|
value?: Options;
|
|
50
52
|
onChangeText?: InputProps["onChange"];
|
|
51
53
|
onSelect?: (value: Options) => void;
|
|
52
|
-
renderOptions?: (
|
|
54
|
+
renderOptions?: (value: {
|
|
55
|
+
optionsFiltered: Options[];
|
|
56
|
+
selectedOption: Options | null | undefined;
|
|
57
|
+
onClick: (option: Options) => void;
|
|
58
|
+
}) => ReactNode;
|
|
53
59
|
} & Omit<InputProps, "value">;
|
|
54
60
|
|
|
55
61
|
const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
@@ -72,6 +78,7 @@ const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
|
72
78
|
onChangeText,
|
|
73
79
|
onSelect,
|
|
74
80
|
renderOptions: customRenderOptions,
|
|
81
|
+
optionContainerClassName,
|
|
75
82
|
...props
|
|
76
83
|
},
|
|
77
84
|
ref
|
|
@@ -86,11 +93,9 @@ const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
|
86
93
|
const keyCode = useRef("");
|
|
87
94
|
|
|
88
95
|
useEffect(() => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
}, [value, selectedOption]);
|
|
96
|
+
setSelectedOption(value);
|
|
97
|
+
setTextValue(value?.label ?? "");
|
|
98
|
+
}, [value]);
|
|
94
99
|
|
|
95
100
|
const handleOnChangeText = useCallback(
|
|
96
101
|
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
@@ -123,11 +128,20 @@ const Dropdown = forwardRef<HTMLInputElement, DropdownProps>(
|
|
|
123
128
|
|
|
124
129
|
const renderOptions = () => {
|
|
125
130
|
if (customRenderOptions) {
|
|
126
|
-
return customRenderOptions(
|
|
131
|
+
return customRenderOptions({
|
|
132
|
+
optionsFiltered,
|
|
133
|
+
selectedOption,
|
|
134
|
+
onClick: handleOptionClick,
|
|
135
|
+
});
|
|
127
136
|
}
|
|
128
137
|
|
|
129
138
|
return (
|
|
130
|
-
<ul
|
|
139
|
+
<ul
|
|
140
|
+
className={cn(
|
|
141
|
+
"absolute mt-1 w-full bg-base-popup border border-base-popup text-base-popup-foreground rounded-md shadow-md z-10 max-h-60 overflow-y-auto",
|
|
142
|
+
optionContainerClassName
|
|
143
|
+
)}
|
|
144
|
+
>
|
|
131
145
|
{optionsFiltered.map((option) => {
|
|
132
146
|
if (option.renderLabel) {
|
|
133
147
|
return (
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
-
import { InputFilter } from "./InputFilter";
|
|
4
|
-
import { Options } from "../Dropdown/Dropdown";
|
|
3
|
+
import { InputFilter, Options } from "./InputFilter";
|
|
5
4
|
|
|
6
5
|
const meta = {
|
|
7
6
|
title: "Components/InputFilter",
|
|
@@ -30,13 +29,14 @@ export const Default = {
|
|
|
30
29
|
args: {
|
|
31
30
|
label: "Choose an option:",
|
|
32
31
|
fullwidth: true,
|
|
32
|
+
disabled: true,
|
|
33
33
|
options,
|
|
34
34
|
},
|
|
35
35
|
render: (args) => {
|
|
36
|
-
const [value, setValue] = useState();
|
|
36
|
+
const [value, setValue] = useState<Options[] | undefined>([]);
|
|
37
37
|
|
|
38
|
-
const handleOnSelect = (
|
|
39
|
-
setValue(
|
|
38
|
+
const handleOnSelect = (values: Options[]) => {
|
|
39
|
+
setValue(values);
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
return (
|
|
@@ -45,15 +45,16 @@ export const Default = {
|
|
|
45
45
|
id="1"
|
|
46
46
|
size="lg"
|
|
47
47
|
options={options}
|
|
48
|
-
|
|
48
|
+
values={value}
|
|
49
49
|
onSelect={handleOnSelect}
|
|
50
|
+
optionContainerClassName="h-[400px]"
|
|
50
51
|
{...args}
|
|
51
52
|
/>
|
|
52
53
|
<InputFilter
|
|
53
54
|
id="2"
|
|
54
55
|
size="md"
|
|
55
56
|
options={options}
|
|
56
|
-
|
|
57
|
+
values={value}
|
|
57
58
|
onSelect={handleOnSelect}
|
|
58
59
|
{...args}
|
|
59
60
|
/>
|
|
@@ -61,7 +62,7 @@ export const Default = {
|
|
|
61
62
|
id="3"
|
|
62
63
|
size="sm"
|
|
63
64
|
options={options}
|
|
64
|
-
|
|
65
|
+
values={value}
|
|
65
66
|
onSelect={handleOnSelect}
|
|
66
67
|
{...args}
|
|
67
68
|
/>
|
|
@@ -4,19 +4,17 @@ import { cva } from "class-variance-authority";
|
|
|
4
4
|
export const filterIconVariant = cva(
|
|
5
5
|
[
|
|
6
6
|
// Base styles
|
|
7
|
-
"absolute
|
|
7
|
+
"absolute contents items-center justify-center cursor-pointer",
|
|
8
8
|
|
|
9
9
|
// Border styles
|
|
10
10
|
"border-l border-l-input-default-stroke",
|
|
11
11
|
"peer-hover:border-l-input-active-stroke",
|
|
12
12
|
"peer-focus:border-l-input-active-stroke",
|
|
13
|
-
"peer-disabled:border-l-input-disable-stroke",
|
|
14
13
|
|
|
15
14
|
// Fill styles
|
|
16
15
|
"fill-primary",
|
|
17
16
|
"peer-hover:fill-input-filled-text",
|
|
18
17
|
"peer-focus:fill-input-filled-text",
|
|
19
|
-
"peer-disabled:fill-input-disable-stroke",
|
|
20
18
|
|
|
21
19
|
// Stroke styles
|
|
22
20
|
"stroke-input-default-stroke",
|
|
@@ -49,7 +47,6 @@ export const filterIconVariant = cva(
|
|
|
49
47
|
"fill-primary-default",
|
|
50
48
|
"peer-hover:fill-primary-default", // TODO wait for refactor color after change function button colors
|
|
51
49
|
"peer-focus:fill-primary-hover", // TODO wait for refactor color after change function button colors
|
|
52
|
-
// "peer-disabled:fill-input-disable-stroke",
|
|
53
50
|
|
|
54
51
|
// Stroke styles
|
|
55
52
|
"stroke-primary-default",
|
|
@@ -57,6 +54,13 @@ export const filterIconVariant = cva(
|
|
|
57
54
|
"peer-focus:stroke-primary-hover",
|
|
58
55
|
],
|
|
59
56
|
},
|
|
57
|
+
disabled: {
|
|
58
|
+
true: [
|
|
59
|
+
"border-l-input-disable-stroke",
|
|
60
|
+
"fill-input-disable-stroke",
|
|
61
|
+
"stroke-input-disable-stroke",
|
|
62
|
+
],
|
|
63
|
+
},
|
|
60
64
|
},
|
|
61
65
|
defaultVariants: {
|
|
62
66
|
size: "md",
|
|
@@ -64,6 +68,7 @@ export const filterIconVariant = cva(
|
|
|
64
68
|
error: false,
|
|
65
69
|
position: "end",
|
|
66
70
|
active: false,
|
|
71
|
+
disabled: false,
|
|
67
72
|
},
|
|
68
73
|
}
|
|
69
74
|
);
|
|
@@ -1,53 +1,312 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
Fragment,
|
|
3
|
+
ReactNode,
|
|
4
|
+
forwardRef,
|
|
5
|
+
useCallback,
|
|
6
|
+
useEffect,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
} from "react";
|
|
11
|
+
|
|
12
|
+
import TextInput, { InputProps } from "../TextInput/TextInput";
|
|
13
|
+
import { cn } from "@/utils/cn";
|
|
14
|
+
import { customInputVariant } from "../Dropdown/Dropdown.styles";
|
|
3
15
|
import Icon from "../Icon/Icon";
|
|
4
16
|
import { filterIconVariant } from "./InputFilter.styles";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
import { Checkbox } from "../Checkbox/Checkbox";
|
|
18
|
+
|
|
19
|
+
type RenderLabelCallbackArg = {
|
|
20
|
+
value: string;
|
|
21
|
+
label: string;
|
|
22
|
+
handleOnClick: () => void;
|
|
23
|
+
className: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type Options = {
|
|
27
|
+
value: string;
|
|
28
|
+
label: string;
|
|
29
|
+
renderLabel?: (config: RenderLabelCallbackArg) => ReactNode;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type InputFilterProps = {
|
|
33
|
+
id?: string;
|
|
34
|
+
label?: string;
|
|
35
|
+
size?: "sm" | "md" | "lg";
|
|
36
|
+
rounded?: "none" | "normal" | "full";
|
|
37
|
+
variant?: "flat" | "outline" | "underline";
|
|
38
|
+
helperText?: string;
|
|
39
|
+
errorMessage?: string;
|
|
40
|
+
filterMode?: boolean;
|
|
41
|
+
fullwidth?: boolean;
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
error?: boolean;
|
|
44
|
+
required?: boolean;
|
|
45
|
+
className?: string;
|
|
46
|
+
optionContainerClassName?: string;
|
|
47
|
+
options: Options[];
|
|
48
|
+
values?: Options[];
|
|
49
|
+
onChangeText?: InputProps["onChange"];
|
|
50
|
+
onSelect?: (values: Options[]) => void;
|
|
51
|
+
renderOptions?: (value: {
|
|
52
|
+
optionsFiltered: Options[];
|
|
53
|
+
selectedOptions: Options[];
|
|
54
|
+
onClick: (option: Options) => void;
|
|
55
|
+
}) => ReactNode;
|
|
56
|
+
} & Omit<InputProps, "value" | "onSelect">;
|
|
17
57
|
|
|
18
58
|
const InputFilter = forwardRef<HTMLInputElement, InputFilterProps>(
|
|
19
|
-
(
|
|
59
|
+
(
|
|
60
|
+
{
|
|
61
|
+
id,
|
|
62
|
+
options = [],
|
|
63
|
+
values = [],
|
|
64
|
+
label,
|
|
65
|
+
size = "md",
|
|
66
|
+
rounded = "normal",
|
|
67
|
+
variant = "outline",
|
|
68
|
+
helperText,
|
|
69
|
+
errorMessage,
|
|
70
|
+
fullwidth = true,
|
|
71
|
+
disabled = false,
|
|
72
|
+
error = false,
|
|
73
|
+
filterMode = false,
|
|
74
|
+
required = true,
|
|
75
|
+
onChangeText,
|
|
76
|
+
onSelect,
|
|
77
|
+
renderOptions: customRenderOptions,
|
|
78
|
+
optionContainerClassName,
|
|
79
|
+
...props
|
|
80
|
+
},
|
|
81
|
+
ref
|
|
82
|
+
) => {
|
|
83
|
+
const _id = id || `${label}-select`;
|
|
84
|
+
|
|
85
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
86
|
+
const [selectedOptions, setSelectedOptions] = useState<Options[]>(values);
|
|
87
|
+
const [textValue, setTextValue] = useState("");
|
|
88
|
+
const keyCode = useRef("");
|
|
89
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
90
|
+
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
setSelectedOptions(values ?? []);
|
|
93
|
+
setTextValue(values?.map((option) => option.label).join(", ") ?? "");
|
|
94
|
+
}, [values]);
|
|
95
|
+
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
98
|
+
if (
|
|
99
|
+
containerRef.current &&
|
|
100
|
+
!containerRef.current.contains(event.target as Node)
|
|
101
|
+
) {
|
|
102
|
+
setIsFocused(false);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
107
|
+
return () =>
|
|
108
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
111
|
+
const handleOnChangeText = useCallback(
|
|
112
|
+
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
113
|
+
onChangeText?.(event);
|
|
114
|
+
setTextValue(event.target.value);
|
|
115
|
+
|
|
116
|
+
if (!event.target.value) {
|
|
117
|
+
clearMismatchValues(event as any);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
[onChangeText]
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const handleOptionClick = useCallback(
|
|
124
|
+
(option: Options) => {
|
|
125
|
+
const isSelected = selectedOptions.some(
|
|
126
|
+
(selected) => selected.value === option.value
|
|
127
|
+
);
|
|
128
|
+
let newSelectedOptions = [...selectedOptions];
|
|
129
|
+
|
|
130
|
+
if (isSelected) {
|
|
131
|
+
newSelectedOptions = newSelectedOptions.filter(
|
|
132
|
+
(selected) => selected.value !== option.value
|
|
133
|
+
);
|
|
134
|
+
} else {
|
|
135
|
+
newSelectedOptions.push(option);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
setSelectedOptions(newSelectedOptions);
|
|
139
|
+
setTextValue(
|
|
140
|
+
newSelectedOptions.map((option) => option.label).join(", ")
|
|
141
|
+
);
|
|
142
|
+
onSelect?.(newSelectedOptions);
|
|
143
|
+
},
|
|
144
|
+
[selectedOptions, onSelect]
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const optionsFiltered = useMemo(() => {
|
|
148
|
+
const lastText = textValue?.split(",").pop();
|
|
149
|
+
const filterText = lastText ?? "";
|
|
150
|
+
|
|
151
|
+
return options.filter(
|
|
152
|
+
(option) =>
|
|
153
|
+
!filterMode ||
|
|
154
|
+
option.label?.toLowerCase().includes(filterText?.toLowerCase())
|
|
155
|
+
);
|
|
156
|
+
}, [options, filterMode, textValue]);
|
|
157
|
+
|
|
158
|
+
const renderOptions = () => {
|
|
159
|
+
if (customRenderOptions) {
|
|
160
|
+
return customRenderOptions({
|
|
161
|
+
optionsFiltered,
|
|
162
|
+
selectedOptions,
|
|
163
|
+
onClick: handleOptionClick,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<ul
|
|
169
|
+
className={cn(
|
|
170
|
+
"absolute mt-1 w-full bg-base-popup border border-base-popup text-base-popup-foreground rounded-md shadow-md z-10 max-h-60 overflow-y-auto",
|
|
171
|
+
optionContainerClassName
|
|
172
|
+
)}
|
|
173
|
+
>
|
|
174
|
+
{optionsFiltered.map((option) => {
|
|
175
|
+
if (option.renderLabel) {
|
|
176
|
+
return (
|
|
177
|
+
<Fragment key={option.value}>
|
|
178
|
+
{option.renderLabel({
|
|
179
|
+
value: option.value,
|
|
180
|
+
label: option.label,
|
|
181
|
+
handleOnClick: () => handleOptionClick(option),
|
|
182
|
+
className: `p-4 typography-subtitile4 hover:bg-gray-100 cursor-pointer flex items-center gap-3 ${
|
|
183
|
+
selectedOptions.some(
|
|
184
|
+
(selected) => selected.value === option.value
|
|
185
|
+
)
|
|
186
|
+
? "bg-gray-200"
|
|
187
|
+
: ""
|
|
188
|
+
}`,
|
|
189
|
+
})}
|
|
190
|
+
</Fragment>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
return (
|
|
194
|
+
<li
|
|
195
|
+
key={option.value}
|
|
196
|
+
onMouseDown={() => handleOptionClick(option)}
|
|
197
|
+
className={`p-4 typography-subtitile4 hover:bg-primary-hover-bg cursor-pointer flex items-center gap-3 ${
|
|
198
|
+
selectedOptions.some(
|
|
199
|
+
(selected) => selected.value === option.value
|
|
200
|
+
)
|
|
201
|
+
? "bg-base-popup-highlight"
|
|
202
|
+
: ""
|
|
203
|
+
}`}
|
|
204
|
+
>
|
|
205
|
+
<Checkbox
|
|
206
|
+
checked={selectedOptions.some(
|
|
207
|
+
(selected) => selected.value === option.value
|
|
208
|
+
)}
|
|
209
|
+
/>
|
|
210
|
+
{option.label}
|
|
211
|
+
</li>
|
|
212
|
+
);
|
|
213
|
+
})}
|
|
214
|
+
{optionsFiltered.length === 0 && (
|
|
215
|
+
<li className="px-4 py-14 text-center text-input-text">
|
|
216
|
+
Not found
|
|
217
|
+
</li>
|
|
218
|
+
)}
|
|
219
|
+
</ul>
|
|
220
|
+
);
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const handleOnFocus = useCallback(
|
|
224
|
+
(e: React.FocusEvent<HTMLInputElement, Element>) => {
|
|
225
|
+
setIsFocused(true);
|
|
226
|
+
props?.onFocus?.(e);
|
|
227
|
+
},
|
|
228
|
+
[props?.onFocus]
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const clearMismatchValues = useCallback(
|
|
232
|
+
(e: React.FocusEvent<HTMLInputElement, Element>) => {
|
|
233
|
+
const matchSelectedValues = optionsFiltered.filter(
|
|
234
|
+
(opt) =>
|
|
235
|
+
opt.value === e.target?.value || opt.label === e.target?.value
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
if (keyCode.current === "Enter") {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
setSelectedOptions(matchSelectedValues);
|
|
243
|
+
setTextValue(
|
|
244
|
+
matchSelectedValues.map((option) => option.label).join(", ")
|
|
245
|
+
);
|
|
246
|
+
onSelect?.(matchSelectedValues);
|
|
247
|
+
},
|
|
248
|
+
[optionsFiltered, textValue]
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const handleOnKeyDown = useCallback(
|
|
252
|
+
(e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
253
|
+
keyCode.current = e.code;
|
|
254
|
+
props?.onKeyDown?.(e);
|
|
255
|
+
},
|
|
256
|
+
[props?.onKeyDown]
|
|
257
|
+
);
|
|
258
|
+
|
|
20
259
|
const filterIconClassName = filterIconVariant({
|
|
21
|
-
size:
|
|
22
|
-
rounded:
|
|
23
|
-
error:
|
|
24
|
-
active: !!
|
|
260
|
+
size: size,
|
|
261
|
+
rounded: rounded,
|
|
262
|
+
error: error,
|
|
263
|
+
active: !!values.length,
|
|
264
|
+
disabled,
|
|
25
265
|
});
|
|
26
266
|
|
|
27
267
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
268
|
+
<div
|
|
269
|
+
ref={containerRef}
|
|
270
|
+
className={`relative ${fullwidth ? "w-full" : ""}`}
|
|
271
|
+
>
|
|
272
|
+
<TextInput
|
|
273
|
+
hasClearIcon={false}
|
|
274
|
+
endIcon={
|
|
275
|
+
<div className={filterIconClassName}>
|
|
276
|
+
<Icon
|
|
277
|
+
type="heroicons"
|
|
278
|
+
name="adjustments-horizontal"
|
|
279
|
+
variant="outline"
|
|
280
|
+
color="inherit"
|
|
281
|
+
stroke="inherit"
|
|
282
|
+
fill="transparent"
|
|
283
|
+
/>
|
|
284
|
+
</div>
|
|
285
|
+
}
|
|
286
|
+
{...props}
|
|
287
|
+
ref={ref}
|
|
288
|
+
readOnly={!filterMode}
|
|
289
|
+
value={textValue}
|
|
290
|
+
onChange={handleOnChangeText}
|
|
291
|
+
label={label}
|
|
292
|
+
placeholder=" "
|
|
293
|
+
type="text"
|
|
294
|
+
rounded={rounded}
|
|
295
|
+
variant={variant}
|
|
296
|
+
helperText={helperText}
|
|
297
|
+
errorMessage={errorMessage}
|
|
298
|
+
fullwidth={fullwidth}
|
|
299
|
+
error={error}
|
|
300
|
+
required={required}
|
|
301
|
+
id={_id}
|
|
302
|
+
disabled={disabled}
|
|
303
|
+
size={size}
|
|
304
|
+
className={customInputVariant({ size })}
|
|
305
|
+
onFocus={handleOnFocus}
|
|
306
|
+
onKeyDown={handleOnKeyDown}
|
|
307
|
+
/>
|
|
308
|
+
{isFocused && renderOptions()}
|
|
309
|
+
</div>
|
|
51
310
|
);
|
|
52
311
|
}
|
|
53
312
|
);
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
1
|
import * as React from "react";
|
|
4
2
|
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
5
|
-
|
|
6
3
|
import { cn } from "@/utils/cn";
|
|
7
4
|
|
|
8
5
|
const RadioGroup = React.forwardRef<
|
|
@@ -27,18 +24,19 @@ const RadioGroupItem = React.forwardRef<
|
|
|
27
24
|
<RadioGroupPrimitive.Item
|
|
28
25
|
ref={ref}
|
|
29
26
|
className={cn(
|
|
30
|
-
"aspect-square box-border
|
|
31
|
-
"hover:border-
|
|
27
|
+
"aspect-square box-border size-4 rounded-full border border-function-default-solid text-function-default-solid",
|
|
28
|
+
"hover:border-function-default-hover",
|
|
32
29
|
"focus:outline-none",
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
|
|
30
|
+
// Disabled state styles
|
|
31
|
+
"data-[disabled]:!border-state-disable-solid data-[disabled]:!fill-state-disable-solid data-[disabled]:!cursor-not-allowed data-[disabled]:!pointer-events-none data-[disabled]:!text-state-disable-solid",
|
|
32
|
+
// Checked state styles
|
|
33
|
+
"data-[state=checked]:border-function-active-solid data-[state=checked]:text-function-active-solid",
|
|
34
|
+
"hover:data-[state=checked]:border-function-active-hover hover:data-[state=checked]:text-function-active-hover",
|
|
36
35
|
className
|
|
37
36
|
)}
|
|
38
37
|
{...props}
|
|
39
38
|
>
|
|
40
39
|
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
|
41
|
-
{/* <div className="bg-primary size-2.5 rounded-full" /> */}
|
|
42
40
|
<svg
|
|
43
41
|
width="10"
|
|
44
42
|
height="10"
|
|
@@ -12,7 +12,7 @@ const meta = {
|
|
|
12
12
|
},
|
|
13
13
|
decorators: [
|
|
14
14
|
(Story) => (
|
|
15
|
-
<div className="p-5 flex w-full">
|
|
15
|
+
<div className="p-5 flex w-full bg-base-bg2">
|
|
16
16
|
<Story />
|
|
17
17
|
</div>
|
|
18
18
|
),
|
|
@@ -30,6 +30,7 @@ export const Default = {
|
|
|
30
30
|
args: {
|
|
31
31
|
label: "Choose an option:",
|
|
32
32
|
fullwidth: true,
|
|
33
|
+
size: "md",
|
|
33
34
|
options,
|
|
34
35
|
},
|
|
35
36
|
render: (args) => {
|
|
@@ -14,7 +14,7 @@ const meta = {
|
|
|
14
14
|
},
|
|
15
15
|
decorators: [
|
|
16
16
|
(Story) => (
|
|
17
|
-
<div className="p-5 flex w-full">
|
|
17
|
+
<div className="p-5 flex w-full bg-base-bg2">
|
|
18
18
|
<Story />
|
|
19
19
|
</div>
|
|
20
20
|
),
|
|
@@ -45,6 +45,10 @@ const variant: any = [
|
|
|
45
45
|
"small3",
|
|
46
46
|
"small4",
|
|
47
47
|
"small5",
|
|
48
|
+
"small6",
|
|
49
|
+
"small7",
|
|
50
|
+
"small8",
|
|
51
|
+
"small9",
|
|
48
52
|
"label1",
|
|
49
53
|
"label2",
|
|
50
54
|
"buttonL",
|
|
@@ -2,6 +2,7 @@ import { cva } from "class-variance-authority";
|
|
|
2
2
|
|
|
3
3
|
export const inputVariant = cva(
|
|
4
4
|
[
|
|
5
|
+
"truncate",
|
|
5
6
|
"border-0 outline-none",
|
|
6
7
|
"p-1 flex w-auto box-border",
|
|
7
8
|
"peer text-input-filled-text placeholder:text-transparent bg-transparent caret-primary",
|
|
@@ -76,47 +77,47 @@ export const inputVariant = cva(
|
|
|
76
77
|
{
|
|
77
78
|
hasSearchIcon: true,
|
|
78
79
|
size: "sm",
|
|
79
|
-
class: "ps-6",
|
|
80
|
+
class: "!ps-6",
|
|
80
81
|
},
|
|
81
82
|
{
|
|
82
83
|
hasSearchIcon: true,
|
|
83
84
|
size: "md",
|
|
84
|
-
class: "ps-9",
|
|
85
|
+
class: "!ps-9",
|
|
85
86
|
},
|
|
86
87
|
{
|
|
87
88
|
hasSearchIcon: true,
|
|
88
89
|
size: "lg",
|
|
89
|
-
class: "ps-11",
|
|
90
|
+
class: "!ps-11",
|
|
90
91
|
},
|
|
91
92
|
{
|
|
92
93
|
leftSectionIcon: true,
|
|
93
94
|
size: "sm",
|
|
94
|
-
class: "ps-[38px]",
|
|
95
|
+
class: "!ps-[38px]",
|
|
95
96
|
},
|
|
96
97
|
{
|
|
97
98
|
leftSectionIcon: true,
|
|
98
99
|
size: "md",
|
|
99
|
-
class: "ps-[46px]",
|
|
100
|
+
class: "!ps-[46px]",
|
|
100
101
|
},
|
|
101
102
|
{
|
|
102
103
|
leftSectionIcon: true,
|
|
103
104
|
size: "lg",
|
|
104
|
-
class: "ps-[72px]",
|
|
105
|
+
class: "!ps-[72px]",
|
|
105
106
|
},
|
|
106
107
|
{
|
|
107
108
|
rightSectionIcon: true,
|
|
108
109
|
size: "sm",
|
|
109
|
-
class: "pe-[38px]",
|
|
110
|
+
class: "!pe-[38px]",
|
|
110
111
|
},
|
|
111
112
|
{
|
|
112
113
|
rightSectionIcon: true,
|
|
113
114
|
size: "md",
|
|
114
|
-
class: "pe-[46px]",
|
|
115
|
+
class: "!pe-[46px]",
|
|
115
116
|
},
|
|
116
117
|
{
|
|
117
118
|
rightSectionIcon: true,
|
|
118
119
|
size: "lg",
|
|
119
|
-
class: "pe-[72px]",
|
|
120
|
+
class: "!pe-[72px]",
|
|
120
121
|
},
|
|
121
122
|
],
|
|
122
123
|
defaultVariants: {
|