@rovula/ui 0.0.8 → 0.0.9
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 +72 -5
- package/dist/cjs/bundle.js +1 -1
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +26 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +367 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.styles.d.ts +11 -0
- package/dist/cjs/types/components/TextInput/TextInput.d.ts +3 -2
- package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +2 -16
- package/dist/cjs/types/index.d.ts +1 -1
- package/dist/components/Dropdown/Dropdown.js +58 -0
- package/dist/components/{Select/Select.stories.js → Dropdown/Dropdown.stories.js} +8 -11
- package/dist/components/Dropdown/Dropdown.styles.js +47 -0
- package/dist/components/TextInput/TextInput.js +3 -3
- package/dist/esm/bundle.css +72 -5
- package/dist/esm/bundle.js +1 -1
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Dropdown/Dropdown.d.ts +26 -0
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +367 -0
- package/dist/esm/types/components/Dropdown/Dropdown.styles.d.ts +11 -0
- package/dist/esm/types/components/TextInput/TextInput.d.ts +3 -2
- package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +2 -16
- package/dist/esm/types/index.d.ts +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.js +1 -1
- package/dist/src/theme/global.css +92 -6
- package/package.json +1 -1
- package/src/components/{Select/Select.stories.tsx → Dropdown/Dropdown.stories.tsx} +11 -14
- package/src/components/Dropdown/Dropdown.styles.ts +54 -0
- package/src/components/Dropdown/Dropdown.tsx +151 -0
- package/src/components/TextInput/TextInput.tsx +11 -2
- package/src/index.ts +1 -1
- package/dist/cjs/types/components/Select/Select copy.d.ts +0 -23
- package/dist/cjs/types/components/Select/Select.d.ts +0 -23
- package/dist/cjs/types/components/Select/Select.stories.d.ts +0 -348
- package/dist/cjs/types/components/Select/Select.styles.d.ts +0 -14
- package/dist/components/Select/Select copy.js +0 -42
- package/dist/components/Select/Select.js +0 -21
- package/dist/components/Select/Select.styles.js +0 -100
- package/dist/esm/types/components/Select/Select copy.d.ts +0 -23
- package/dist/esm/types/components/Select/Select.d.ts +0 -23
- package/dist/esm/types/components/Select/Select.stories.d.ts +0 -348
- package/dist/esm/types/components/Select/Select.styles.d.ts +0 -14
- package/src/components/Select/Select copy.tsx +0 -103
- package/src/components/Select/Select.styles.ts +0 -111
- package/src/components/Select/Select.tsx +0 -54
|
@@ -812,12 +812,8 @@ video {
|
|
|
812
812
|
right: 0px;
|
|
813
813
|
}
|
|
814
814
|
|
|
815
|
-
.
|
|
816
|
-
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
.top-4 {
|
|
820
|
-
top: 1rem;
|
|
815
|
+
.z-10 {
|
|
816
|
+
z-index: 10;
|
|
821
817
|
}
|
|
822
818
|
|
|
823
819
|
.z-50 {
|
|
@@ -897,6 +893,20 @@ video {
|
|
|
897
893
|
height: 1.25rem;
|
|
898
894
|
}
|
|
899
895
|
|
|
896
|
+
.size-6 {
|
|
897
|
+
width: 1.5rem;
|
|
898
|
+
height: 1.5rem;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
.size-\[14px\] {
|
|
902
|
+
width: 14px;
|
|
903
|
+
height: 14px;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.max-h-60 {
|
|
907
|
+
max-height: 15rem;
|
|
908
|
+
}
|
|
909
|
+
|
|
900
910
|
.w-\[200px\] {
|
|
901
911
|
width: 200px;
|
|
902
912
|
}
|
|
@@ -917,6 +927,11 @@ video {
|
|
|
917
927
|
max-width: 48rem;
|
|
918
928
|
}
|
|
919
929
|
|
|
930
|
+
.rotate-180 {
|
|
931
|
+
--tw-rotate: 180deg;
|
|
932
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
933
|
+
}
|
|
934
|
+
|
|
920
935
|
.cursor-pointer {
|
|
921
936
|
cursor: pointer;
|
|
922
937
|
}
|
|
@@ -982,6 +997,10 @@ video {
|
|
|
982
997
|
overflow-x: auto;
|
|
983
998
|
}
|
|
984
999
|
|
|
1000
|
+
.overflow-y-auto {
|
|
1001
|
+
overflow-y: auto;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
985
1004
|
.whitespace-nowrap {
|
|
986
1005
|
white-space: nowrap;
|
|
987
1006
|
}
|
|
@@ -1010,6 +1029,10 @@ video {
|
|
|
1010
1029
|
border-radius: 0.5rem;
|
|
1011
1030
|
}
|
|
1012
1031
|
|
|
1032
|
+
.rounded-md {
|
|
1033
|
+
border-radius: 0.375rem;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1013
1036
|
.rounded-none {
|
|
1014
1037
|
border-radius: 0px;
|
|
1015
1038
|
}
|
|
@@ -1039,6 +1062,11 @@ video {
|
|
|
1039
1062
|
border-color: rgb(var(--error-100) / var(--tw-border-opacity));
|
|
1040
1063
|
}
|
|
1041
1064
|
|
|
1065
|
+
.border-gray-300 {
|
|
1066
|
+
--tw-border-opacity: 1;
|
|
1067
|
+
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1042
1070
|
.border-info {
|
|
1043
1071
|
--tw-border-opacity: 1;
|
|
1044
1072
|
border-color: rgb(var(--info-default) / var(--tw-border-opacity));
|
|
@@ -1083,6 +1111,11 @@ video {
|
|
|
1083
1111
|
background-color: rgb(var(--error-100) / var(--tw-bg-opacity));
|
|
1084
1112
|
}
|
|
1085
1113
|
|
|
1114
|
+
.bg-gray-200 {
|
|
1115
|
+
--tw-bg-opacity: 1;
|
|
1116
|
+
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1086
1119
|
.bg-info {
|
|
1087
1120
|
--tw-bg-opacity: 1;
|
|
1088
1121
|
background-color: rgb(var(--info-default) / var(--tw-bg-opacity));
|
|
@@ -1127,6 +1160,11 @@ video {
|
|
|
1127
1160
|
background-color: rgb(var(--warning-default) / var(--tw-bg-opacity));
|
|
1128
1161
|
}
|
|
1129
1162
|
|
|
1163
|
+
.bg-white {
|
|
1164
|
+
--tw-bg-opacity: 1;
|
|
1165
|
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1130
1168
|
.fill-error {
|
|
1131
1169
|
fill: rgb(var(--error-100) / 1);
|
|
1132
1170
|
}
|
|
@@ -1135,6 +1173,18 @@ video {
|
|
|
1135
1173
|
fill: rgb(var(--input-active-stroke-color) / 1);
|
|
1136
1174
|
}
|
|
1137
1175
|
|
|
1176
|
+
.fill-input-text {
|
|
1177
|
+
fill: rgb(var(--input-default-text-color) / 1);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.fill-input-text-active {
|
|
1181
|
+
fill: rgb(var(--input-active-text-color) / 1);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
.fill-input-text-disabled {
|
|
1185
|
+
fill: rgb(var(--input-disabled-text-color) / 1);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1138
1188
|
.p-1 {
|
|
1139
1189
|
padding: 0.25rem;
|
|
1140
1190
|
}
|
|
@@ -1176,6 +1226,11 @@ video {
|
|
|
1176
1226
|
padding-bottom: 0.25rem;
|
|
1177
1227
|
}
|
|
1178
1228
|
|
|
1229
|
+
.py-14 {
|
|
1230
|
+
padding-top: 3.5rem;
|
|
1231
|
+
padding-bottom: 3.5rem;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1179
1234
|
.py-2 {
|
|
1180
1235
|
padding-top: 0.5rem;
|
|
1181
1236
|
padding-bottom: 0.5rem;
|
|
@@ -1186,6 +1241,22 @@ video {
|
|
|
1186
1241
|
padding-bottom: 1rem;
|
|
1187
1242
|
}
|
|
1188
1243
|
|
|
1244
|
+
.pe-\[30px\] {
|
|
1245
|
+
padding-inline-end: 30px;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
.pe-\[40px\] {
|
|
1249
|
+
padding-inline-end: 40px;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
.pe-\[48px\] {
|
|
1253
|
+
padding-inline-end: 48px;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
.text-center {
|
|
1257
|
+
text-align: center;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1189
1260
|
.align-middle {
|
|
1190
1261
|
vertical-align: middle;
|
|
1191
1262
|
}
|
|
@@ -1453,6 +1524,12 @@ video {
|
|
|
1453
1524
|
text-underline-offset: 4px;
|
|
1454
1525
|
}
|
|
1455
1526
|
|
|
1527
|
+
.shadow-md {
|
|
1528
|
+
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
1529
|
+
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
|
1530
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1456
1533
|
.outline-none {
|
|
1457
1534
|
outline: 2px solid transparent;
|
|
1458
1535
|
outline-offset: 2px;
|
|
@@ -1487,6 +1564,10 @@ video {
|
|
|
1487
1564
|
--tw-ring-color: rgb(var(--input-disabled-stroke-color) / var(--tw-ring-opacity));
|
|
1488
1565
|
}
|
|
1489
1566
|
|
|
1567
|
+
.filter {
|
|
1568
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1490
1571
|
.transition-all {
|
|
1491
1572
|
transition-property: all;
|
|
1492
1573
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -1671,6 +1752,11 @@ video {
|
|
|
1671
1752
|
background-color: rgb(var(--error-120) / var(--tw-bg-opacity));
|
|
1672
1753
|
}
|
|
1673
1754
|
|
|
1755
|
+
.hover\:bg-gray-100:hover {
|
|
1756
|
+
--tw-bg-opacity: 1;
|
|
1757
|
+
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1674
1760
|
.hover\:bg-info-100:hover {
|
|
1675
1761
|
--tw-bg-opacity: 1;
|
|
1676
1762
|
background-color: rgb(var(--info-100)) / var(--tw-bg-opacity));
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
-
import
|
|
3
|
+
import Dropdown from "./Dropdown";
|
|
4
4
|
|
|
5
5
|
// More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
|
|
6
6
|
const meta = {
|
|
7
|
-
title: "Components/
|
|
8
|
-
component:
|
|
7
|
+
title: "Components/Dropdown",
|
|
8
|
+
component: Dropdown,
|
|
9
9
|
tags: ["autodocs"],
|
|
10
10
|
parameters: {
|
|
11
11
|
// More on how to position stories at: https://storybook.js.org/docs/7.0/react/configure/story-layout
|
|
@@ -18,21 +18,18 @@ const meta = {
|
|
|
18
18
|
</div>
|
|
19
19
|
),
|
|
20
20
|
],
|
|
21
|
-
} satisfies Meta<typeof
|
|
21
|
+
} satisfies Meta<typeof Dropdown>;
|
|
22
22
|
|
|
23
23
|
export default meta;
|
|
24
24
|
|
|
25
|
-
const options =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{ value: "option4", label: "Option 4" },
|
|
30
|
-
];
|
|
25
|
+
const options = new Array(100).fill("").map((__, index) => ({
|
|
26
|
+
value: `option${index + 1}`,
|
|
27
|
+
label: `Option ${index + 1}`,
|
|
28
|
+
}));
|
|
31
29
|
|
|
32
30
|
export const Default = {
|
|
33
31
|
args: {
|
|
34
32
|
label: "Choose an option:",
|
|
35
|
-
// value: "",
|
|
36
33
|
fullwidth: true,
|
|
37
34
|
options,
|
|
38
35
|
},
|
|
@@ -43,9 +40,9 @@ export const Default = {
|
|
|
43
40
|
};
|
|
44
41
|
return (
|
|
45
42
|
<div className="flex flex-row gap-4 w-full">
|
|
46
|
-
<
|
|
47
|
-
<
|
|
48
|
-
<
|
|
43
|
+
<Dropdown id="1" size="lg" options={options} {...args} />
|
|
44
|
+
<Dropdown id="2" size="md" options={options} {...args} />
|
|
45
|
+
<Dropdown id="3" size="sm" options={options} {...args} />
|
|
49
46
|
</div>
|
|
50
47
|
);
|
|
51
48
|
},
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
export const iconWrapperVariant = cva(
|
|
5
|
+
["absolute inset-y-0 right-0 flex items-center justify-center"],
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
size: {
|
|
9
|
+
sm: "mr-2",
|
|
10
|
+
md: "mr-3",
|
|
11
|
+
lg: "mr-4",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: {
|
|
15
|
+
size: "md",
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const dropdownIconVariant = cva(["transition-all"], {
|
|
21
|
+
variants: {
|
|
22
|
+
size: {
|
|
23
|
+
sm: "size-[14px]",
|
|
24
|
+
md: "size-5",
|
|
25
|
+
lg: "size-6",
|
|
26
|
+
},
|
|
27
|
+
disabled: {
|
|
28
|
+
true: "fill-input-text-disabled",
|
|
29
|
+
false: "fill-input-text",
|
|
30
|
+
},
|
|
31
|
+
isFocus: {
|
|
32
|
+
true: "fill-input-text-active rotate-180",
|
|
33
|
+
false: "",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
defaultVariants: {
|
|
37
|
+
size: "md",
|
|
38
|
+
disabled: false,
|
|
39
|
+
isFocus: false,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const customInputVariant = cva([], {
|
|
44
|
+
variants: {
|
|
45
|
+
size: {
|
|
46
|
+
sm: "pe-[30px]",
|
|
47
|
+
md: "pe-[40px]",
|
|
48
|
+
lg: "pe-[48px]",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
defaultVariants: {
|
|
52
|
+
size: "md",
|
|
53
|
+
},
|
|
54
|
+
});
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import TextInput, { InputProps } from "../TextInput/TextInput";
|
|
4
|
+
import {
|
|
5
|
+
customInputVariant,
|
|
6
|
+
dropdownIconVariant,
|
|
7
|
+
iconWrapperVariant,
|
|
8
|
+
} from "./Dropdown.styles";
|
|
9
|
+
|
|
10
|
+
import { ChevronDownIcon } from "@heroicons/react/16/solid";
|
|
11
|
+
|
|
12
|
+
type Options = {
|
|
13
|
+
value: string;
|
|
14
|
+
label: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type DropdownProps = {
|
|
18
|
+
id?: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
size?: "sm" | "md" | "lg";
|
|
21
|
+
rounded?: "none" | "normal" | "full";
|
|
22
|
+
variant?: "flat" | "outline" | "underline";
|
|
23
|
+
helperText?: string;
|
|
24
|
+
errorMessage?: string;
|
|
25
|
+
filterMode?: boolean;
|
|
26
|
+
fullwidth?: boolean;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
error?: boolean;
|
|
29
|
+
required?: boolean;
|
|
30
|
+
className?: string;
|
|
31
|
+
options: Options[];
|
|
32
|
+
value?: Options;
|
|
33
|
+
onChangeText?: InputProps["onChange"];
|
|
34
|
+
onSelect?: (value: Options) => void;
|
|
35
|
+
} & Omit<InputProps, "value">;
|
|
36
|
+
|
|
37
|
+
const Dropdown = ({
|
|
38
|
+
id,
|
|
39
|
+
options,
|
|
40
|
+
value,
|
|
41
|
+
label,
|
|
42
|
+
size = "md",
|
|
43
|
+
rounded = "normal",
|
|
44
|
+
variant = "outline",
|
|
45
|
+
helperText,
|
|
46
|
+
errorMessage,
|
|
47
|
+
fullwidth = true,
|
|
48
|
+
disabled = false,
|
|
49
|
+
error = false,
|
|
50
|
+
filterMode = false,
|
|
51
|
+
required = true,
|
|
52
|
+
onChangeText,
|
|
53
|
+
onSelect,
|
|
54
|
+
...props
|
|
55
|
+
}: DropdownProps) => {
|
|
56
|
+
const _id = id || `${label}-select`;
|
|
57
|
+
|
|
58
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
59
|
+
const [selectedOption, setSelectedOption] = useState<
|
|
60
|
+
Options | null | undefined
|
|
61
|
+
>(null);
|
|
62
|
+
const [textValue, setTextValue] = useState("");
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (value && !selectedOption) {
|
|
66
|
+
setSelectedOption(value);
|
|
67
|
+
}
|
|
68
|
+
}, [value, selectedOption]);
|
|
69
|
+
|
|
70
|
+
const handleOnChangeText = useCallback(
|
|
71
|
+
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
72
|
+
onChangeText?.(event);
|
|
73
|
+
setTextValue(event.target.value);
|
|
74
|
+
},
|
|
75
|
+
[onChangeText]
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const handleOptionClick = useCallback(
|
|
79
|
+
(option: Options) => {
|
|
80
|
+
setSelectedOption(option);
|
|
81
|
+
setTextValue(option.label);
|
|
82
|
+
onSelect?.(option);
|
|
83
|
+
},
|
|
84
|
+
[onSelect]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const optionsFiltered = useMemo(() => {
|
|
88
|
+
return options.filter(
|
|
89
|
+
(option) =>
|
|
90
|
+
!filterMode ||
|
|
91
|
+
option.label?.toLowerCase().includes(textValue?.toLowerCase())
|
|
92
|
+
);
|
|
93
|
+
}, [options, filterMode, textValue]);
|
|
94
|
+
|
|
95
|
+
const renderOptions = () => (
|
|
96
|
+
<ul className="absolute mt-1 w-full bg-white border border-gray-300 rounded-md shadow-md z-10 max-h-60 overflow-y-auto">
|
|
97
|
+
{optionsFiltered.map((option) => (
|
|
98
|
+
<li
|
|
99
|
+
key={option.value}
|
|
100
|
+
onMouseDown={() => handleOptionClick(option)}
|
|
101
|
+
className={`px-4 py-2 hover:bg-gray-100 cursor-pointer ${
|
|
102
|
+
selectedOption?.value === option.value ? " bg-gray-200" : ""
|
|
103
|
+
}`}
|
|
104
|
+
>
|
|
105
|
+
{option.label}
|
|
106
|
+
</li>
|
|
107
|
+
))}
|
|
108
|
+
{optionsFiltered.length === 0 && (
|
|
109
|
+
<li className="px-4 py-14 text-center text-input-text">Not found</li>
|
|
110
|
+
)}
|
|
111
|
+
</ul>
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<div className={`relative ${fullwidth ? "w-full" : ""}`}>
|
|
116
|
+
<TextInput
|
|
117
|
+
{...props}
|
|
118
|
+
readOnly={!filterMode}
|
|
119
|
+
value={textValue}
|
|
120
|
+
onChange={handleOnChangeText}
|
|
121
|
+
label={label}
|
|
122
|
+
placeholder=" "
|
|
123
|
+
type="text"
|
|
124
|
+
rounded={rounded}
|
|
125
|
+
variant={variant}
|
|
126
|
+
helperText={helperText}
|
|
127
|
+
errorMessage={errorMessage}
|
|
128
|
+
fullwidth={fullwidth}
|
|
129
|
+
error={error}
|
|
130
|
+
required={required}
|
|
131
|
+
id={_id}
|
|
132
|
+
disabled={disabled}
|
|
133
|
+
hasClearIcon={false}
|
|
134
|
+
size={size}
|
|
135
|
+
className={customInputVariant({ size })}
|
|
136
|
+
onFocus={() => setIsFocused(true)}
|
|
137
|
+
onBlur={() => setIsFocused(false)}
|
|
138
|
+
endIcon={
|
|
139
|
+
<div className={iconWrapperVariant({ size })}>
|
|
140
|
+
<ChevronDownIcon
|
|
141
|
+
className={dropdownIconVariant({ size, isFocus: isFocused })}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
}
|
|
145
|
+
/>
|
|
146
|
+
{isFocused && renderOptions()}
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export default Dropdown;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
FC,
|
|
3
|
+
ReactNode,
|
|
4
|
+
forwardRef,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useRef,
|
|
7
|
+
} from "react";
|
|
2
8
|
import {
|
|
3
9
|
helperTextVariant,
|
|
4
10
|
iconVariant,
|
|
@@ -9,7 +15,7 @@ import {
|
|
|
9
15
|
import { twMerge } from "tailwind-merge";
|
|
10
16
|
import { XCircleIcon, ExclamationCircleIcon } from "@heroicons/react/16/solid";
|
|
11
17
|
|
|
12
|
-
type InputProps = {
|
|
18
|
+
export type InputProps = {
|
|
13
19
|
id?: string;
|
|
14
20
|
label?: string;
|
|
15
21
|
size?: "sm" | "md" | "lg";
|
|
@@ -23,6 +29,7 @@ type InputProps = {
|
|
|
23
29
|
error?: boolean;
|
|
24
30
|
required?: boolean;
|
|
25
31
|
hasClearIcon?: boolean;
|
|
32
|
+
endIcon?: ReactNode;
|
|
26
33
|
className?: string;
|
|
27
34
|
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">;
|
|
28
35
|
|
|
@@ -42,6 +49,7 @@ const TextInput: FC<InputProps> = forwardRef(
|
|
|
42
49
|
error = false,
|
|
43
50
|
required = true,
|
|
44
51
|
hasClearIcon = true,
|
|
52
|
+
endIcon,
|
|
45
53
|
...props
|
|
46
54
|
},
|
|
47
55
|
ref
|
|
@@ -97,6 +105,7 @@ const TextInput: FC<InputProps> = forwardRef(
|
|
|
97
105
|
/>
|
|
98
106
|
</div>
|
|
99
107
|
)}
|
|
108
|
+
{endIcon}
|
|
100
109
|
<label htmlFor={_id} className={labelClassname}>
|
|
101
110
|
{label} {required && <span className="text-error">*</span>}
|
|
102
111
|
</label>
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { default as Table } from "./components/Table/Table";
|
|
|
6
6
|
export { default as TextInput } from "./components/TextInput/TextInput";
|
|
7
7
|
export { default as Text } from "./components/Text/Text";
|
|
8
8
|
export { default as Tabs } from "./components/Tabs/Tabs";
|
|
9
|
-
export { default as
|
|
9
|
+
export { default as Dropdown } from "./components/Dropdown/Dropdown";
|
|
10
10
|
|
|
11
11
|
// UTILS
|
|
12
12
|
export {
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type Options = {
|
|
3
|
-
value: string;
|
|
4
|
-
label: string;
|
|
5
|
-
};
|
|
6
|
-
type SelectProps = {
|
|
7
|
-
id?: string;
|
|
8
|
-
label?: string;
|
|
9
|
-
size?: "sm" | "md" | "lg";
|
|
10
|
-
rounded?: "none" | "normal" | "full";
|
|
11
|
-
variant?: "flat" | "outline" | "underline";
|
|
12
|
-
type?: React.HTMLInputTypeAttribute;
|
|
13
|
-
helperText?: string;
|
|
14
|
-
errorMessage?: string;
|
|
15
|
-
fullwidth?: boolean;
|
|
16
|
-
disabled?: boolean;
|
|
17
|
-
error?: boolean;
|
|
18
|
-
required?: boolean;
|
|
19
|
-
className?: string;
|
|
20
|
-
options: Options[];
|
|
21
|
-
} & Omit<React.InputHTMLAttributes<HTMLSelectElement>, "size">;
|
|
22
|
-
declare const Select: ({ id, options, label, size, rounded, variant, type, helperText, errorMessage, fullwidth, disabled, error, required, ...props }: SelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
-
export default Select;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type Options = {
|
|
3
|
-
value: string;
|
|
4
|
-
label: string;
|
|
5
|
-
};
|
|
6
|
-
type SelectProps = {
|
|
7
|
-
id?: string;
|
|
8
|
-
label?: string;
|
|
9
|
-
size?: "sm" | "md" | "lg";
|
|
10
|
-
rounded?: "none" | "normal" | "full";
|
|
11
|
-
variant?: "flat" | "outline" | "underline";
|
|
12
|
-
type?: React.HTMLInputTypeAttribute;
|
|
13
|
-
helperText?: string;
|
|
14
|
-
errorMessage?: string;
|
|
15
|
-
fullwidth?: boolean;
|
|
16
|
-
disabled?: boolean;
|
|
17
|
-
error?: boolean;
|
|
18
|
-
required?: boolean;
|
|
19
|
-
className?: string;
|
|
20
|
-
options: Options[];
|
|
21
|
-
} & Omit<React.InputHTMLAttributes<HTMLSelectElement>, "size">;
|
|
22
|
-
declare const Select: ({ id, options, label, size, rounded, variant, type, helperText, errorMessage, fullwidth, disabled, error, required, ...props }: SelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
-
export default Select;
|