lecom-ui 5.2.88 → 5.2.89
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/README.md +1 -1
- package/dist/components/Calendar/Calendar.js +380 -0
- package/dist/components/Collapse/Collapse.js +94 -0
- package/dist/components/Combobox/Combobox.js +128 -0
- package/dist/components/CustomDivider/CustomDivider.js +234 -0
- package/dist/components/DataTable/DataTable.utils.js +3 -10
- package/dist/components/DataTable/Table.js +2 -1
- package/dist/components/DatePicker/DatePicker.js +55 -0
- package/dist/components/Pagination/Pagination.js +3 -2
- package/dist/components/Steps/Steps.js +102 -0
- package/dist/components/Switch/Switch.js +42 -6
- package/dist/components/TagInput/TagInput.js +106 -0
- package/dist/index.d.ts +130 -11
- package/dist/index.js +9 -0
- package/dist/plugin/extend.js +78 -78
- package/dist/plugin/fontFaces.js +172 -172
- package/dist/plugin/general.js +12 -12
- package/dist/plugin/pluginDev.cjs +5 -5
- package/dist/plugin/pluginNext.cjs +5 -5
- package/dist/plugin/pluginNextTurbo.cjs +5 -5
- package/dist/plugin/pluginVite.cjs +5 -5
- package/dist/plugin/template.js +31 -31
- package/dist/plugin/typographies.js +152 -152
- package/dist/plugin/varsTheme.js +79 -79
- package/dist/style.min.css +1 -1
- package/package.json +10 -5
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useFormContext, Controller } from 'react-hook-form';
|
|
3
|
+
import { cn } from '../../lib/utils.js';
|
|
4
|
+
import { Button } from '../Button/Button.js';
|
|
5
|
+
|
|
6
|
+
function getDividerContent({
|
|
7
|
+
name,
|
|
8
|
+
children,
|
|
9
|
+
control,
|
|
10
|
+
optionLabels,
|
|
11
|
+
ButtonComponent,
|
|
12
|
+
buttonSize,
|
|
13
|
+
buttonClassName,
|
|
14
|
+
isActive,
|
|
15
|
+
plain
|
|
16
|
+
}) {
|
|
17
|
+
if (children) {
|
|
18
|
+
return /* @__PURE__ */ React.createElement("span", { className: "relative z-10 px-2 bg-white" }, children);
|
|
19
|
+
}
|
|
20
|
+
if (!name) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"CustomDivider: prop `name` \xE9 obrigat\xF3ria se n\xE3o houver children."
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return /* @__PURE__ */ React.createElement(
|
|
26
|
+
Controller,
|
|
27
|
+
{
|
|
28
|
+
name,
|
|
29
|
+
control,
|
|
30
|
+
render: ({ field: { value, onChange } }) => /* @__PURE__ */ React.createElement(
|
|
31
|
+
OptionButtons,
|
|
32
|
+
{
|
|
33
|
+
value,
|
|
34
|
+
onChange,
|
|
35
|
+
isActive,
|
|
36
|
+
plain,
|
|
37
|
+
optionLabels,
|
|
38
|
+
ButtonComponent,
|
|
39
|
+
buttonSize,
|
|
40
|
+
buttonClassName
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
function DividerLine({
|
|
47
|
+
dashed,
|
|
48
|
+
plain,
|
|
49
|
+
isGroupDivider,
|
|
50
|
+
isActive,
|
|
51
|
+
className,
|
|
52
|
+
style
|
|
53
|
+
}) {
|
|
54
|
+
return /* @__PURE__ */ React.createElement(
|
|
55
|
+
"div",
|
|
56
|
+
{
|
|
57
|
+
className: cn(
|
|
58
|
+
"w-full",
|
|
59
|
+
isGroupDivider ? "my-4" : "my-2",
|
|
60
|
+
isActive ? "opacity-100" : "opacity-50",
|
|
61
|
+
className
|
|
62
|
+
),
|
|
63
|
+
style
|
|
64
|
+
},
|
|
65
|
+
/* @__PURE__ */ React.createElement(
|
|
66
|
+
"div",
|
|
67
|
+
{
|
|
68
|
+
className: cn(
|
|
69
|
+
"w-full border-t",
|
|
70
|
+
dashed ? "border-dashed" : "border-solid",
|
|
71
|
+
plain ? "border-gray-200" : "border-gray-300"
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
function OptionButtons({
|
|
78
|
+
value,
|
|
79
|
+
onChange,
|
|
80
|
+
isActive,
|
|
81
|
+
plain,
|
|
82
|
+
optionLabels,
|
|
83
|
+
ButtonComponent,
|
|
84
|
+
buttonSize,
|
|
85
|
+
buttonClassName
|
|
86
|
+
}) {
|
|
87
|
+
const [labelAnd, labelOr] = optionLabels;
|
|
88
|
+
const Btn = ButtonComponent;
|
|
89
|
+
return /* @__PURE__ */ React.createElement(
|
|
90
|
+
"div",
|
|
91
|
+
{
|
|
92
|
+
className: cn(
|
|
93
|
+
"relative z-10 inline-flex overflow-hidden",
|
|
94
|
+
plain ? "bg-white" : "rounded-md border border-gray-300 bg-white shadow-sm"
|
|
95
|
+
)
|
|
96
|
+
},
|
|
97
|
+
/* @__PURE__ */ React.createElement(
|
|
98
|
+
Btn,
|
|
99
|
+
{
|
|
100
|
+
type: "button",
|
|
101
|
+
variant: "ghost",
|
|
102
|
+
color: "grey",
|
|
103
|
+
size: buttonSize,
|
|
104
|
+
onClick: () => onChange("AND"),
|
|
105
|
+
disabled: !isActive,
|
|
106
|
+
className: cn(
|
|
107
|
+
"px-4 py-1 text-sm transition !rounded-none",
|
|
108
|
+
value === "AND" ? "bg-blue-600 text-white hover:bg-blue-500" : "bg-white text-gray-700 hover:bg-blue-50",
|
|
109
|
+
buttonClassName
|
|
110
|
+
)
|
|
111
|
+
},
|
|
112
|
+
labelAnd
|
|
113
|
+
),
|
|
114
|
+
/* @__PURE__ */ React.createElement(
|
|
115
|
+
Btn,
|
|
116
|
+
{
|
|
117
|
+
type: "button",
|
|
118
|
+
variant: "ghost",
|
|
119
|
+
color: "grey",
|
|
120
|
+
size: buttonSize,
|
|
121
|
+
onClick: () => onChange("OR"),
|
|
122
|
+
disabled: !isActive,
|
|
123
|
+
className: cn(
|
|
124
|
+
"px-4 py-1 text-sm transition !rounded-none",
|
|
125
|
+
value === "OR" ? "bg-blue-600 text-white hover:bg-blue-500" : "bg-white text-gray-700 hover:bg-blue-50",
|
|
126
|
+
buttonClassName
|
|
127
|
+
)
|
|
128
|
+
},
|
|
129
|
+
labelOr
|
|
130
|
+
)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
function getJustifyClass(orientation) {
|
|
134
|
+
const map = {
|
|
135
|
+
left: "justify-start",
|
|
136
|
+
center: "justify-center",
|
|
137
|
+
right: "justify-end"
|
|
138
|
+
};
|
|
139
|
+
return map[orientation];
|
|
140
|
+
}
|
|
141
|
+
function DividerWrapper({
|
|
142
|
+
isGroupDivider,
|
|
143
|
+
isActive,
|
|
144
|
+
orientation = "center",
|
|
145
|
+
dashed,
|
|
146
|
+
plain,
|
|
147
|
+
className,
|
|
148
|
+
style,
|
|
149
|
+
children
|
|
150
|
+
}) {
|
|
151
|
+
return /* @__PURE__ */ React.createElement(
|
|
152
|
+
"div",
|
|
153
|
+
{
|
|
154
|
+
className: cn(
|
|
155
|
+
"relative w-full flex items-center",
|
|
156
|
+
isGroupDivider ? "my-4" : "my-2",
|
|
157
|
+
isActive ? "opacity-100" : "opacity-50",
|
|
158
|
+
getJustifyClass(orientation),
|
|
159
|
+
className
|
|
160
|
+
),
|
|
161
|
+
style
|
|
162
|
+
},
|
|
163
|
+
/* @__PURE__ */ React.createElement(
|
|
164
|
+
"div",
|
|
165
|
+
{
|
|
166
|
+
className: cn(
|
|
167
|
+
"absolute inset-x-0 border-t",
|
|
168
|
+
dashed ? "border-dashed" : "border-solid",
|
|
169
|
+
plain ? "border-gray-200" : "border-gray-300"
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
),
|
|
173
|
+
children
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
function CustomDivider({
|
|
177
|
+
name,
|
|
178
|
+
control,
|
|
179
|
+
isActive = true,
|
|
180
|
+
isGroupDivider = false,
|
|
181
|
+
orientation = "center",
|
|
182
|
+
dashed = false,
|
|
183
|
+
plain = false,
|
|
184
|
+
lineOnly = false,
|
|
185
|
+
optionLabels = ["E", "OU"],
|
|
186
|
+
ButtonComponent = Button,
|
|
187
|
+
buttonSize = "medium",
|
|
188
|
+
buttonClassName,
|
|
189
|
+
className,
|
|
190
|
+
style,
|
|
191
|
+
children
|
|
192
|
+
}) {
|
|
193
|
+
const formContext = useFormContext();
|
|
194
|
+
const controlToUse = control ?? formContext?.control;
|
|
195
|
+
if (lineOnly && !children) {
|
|
196
|
+
return /* @__PURE__ */ React.createElement(
|
|
197
|
+
DividerLine,
|
|
198
|
+
{
|
|
199
|
+
dashed,
|
|
200
|
+
plain,
|
|
201
|
+
isGroupDivider,
|
|
202
|
+
isActive,
|
|
203
|
+
className,
|
|
204
|
+
style
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
return /* @__PURE__ */ React.createElement(
|
|
209
|
+
DividerWrapper,
|
|
210
|
+
{
|
|
211
|
+
isGroupDivider,
|
|
212
|
+
isActive,
|
|
213
|
+
orientation,
|
|
214
|
+
dashed,
|
|
215
|
+
plain,
|
|
216
|
+
className,
|
|
217
|
+
style
|
|
218
|
+
},
|
|
219
|
+
getDividerContent({
|
|
220
|
+
name,
|
|
221
|
+
children,
|
|
222
|
+
control: controlToUse,
|
|
223
|
+
optionLabels,
|
|
224
|
+
ButtonComponent,
|
|
225
|
+
buttonSize,
|
|
226
|
+
buttonClassName,
|
|
227
|
+
isActive,
|
|
228
|
+
plain
|
|
229
|
+
})
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
CustomDivider.displayName = "CustomDivider";
|
|
233
|
+
|
|
234
|
+
export { CustomDivider };
|
|
@@ -60,7 +60,8 @@ function buildColumns({
|
|
|
60
60
|
className: clsx(
|
|
61
61
|
"group flex items-center gap-1",
|
|
62
62
|
hasSort && "hover:cursor-pointer"
|
|
63
|
-
)
|
|
63
|
+
),
|
|
64
|
+
onClick: () => externalColumn.onSort?.({ table, column })
|
|
64
65
|
},
|
|
65
66
|
typeof externalColumn.title === "string" ? /* @__PURE__ */ React.createElement(
|
|
66
67
|
Typography,
|
|
@@ -76,15 +77,7 @@ function buildColumns({
|
|
|
76
77
|
ArrowUpDown,
|
|
77
78
|
{
|
|
78
79
|
size: 16,
|
|
79
|
-
className: "text-grey-400 group-hover:text-grey-950
|
|
80
|
-
onClick: (e) => {
|
|
81
|
-
e.stopPropagation();
|
|
82
|
-
const handler = column.getToggleSortingHandler?.();
|
|
83
|
-
if (handler) handler(e);
|
|
84
|
-
else if (externalColumn.onSort) {
|
|
85
|
-
externalColumn.onSort({ table, column });
|
|
86
|
-
}
|
|
87
|
-
}
|
|
80
|
+
className: "text-grey-400 group-hover:text-grey-950"
|
|
88
81
|
}
|
|
89
82
|
)
|
|
90
83
|
);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Button } from '../Button/Button.js';
|
|
3
|
+
import { Calendar } from '../Calendar/Calendar.js';
|
|
4
|
+
import { Popover, PopoverTrigger, PopoverContent } from '../Popover/Popover.js';
|
|
5
|
+
import { cn } from '../../lib/utils.js';
|
|
6
|
+
import { format } from 'date-fns';
|
|
7
|
+
import { CalendarIcon } from 'lucide-react';
|
|
8
|
+
|
|
9
|
+
function DatePicker({
|
|
10
|
+
className,
|
|
11
|
+
variant = "outlined",
|
|
12
|
+
locale,
|
|
13
|
+
placeholder = "Pick a date",
|
|
14
|
+
value,
|
|
15
|
+
onChange,
|
|
16
|
+
format: format$1 = "PPP",
|
|
17
|
+
status
|
|
18
|
+
}) {
|
|
19
|
+
const [internalDate, setInternalDate] = React.useState();
|
|
20
|
+
const isControlled = value !== void 0 && onChange !== void 0;
|
|
21
|
+
const date = isControlled ? value : internalDate;
|
|
22
|
+
const handleSelect = (selected) => {
|
|
23
|
+
if (isControlled && onChange) {
|
|
24
|
+
onChange(selected);
|
|
25
|
+
} else {
|
|
26
|
+
setInternalDate(selected);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return /* @__PURE__ */ React.createElement(Popover, null, /* @__PURE__ */ React.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React.createElement(
|
|
30
|
+
Button,
|
|
31
|
+
{
|
|
32
|
+
variant,
|
|
33
|
+
className: cn(
|
|
34
|
+
"w-[240px] justify-start text-left font-normal",
|
|
35
|
+
!date && "text-muted-foreground",
|
|
36
|
+
className,
|
|
37
|
+
status
|
|
38
|
+
)
|
|
39
|
+
},
|
|
40
|
+
/* @__PURE__ */ React.createElement(CalendarIcon, { className: "mr-2 h-4 w-4" }),
|
|
41
|
+
date ? format(date, format$1, { locale }) : /* @__PURE__ */ React.createElement("span", null, placeholder)
|
|
42
|
+
)), /* @__PURE__ */ React.createElement(PopoverContent, { className: "w-auto p-0", align: "start" }, /* @__PURE__ */ React.createElement(
|
|
43
|
+
Calendar,
|
|
44
|
+
{
|
|
45
|
+
mode: "single",
|
|
46
|
+
selected: date,
|
|
47
|
+
onSelect: handleSelect,
|
|
48
|
+
autoFocus: true,
|
|
49
|
+
locale
|
|
50
|
+
}
|
|
51
|
+
)));
|
|
52
|
+
}
|
|
53
|
+
DatePicker.displayName = "DatePicker";
|
|
54
|
+
|
|
55
|
+
export { DatePicker };
|
|
@@ -184,7 +184,8 @@ const Pagination = ({
|
|
|
184
184
|
totalRowsSelected = 0,
|
|
185
185
|
onChangePerPage,
|
|
186
186
|
className,
|
|
187
|
-
activeColor
|
|
187
|
+
activeColor,
|
|
188
|
+
showPerPageSelector = true
|
|
188
189
|
}) => {
|
|
189
190
|
const mapPaginationItem = (item) => {
|
|
190
191
|
const componentProps = {
|
|
@@ -218,7 +219,7 @@ const Pagination = ({
|
|
|
218
219
|
{
|
|
219
220
|
className: cn("flex items-center justify-between mt-6 gap-4", className)
|
|
220
221
|
},
|
|
221
|
-
/* @__PURE__ */ React.createElement(
|
|
222
|
+
showPerPageSelector && /* @__PURE__ */ React.createElement(
|
|
222
223
|
PaginationPerPage,
|
|
223
224
|
{
|
|
224
225
|
onChangePerPage,
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../lib/utils.js';
|
|
3
|
+
|
|
4
|
+
const Steps = ({
|
|
5
|
+
items,
|
|
6
|
+
current = 0,
|
|
7
|
+
className,
|
|
8
|
+
dotSize = "medium",
|
|
9
|
+
color = "blue"
|
|
10
|
+
}) => {
|
|
11
|
+
const getStepStatus = (index, item) => {
|
|
12
|
+
if (item.status) return item.status;
|
|
13
|
+
if (index < current) return "completed";
|
|
14
|
+
if (index === current) return "current";
|
|
15
|
+
return "pending";
|
|
16
|
+
};
|
|
17
|
+
const getDotSizeClasses = () => {
|
|
18
|
+
const outerDotSizeClasses = {
|
|
19
|
+
small: "w-[10px] h-[10px]",
|
|
20
|
+
medium: "w-6 h-6",
|
|
21
|
+
large: "w-8 h-8"
|
|
22
|
+
};
|
|
23
|
+
const innerDotSizeClasses = {
|
|
24
|
+
small: "",
|
|
25
|
+
medium: "w-2 h-2",
|
|
26
|
+
large: "w-3 h-3"
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
outer: outerDotSizeClasses[dotSize],
|
|
30
|
+
inner: innerDotSizeClasses[dotSize]
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const getStepIcon = () => dotSize !== "small" ? /* @__PURE__ */ React.createElement("div", { className: cn("rounded-full", getDotSizeClasses().inner) }) : null;
|
|
34
|
+
const getStepColors = () => {
|
|
35
|
+
const colorOptions = {
|
|
36
|
+
blue: "bg-blue-600 border-blue-600",
|
|
37
|
+
red: "bg-red-600 border-red-600",
|
|
38
|
+
green: "bg-green-600 border-green-600",
|
|
39
|
+
purple: "bg-purple-600 border-purple-600",
|
|
40
|
+
orange: "bg-orange-500 border-orange-500"
|
|
41
|
+
};
|
|
42
|
+
return colorOptions[color] || colorOptions.blue;
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ React.createElement("div", { className: cn("relative", className) }, items.map((item, index) => {
|
|
45
|
+
const status = getStepStatus(index, item);
|
|
46
|
+
const isCurrent = index === current;
|
|
47
|
+
const isLast = index === items.length - 1;
|
|
48
|
+
return /* @__PURE__ */ React.createElement("div", { key: index, className: "relative flex items-baseline" }, !isLast && /* @__PURE__ */ React.createElement(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
className: cn("absolute border-l border-dashed -z-10", {
|
|
52
|
+
"left-[4.5px]": dotSize === "small",
|
|
53
|
+
"left-3": dotSize === "medium",
|
|
54
|
+
"left-4": dotSize === "large",
|
|
55
|
+
"border-blue-300": color === "blue",
|
|
56
|
+
"border-red-300": color === "red",
|
|
57
|
+
"border-green-300": color === "green",
|
|
58
|
+
"border-purple-300": color === "purple",
|
|
59
|
+
"border-orange-300": color === "orange"
|
|
60
|
+
}),
|
|
61
|
+
style: {
|
|
62
|
+
top: dotSize === "small" ? "10px" : dotSize === "medium" ? "16px" : "24px",
|
|
63
|
+
height: dotSize === "small" ? "calc(100% - 10px)" : dotSize === "medium" ? "calc(100% - 24px)" : "calc(100% - 32px)"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
), /* @__PURE__ */ React.createElement(
|
|
67
|
+
"div",
|
|
68
|
+
{
|
|
69
|
+
className: cn(
|
|
70
|
+
"relative z-10 flex items-center justify-center rounded-full",
|
|
71
|
+
getDotSizeClasses().outer,
|
|
72
|
+
getStepColors(),
|
|
73
|
+
dotSize === "small" ? "" : "border"
|
|
74
|
+
)
|
|
75
|
+
},
|
|
76
|
+
getStepIcon()
|
|
77
|
+
), /* @__PURE__ */ React.createElement(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
className: cn("pb-6 flex-1 mt-0", {
|
|
81
|
+
"ml-[14px]": dotSize === "small",
|
|
82
|
+
"ml-4": dotSize === "medium",
|
|
83
|
+
"ml-5": dotSize === "large"
|
|
84
|
+
})
|
|
85
|
+
},
|
|
86
|
+
/* @__PURE__ */ React.createElement(
|
|
87
|
+
"div",
|
|
88
|
+
{
|
|
89
|
+
className: cn(
|
|
90
|
+
"text-sm font-medium",
|
|
91
|
+
status === "completed" || isCurrent ? "text-gray-900" : "text-gray-500"
|
|
92
|
+
)
|
|
93
|
+
},
|
|
94
|
+
item.title
|
|
95
|
+
),
|
|
96
|
+
item.description && /* @__PURE__ */ React.createElement("div", { className: "mt-1" }, typeof item.description === "string" ? /* @__PURE__ */ React.createElement("div", { className: "text-sm text-gray-600" }, item.description) : item.description)
|
|
97
|
+
));
|
|
98
|
+
}));
|
|
99
|
+
};
|
|
100
|
+
Steps.displayName = "Steps";
|
|
101
|
+
|
|
102
|
+
export { Steps };
|
|
@@ -1,24 +1,60 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { cn } from '../../lib/utils.js';
|
|
3
2
|
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
3
|
+
import { cn } from '../../lib/utils.js';
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const Spinner = () => /* @__PURE__ */ React.createElement("svg", { className: "animate-spin h-4 w-4 text-blue-600", viewBox: "0 0 24 24" }, /* @__PURE__ */ React.createElement(
|
|
6
|
+
"circle",
|
|
7
|
+
{
|
|
8
|
+
className: "opacity-25",
|
|
9
|
+
cx: "12",
|
|
10
|
+
cy: "12",
|
|
11
|
+
r: "10",
|
|
12
|
+
stroke: "currentColor",
|
|
13
|
+
strokeWidth: "4",
|
|
14
|
+
fill: "none"
|
|
15
|
+
}
|
|
16
|
+
), /* @__PURE__ */ React.createElement(
|
|
17
|
+
"path",
|
|
18
|
+
{
|
|
19
|
+
className: "opacity-75",
|
|
20
|
+
fill: "currentColor",
|
|
21
|
+
d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"
|
|
22
|
+
}
|
|
23
|
+
));
|
|
24
|
+
const Switch = React.forwardRef(({ className, loading = false, disabled, ...props }, ref) => /* @__PURE__ */ React.createElement(
|
|
6
25
|
SwitchPrimitives.Root,
|
|
7
26
|
{
|
|
27
|
+
ref,
|
|
28
|
+
disabled: disabled || loading,
|
|
8
29
|
className: cn(
|
|
9
|
-
"peer flex items-center shrink-0 h-6 w-12 p-[2px] group rounded-full cursor-pointer bg-transparent focus:outline-none transition-colors
|
|
30
|
+
"peer flex items-center shrink-0 h-6 w-12 p-[2px] group rounded-full cursor-pointer bg-transparent focus:outline-none transition-colors",
|
|
31
|
+
"data-[state=unchecked]:border-2 data-[state=unchecked]:border-grey-400",
|
|
32
|
+
"data-[state=unchecked]:hover:border-grey-500 data-[state=unchecked]:active:border-grey-700",
|
|
33
|
+
"data-[state=unchecked]:disabled:border-grey-300",
|
|
34
|
+
"data-[state=checked]:bg-blue-600 data-[state=checked]:hover:bg-blue-700",
|
|
35
|
+
"data-[state=checked]:active:bg-blue-800 data-[state=checked]:disabled:bg-blue-200",
|
|
36
|
+
"disabled:cursor-not-allowed",
|
|
10
37
|
className
|
|
11
38
|
),
|
|
12
|
-
ref,
|
|
13
39
|
...props
|
|
14
40
|
},
|
|
15
41
|
/* @__PURE__ */ React.createElement(
|
|
16
42
|
SwitchPrimitives.Thumb,
|
|
17
43
|
{
|
|
18
44
|
className: cn(
|
|
19
|
-
"pointer-events-none rounded-full shadow-sm transition-all h-4 w-4
|
|
45
|
+
"pointer-events-none rounded-full shadow-sm transition-all h-4 w-4",
|
|
46
|
+
"data-[state=unchecked]:bg-grey-400 data-[state=unchecked]:translate-x-1",
|
|
47
|
+
"group-hover:data-[state=unchecked]:bg-grey-500",
|
|
48
|
+
"group-focus:ring-8 group-focus:ring-blue-200 group-focus:ring-opacity-50",
|
|
49
|
+
"group-active:group-enabled:h-5 group-active:group-enabled:w-5",
|
|
50
|
+
"group-active:data-[state=unchecked]:bg-grey-700",
|
|
51
|
+
"group-active:group-enabled:data-[state=unchecked]:translate-x-[-2px]",
|
|
52
|
+
"group-disabled:data-[state=unchecked]:bg-grey-300 group-disabled:data-[state=unchecked]:bg-opacity-65",
|
|
53
|
+
"data-[state=checked]:bg-white data-[state=checked]:translate-x-6",
|
|
54
|
+
"flex items-center justify-center"
|
|
20
55
|
)
|
|
21
|
-
}
|
|
56
|
+
},
|
|
57
|
+
loading && /* @__PURE__ */ React.createElement(Spinner, null)
|
|
22
58
|
)
|
|
23
59
|
));
|
|
24
60
|
Switch.displayName = "Switch";
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { X } from 'lucide-react';
|
|
3
|
+
import { cn } from '../../lib/utils.js';
|
|
4
|
+
import { Tag } from '../Tag/Tag.js';
|
|
5
|
+
import { textareaVariants } from '../Textarea/Textarea.js';
|
|
6
|
+
import { Typography } from '../Typography/Typography.js';
|
|
7
|
+
|
|
8
|
+
function TagInput({
|
|
9
|
+
value,
|
|
10
|
+
onRemove,
|
|
11
|
+
placeholder = "Nenhum item selecionado",
|
|
12
|
+
disabled = false,
|
|
13
|
+
readOnly = false,
|
|
14
|
+
className = "",
|
|
15
|
+
variant = "default",
|
|
16
|
+
radius = "default",
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
const ref = React.useRef(null);
|
|
20
|
+
const [maxVisibleCount, setMaxVisibleCount] = React.useState(
|
|
21
|
+
null
|
|
22
|
+
);
|
|
23
|
+
const [hiddenCount, setHiddenCount] = React.useState(0);
|
|
24
|
+
const calculateMaxVisible = React.useCallback(() => {
|
|
25
|
+
const container = ref.current;
|
|
26
|
+
if (!container) return;
|
|
27
|
+
const children = Array.from(container.children).filter(
|
|
28
|
+
(el) => el.dataset.tag === "true"
|
|
29
|
+
);
|
|
30
|
+
const lines = [];
|
|
31
|
+
children.forEach((c) => {
|
|
32
|
+
const t = c.offsetTop;
|
|
33
|
+
if (!lines.includes(t)) lines.push(t);
|
|
34
|
+
});
|
|
35
|
+
if (lines.length <= 2) {
|
|
36
|
+
setMaxVisibleCount(children.length);
|
|
37
|
+
setHiddenCount(0);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const second = lines[1];
|
|
41
|
+
let count = 0;
|
|
42
|
+
for (const c of children) {
|
|
43
|
+
if (c.offsetTop > second) break;
|
|
44
|
+
count++;
|
|
45
|
+
}
|
|
46
|
+
setMaxVisibleCount(count);
|
|
47
|
+
setHiddenCount(children.length - count);
|
|
48
|
+
}, []);
|
|
49
|
+
React.useLayoutEffect(() => {
|
|
50
|
+
if (maxVisibleCount === null) {
|
|
51
|
+
const id = window.requestAnimationFrame(calculateMaxVisible);
|
|
52
|
+
return () => window.cancelAnimationFrame(id);
|
|
53
|
+
}
|
|
54
|
+
}, [maxVisibleCount, calculateMaxVisible]);
|
|
55
|
+
const visibleCount = maxVisibleCount === null ? value.length : maxVisibleCount;
|
|
56
|
+
const displayTags = value.slice(0, visibleCount);
|
|
57
|
+
const currentHiddenCount = Math.max(value.length - visibleCount, 0);
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
setHiddenCount(currentHiddenCount);
|
|
60
|
+
}, [currentHiddenCount]);
|
|
61
|
+
const textareaRadius = radius === "full" ? "large" : radius;
|
|
62
|
+
return /* @__PURE__ */ React.createElement(
|
|
63
|
+
"div",
|
|
64
|
+
{
|
|
65
|
+
ref,
|
|
66
|
+
className: cn(
|
|
67
|
+
textareaVariants({ variant, radius: textareaRadius }),
|
|
68
|
+
"flex flex-wrap items-start min-h-10 gap-1 py-2 px-3",
|
|
69
|
+
disabled && "opacity-50 pointer-events-none",
|
|
70
|
+
className
|
|
71
|
+
),
|
|
72
|
+
tabIndex: 0,
|
|
73
|
+
"aria-disabled": disabled,
|
|
74
|
+
style: { resize: "none", cursor: disabled ? "not-allowed" : "text" },
|
|
75
|
+
...props
|
|
76
|
+
},
|
|
77
|
+
value.length === 0 && /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-grey-400" }, placeholder),
|
|
78
|
+
displayTags.map((item) => /* @__PURE__ */ React.createElement(Tag, { key: item.value, "data-tag": "true", color: "blue" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-blue-600" }, item.label), !readOnly && /* @__PURE__ */ React.createElement(
|
|
79
|
+
X,
|
|
80
|
+
{
|
|
81
|
+
className: "w-4 h-4 cursor-pointer",
|
|
82
|
+
onClick: (e) => {
|
|
83
|
+
e.stopPropagation();
|
|
84
|
+
onRemove(item.value);
|
|
85
|
+
},
|
|
86
|
+
"aria-label": `Remover ${item.label}`,
|
|
87
|
+
tabIndex: 0
|
|
88
|
+
}
|
|
89
|
+
))),
|
|
90
|
+
hiddenCount > 0 && /* @__PURE__ */ React.createElement(Tag, { color: "grey", "data-tag": "true" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-grey-600" }, "+", hiddenCount), !readOnly && /* @__PURE__ */ React.createElement(
|
|
91
|
+
X,
|
|
92
|
+
{
|
|
93
|
+
className: "w-4 h-4 cursor-pointer text-grey-500 hover:text-grey-700",
|
|
94
|
+
onClick: (e) => {
|
|
95
|
+
e.stopPropagation();
|
|
96
|
+
const next = value[visibleCount]?.value;
|
|
97
|
+
if (next) onRemove(next);
|
|
98
|
+
},
|
|
99
|
+
"aria-label": "Remover pr\xF3xima tag oculta",
|
|
100
|
+
tabIndex: 0
|
|
101
|
+
}
|
|
102
|
+
))
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { TagInput };
|