lecom-ui 5.2.75 → 5.2.77
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/DataTable/DataTable.utils.js +10 -3
- package/dist/components/DataTable/Table.js +1 -2
- package/dist/components/Switch/Switch.js +6 -42
- package/dist/index.d.ts +10 -110
- package/dist/index.js +0 -5
- 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 +5 -8
- package/dist/components/Collapse/Collapse.js +0 -94
- package/dist/components/Combobox/Combobox.js +0 -128
- package/dist/components/CustomDivider/CustomDivider.js +0 -207
- package/dist/components/Steps/Steps.js +0 -102
- package/dist/components/TagInput/TagInput.js +0 -107
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { ChevronUpIcon, ChevronDownIcon } from 'lucide-react';
|
|
3
|
-
import { cn } from '../../lib/utils.js';
|
|
4
|
-
import { Button } from '../Button/Button.js';
|
|
5
|
-
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../Command/Command.js';
|
|
6
|
-
import { Popover, PopoverTrigger, PopoverContent } from '../Popover/Popover.js';
|
|
7
|
-
import { Typography } from '../Typography/Typography.js';
|
|
8
|
-
|
|
9
|
-
function Combobox({
|
|
10
|
-
options,
|
|
11
|
-
value,
|
|
12
|
-
onChange,
|
|
13
|
-
placeholder = "Selecione...",
|
|
14
|
-
disabled = false,
|
|
15
|
-
notFoundContent = "Nenhuma op\xE7\xE3o encontrada.",
|
|
16
|
-
status = "default",
|
|
17
|
-
searchTerm = "Pesquisar...",
|
|
18
|
-
triggerClassName,
|
|
19
|
-
contentClassName
|
|
20
|
-
}) {
|
|
21
|
-
const [open, setOpen] = React.useState(false);
|
|
22
|
-
const [search, setSearch] = React.useState("");
|
|
23
|
-
const filterOptions = React.useCallback(
|
|
24
|
-
(opts) => {
|
|
25
|
-
const searchLower = search.toLowerCase();
|
|
26
|
-
return opts.map((item) => {
|
|
27
|
-
if ("options" in item) {
|
|
28
|
-
const filtered = item.options.filter(
|
|
29
|
-
(opt) => opt.label.toLowerCase().includes(searchLower) || opt.value.toLowerCase().includes(searchLower)
|
|
30
|
-
);
|
|
31
|
-
if (!filtered.length) return null;
|
|
32
|
-
return { ...item, options: filtered };
|
|
33
|
-
}
|
|
34
|
-
return item.label.toLowerCase().includes(searchLower) || item.value.toLowerCase().includes(searchLower) ? item : null;
|
|
35
|
-
}).filter(Boolean);
|
|
36
|
-
},
|
|
37
|
-
[search]
|
|
38
|
-
);
|
|
39
|
-
const filteredOptions = React.useMemo(
|
|
40
|
-
() => !search ? options : filterOptions(options),
|
|
41
|
-
[options, search, filterOptions]
|
|
42
|
-
);
|
|
43
|
-
const selectedLabel = options.flatMap((opt) => "options" in opt ? opt.options : [opt]).find((opt) => opt.value === value)?.label || placeholder;
|
|
44
|
-
React.useEffect(() => {
|
|
45
|
-
if (!open) setSearch("");
|
|
46
|
-
}, [open]);
|
|
47
|
-
return /* @__PURE__ */ React.createElement(Popover, { open, onOpenChange: setOpen }, /* @__PURE__ */ React.createElement(PopoverTrigger, { asChild: true, className: cn(contentClassName) }, /* @__PURE__ */ React.createElement(
|
|
48
|
-
Button,
|
|
49
|
-
{
|
|
50
|
-
type: "button",
|
|
51
|
-
role: "combobox",
|
|
52
|
-
"aria-expanded": open,
|
|
53
|
-
className: cn(
|
|
54
|
-
triggerClassName,
|
|
55
|
-
"w-full h-10 bg-white rounded-md px-3 text-left shadow-sm flex items-center justify-between transition",
|
|
56
|
-
status === "error" ? "border border-red-500 hover:ring-1 hover:ring-red-500 focus:ring-1 focus:ring-red-500" : "border border-gray-300 hover:ring-1 hover:ring-blue-600 focus:ring-1 focus:ring-blue-600",
|
|
57
|
-
!value && "text-gray-400",
|
|
58
|
-
disabled && "opacity-50 pointer-events-none",
|
|
59
|
-
"hover:bg-white focus:!bg-white active:!bg-white"
|
|
60
|
-
),
|
|
61
|
-
disabled
|
|
62
|
-
},
|
|
63
|
-
/* @__PURE__ */ React.createElement(
|
|
64
|
-
"span",
|
|
65
|
-
{
|
|
66
|
-
className: cn(
|
|
67
|
-
value ? "text-black" : "text-gray-400",
|
|
68
|
-
"font-normal truncate max-w-[calc(100%-2.5rem)]"
|
|
69
|
-
)
|
|
70
|
-
},
|
|
71
|
-
/* @__PURE__ */ React.createElement(Typography, { variant: "body-medium-400" }, selectedLabel)
|
|
72
|
-
),
|
|
73
|
-
open ? /* @__PURE__ */ React.createElement(
|
|
74
|
-
ChevronUpIcon,
|
|
75
|
-
{
|
|
76
|
-
className: "ml-2 h-4 w-4 shrink-0 text-gray-400",
|
|
77
|
-
color: "black"
|
|
78
|
-
}
|
|
79
|
-
) : /* @__PURE__ */ React.createElement(
|
|
80
|
-
ChevronDownIcon,
|
|
81
|
-
{
|
|
82
|
-
className: "ml-2 h-4 w-4 shrink-0 text-gray-400",
|
|
83
|
-
color: "black"
|
|
84
|
-
}
|
|
85
|
-
)
|
|
86
|
-
)), /* @__PURE__ */ React.createElement(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0" }, /* @__PURE__ */ React.createElement(Command, null, /* @__PURE__ */ React.createElement(
|
|
87
|
-
CommandInput,
|
|
88
|
-
{
|
|
89
|
-
placeholder: searchTerm,
|
|
90
|
-
value: search,
|
|
91
|
-
onValueChange: setSearch
|
|
92
|
-
}
|
|
93
|
-
), /* @__PURE__ */ React.createElement(CommandList, null, /* @__PURE__ */ React.createElement(CommandEmpty, null, notFoundContent), filteredOptions.map(
|
|
94
|
-
(item, idx) => "options" in item ? /* @__PURE__ */ React.createElement(CommandGroup, { key: `${item.label}-${idx}`, heading: item.label }, item.options.map((opt) => /* @__PURE__ */ React.createElement(
|
|
95
|
-
CommandItem,
|
|
96
|
-
{
|
|
97
|
-
key: opt.value,
|
|
98
|
-
onSelect: () => {
|
|
99
|
-
if (opt.disabled) return;
|
|
100
|
-
onChange(opt.value === value ? null : opt.value);
|
|
101
|
-
setOpen(false);
|
|
102
|
-
},
|
|
103
|
-
className: cn(
|
|
104
|
-
opt.value === value ? "bg-blue-100 font-semibold text-black" : "hover:bg-gray-100",
|
|
105
|
-
opt.disabled && "opacity-50 pointer-events-none"
|
|
106
|
-
)
|
|
107
|
-
},
|
|
108
|
-
opt.label
|
|
109
|
-
))) : /* @__PURE__ */ React.createElement(
|
|
110
|
-
CommandItem,
|
|
111
|
-
{
|
|
112
|
-
key: item.value,
|
|
113
|
-
onSelect: () => {
|
|
114
|
-
if (item.disabled) return;
|
|
115
|
-
onChange(item.value === value ? null : item.value);
|
|
116
|
-
setOpen(false);
|
|
117
|
-
},
|
|
118
|
-
className: cn(
|
|
119
|
-
item.value === value ? "bg-blue-100 font-semibold text-black" : "hover:bg-gray-100",
|
|
120
|
-
item.disabled && "opacity-50 pointer-events-none"
|
|
121
|
-
)
|
|
122
|
-
},
|
|
123
|
-
item.label
|
|
124
|
-
)
|
|
125
|
-
)))));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export { Combobox };
|
|
@@ -1,207 +0,0 @@
|
|
|
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 DividerLine({
|
|
7
|
-
dashed,
|
|
8
|
-
plain,
|
|
9
|
-
isGroupDivider,
|
|
10
|
-
isActive,
|
|
11
|
-
className,
|
|
12
|
-
style
|
|
13
|
-
}) {
|
|
14
|
-
return /* @__PURE__ */ React.createElement(
|
|
15
|
-
"div",
|
|
16
|
-
{
|
|
17
|
-
className: cn(
|
|
18
|
-
"w-full",
|
|
19
|
-
isGroupDivider ? "my-4" : "my-2",
|
|
20
|
-
isActive ? "opacity-100" : "opacity-50",
|
|
21
|
-
className
|
|
22
|
-
),
|
|
23
|
-
style
|
|
24
|
-
},
|
|
25
|
-
/* @__PURE__ */ React.createElement(
|
|
26
|
-
"div",
|
|
27
|
-
{
|
|
28
|
-
className: cn(
|
|
29
|
-
"w-full border-t",
|
|
30
|
-
dashed ? "border-dashed" : "border-solid",
|
|
31
|
-
plain ? "border-gray-200" : "border-gray-300"
|
|
32
|
-
)
|
|
33
|
-
}
|
|
34
|
-
)
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
function OptionButtons({
|
|
38
|
-
value,
|
|
39
|
-
onChange,
|
|
40
|
-
isActive,
|
|
41
|
-
plain,
|
|
42
|
-
optionLabels,
|
|
43
|
-
ButtonComponent,
|
|
44
|
-
buttonSize,
|
|
45
|
-
buttonClassName
|
|
46
|
-
}) {
|
|
47
|
-
const [labelAnd, labelOr] = optionLabels;
|
|
48
|
-
const Btn = ButtonComponent;
|
|
49
|
-
return /* @__PURE__ */ React.createElement(
|
|
50
|
-
"div",
|
|
51
|
-
{
|
|
52
|
-
className: cn(
|
|
53
|
-
"relative z-10 inline-flex overflow-hidden",
|
|
54
|
-
plain ? "bg-white" : "rounded-md border border-gray-300 bg-white shadow-sm"
|
|
55
|
-
)
|
|
56
|
-
},
|
|
57
|
-
/* @__PURE__ */ React.createElement(
|
|
58
|
-
Btn,
|
|
59
|
-
{
|
|
60
|
-
type: "button",
|
|
61
|
-
variant: "ghost",
|
|
62
|
-
color: "grey",
|
|
63
|
-
size: buttonSize,
|
|
64
|
-
onClick: () => onChange("AND"),
|
|
65
|
-
disabled: !isActive,
|
|
66
|
-
className: cn(
|
|
67
|
-
"px-4 py-1 text-sm transition !rounded-none",
|
|
68
|
-
value === "AND" ? "bg-blue-600 text-white hover:bg-blue-500" : "bg-white text-gray-700 hover:bg-blue-50",
|
|
69
|
-
buttonClassName
|
|
70
|
-
)
|
|
71
|
-
},
|
|
72
|
-
labelAnd
|
|
73
|
-
),
|
|
74
|
-
/* @__PURE__ */ React.createElement(
|
|
75
|
-
Btn,
|
|
76
|
-
{
|
|
77
|
-
type: "button",
|
|
78
|
-
variant: "ghost",
|
|
79
|
-
color: "grey",
|
|
80
|
-
size: buttonSize,
|
|
81
|
-
onClick: () => onChange("OR"),
|
|
82
|
-
disabled: !isActive,
|
|
83
|
-
className: cn(
|
|
84
|
-
"px-4 py-1 text-sm transition !rounded-none",
|
|
85
|
-
value === "OR" ? "bg-blue-600 text-white hover:bg-blue-500" : "bg-white text-gray-700 hover:bg-blue-50",
|
|
86
|
-
buttonClassName
|
|
87
|
-
)
|
|
88
|
-
},
|
|
89
|
-
labelOr
|
|
90
|
-
)
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
function CustomDivider({
|
|
94
|
-
name,
|
|
95
|
-
control,
|
|
96
|
-
isActive = true,
|
|
97
|
-
isGroupDivider = false,
|
|
98
|
-
orientation = "center",
|
|
99
|
-
dashed = false,
|
|
100
|
-
plain = false,
|
|
101
|
-
lineOnly = false,
|
|
102
|
-
optionLabels = ["E", "OU"],
|
|
103
|
-
ButtonComponent = Button,
|
|
104
|
-
buttonSize = "medium",
|
|
105
|
-
buttonClassName,
|
|
106
|
-
className,
|
|
107
|
-
style,
|
|
108
|
-
children
|
|
109
|
-
}) {
|
|
110
|
-
const formContext = useFormContext();
|
|
111
|
-
const controlToUse = control ?? formContext?.control;
|
|
112
|
-
const justifyMap = {
|
|
113
|
-
left: "justify-start",
|
|
114
|
-
center: "justify-center",
|
|
115
|
-
right: "justify-end"
|
|
116
|
-
};
|
|
117
|
-
if (lineOnly && !children) {
|
|
118
|
-
return /* @__PURE__ */ React.createElement(
|
|
119
|
-
DividerLine,
|
|
120
|
-
{
|
|
121
|
-
dashed,
|
|
122
|
-
plain,
|
|
123
|
-
isGroupDivider,
|
|
124
|
-
isActive,
|
|
125
|
-
className,
|
|
126
|
-
style
|
|
127
|
-
}
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
if (children) {
|
|
131
|
-
return /* @__PURE__ */ React.createElement(
|
|
132
|
-
"div",
|
|
133
|
-
{
|
|
134
|
-
className: cn(
|
|
135
|
-
"relative w-full flex items-center",
|
|
136
|
-
isGroupDivider ? "my-4" : "my-2",
|
|
137
|
-
isActive ? "opacity-100" : "opacity-50",
|
|
138
|
-
justifyMap[orientation],
|
|
139
|
-
className
|
|
140
|
-
),
|
|
141
|
-
style
|
|
142
|
-
},
|
|
143
|
-
/* @__PURE__ */ React.createElement(
|
|
144
|
-
"div",
|
|
145
|
-
{
|
|
146
|
-
className: cn(
|
|
147
|
-
"absolute inset-x-0 border-t",
|
|
148
|
-
dashed ? "border-dashed" : "border-solid",
|
|
149
|
-
plain ? "border-gray-200" : "border-gray-300"
|
|
150
|
-
)
|
|
151
|
-
}
|
|
152
|
-
),
|
|
153
|
-
/* @__PURE__ */ React.createElement("span", { className: "relative z-10 px-2 bg-white" }, children)
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
if (!name) {
|
|
157
|
-
throw new Error(
|
|
158
|
-
"CustomDivider: prop `name` \xE9 obrigat\xF3ria se `lineOnly` for false."
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
return /* @__PURE__ */ React.createElement(
|
|
162
|
-
"div",
|
|
163
|
-
{
|
|
164
|
-
className: cn(
|
|
165
|
-
"relative w-full flex items-center",
|
|
166
|
-
isGroupDivider ? "my-4" : "my-2",
|
|
167
|
-
isActive ? "opacity-100" : "opacity-50",
|
|
168
|
-
justifyMap[orientation],
|
|
169
|
-
className
|
|
170
|
-
),
|
|
171
|
-
style
|
|
172
|
-
},
|
|
173
|
-
/* @__PURE__ */ React.createElement(
|
|
174
|
-
"div",
|
|
175
|
-
{
|
|
176
|
-
className: cn(
|
|
177
|
-
"absolute inset-x-0 border-t",
|
|
178
|
-
dashed ? "border-dashed" : "border-solid",
|
|
179
|
-
plain ? "border-gray-200" : "border-gray-300"
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
),
|
|
183
|
-
/* @__PURE__ */ React.createElement(
|
|
184
|
-
Controller,
|
|
185
|
-
{
|
|
186
|
-
name,
|
|
187
|
-
control: controlToUse,
|
|
188
|
-
render: ({ field: { value, onChange } }) => /* @__PURE__ */ React.createElement(
|
|
189
|
-
OptionButtons,
|
|
190
|
-
{
|
|
191
|
-
value,
|
|
192
|
-
onChange,
|
|
193
|
-
isActive,
|
|
194
|
-
plain,
|
|
195
|
-
optionLabels,
|
|
196
|
-
ButtonComponent,
|
|
197
|
-
buttonSize,
|
|
198
|
-
buttonClassName
|
|
199
|
-
}
|
|
200
|
-
)
|
|
201
|
-
}
|
|
202
|
-
)
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
CustomDivider.displayName = "CustomDivider";
|
|
206
|
-
|
|
207
|
-
export { CustomDivider };
|
|
@@ -1,102 +0,0 @@
|
|
|
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,107 +0,0 @@
|
|
|
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
|
-
size = "default",
|
|
16
|
-
variant = "default",
|
|
17
|
-
radius = "default",
|
|
18
|
-
...props
|
|
19
|
-
}) {
|
|
20
|
-
const ref = React.useRef(null);
|
|
21
|
-
const [maxVisibleCount, setMaxVisibleCount] = React.useState(
|
|
22
|
-
null
|
|
23
|
-
);
|
|
24
|
-
const [hiddenCount, setHiddenCount] = React.useState(0);
|
|
25
|
-
const calculateMaxVisible = React.useCallback(() => {
|
|
26
|
-
const container = ref.current;
|
|
27
|
-
if (!container) return;
|
|
28
|
-
const children = Array.from(container.children).filter(
|
|
29
|
-
(el) => el.dataset.tag === "true"
|
|
30
|
-
);
|
|
31
|
-
const lines = [];
|
|
32
|
-
children.forEach((c) => {
|
|
33
|
-
const t = c.offsetTop;
|
|
34
|
-
if (!lines.includes(t)) lines.push(t);
|
|
35
|
-
});
|
|
36
|
-
if (lines.length <= 2) {
|
|
37
|
-
setMaxVisibleCount(children.length);
|
|
38
|
-
setHiddenCount(0);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const second = lines[1];
|
|
42
|
-
let count = 0;
|
|
43
|
-
for (const c of children) {
|
|
44
|
-
if (c.offsetTop > second) break;
|
|
45
|
-
count++;
|
|
46
|
-
}
|
|
47
|
-
setMaxVisibleCount(count);
|
|
48
|
-
setHiddenCount(children.length - count);
|
|
49
|
-
}, []);
|
|
50
|
-
React.useLayoutEffect(() => {
|
|
51
|
-
if (maxVisibleCount === null) {
|
|
52
|
-
const id = window.requestAnimationFrame(calculateMaxVisible);
|
|
53
|
-
return () => window.cancelAnimationFrame(id);
|
|
54
|
-
}
|
|
55
|
-
}, [maxVisibleCount, calculateMaxVisible]);
|
|
56
|
-
const visibleCount = maxVisibleCount === null ? value.length : maxVisibleCount;
|
|
57
|
-
const displayTags = value.slice(0, visibleCount);
|
|
58
|
-
const currentHiddenCount = Math.max(value.length - visibleCount, 0);
|
|
59
|
-
React.useEffect(() => {
|
|
60
|
-
setHiddenCount(currentHiddenCount);
|
|
61
|
-
}, [currentHiddenCount]);
|
|
62
|
-
const textareaRadius = radius === "full" ? "large" : radius;
|
|
63
|
-
return /* @__PURE__ */ React.createElement(
|
|
64
|
-
"div",
|
|
65
|
-
{
|
|
66
|
-
ref,
|
|
67
|
-
className: cn(
|
|
68
|
-
textareaVariants({ variant, radius: textareaRadius }),
|
|
69
|
-
"flex flex-wrap items-start min-h-10 gap-1 py-2 px-3",
|
|
70
|
-
disabled && "opacity-50 pointer-events-none",
|
|
71
|
-
className
|
|
72
|
-
),
|
|
73
|
-
tabIndex: 0,
|
|
74
|
-
"aria-disabled": disabled,
|
|
75
|
-
style: { resize: "none", cursor: disabled ? "not-allowed" : "text" },
|
|
76
|
-
...props
|
|
77
|
-
},
|
|
78
|
-
value.length === 0 && /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-grey-400" }, placeholder),
|
|
79
|
-
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(
|
|
80
|
-
X,
|
|
81
|
-
{
|
|
82
|
-
className: "w-4 h-4 cursor-pointer",
|
|
83
|
-
onClick: (e) => {
|
|
84
|
-
e.stopPropagation();
|
|
85
|
-
onRemove(item.value);
|
|
86
|
-
},
|
|
87
|
-
"aria-label": `Remover ${item.label}`,
|
|
88
|
-
tabIndex: 0
|
|
89
|
-
}
|
|
90
|
-
))),
|
|
91
|
-
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(
|
|
92
|
-
X,
|
|
93
|
-
{
|
|
94
|
-
className: "w-4 h-4 cursor-pointer text-grey-500 hover:text-grey-700",
|
|
95
|
-
onClick: (e) => {
|
|
96
|
-
e.stopPropagation();
|
|
97
|
-
const next = value[visibleCount]?.value;
|
|
98
|
-
if (next) onRemove(next);
|
|
99
|
-
},
|
|
100
|
-
"aria-label": "Remover pr\xF3xima tag oculta",
|
|
101
|
-
tabIndex: 0
|
|
102
|
-
}
|
|
103
|
-
))
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export { TagInput };
|