myoperator-ui 0.0.39 → 0.0.41
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/index.js +541 -381
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -54,11 +54,27 @@ function prefixTailwindClasses(content, prefix) {
|
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
async function getRegistry(prefix = "") {
|
|
57
|
-
|
|
57
|
+
return {
|
|
58
|
+
"badge": {
|
|
59
|
+
name: "badge",
|
|
60
|
+
description: "A status badge component with active, failed, and disabled variants",
|
|
61
|
+
dependencies: [
|
|
62
|
+
"class-variance-authority",
|
|
63
|
+
"clsx",
|
|
64
|
+
"tailwind-merge"
|
|
65
|
+
],
|
|
66
|
+
files: [
|
|
67
|
+
{
|
|
68
|
+
name: "badge.tsx",
|
|
69
|
+
content: prefixTailwindClasses(`import * as React from "react"
|
|
58
70
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
59
71
|
|
|
60
72
|
import { cn } from "@/lib/utils"
|
|
61
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Badge variants for status indicators.
|
|
76
|
+
* Pill-shaped badges with different colors for different states.
|
|
77
|
+
*/
|
|
62
78
|
const badgeVariants = cva(
|
|
63
79
|
"inline-flex items-center justify-center rounded-full text-sm font-semibold transition-colors whitespace-nowrap",
|
|
64
80
|
{
|
|
@@ -82,10 +98,23 @@ const badgeVariants = cva(
|
|
|
82
98
|
}
|
|
83
99
|
)
|
|
84
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Badge component for displaying status indicators.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* \`\`\`tsx
|
|
106
|
+
* <Badge variant="active">Active</Badge>
|
|
107
|
+
* <Badge variant="failed">Failed</Badge>
|
|
108
|
+
* <Badge variant="disabled">Disabled</Badge>
|
|
109
|
+
* <Badge variant="active" leftIcon={<CheckIcon />}>Active</Badge>
|
|
110
|
+
* \`\`\`
|
|
111
|
+
*/
|
|
85
112
|
export interface BadgeProps
|
|
86
113
|
extends React.HTMLAttributes<HTMLDivElement>,
|
|
87
114
|
VariantProps<typeof badgeVariants> {
|
|
115
|
+
/** Icon displayed on the left side of the badge text */
|
|
88
116
|
leftIcon?: React.ReactNode
|
|
117
|
+
/** Icon displayed on the right side of the badge text */
|
|
89
118
|
rightIcon?: React.ReactNode
|
|
90
119
|
}
|
|
91
120
|
|
|
@@ -107,199 +136,499 @@ const Badge = React.forwardRef<HTMLDivElement, BadgeProps>(
|
|
|
107
136
|
Badge.displayName = "Badge"
|
|
108
137
|
|
|
109
138
|
export { Badge, badgeVariants }
|
|
110
|
-
`, prefix)
|
|
111
|
-
|
|
139
|
+
`, prefix)
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
"button": {
|
|
144
|
+
name: "button",
|
|
145
|
+
description: "A customizable button component with variants, sizes, and icons",
|
|
146
|
+
dependencies: [
|
|
147
|
+
"@radix-ui/react-slot",
|
|
148
|
+
"class-variance-authority",
|
|
149
|
+
"clsx",
|
|
150
|
+
"tailwind-merge",
|
|
151
|
+
"lucide-react"
|
|
152
|
+
],
|
|
153
|
+
files: [
|
|
154
|
+
{
|
|
155
|
+
name: "button.tsx",
|
|
156
|
+
content: prefixTailwindClasses(`import * as React from "react"
|
|
157
|
+
import { Slot } from "@radix-ui/react-slot"
|
|
112
158
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
159
|
+
import { Loader2 } from "lucide-react"
|
|
113
160
|
|
|
114
161
|
import { cn } from "@/lib/utils"
|
|
115
162
|
|
|
116
|
-
const
|
|
117
|
-
"inline-flex items-center justify-center rounded text-sm transition-colors",
|
|
163
|
+
const buttonVariants = cva(
|
|
164
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
118
165
|
{
|
|
119
166
|
variants: {
|
|
120
167
|
variant: {
|
|
121
|
-
default: "bg-[#
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
168
|
+
default: "bg-[#343E55] text-white hover:bg-[#343E55]/90",
|
|
169
|
+
destructive:
|
|
170
|
+
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
171
|
+
outline:
|
|
172
|
+
"border border-[#343E55] bg-transparent text-[#343E55] hover:bg-[#343E55] hover:text-white",
|
|
173
|
+
secondary:
|
|
174
|
+
"bg-[#343E55]/20 text-[#343E55] hover:bg-[#343E55]/30",
|
|
175
|
+
ghost: "hover:bg-[#343E55]/10 hover:text-[#343E55]",
|
|
176
|
+
link: "text-[#343E55] underline-offset-4 hover:underline",
|
|
127
177
|
},
|
|
128
178
|
size: {
|
|
129
|
-
default: "
|
|
130
|
-
sm: "
|
|
131
|
-
lg: "
|
|
132
|
-
|
|
133
|
-
interactive: {
|
|
134
|
-
true: "cursor-pointer hover:bg-[#E5E7EB] active:bg-[#D1D5DB]",
|
|
135
|
-
false: "",
|
|
136
|
-
},
|
|
137
|
-
selected: {
|
|
138
|
-
true: "ring-2 ring-[#343E55] ring-offset-1",
|
|
139
|
-
false: "",
|
|
179
|
+
default: "py-2.5 px-4",
|
|
180
|
+
sm: "py-2 px-3 text-xs",
|
|
181
|
+
lg: "py-3 px-6",
|
|
182
|
+
icon: "p-2.5",
|
|
140
183
|
},
|
|
141
184
|
},
|
|
142
185
|
defaultVariants: {
|
|
143
186
|
variant: "default",
|
|
144
187
|
size: "default",
|
|
145
|
-
interactive: false,
|
|
146
|
-
selected: false,
|
|
147
188
|
},
|
|
148
189
|
}
|
|
149
190
|
)
|
|
150
191
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Button component for user interactions.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* \`\`\`tsx
|
|
197
|
+
* <Button variant="default" size="default">
|
|
198
|
+
* Click me
|
|
199
|
+
* </Button>
|
|
200
|
+
* \`\`\`
|
|
201
|
+
*/
|
|
202
|
+
export interface ButtonProps
|
|
203
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
204
|
+
VariantProps<typeof buttonVariants> {
|
|
205
|
+
/** Render as child element using Radix Slot */
|
|
206
|
+
asChild?: boolean
|
|
207
|
+
/** Icon displayed on the left side of the button text */
|
|
208
|
+
leftIcon?: React.ReactNode
|
|
209
|
+
/** Icon displayed on the right side of the button text */
|
|
210
|
+
rightIcon?: React.ReactNode
|
|
211
|
+
/** Shows loading spinner and disables button */
|
|
212
|
+
loading?: boolean
|
|
213
|
+
/** Text shown during loading state */
|
|
214
|
+
loadingText?: string
|
|
157
215
|
}
|
|
158
216
|
|
|
159
|
-
const
|
|
160
|
-
({
|
|
217
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
218
|
+
({
|
|
219
|
+
className,
|
|
220
|
+
variant,
|
|
221
|
+
size,
|
|
222
|
+
asChild = false,
|
|
223
|
+
leftIcon,
|
|
224
|
+
rightIcon,
|
|
225
|
+
loading = false,
|
|
226
|
+
loadingText,
|
|
227
|
+
children,
|
|
228
|
+
disabled,
|
|
229
|
+
...props
|
|
230
|
+
}, ref) => {
|
|
231
|
+
const Comp = asChild ? Slot : "button"
|
|
232
|
+
|
|
161
233
|
return (
|
|
162
|
-
<
|
|
163
|
-
className={cn(
|
|
234
|
+
<Comp
|
|
235
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
164
236
|
ref={ref}
|
|
165
|
-
|
|
166
|
-
tabIndex={interactive ? 0 : undefined}
|
|
167
|
-
aria-selected={selected}
|
|
237
|
+
disabled={disabled || loading}
|
|
168
238
|
{...props}
|
|
169
239
|
>
|
|
170
|
-
{
|
|
171
|
-
|
|
240
|
+
{loading ? (
|
|
241
|
+
<>
|
|
242
|
+
<Loader2 className="animate-spin" />
|
|
243
|
+
{loadingText || children}
|
|
244
|
+
</>
|
|
245
|
+
) : (
|
|
246
|
+
<>
|
|
247
|
+
{leftIcon}
|
|
248
|
+
{children}
|
|
249
|
+
{rightIcon}
|
|
250
|
+
</>
|
|
172
251
|
)}
|
|
173
|
-
|
|
174
|
-
</span>
|
|
252
|
+
</Comp>
|
|
175
253
|
)
|
|
176
254
|
}
|
|
177
255
|
)
|
|
178
|
-
|
|
256
|
+
Button.displayName = "Button"
|
|
179
257
|
|
|
180
|
-
export {
|
|
181
|
-
`, prefix)
|
|
182
|
-
|
|
183
|
-
|
|
258
|
+
export { Button, buttonVariants }
|
|
259
|
+
`, prefix)
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
"dropdown-menu": {
|
|
264
|
+
name: "dropdown-menu",
|
|
265
|
+
description: "A dropdown menu component for displaying actions and options",
|
|
266
|
+
dependencies: [
|
|
267
|
+
"@radix-ui/react-dropdown-menu",
|
|
268
|
+
"clsx",
|
|
269
|
+
"tailwind-merge",
|
|
270
|
+
"lucide-react"
|
|
271
|
+
],
|
|
272
|
+
files: [
|
|
273
|
+
{
|
|
274
|
+
name: "dropdown-menu.tsx",
|
|
275
|
+
content: prefixTailwindClasses(`import * as React from "react"
|
|
276
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
|
277
|
+
import { Check, ChevronRight, Circle } from "lucide-react"
|
|
184
278
|
|
|
185
279
|
import { cn } from "@/lib/utils"
|
|
186
280
|
|
|
187
|
-
|
|
188
|
-
* Table size variants for row height.
|
|
189
|
-
*/
|
|
190
|
-
const tableVariants = cva(
|
|
191
|
-
"w-full caption-bottom text-sm",
|
|
192
|
-
{
|
|
193
|
-
variants: {
|
|
194
|
-
size: {
|
|
195
|
-
sm: "[&_td]:py-2 [&_th]:py-2",
|
|
196
|
-
md: "[&_td]:py-3 [&_th]:py-3",
|
|
197
|
-
lg: "[&_td]:py-4 [&_th]:py-4",
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
defaultVariants: {
|
|
201
|
-
size: "md",
|
|
202
|
-
},
|
|
203
|
-
}
|
|
204
|
-
)
|
|
281
|
+
const DropdownMenu = DropdownMenuPrimitive.Root
|
|
205
282
|
|
|
206
|
-
|
|
207
|
-
extends React.HTMLAttributes<HTMLTableElement>,
|
|
208
|
-
VariantProps<typeof tableVariants> {
|
|
209
|
-
/** Remove outer border from the table */
|
|
210
|
-
withoutBorder?: boolean
|
|
211
|
-
}
|
|
283
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
|
212
284
|
|
|
213
|
-
const
|
|
214
|
-
({ className, size, withoutBorder, ...props }, ref) => (
|
|
215
|
-
<div className={cn(
|
|
216
|
-
"relative w-full overflow-auto",
|
|
217
|
-
!withoutBorder && "rounded-lg border border-[#E5E7EB]"
|
|
218
|
-
)}>
|
|
219
|
-
<table
|
|
220
|
-
ref={ref}
|
|
221
|
-
className={cn(tableVariants({ size, className }))}
|
|
222
|
-
{...props}
|
|
223
|
-
/>
|
|
224
|
-
</div>
|
|
225
|
-
)
|
|
226
|
-
)
|
|
227
|
-
Table.displayName = "Table"
|
|
285
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
|
228
286
|
|
|
229
|
-
const
|
|
230
|
-
HTMLTableSectionElement,
|
|
231
|
-
React.HTMLAttributes<HTMLTableSectionElement>
|
|
232
|
-
>(({ className, ...props }, ref) => (
|
|
233
|
-
<thead
|
|
234
|
-
ref={ref}
|
|
235
|
-
className={cn("bg-[#F9FAFB] [&_tr]:border-b", className)}
|
|
236
|
-
{...props}
|
|
237
|
-
/>
|
|
238
|
-
))
|
|
239
|
-
TableHeader.displayName = "TableHeader"
|
|
287
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
|
240
288
|
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
289
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
|
290
|
+
|
|
291
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
|
292
|
+
|
|
293
|
+
const DropdownMenuSubTrigger = React.forwardRef<
|
|
294
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
|
295
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
296
|
+
inset?: boolean
|
|
297
|
+
}
|
|
298
|
+
>(({ className, inset, children, ...props }, ref) => (
|
|
299
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
246
300
|
ref={ref}
|
|
247
|
-
className={cn(
|
|
301
|
+
className={cn(
|
|
302
|
+
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-[#F3F4F6] data-[state=open]:bg-[#F3F4F6]",
|
|
303
|
+
inset && "pl-8",
|
|
304
|
+
className
|
|
305
|
+
)}
|
|
248
306
|
{...props}
|
|
249
|
-
|
|
307
|
+
>
|
|
308
|
+
{children}
|
|
309
|
+
<ChevronRight className="ml-auto h-4 w-4" />
|
|
310
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
250
311
|
))
|
|
251
|
-
|
|
312
|
+
DropdownMenuSubTrigger.displayName =
|
|
313
|
+
DropdownMenuPrimitive.SubTrigger.displayName
|
|
252
314
|
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
React.
|
|
315
|
+
const DropdownMenuSubContent = React.forwardRef<
|
|
316
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
317
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
256
318
|
>(({ className, ...props }, ref) => (
|
|
257
|
-
<
|
|
319
|
+
<DropdownMenuPrimitive.SubContent
|
|
258
320
|
ref={ref}
|
|
259
321
|
className={cn(
|
|
260
|
-
"border-
|
|
322
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-[#E5E7EB] bg-white p-1 text-[#333333] shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
261
323
|
className
|
|
262
324
|
)}
|
|
263
325
|
{...props}
|
|
264
326
|
/>
|
|
265
327
|
))
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
export interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
|
269
|
-
/** Highlight the row with a colored background */
|
|
270
|
-
highlighted?: boolean
|
|
271
|
-
}
|
|
328
|
+
DropdownMenuSubContent.displayName =
|
|
329
|
+
DropdownMenuPrimitive.SubContent.displayName
|
|
272
330
|
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
331
|
+
const DropdownMenuContent = React.forwardRef<
|
|
332
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
333
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
334
|
+
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
335
|
+
<DropdownMenuPrimitive.Portal>
|
|
336
|
+
<DropdownMenuPrimitive.Content
|
|
276
337
|
ref={ref}
|
|
338
|
+
sideOffset={sideOffset}
|
|
277
339
|
className={cn(
|
|
278
|
-
"
|
|
279
|
-
|
|
280
|
-
? "bg-[#EBF5FF]"
|
|
281
|
-
: "hover:bg-[#F9FAFB]/50 data-[state=selected]:bg-[#F3F4F6]",
|
|
340
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-[#E5E7EB] bg-white p-1 text-[#333333] shadow-md",
|
|
341
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
282
342
|
className
|
|
283
343
|
)}
|
|
284
344
|
{...props}
|
|
285
345
|
/>
|
|
286
|
-
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
export interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
|
|
291
|
-
/** Make this column sticky on horizontal scroll */
|
|
292
|
-
sticky?: boolean
|
|
293
|
-
/** Sort direction indicator */
|
|
294
|
-
sortDirection?: 'asc' | 'desc' | null
|
|
295
|
-
/** Show info icon with tooltip */
|
|
296
|
-
infoTooltip?: string
|
|
297
|
-
}
|
|
346
|
+
</DropdownMenuPrimitive.Portal>
|
|
347
|
+
))
|
|
348
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
|
298
349
|
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
350
|
+
const DropdownMenuItem = React.forwardRef<
|
|
351
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
|
352
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
|
353
|
+
inset?: boolean
|
|
354
|
+
}
|
|
355
|
+
>(({ className, inset, ...props }, ref) => (
|
|
356
|
+
<DropdownMenuPrimitive.Item
|
|
357
|
+
ref={ref}
|
|
358
|
+
className={cn(
|
|
359
|
+
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-[#F3F4F6] focus:text-[#333333] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
360
|
+
inset && "pl-8",
|
|
361
|
+
className
|
|
362
|
+
)}
|
|
363
|
+
{...props}
|
|
364
|
+
/>
|
|
365
|
+
))
|
|
366
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
|
367
|
+
|
|
368
|
+
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
369
|
+
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
370
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
371
|
+
>(({ className, children, checked, ...props }, ref) => (
|
|
372
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
373
|
+
ref={ref}
|
|
374
|
+
className={cn(
|
|
375
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[#F3F4F6] focus:text-[#333333] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
376
|
+
className
|
|
377
|
+
)}
|
|
378
|
+
checked={checked}
|
|
379
|
+
{...props}
|
|
380
|
+
>
|
|
381
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
382
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
383
|
+
<Check className="h-4 w-4" />
|
|
384
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
385
|
+
</span>
|
|
386
|
+
{children}
|
|
387
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
388
|
+
))
|
|
389
|
+
DropdownMenuCheckboxItem.displayName =
|
|
390
|
+
DropdownMenuPrimitive.CheckboxItem.displayName
|
|
391
|
+
|
|
392
|
+
const DropdownMenuRadioItem = React.forwardRef<
|
|
393
|
+
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
394
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
395
|
+
>(({ className, children, ...props }, ref) => (
|
|
396
|
+
<DropdownMenuPrimitive.RadioItem
|
|
397
|
+
ref={ref}
|
|
398
|
+
className={cn(
|
|
399
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[#F3F4F6] focus:text-[#333333] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
400
|
+
className
|
|
401
|
+
)}
|
|
402
|
+
{...props}
|
|
403
|
+
>
|
|
404
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
405
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
406
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
407
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
408
|
+
</span>
|
|
409
|
+
{children}
|
|
410
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
411
|
+
))
|
|
412
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
|
|
413
|
+
|
|
414
|
+
const DropdownMenuLabel = React.forwardRef<
|
|
415
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
|
416
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
|
417
|
+
inset?: boolean
|
|
418
|
+
}
|
|
419
|
+
>(({ className, inset, ...props }, ref) => (
|
|
420
|
+
<DropdownMenuPrimitive.Label
|
|
421
|
+
ref={ref}
|
|
422
|
+
className={cn(
|
|
423
|
+
"px-2 py-1.5 text-sm font-semibold",
|
|
424
|
+
inset && "pl-8",
|
|
425
|
+
className
|
|
426
|
+
)}
|
|
427
|
+
{...props}
|
|
428
|
+
/>
|
|
429
|
+
))
|
|
430
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
|
431
|
+
|
|
432
|
+
const DropdownMenuSeparator = React.forwardRef<
|
|
433
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
|
434
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
435
|
+
>(({ className, ...props }, ref) => (
|
|
436
|
+
<DropdownMenuPrimitive.Separator
|
|
437
|
+
ref={ref}
|
|
438
|
+
className={cn("-mx-1 my-1 h-px bg-[#E5E7EB]", className)}
|
|
439
|
+
{...props}
|
|
440
|
+
/>
|
|
441
|
+
))
|
|
442
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
|
443
|
+
|
|
444
|
+
const DropdownMenuShortcut = ({
|
|
445
|
+
className,
|
|
446
|
+
...props
|
|
447
|
+
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
448
|
+
return (
|
|
449
|
+
<span
|
|
450
|
+
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
|
|
451
|
+
{...props}
|
|
452
|
+
/>
|
|
453
|
+
)
|
|
454
|
+
}
|
|
455
|
+
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
|
|
456
|
+
|
|
457
|
+
export {
|
|
458
|
+
DropdownMenu,
|
|
459
|
+
DropdownMenuTrigger,
|
|
460
|
+
DropdownMenuContent,
|
|
461
|
+
DropdownMenuItem,
|
|
462
|
+
DropdownMenuCheckboxItem,
|
|
463
|
+
DropdownMenuRadioItem,
|
|
464
|
+
DropdownMenuLabel,
|
|
465
|
+
DropdownMenuSeparator,
|
|
466
|
+
DropdownMenuShortcut,
|
|
467
|
+
DropdownMenuGroup,
|
|
468
|
+
DropdownMenuPortal,
|
|
469
|
+
DropdownMenuSub,
|
|
470
|
+
DropdownMenuSubContent,
|
|
471
|
+
DropdownMenuSubTrigger,
|
|
472
|
+
DropdownMenuRadioGroup,
|
|
473
|
+
}
|
|
474
|
+
`, prefix)
|
|
475
|
+
}
|
|
476
|
+
]
|
|
477
|
+
},
|
|
478
|
+
"table": {
|
|
479
|
+
name: "table",
|
|
480
|
+
description: "A composable table component with size variants, loading/empty states, sticky columns, and sorting support",
|
|
481
|
+
dependencies: [
|
|
482
|
+
"class-variance-authority",
|
|
483
|
+
"clsx",
|
|
484
|
+
"tailwind-merge"
|
|
485
|
+
],
|
|
486
|
+
files: [
|
|
487
|
+
{
|
|
488
|
+
name: "table.tsx",
|
|
489
|
+
content: prefixTailwindClasses(`import * as React from "react"
|
|
490
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
491
|
+
|
|
492
|
+
import { cn } from "@/lib/utils"
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Table size variants for row height.
|
|
496
|
+
*/
|
|
497
|
+
const tableVariants = cva(
|
|
498
|
+
"w-full caption-bottom text-sm",
|
|
499
|
+
{
|
|
500
|
+
variants: {
|
|
501
|
+
size: {
|
|
502
|
+
sm: "[&_td]:py-2 [&_th]:py-2",
|
|
503
|
+
md: "[&_td]:py-3 [&_th]:py-3",
|
|
504
|
+
lg: "[&_td]:py-4 [&_th]:py-4",
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
defaultVariants: {
|
|
508
|
+
size: "md",
|
|
509
|
+
},
|
|
510
|
+
}
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Table component for displaying tabular data.
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* \`\`\`tsx
|
|
518
|
+
* <Table size="md" withoutBorder>
|
|
519
|
+
* <TableHeader>
|
|
520
|
+
* <TableRow>
|
|
521
|
+
* <TableHead>Name</TableHead>
|
|
522
|
+
* <TableHead>Status</TableHead>
|
|
523
|
+
* </TableRow>
|
|
524
|
+
* </TableHeader>
|
|
525
|
+
* <TableBody>
|
|
526
|
+
* <TableRow>
|
|
527
|
+
* <TableCell>Item 1</TableCell>
|
|
528
|
+
* <TableCell><Badge variant="active">Active</Badge></TableCell>
|
|
529
|
+
* </TableRow>
|
|
530
|
+
* </TableBody>
|
|
531
|
+
* </Table>
|
|
532
|
+
* \`\`\`
|
|
533
|
+
*/
|
|
534
|
+
|
|
535
|
+
export interface TableProps
|
|
536
|
+
extends React.HTMLAttributes<HTMLTableElement>,
|
|
537
|
+
VariantProps<typeof tableVariants> {
|
|
538
|
+
/** Remove outer border from the table */
|
|
539
|
+
withoutBorder?: boolean
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const Table = React.forwardRef<HTMLTableElement, TableProps>(
|
|
543
|
+
({ className, size, withoutBorder, ...props }, ref) => (
|
|
544
|
+
<div className={cn(
|
|
545
|
+
"relative w-full overflow-auto",
|
|
546
|
+
!withoutBorder && "rounded-lg border border-[#E5E7EB]"
|
|
547
|
+
)}>
|
|
548
|
+
<table
|
|
549
|
+
ref={ref}
|
|
550
|
+
className={cn(tableVariants({ size, className }))}
|
|
551
|
+
{...props}
|
|
552
|
+
/>
|
|
553
|
+
</div>
|
|
554
|
+
)
|
|
555
|
+
)
|
|
556
|
+
Table.displayName = "Table"
|
|
557
|
+
|
|
558
|
+
const TableHeader = React.forwardRef<
|
|
559
|
+
HTMLTableSectionElement,
|
|
560
|
+
React.HTMLAttributes<HTMLTableSectionElement>
|
|
561
|
+
>(({ className, ...props }, ref) => (
|
|
562
|
+
<thead
|
|
563
|
+
ref={ref}
|
|
564
|
+
className={cn("bg-[#F9FAFB] [&_tr]:border-b", className)}
|
|
565
|
+
{...props}
|
|
566
|
+
/>
|
|
567
|
+
))
|
|
568
|
+
TableHeader.displayName = "TableHeader"
|
|
569
|
+
|
|
570
|
+
const TableBody = React.forwardRef<
|
|
571
|
+
HTMLTableSectionElement,
|
|
572
|
+
React.HTMLAttributes<HTMLTableSectionElement>
|
|
573
|
+
>(({ className, ...props }, ref) => (
|
|
574
|
+
<tbody
|
|
575
|
+
ref={ref}
|
|
576
|
+
className={cn("[&_tr:last-child]:border-0", className)}
|
|
577
|
+
{...props}
|
|
578
|
+
/>
|
|
579
|
+
))
|
|
580
|
+
TableBody.displayName = "TableBody"
|
|
581
|
+
|
|
582
|
+
const TableFooter = React.forwardRef<
|
|
583
|
+
HTMLTableSectionElement,
|
|
584
|
+
React.HTMLAttributes<HTMLTableSectionElement>
|
|
585
|
+
>(({ className, ...props }, ref) => (
|
|
586
|
+
<tfoot
|
|
587
|
+
ref={ref}
|
|
588
|
+
className={cn(
|
|
589
|
+
"border-t bg-[#F9FAFB] font-medium [&>tr]:last:border-b-0",
|
|
590
|
+
className
|
|
591
|
+
)}
|
|
592
|
+
{...props}
|
|
593
|
+
/>
|
|
594
|
+
))
|
|
595
|
+
TableFooter.displayName = "TableFooter"
|
|
596
|
+
|
|
597
|
+
export interface TableRowProps extends React.HTMLAttributes<HTMLTableRowElement> {
|
|
598
|
+
/** Highlight the row with a colored background */
|
|
599
|
+
highlighted?: boolean
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(
|
|
603
|
+
({ className, highlighted, ...props }, ref) => (
|
|
604
|
+
<tr
|
|
605
|
+
ref={ref}
|
|
606
|
+
className={cn(
|
|
607
|
+
"border-b border-[#E5E7EB] transition-colors",
|
|
608
|
+
highlighted
|
|
609
|
+
? "bg-[#EBF5FF]"
|
|
610
|
+
: "hover:bg-[#F9FAFB]/50 data-[state=selected]:bg-[#F3F4F6]",
|
|
611
|
+
className
|
|
612
|
+
)}
|
|
613
|
+
{...props}
|
|
614
|
+
/>
|
|
615
|
+
)
|
|
616
|
+
)
|
|
617
|
+
TableRow.displayName = "TableRow"
|
|
618
|
+
|
|
619
|
+
export interface TableHeadProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
|
|
620
|
+
/** Make this column sticky on horizontal scroll */
|
|
621
|
+
sticky?: boolean
|
|
622
|
+
/** Sort direction indicator */
|
|
623
|
+
sortDirection?: 'asc' | 'desc' | null
|
|
624
|
+
/** Show info icon with tooltip */
|
|
625
|
+
infoTooltip?: string
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(
|
|
629
|
+
({ className, sticky, sortDirection, infoTooltip, children, ...props }, ref) => (
|
|
630
|
+
<th
|
|
631
|
+
ref={ref}
|
|
303
632
|
className={cn(
|
|
304
633
|
"h-12 px-4 text-left align-middle font-medium text-[#6B7280] text-xs uppercase tracking-wider [&:has([role=checkbox])]:pr-0",
|
|
305
634
|
sticky && "sticky left-0 bg-[#F9FAFB] z-10",
|
|
@@ -437,278 +766,109 @@ export {
|
|
|
437
766
|
TableAvatar,
|
|
438
767
|
tableVariants,
|
|
439
768
|
}
|
|
440
|
-
`, prefix)
|
|
441
|
-
|
|
442
|
-
|
|
769
|
+
`, prefix)
|
|
770
|
+
}
|
|
771
|
+
]
|
|
772
|
+
},
|
|
773
|
+
"tag": {
|
|
774
|
+
name: "tag",
|
|
775
|
+
description: "A tag component for event labels with optional bold label prefix",
|
|
776
|
+
dependencies: [
|
|
777
|
+
"class-variance-authority",
|
|
778
|
+
"clsx",
|
|
779
|
+
"tailwind-merge"
|
|
780
|
+
],
|
|
781
|
+
files: [
|
|
782
|
+
{
|
|
783
|
+
name: "tag.tsx",
|
|
784
|
+
content: prefixTailwindClasses(`import * as React from "react"
|
|
443
785
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
444
|
-
import { Loader2 } from "lucide-react"
|
|
445
786
|
|
|
446
787
|
import { cn } from "@/lib/utils"
|
|
447
788
|
|
|
448
|
-
|
|
449
|
-
|
|
789
|
+
/**
|
|
790
|
+
* Tag variants for event labels and categories.
|
|
791
|
+
* Rounded rectangle tags with optional bold labels.
|
|
792
|
+
*/
|
|
793
|
+
const tagVariants = cva(
|
|
794
|
+
"inline-flex items-center justify-center rounded text-sm transition-colors",
|
|
450
795
|
{
|
|
451
796
|
variants: {
|
|
452
797
|
variant: {
|
|
453
|
-
default: "bg-[#
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
"bg-[#343E55]/20 text-[#343E55] border-0 hover:bg-[#343E55]/30",
|
|
460
|
-
ghost: "border-0 hover:bg-[#343E55]/10 hover:text-[#343E55]",
|
|
461
|
-
link: "text-[#343E55] border-0 underline-offset-4 hover:underline",
|
|
798
|
+
default: "bg-[#F3F4F6] text-[#333333]",
|
|
799
|
+
primary: "bg-[#343E55]/10 text-[#343E55]",
|
|
800
|
+
secondary: "bg-[#E5E7EB] text-[#374151]",
|
|
801
|
+
success: "bg-[#E5FFF5] text-[#00A651]",
|
|
802
|
+
warning: "bg-[#FFF8E5] text-[#F59E0B]",
|
|
803
|
+
error: "bg-[#FFECEC] text-[#FF3B3B]",
|
|
462
804
|
},
|
|
463
805
|
size: {
|
|
464
|
-
default: "
|
|
465
|
-
sm: "
|
|
466
|
-
lg: "
|
|
467
|
-
|
|
806
|
+
default: "px-2 py-1",
|
|
807
|
+
sm: "px-1.5 py-0.5 text-xs",
|
|
808
|
+
lg: "px-3 py-1.5",
|
|
809
|
+
},
|
|
810
|
+
interactive: {
|
|
811
|
+
true: "cursor-pointer hover:bg-[#E5E7EB] active:bg-[#D1D5DB]",
|
|
812
|
+
false: "",
|
|
813
|
+
},
|
|
814
|
+
selected: {
|
|
815
|
+
true: "ring-2 ring-[#343E55] ring-offset-1",
|
|
816
|
+
false: "",
|
|
468
817
|
},
|
|
469
818
|
},
|
|
470
819
|
defaultVariants: {
|
|
471
820
|
variant: "default",
|
|
472
821
|
size: "default",
|
|
822
|
+
interactive: false,
|
|
823
|
+
selected: false,
|
|
473
824
|
},
|
|
474
825
|
}
|
|
475
826
|
)
|
|
476
827
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
828
|
+
/**
|
|
829
|
+
* Tag component for displaying event labels and categories.
|
|
830
|
+
*
|
|
831
|
+
* @example
|
|
832
|
+
* \`\`\`tsx
|
|
833
|
+
* <Tag>After Call Event</Tag>
|
|
834
|
+
* <Tag label="In Call Event:">Start of call, Bridge, Call ended</Tag>
|
|
835
|
+
* <Tag interactive onClick={() => console.log('clicked')}>Clickable</Tag>
|
|
836
|
+
* \`\`\`
|
|
837
|
+
*/
|
|
838
|
+
export interface TagProps
|
|
839
|
+
extends React.HTMLAttributes<HTMLSpanElement>,
|
|
840
|
+
VariantProps<typeof tagVariants> {
|
|
841
|
+
/** Bold label prefix displayed before the content */
|
|
842
|
+
label?: string
|
|
843
|
+
/** Make the tag clickable with hover/active states */
|
|
844
|
+
interactive?: boolean
|
|
845
|
+
/** Show selected state with ring outline */
|
|
846
|
+
selected?: boolean
|
|
485
847
|
}
|
|
486
848
|
|
|
487
|
-
const
|
|
488
|
-
({
|
|
489
|
-
className,
|
|
490
|
-
variant,
|
|
491
|
-
size,
|
|
492
|
-
asChild = false,
|
|
493
|
-
leftIcon,
|
|
494
|
-
rightIcon,
|
|
495
|
-
loading = false,
|
|
496
|
-
loadingText,
|
|
497
|
-
children,
|
|
498
|
-
disabled,
|
|
499
|
-
...props
|
|
500
|
-
}, ref) => {
|
|
501
|
-
const Comp = asChild ? Slot : "button"
|
|
502
|
-
|
|
849
|
+
const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
|
|
850
|
+
({ className, variant, size, interactive, selected, label, children, ...props }, ref) => {
|
|
503
851
|
return (
|
|
504
|
-
<
|
|
505
|
-
className={cn(
|
|
852
|
+
<span
|
|
853
|
+
className={cn(tagVariants({ variant, size, interactive, selected, className }))}
|
|
506
854
|
ref={ref}
|
|
507
|
-
|
|
855
|
+
role={interactive ? "button" : undefined}
|
|
856
|
+
tabIndex={interactive ? 0 : undefined}
|
|
857
|
+
aria-selected={selected}
|
|
508
858
|
{...props}
|
|
509
859
|
>
|
|
510
|
-
{
|
|
511
|
-
|
|
512
|
-
<Loader2 className="animate-spin" />
|
|
513
|
-
{loadingText || children}
|
|
514
|
-
</>
|
|
515
|
-
) : (
|
|
516
|
-
<>
|
|
517
|
-
{leftIcon}
|
|
518
|
-
{children}
|
|
519
|
-
{rightIcon}
|
|
520
|
-
</>
|
|
860
|
+
{label && (
|
|
861
|
+
<span className="font-semibold mr-1">{label}</span>
|
|
521
862
|
)}
|
|
522
|
-
|
|
863
|
+
<span className="font-normal">{children}</span>
|
|
864
|
+
</span>
|
|
523
865
|
)
|
|
524
866
|
}
|
|
525
867
|
)
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
export { Button, buttonVariants }
|
|
529
|
-
`, prefix);
|
|
530
|
-
const dropdownMenuContent = prefixTailwindClasses(`import * as React from "react"
|
|
531
|
-
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
|
532
|
-
import { Check, ChevronRight, Circle } from "lucide-react"
|
|
533
|
-
|
|
534
|
-
import { cn } from "@/lib/utils"
|
|
535
|
-
|
|
536
|
-
const DropdownMenu = DropdownMenuPrimitive.Root
|
|
537
|
-
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
|
538
|
-
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
|
539
|
-
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
|
540
|
-
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
|
541
|
-
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
|
542
|
-
|
|
543
|
-
const DropdownMenuContent = React.forwardRef<
|
|
544
|
-
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
545
|
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
546
|
-
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
547
|
-
<DropdownMenuPrimitive.Portal>
|
|
548
|
-
<DropdownMenuPrimitive.Content
|
|
549
|
-
ref={ref}
|
|
550
|
-
sideOffset={sideOffset}
|
|
551
|
-
className={cn(
|
|
552
|
-
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-[#E5E7EB] bg-white p-1 text-[#333333] shadow-md",
|
|
553
|
-
className
|
|
554
|
-
)}
|
|
555
|
-
{...props}
|
|
556
|
-
/>
|
|
557
|
-
</DropdownMenuPrimitive.Portal>
|
|
558
|
-
))
|
|
559
|
-
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
|
560
|
-
|
|
561
|
-
const DropdownMenuItem = React.forwardRef<
|
|
562
|
-
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
|
563
|
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
|
564
|
-
inset?: boolean
|
|
565
|
-
}
|
|
566
|
-
>(({ className, inset, ...props }, ref) => (
|
|
567
|
-
<DropdownMenuPrimitive.Item
|
|
568
|
-
ref={ref}
|
|
569
|
-
className={cn(
|
|
570
|
-
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-[#F3F4F6] focus:text-[#333333] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
571
|
-
inset && "pl-8",
|
|
572
|
-
className
|
|
573
|
-
)}
|
|
574
|
-
{...props}
|
|
575
|
-
/>
|
|
576
|
-
))
|
|
577
|
-
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
|
578
|
-
|
|
579
|
-
const DropdownMenuLabel = React.forwardRef<
|
|
580
|
-
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
|
581
|
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
|
582
|
-
inset?: boolean
|
|
583
|
-
}
|
|
584
|
-
>(({ className, inset, ...props }, ref) => (
|
|
585
|
-
<DropdownMenuPrimitive.Label
|
|
586
|
-
ref={ref}
|
|
587
|
-
className={cn(
|
|
588
|
-
"px-2 py-1.5 text-sm font-semibold",
|
|
589
|
-
inset && "pl-8",
|
|
590
|
-
className
|
|
591
|
-
)}
|
|
592
|
-
{...props}
|
|
593
|
-
/>
|
|
594
|
-
))
|
|
595
|
-
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
|
596
|
-
|
|
597
|
-
const DropdownMenuSeparator = React.forwardRef<
|
|
598
|
-
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
|
599
|
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
600
|
-
>(({ className, ...props }, ref) => (
|
|
601
|
-
<DropdownMenuPrimitive.Separator
|
|
602
|
-
ref={ref}
|
|
603
|
-
className={cn("-mx-1 my-1 h-px bg-[#E5E7EB]", className)}
|
|
604
|
-
{...props}
|
|
605
|
-
/>
|
|
606
|
-
))
|
|
607
|
-
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
|
608
|
-
|
|
609
|
-
const DropdownMenuShortcut = ({
|
|
610
|
-
className,
|
|
611
|
-
...props
|
|
612
|
-
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
613
|
-
return (
|
|
614
|
-
<span
|
|
615
|
-
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
|
|
616
|
-
{...props}
|
|
617
|
-
/>
|
|
618
|
-
)
|
|
619
|
-
}
|
|
620
|
-
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
|
|
868
|
+
Tag.displayName = "Tag"
|
|
621
869
|
|
|
622
|
-
export {
|
|
623
|
-
|
|
624
|
-
DropdownMenuTrigger,
|
|
625
|
-
DropdownMenuContent,
|
|
626
|
-
DropdownMenuItem,
|
|
627
|
-
DropdownMenuLabel,
|
|
628
|
-
DropdownMenuSeparator,
|
|
629
|
-
DropdownMenuShortcut,
|
|
630
|
-
DropdownMenuGroup,
|
|
631
|
-
DropdownMenuPortal,
|
|
632
|
-
DropdownMenuSub,
|
|
633
|
-
DropdownMenuRadioGroup,
|
|
634
|
-
}
|
|
635
|
-
`, prefix);
|
|
636
|
-
return {
|
|
637
|
-
button: {
|
|
638
|
-
name: "button",
|
|
639
|
-
description: "A customizable button component with variants, sizes, and icons",
|
|
640
|
-
dependencies: [
|
|
641
|
-
"@radix-ui/react-slot",
|
|
642
|
-
"class-variance-authority",
|
|
643
|
-
"clsx",
|
|
644
|
-
"tailwind-merge",
|
|
645
|
-
"lucide-react"
|
|
646
|
-
],
|
|
647
|
-
files: [
|
|
648
|
-
{
|
|
649
|
-
name: "button.tsx",
|
|
650
|
-
content: buttonContent
|
|
651
|
-
}
|
|
652
|
-
]
|
|
653
|
-
},
|
|
654
|
-
badge: {
|
|
655
|
-
name: "badge",
|
|
656
|
-
description: "A status badge component with active, failed, and disabled variants",
|
|
657
|
-
dependencies: [
|
|
658
|
-
"class-variance-authority",
|
|
659
|
-
"clsx",
|
|
660
|
-
"tailwind-merge"
|
|
661
|
-
],
|
|
662
|
-
files: [
|
|
663
|
-
{
|
|
664
|
-
name: "badge.tsx",
|
|
665
|
-
content: badgeContent
|
|
666
|
-
}
|
|
667
|
-
]
|
|
668
|
-
},
|
|
669
|
-
tag: {
|
|
670
|
-
name: "tag",
|
|
671
|
-
description: "A tag component for event labels with optional bold label prefix",
|
|
672
|
-
dependencies: [
|
|
673
|
-
"class-variance-authority",
|
|
674
|
-
"clsx",
|
|
675
|
-
"tailwind-merge"
|
|
676
|
-
],
|
|
677
|
-
files: [
|
|
678
|
-
{
|
|
679
|
-
name: "tag.tsx",
|
|
680
|
-
content: tagContent
|
|
681
|
-
}
|
|
682
|
-
]
|
|
683
|
-
},
|
|
684
|
-
table: {
|
|
685
|
-
name: "table",
|
|
686
|
-
description: "A composable table component with size variants, loading/empty states, sticky columns, and sorting support",
|
|
687
|
-
dependencies: [
|
|
688
|
-
"class-variance-authority",
|
|
689
|
-
"clsx",
|
|
690
|
-
"tailwind-merge"
|
|
691
|
-
],
|
|
692
|
-
files: [
|
|
693
|
-
{
|
|
694
|
-
name: "table.tsx",
|
|
695
|
-
content: tableContent
|
|
696
|
-
}
|
|
697
|
-
]
|
|
698
|
-
},
|
|
699
|
-
"dropdown-menu": {
|
|
700
|
-
name: "dropdown-menu",
|
|
701
|
-
description: "A dropdown menu component for displaying actions and options",
|
|
702
|
-
dependencies: [
|
|
703
|
-
"@radix-ui/react-dropdown-menu",
|
|
704
|
-
"clsx",
|
|
705
|
-
"tailwind-merge",
|
|
706
|
-
"lucide-react"
|
|
707
|
-
],
|
|
708
|
-
files: [
|
|
709
|
-
{
|
|
710
|
-
name: "dropdown-menu.tsx",
|
|
711
|
-
content: dropdownMenuContent
|
|
870
|
+
export { Tag, tagVariants }
|
|
871
|
+
`, prefix)
|
|
712
872
|
}
|
|
713
873
|
]
|
|
714
874
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myoperator-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"description": "CLI for adding myOperator UI components to your project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./dist/index.js",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"
|
|
14
|
+
"generate-registry": "node scripts/generate-registry.js",
|
|
15
|
+
"build": "npm run generate-registry && tsup src/index.ts --format esm --dts",
|
|
15
16
|
"dev": "tsup src/index.ts --format esm --watch",
|
|
16
17
|
"typecheck": "tsc --noEmit"
|
|
17
18
|
},
|