torch-glare 2.1.7 → 2.2.1
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/apps/lib/components/BadgeField.tsx +143 -17
- package/apps/lib/components/ContextMenu.tsx +524 -0
- package/apps/lib/components/DropdownMenu.tsx +254 -102
- package/apps/lib/components/SearchableSelect.tsx +308 -0
- package/apps/lib/components/SearchableTable.tsx +363 -0
- package/apps/lib/components/Table.tsx +6 -6
- package/docs/components/badge-field.md +95 -91
- package/docs/components/context-menu.md +458 -0
- package/docs/components/dropdown-menu.md +68 -58
- package/docs/components/searchable-select.md +359 -0
- package/docs/components/searchable-table.md +419 -0
- package/docs/reference/tailwind-plugins.md +21 -1
- package/docs/tutorials/getting-started.md +15 -1
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ import { Icon, Input, Group, Trilling } from "./Input";
|
|
|
15
15
|
import { useClickOutside } from "../hooks/useClickOutside";
|
|
16
16
|
import { Badge } from "./Badge";
|
|
17
17
|
import { Tag, useTagSelection } from "../hooks/useTagSelection";
|
|
18
|
+
import { cva } from "class-variance-authority";
|
|
18
19
|
|
|
19
20
|
interface Props
|
|
20
21
|
extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "variant"> {
|
|
@@ -30,6 +31,7 @@ interface Props
|
|
|
30
31
|
actionButton?: ReactNode;
|
|
31
32
|
tags: Tag[];
|
|
32
33
|
onValueChange?: (tags: Tag[]) => void;
|
|
34
|
+
addLabel?: string
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
@@ -47,7 +49,10 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
47
49
|
actionButton,
|
|
48
50
|
theme,
|
|
49
51
|
tags,
|
|
52
|
+
addLabel = "add",
|
|
53
|
+
dir,
|
|
50
54
|
children,
|
|
55
|
+
onValueChange,
|
|
51
56
|
...props
|
|
52
57
|
},
|
|
53
58
|
forwardedRef
|
|
@@ -81,11 +86,17 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
81
86
|
searchTags
|
|
82
87
|
} = useTagSelection({
|
|
83
88
|
Tags: tags,
|
|
84
|
-
onTagsChange: (e) =>
|
|
85
|
-
target
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
onTagsChange: (e) => {
|
|
90
|
+
// Native onChange keeps the event-shaped API (Tag[] in target.value)
|
|
91
|
+
// for react-hook-form / Controller; onValueChange is the typed, direct
|
|
92
|
+
// callback consumers and the docs use.
|
|
93
|
+
props.onChange?.({
|
|
94
|
+
target: {
|
|
95
|
+
value: e
|
|
96
|
+
}
|
|
97
|
+
} as any);
|
|
98
|
+
onValueChange?.(e);
|
|
99
|
+
},
|
|
89
100
|
inputRef
|
|
90
101
|
});
|
|
91
102
|
|
|
@@ -98,6 +109,7 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
98
109
|
>
|
|
99
110
|
<PopoverTrigger asChild>
|
|
100
111
|
<Group
|
|
112
|
+
dir={dir}
|
|
101
113
|
error={errorMessage !== undefined}
|
|
102
114
|
onTable={onTable}
|
|
103
115
|
data-theme={theme}
|
|
@@ -167,37 +179,151 @@ export const BadgeField = forwardRef<HTMLInputElement, Props>(
|
|
|
167
179
|
</Tooltip>
|
|
168
180
|
|
|
169
181
|
<PopoverContent
|
|
182
|
+
dir={dir}
|
|
170
183
|
data-theme={theme}
|
|
171
184
|
ref={popoverContentRef}
|
|
172
185
|
style={{ width: dropDownListWidth }}
|
|
173
186
|
variant={variant}
|
|
174
187
|
onKeyDown={handleKeyDown}
|
|
175
|
-
className="
|
|
188
|
+
className={cn(menuContentContinerStyles({ variant: "PresentationStyle" }), "p-1 rounded-[17px]")}
|
|
189
|
+
|
|
190
|
+
// Reuse the DropdownMenu surface so the list matches the menu design.
|
|
176
191
|
>
|
|
177
|
-
|
|
192
|
+
<div
|
|
193
|
+
className={cn(menuContentStyles({ variant: "PresentationStyle" }), "p-0")}
|
|
194
|
+
|
|
195
|
+
>
|
|
178
196
|
{filteredTags.length > 0 ? (
|
|
179
197
|
filteredTags.map((tag, index) => (
|
|
180
|
-
<
|
|
198
|
+
<button
|
|
199
|
+
type="button"
|
|
181
200
|
key={tag.id}
|
|
182
|
-
size={size}
|
|
183
|
-
color={tag.variant as any}
|
|
184
|
-
label={tag.name}
|
|
185
201
|
onClick={() => handleSelectTag(tag.id)}
|
|
186
|
-
|
|
202
|
+
data-highlighted={focusedPopoverIndex === index ? "" : undefined}
|
|
187
203
|
tabIndex={focusedPopoverIndex === index ? 0 : -1}
|
|
188
|
-
|
|
204
|
+
className={cn(
|
|
205
|
+
MenuItemStyles({ variant: "Default", size: "M" }),
|
|
206
|
+
"w-full p-1 shrink-0 h-fit"
|
|
207
|
+
)}
|
|
208
|
+
>
|
|
209
|
+
<div className="flex items-center justify-between w-full">
|
|
210
|
+
<Badge size={size} badgeStyle={"solid"} color={tag.variant as any} label={tag.name} />
|
|
211
|
+
|
|
212
|
+
<div className="flex group-hover:opacity-100 opacity-0 px-[4px] py-[2px] items-center rounded-[6px] bg-white-50">
|
|
213
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" className="rtl:rotate-180" fill="none">
|
|
214
|
+
<path d="M3.91422 5.49995H10V6.49995H3.91422L6.5962 9.1819L5.8891 9.889L2 5.99995L5.8891 2.11084L6.5962 2.81794L3.91422 5.49995Z" fill="black" />
|
|
215
|
+
</svg>
|
|
216
|
+
<p className="text-black-1000 text-right text-[12px] font-[510] leading-[148%]">
|
|
217
|
+
{addLabel}
|
|
218
|
+
</p>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</button>
|
|
189
222
|
))
|
|
190
223
|
) : (
|
|
191
|
-
<div className="
|
|
224
|
+
<div className="px-3 py-2 typography-body-small-regular text-white-alpha-75">
|
|
192
225
|
{tags.length === 0
|
|
193
226
|
? "All tags selected"
|
|
194
227
|
: "No matching tags found"}
|
|
195
228
|
</div>
|
|
196
|
-
)}
|
|
197
|
-
</>
|
|
229
|
+
)} </div>
|
|
198
230
|
</PopoverContent>
|
|
199
|
-
</Popover>
|
|
231
|
+
</Popover >
|
|
200
232
|
);
|
|
201
233
|
}
|
|
202
234
|
);
|
|
203
235
|
BadgeField.displayName = "BadgeField";
|
|
236
|
+
|
|
237
|
+
// Local copies of the menu surface styles so the dropdown list matches the
|
|
238
|
+
// DropdownMenu/ContextMenu design (self-contained — no shared module).
|
|
239
|
+
const menuContentStyles = cva(
|
|
240
|
+
[
|
|
241
|
+
"rounded-[10px]",
|
|
242
|
+
"min-w-[240px]",
|
|
243
|
+
"outline-none",
|
|
244
|
+
"overflow-scroll",
|
|
245
|
+
"data-[state=open]:animate-in",
|
|
246
|
+
"data-[state=open]:fade-in-0",
|
|
247
|
+
"overflow-x-hidden",
|
|
248
|
+
"scrollbar-hide",
|
|
249
|
+
"flex gap-[1px] flex-col",
|
|
250
|
+
],
|
|
251
|
+
{
|
|
252
|
+
variants: {
|
|
253
|
+
variant: {
|
|
254
|
+
PresentationStyle: [
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
defaultVariants: {
|
|
258
|
+
variant: "PresentationStyle",
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
const menuContentContinerStyles = cva(
|
|
264
|
+
[
|
|
265
|
+
"rounded-[14px]",
|
|
266
|
+
"min-w-[240px]",
|
|
267
|
+
"outline-none",
|
|
268
|
+
"overflow-scroll",
|
|
269
|
+
"data-[state=open]:animate-in",
|
|
270
|
+
"data-[state=open]:fade-in-0",
|
|
271
|
+
"overflow-x-hidden",
|
|
272
|
+
"scrollbar-hide",
|
|
273
|
+
"backdrop-blur-[21px]",
|
|
274
|
+
"flex gap-1 flex-col",
|
|
275
|
+
],
|
|
276
|
+
{
|
|
277
|
+
variants: {
|
|
278
|
+
variant: {
|
|
279
|
+
PresentationStyle: [
|
|
280
|
+
"bg-[rgba(61,64,69,0.72)]",
|
|
281
|
+
"shadow-[0_0_32px_2px_rgba(0,0,0,0.20),0_0_48px_2px_rgba(0,0,0,0.05)]",
|
|
282
|
+
],
|
|
283
|
+
},
|
|
284
|
+
defaultVariants: {
|
|
285
|
+
variant: "PresentationStyle",
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
const MenuItemStyles = cva(
|
|
292
|
+
[
|
|
293
|
+
"text-content-presentation-global-primary-light typography-body-medium-regular",
|
|
294
|
+
"outline-none",
|
|
295
|
+
"border",
|
|
296
|
+
"border-transparent",
|
|
297
|
+
"flex",
|
|
298
|
+
"items-center",
|
|
299
|
+
"justify-start",
|
|
300
|
+
"text-overflow",
|
|
301
|
+
"overflow-hidden",
|
|
302
|
+
"transition-all",
|
|
303
|
+
"bg-[rgba(184,192,204,0.36)]",
|
|
304
|
+
"ease-in-out",
|
|
305
|
+
"duration-300",
|
|
306
|
+
"flex",
|
|
307
|
+
"p-1",
|
|
308
|
+
"w-full",
|
|
309
|
+
"items-center ",
|
|
310
|
+
"group",
|
|
311
|
+
],
|
|
312
|
+
{
|
|
313
|
+
variants: {
|
|
314
|
+
variant: {
|
|
315
|
+
Default: [
|
|
316
|
+
"hover:bg-[rgba(184,192,204,0.50)] ",
|
|
317
|
+
],
|
|
318
|
+
},
|
|
319
|
+
size: {
|
|
320
|
+
S: ["typography-body-small-regular", "h-[24px]"],
|
|
321
|
+
M: ["typography-body-medium-regular", "h-[32px]"],
|
|
322
|
+
},
|
|
323
|
+
defaultVariants: {
|
|
324
|
+
variant: "Default",
|
|
325
|
+
size: "M",
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
}
|
|
329
|
+
);
|