myoperator-mcp 0.2.112 → 0.2.114
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 +660 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -555,7 +555,7 @@ const AlertDescription = React.forwardRef<
|
|
|
555
555
|
HTMLParagraphElement,
|
|
556
556
|
React.HTMLAttributes<HTMLParagraphElement>
|
|
557
557
|
>(({ className, ...props }, ref) => (
|
|
558
|
-
<p ref={ref} className={cn("mt-1 text-sm", className)} {...props} />
|
|
558
|
+
<p ref={ref} className={cn("m-0 mt-1 text-sm", className)} {...props} />
|
|
559
559
|
));
|
|
560
560
|
AlertDescription.displayName = "AlertDescription";
|
|
561
561
|
|
|
@@ -1136,6 +1136,590 @@ const ConfirmationModal = React.forwardRef<
|
|
|
1136
1136
|
ConfirmationModal.displayName = "ConfirmationModal";
|
|
1137
1137
|
|
|
1138
1138
|
export { ConfirmationModal };
|
|
1139
|
+
`,
|
|
1140
|
+
"creatable-multi-select": `import * as React from "react"
|
|
1141
|
+
import { cva } from "class-variance-authority"
|
|
1142
|
+
import { ChevronDown, ChevronRight, Plus, X, Info } from "lucide-react"
|
|
1143
|
+
|
|
1144
|
+
import { cn } from "@/lib/utils"
|
|
1145
|
+
|
|
1146
|
+
const creatableMultiSelectTriggerVariants = cva(
|
|
1147
|
+
"flex items-center gap-2 flex-wrap min-h-[42px] w-full px-4 py-2 rounded bg-semantic-bg-primary cursor-text transition-shadow",
|
|
1148
|
+
{
|
|
1149
|
+
variants: {
|
|
1150
|
+
state: {
|
|
1151
|
+
default:
|
|
1152
|
+
"border border-semantic-border-input hover:border-semantic-border-input-focus",
|
|
1153
|
+
error:
|
|
1154
|
+
"border border-semantic-error-primary/40 hover:border-semantic-error-primary",
|
|
1155
|
+
focused:
|
|
1156
|
+
"border border-semantic-border-focus shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
1157
|
+
"focused-error":
|
|
1158
|
+
"border border-semantic-error-primary/60 shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
|
|
1159
|
+
},
|
|
1160
|
+
},
|
|
1161
|
+
defaultVariants: {
|
|
1162
|
+
state: "default",
|
|
1163
|
+
},
|
|
1164
|
+
}
|
|
1165
|
+
)
|
|
1166
|
+
|
|
1167
|
+
export interface CreatableMultiSelectOption {
|
|
1168
|
+
value: string
|
|
1169
|
+
label: string
|
|
1170
|
+
disabled?: boolean
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
export interface CreatableMultiSelectProps
|
|
1174
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
1175
|
+
/** Currently selected values */
|
|
1176
|
+
value?: string[]
|
|
1177
|
+
/** Callback when values change */
|
|
1178
|
+
onValueChange?: (values: string[]) => void
|
|
1179
|
+
/** Available preset options */
|
|
1180
|
+
options?: CreatableMultiSelectOption[]
|
|
1181
|
+
/** Placeholder when no values selected */
|
|
1182
|
+
placeholder?: string
|
|
1183
|
+
/** Whether the component is disabled */
|
|
1184
|
+
disabled?: boolean
|
|
1185
|
+
/** Error state */
|
|
1186
|
+
state?: "default" | "error"
|
|
1187
|
+
/** Hint text shown at top of dropdown when open */
|
|
1188
|
+
creatableHint?: string
|
|
1189
|
+
/** Helper text shown below the trigger */
|
|
1190
|
+
helperText?: string
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
const CreatableMultiSelect = React.forwardRef<
|
|
1194
|
+
HTMLDivElement,
|
|
1195
|
+
CreatableMultiSelectProps
|
|
1196
|
+
>(
|
|
1197
|
+
(
|
|
1198
|
+
{
|
|
1199
|
+
className,
|
|
1200
|
+
value = [],
|
|
1201
|
+
onValueChange,
|
|
1202
|
+
options = [],
|
|
1203
|
+
placeholder = "Enter or select",
|
|
1204
|
+
disabled = false,
|
|
1205
|
+
state = "default",
|
|
1206
|
+
creatableHint = "Type to create a custom option",
|
|
1207
|
+
helperText,
|
|
1208
|
+
...props
|
|
1209
|
+
},
|
|
1210
|
+
ref
|
|
1211
|
+
) => {
|
|
1212
|
+
const [isOpen, setIsOpen] = React.useState(false)
|
|
1213
|
+
const [inputValue, setInputValue] = React.useState("")
|
|
1214
|
+
const containerRef = React.useRef<HTMLDivElement>(null)
|
|
1215
|
+
const inputRef = React.useRef<HTMLInputElement>(null)
|
|
1216
|
+
|
|
1217
|
+
React.useImperativeHandle(ref, () => containerRef.current!)
|
|
1218
|
+
|
|
1219
|
+
const addValue = React.useCallback(
|
|
1220
|
+
(val: string) => {
|
|
1221
|
+
const trimmed = val.trim()
|
|
1222
|
+
if (trimmed && !value.includes(trimmed)) {
|
|
1223
|
+
onValueChange?.([...value, trimmed])
|
|
1224
|
+
setInputValue("")
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1227
|
+
[value, onValueChange]
|
|
1228
|
+
)
|
|
1229
|
+
|
|
1230
|
+
const removeValue = React.useCallback(
|
|
1231
|
+
(val: string) => {
|
|
1232
|
+
onValueChange?.(value.filter((v) => v !== val))
|
|
1233
|
+
},
|
|
1234
|
+
[value, onValueChange]
|
|
1235
|
+
)
|
|
1236
|
+
|
|
1237
|
+
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
1238
|
+
if (e.key === "Enter") {
|
|
1239
|
+
e.preventDefault()
|
|
1240
|
+
if (inputValue.trim()) addValue(inputValue)
|
|
1241
|
+
} else if (e.key === "Backspace" && !inputValue && value.length > 0) {
|
|
1242
|
+
removeValue(value[value.length - 1])
|
|
1243
|
+
} else if (e.key === "Escape") {
|
|
1244
|
+
setIsOpen(false)
|
|
1245
|
+
setInputValue("")
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// Close on outside click
|
|
1250
|
+
React.useEffect(() => {
|
|
1251
|
+
const handler = (e: MouseEvent) => {
|
|
1252
|
+
if (
|
|
1253
|
+
containerRef.current &&
|
|
1254
|
+
!containerRef.current.contains(e.target as Node)
|
|
1255
|
+
) {
|
|
1256
|
+
setIsOpen(false)
|
|
1257
|
+
setInputValue("")
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
document.addEventListener("mousedown", handler)
|
|
1261
|
+
return () => document.removeEventListener("mousedown", handler)
|
|
1262
|
+
}, [])
|
|
1263
|
+
|
|
1264
|
+
const availablePresets = options.filter(
|
|
1265
|
+
(o) => !value.includes(o.value) && !o.disabled
|
|
1266
|
+
)
|
|
1267
|
+
const filteredPresets = inputValue.trim()
|
|
1268
|
+
? availablePresets.filter((o) =>
|
|
1269
|
+
o.label.toLowerCase().includes(inputValue.trim().toLowerCase())
|
|
1270
|
+
)
|
|
1271
|
+
: availablePresets
|
|
1272
|
+
const canAddCustom =
|
|
1273
|
+
Boolean(inputValue.trim()) && !value.includes(inputValue.trim())
|
|
1274
|
+
|
|
1275
|
+
const triggerState = isOpen
|
|
1276
|
+
? state === "error"
|
|
1277
|
+
? "focused-error"
|
|
1278
|
+
: "focused"
|
|
1279
|
+
: state
|
|
1280
|
+
|
|
1281
|
+
return (
|
|
1282
|
+
<div
|
|
1283
|
+
ref={containerRef}
|
|
1284
|
+
className={cn("relative w-full", className)}
|
|
1285
|
+
{...props}
|
|
1286
|
+
>
|
|
1287
|
+
{/* Trigger */}
|
|
1288
|
+
<div
|
|
1289
|
+
className={cn(
|
|
1290
|
+
creatableMultiSelectTriggerVariants({ state: triggerState }),
|
|
1291
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
1292
|
+
)}
|
|
1293
|
+
onClick={() => {
|
|
1294
|
+
if (disabled) return
|
|
1295
|
+
setIsOpen(true)
|
|
1296
|
+
inputRef.current?.focus()
|
|
1297
|
+
}}
|
|
1298
|
+
>
|
|
1299
|
+
{/* Selected chips */}
|
|
1300
|
+
{value.map((val) => {
|
|
1301
|
+
const optLabel =
|
|
1302
|
+
options.find((o) => o.value === val)?.label || val
|
|
1303
|
+
return (
|
|
1304
|
+
<span
|
|
1305
|
+
key={val}
|
|
1306
|
+
className="inline-flex items-center gap-2 bg-semantic-info-surface px-2 py-1 rounded text-sm text-semantic-text-primary whitespace-nowrap"
|
|
1307
|
+
>
|
|
1308
|
+
{optLabel}
|
|
1309
|
+
<button
|
|
1310
|
+
type="button"
|
|
1311
|
+
onMouseDown={(e) => {
|
|
1312
|
+
e.stopPropagation()
|
|
1313
|
+
e.preventDefault()
|
|
1314
|
+
removeValue(val)
|
|
1315
|
+
}}
|
|
1316
|
+
className="shrink-0 flex items-center justify-center text-semantic-text-muted hover:text-semantic-text-primary transition-colors"
|
|
1317
|
+
aria-label={\`Remove \${optLabel}\`}
|
|
1318
|
+
>
|
|
1319
|
+
<X className="size-2.5" />
|
|
1320
|
+
</button>
|
|
1321
|
+
</span>
|
|
1322
|
+
)
|
|
1323
|
+
})}
|
|
1324
|
+
|
|
1325
|
+
{/* Text input */}
|
|
1326
|
+
<input
|
|
1327
|
+
ref={inputRef}
|
|
1328
|
+
type="text"
|
|
1329
|
+
value={inputValue}
|
|
1330
|
+
onChange={(e) => {
|
|
1331
|
+
setInputValue(e.target.value)
|
|
1332
|
+
if (!isOpen) setIsOpen(true)
|
|
1333
|
+
}}
|
|
1334
|
+
onFocus={() => {
|
|
1335
|
+
if (!disabled) setIsOpen(true)
|
|
1336
|
+
}}
|
|
1337
|
+
onKeyDown={handleKeyDown}
|
|
1338
|
+
disabled={disabled}
|
|
1339
|
+
placeholder={value.length === 0 ? placeholder : ""}
|
|
1340
|
+
className="flex-1 min-w-[100px] text-base bg-transparent outline-none text-semantic-text-primary placeholder:text-semantic-text-muted"
|
|
1341
|
+
role="combobox"
|
|
1342
|
+
aria-expanded={isOpen}
|
|
1343
|
+
aria-haspopup="listbox"
|
|
1344
|
+
/>
|
|
1345
|
+
|
|
1346
|
+
{/* Chevron */}
|
|
1347
|
+
{isOpen ? (
|
|
1348
|
+
<ChevronRight className="size-5 text-semantic-text-muted shrink-0 ml-auto" />
|
|
1349
|
+
) : (
|
|
1350
|
+
<ChevronDown className="size-5 text-semantic-text-muted shrink-0 ml-auto" />
|
|
1351
|
+
)}
|
|
1352
|
+
</div>
|
|
1353
|
+
|
|
1354
|
+
{/* Dropdown panel */}
|
|
1355
|
+
{isOpen && (
|
|
1356
|
+
<div className="absolute z-[9999] top-full mt-1 w-full bg-semantic-bg-primary border border-semantic-border-layout rounded shadow-md animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200">
|
|
1357
|
+
{/* Creatable hint \u2014 contextual */}
|
|
1358
|
+
<div className="flex items-center justify-between px-4 py-2 border-b border-semantic-border-layout">
|
|
1359
|
+
{canAddCustom ? (
|
|
1360
|
+
<span className="text-sm font-medium text-semantic-text-primary">
|
|
1361
|
+
Press enter to add “{inputValue.trim()}”
|
|
1362
|
+
</span>
|
|
1363
|
+
) : (
|
|
1364
|
+
<span className="text-sm text-semantic-text-muted">
|
|
1365
|
+
{creatableHint}
|
|
1366
|
+
</span>
|
|
1367
|
+
)}
|
|
1368
|
+
<kbd className="inline-flex items-center gap-0.5 rounded border border-semantic-border-layout bg-semantic-bg-ui px-1.5 py-0.5 text-[10px] text-semantic-text-muted font-medium">
|
|
1369
|
+
Enter \u21B5
|
|
1370
|
+
</kbd>
|
|
1371
|
+
</div>
|
|
1372
|
+
|
|
1373
|
+
{/* Preset option chips */}
|
|
1374
|
+
{filteredPresets.length > 0 && (
|
|
1375
|
+
<div className="px-2.5 py-2 flex flex-wrap gap-1.5">
|
|
1376
|
+
{filteredPresets.map((option) => (
|
|
1377
|
+
<button
|
|
1378
|
+
key={option.value}
|
|
1379
|
+
type="button"
|
|
1380
|
+
onMouseDown={(e) => {
|
|
1381
|
+
e.preventDefault()
|
|
1382
|
+
addValue(option.value)
|
|
1383
|
+
}}
|
|
1384
|
+
className="inline-flex items-center gap-1.5 bg-semantic-bg-ui px-2.5 py-1.5 rounded text-sm text-semantic-text-primary hover:bg-semantic-bg-hover transition-colors whitespace-nowrap"
|
|
1385
|
+
>
|
|
1386
|
+
<Plus className="size-3 shrink-0 text-semantic-text-muted" />
|
|
1387
|
+
{option.label}
|
|
1388
|
+
</button>
|
|
1389
|
+
))}
|
|
1390
|
+
</div>
|
|
1391
|
+
)}
|
|
1392
|
+
|
|
1393
|
+
</div>
|
|
1394
|
+
)}
|
|
1395
|
+
|
|
1396
|
+
{/* Helper text below trigger */}
|
|
1397
|
+
{helperText && !isOpen && (
|
|
1398
|
+
<div className="flex items-center gap-1.5 mt-1.5">
|
|
1399
|
+
<Info className="size-[18px] shrink-0 text-semantic-text-muted" />
|
|
1400
|
+
<p className="m-0 text-sm text-semantic-text-muted">
|
|
1401
|
+
{helperText}
|
|
1402
|
+
</p>
|
|
1403
|
+
</div>
|
|
1404
|
+
)}
|
|
1405
|
+
</div>
|
|
1406
|
+
)
|
|
1407
|
+
}
|
|
1408
|
+
)
|
|
1409
|
+
CreatableMultiSelect.displayName = "CreatableMultiSelect"
|
|
1410
|
+
|
|
1411
|
+
export { CreatableMultiSelect, creatableMultiSelectTriggerVariants }
|
|
1412
|
+
`,
|
|
1413
|
+
"creatable-select": `import * as React from "react"
|
|
1414
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
1415
|
+
import { ChevronDown, Check } from "lucide-react"
|
|
1416
|
+
|
|
1417
|
+
import { cn } from "@/lib/utils"
|
|
1418
|
+
|
|
1419
|
+
const creatableSelectTriggerVariants = cva(
|
|
1420
|
+
"flex h-[42px] w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
|
|
1421
|
+
{
|
|
1422
|
+
variants: {
|
|
1423
|
+
state: {
|
|
1424
|
+
default:
|
|
1425
|
+
"border border-semantic-border-input focus-within:border-semantic-border-input-focus/50 focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
1426
|
+
error:
|
|
1427
|
+
"border border-semantic-error-primary/40 focus-within:border-semantic-error-primary/60 focus-within:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
|
|
1428
|
+
},
|
|
1429
|
+
},
|
|
1430
|
+
defaultVariants: {
|
|
1431
|
+
state: "default",
|
|
1432
|
+
},
|
|
1433
|
+
}
|
|
1434
|
+
)
|
|
1435
|
+
|
|
1436
|
+
export interface CreatableSelectOption {
|
|
1437
|
+
value: string
|
|
1438
|
+
label: string
|
|
1439
|
+
disabled?: boolean
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
export interface CreatableSelectProps
|
|
1443
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange">,
|
|
1444
|
+
VariantProps<typeof creatableSelectTriggerVariants> {
|
|
1445
|
+
/** Currently selected value */
|
|
1446
|
+
value?: string
|
|
1447
|
+
/** Callback when value changes (selection or creation) */
|
|
1448
|
+
onValueChange?: (value: string) => void
|
|
1449
|
+
/** Available options */
|
|
1450
|
+
options?: CreatableSelectOption[]
|
|
1451
|
+
/** Placeholder when no value selected */
|
|
1452
|
+
placeholder?: string
|
|
1453
|
+
/** Hint text shown above options when dropdown is open */
|
|
1454
|
+
creatableHint?: string
|
|
1455
|
+
/** Whether the select is disabled */
|
|
1456
|
+
disabled?: boolean
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
const CreatableSelect = React.forwardRef<HTMLDivElement, CreatableSelectProps>(
|
|
1460
|
+
(
|
|
1461
|
+
{
|
|
1462
|
+
className,
|
|
1463
|
+
state,
|
|
1464
|
+
value,
|
|
1465
|
+
onValueChange,
|
|
1466
|
+
options = [],
|
|
1467
|
+
placeholder = "Select an option",
|
|
1468
|
+
creatableHint = "Type to create a custom option",
|
|
1469
|
+
disabled = false,
|
|
1470
|
+
...props
|
|
1471
|
+
},
|
|
1472
|
+
ref
|
|
1473
|
+
) => {
|
|
1474
|
+
const [open, setOpen] = React.useState(false)
|
|
1475
|
+
const [search, setSearch] = React.useState("")
|
|
1476
|
+
const [highlightIndex, setHighlightIndex] = React.useState(-1)
|
|
1477
|
+
const containerRef = React.useRef<HTMLDivElement>(null)
|
|
1478
|
+
const inputRef = React.useRef<HTMLInputElement>(null)
|
|
1479
|
+
const listRef = React.useRef<HTMLDivElement>(null)
|
|
1480
|
+
|
|
1481
|
+
// Merge forwarded ref with internal ref
|
|
1482
|
+
React.useImperativeHandle(ref, () => containerRef.current!)
|
|
1483
|
+
|
|
1484
|
+
const selectedLabel = React.useMemo(() => {
|
|
1485
|
+
const found = options.find((o) => o.value === value)
|
|
1486
|
+
return found ? found.label : value || ""
|
|
1487
|
+
}, [options, value])
|
|
1488
|
+
|
|
1489
|
+
const filtered = React.useMemo(() => {
|
|
1490
|
+
if (!search.trim()) return options
|
|
1491
|
+
const q = search.toLowerCase()
|
|
1492
|
+
return options.filter((o) => o.label.toLowerCase().includes(q))
|
|
1493
|
+
}, [options, search])
|
|
1494
|
+
|
|
1495
|
+
const isCustom =
|
|
1496
|
+
search.trim().length > 0 &&
|
|
1497
|
+
!options.some((o) => o.label.toLowerCase() === search.trim().toLowerCase())
|
|
1498
|
+
|
|
1499
|
+
const handleOpen = () => {
|
|
1500
|
+
if (disabled) return
|
|
1501
|
+
setOpen(true)
|
|
1502
|
+
setSearch("")
|
|
1503
|
+
setHighlightIndex(-1)
|
|
1504
|
+
requestAnimationFrame(() => inputRef.current?.focus())
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
const handleSelect = React.useCallback(
|
|
1508
|
+
(val: string) => {
|
|
1509
|
+
onValueChange?.(val)
|
|
1510
|
+
setOpen(false)
|
|
1511
|
+
setSearch("")
|
|
1512
|
+
},
|
|
1513
|
+
[onValueChange]
|
|
1514
|
+
)
|
|
1515
|
+
|
|
1516
|
+
const handleCreate = React.useCallback(() => {
|
|
1517
|
+
const trimmed = search.trim()
|
|
1518
|
+
if (trimmed) {
|
|
1519
|
+
onValueChange?.(trimmed)
|
|
1520
|
+
setOpen(false)
|
|
1521
|
+
setSearch("")
|
|
1522
|
+
}
|
|
1523
|
+
}, [search, onValueChange])
|
|
1524
|
+
|
|
1525
|
+
const handleKeyDown = (e: React.KeyboardEvent) => {
|
|
1526
|
+
if (e.key === "Escape") {
|
|
1527
|
+
e.preventDefault()
|
|
1528
|
+
setOpen(false)
|
|
1529
|
+
return
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
if (e.key === "Enter") {
|
|
1533
|
+
e.preventDefault()
|
|
1534
|
+
if (highlightIndex >= 0 && highlightIndex < filtered.length) {
|
|
1535
|
+
const opt = filtered[highlightIndex]
|
|
1536
|
+
if (!opt.disabled) handleSelect(opt.value)
|
|
1537
|
+
} else if (isCustom) {
|
|
1538
|
+
handleCreate()
|
|
1539
|
+
} else if (filtered.length === 1 && !filtered[0].disabled) {
|
|
1540
|
+
handleSelect(filtered[0].value)
|
|
1541
|
+
}
|
|
1542
|
+
return
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
if (e.key === "ArrowDown") {
|
|
1546
|
+
e.preventDefault()
|
|
1547
|
+
setHighlightIndex((prev) => {
|
|
1548
|
+
const next = prev + 1
|
|
1549
|
+
return next >= filtered.length ? 0 : next
|
|
1550
|
+
})
|
|
1551
|
+
return
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
if (e.key === "ArrowUp") {
|
|
1555
|
+
e.preventDefault()
|
|
1556
|
+
setHighlightIndex((prev) => {
|
|
1557
|
+
const next = prev - 1
|
|
1558
|
+
return next < 0 ? filtered.length - 1 : next
|
|
1559
|
+
})
|
|
1560
|
+
return
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// Scroll highlighted item into view
|
|
1565
|
+
React.useEffect(() => {
|
|
1566
|
+
if (highlightIndex >= 0 && listRef.current) {
|
|
1567
|
+
const item = listRef.current.children[highlightIndex] as HTMLElement
|
|
1568
|
+
item?.scrollIntoView({ block: "nearest" })
|
|
1569
|
+
}
|
|
1570
|
+
}, [highlightIndex])
|
|
1571
|
+
|
|
1572
|
+
// Close on outside click
|
|
1573
|
+
React.useEffect(() => {
|
|
1574
|
+
if (!open) return
|
|
1575
|
+
const handler = (e: MouseEvent) => {
|
|
1576
|
+
if (
|
|
1577
|
+
containerRef.current &&
|
|
1578
|
+
!containerRef.current.contains(e.target as Node)
|
|
1579
|
+
) {
|
|
1580
|
+
setOpen(false)
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
document.addEventListener("mousedown", handler)
|
|
1584
|
+
return () => document.removeEventListener("mousedown", handler)
|
|
1585
|
+
}, [open])
|
|
1586
|
+
|
|
1587
|
+
// Reset highlight when filter changes
|
|
1588
|
+
React.useEffect(() => {
|
|
1589
|
+
setHighlightIndex(-1)
|
|
1590
|
+
}, [search])
|
|
1591
|
+
|
|
1592
|
+
return (
|
|
1593
|
+
<div
|
|
1594
|
+
ref={containerRef}
|
|
1595
|
+
className={cn("relative w-full", className)}
|
|
1596
|
+
{...props}
|
|
1597
|
+
>
|
|
1598
|
+
{/* Trigger / Input */}
|
|
1599
|
+
{open ? (
|
|
1600
|
+
<div
|
|
1601
|
+
className={cn(
|
|
1602
|
+
creatableSelectTriggerVariants({ state }),
|
|
1603
|
+
"cursor-text"
|
|
1604
|
+
)}
|
|
1605
|
+
onClick={() => inputRef.current?.focus()}
|
|
1606
|
+
>
|
|
1607
|
+
<input
|
|
1608
|
+
ref={inputRef}
|
|
1609
|
+
type="text"
|
|
1610
|
+
value={search}
|
|
1611
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
1612
|
+
onKeyDown={handleKeyDown}
|
|
1613
|
+
className="flex-1 min-w-0 bg-transparent outline-none text-base text-semantic-text-primary placeholder:text-semantic-text-muted"
|
|
1614
|
+
placeholder={selectedLabel || placeholder}
|
|
1615
|
+
aria-expanded="true"
|
|
1616
|
+
aria-haspopup="listbox"
|
|
1617
|
+
role="combobox"
|
|
1618
|
+
aria-autocomplete="list"
|
|
1619
|
+
/>
|
|
1620
|
+
<ChevronDown className="size-4 text-semantic-text-muted opacity-70 shrink-0 rotate-180 transition-transform" />
|
|
1621
|
+
</div>
|
|
1622
|
+
) : (
|
|
1623
|
+
<button
|
|
1624
|
+
type="button"
|
|
1625
|
+
onClick={handleOpen}
|
|
1626
|
+
disabled={disabled}
|
|
1627
|
+
className={cn(
|
|
1628
|
+
creatableSelectTriggerVariants({ state }),
|
|
1629
|
+
"cursor-pointer text-left"
|
|
1630
|
+
)}
|
|
1631
|
+
aria-haspopup="listbox"
|
|
1632
|
+
aria-expanded="false"
|
|
1633
|
+
>
|
|
1634
|
+
<span
|
|
1635
|
+
className={cn(
|
|
1636
|
+
"line-clamp-1",
|
|
1637
|
+
!selectedLabel && "text-semantic-text-muted"
|
|
1638
|
+
)}
|
|
1639
|
+
>
|
|
1640
|
+
{selectedLabel || placeholder}
|
|
1641
|
+
</span>
|
|
1642
|
+
<ChevronDown className="size-4 text-semantic-text-muted opacity-70 shrink-0" />
|
|
1643
|
+
</button>
|
|
1644
|
+
)}
|
|
1645
|
+
|
|
1646
|
+
{/* Dropdown */}
|
|
1647
|
+
{open && (
|
|
1648
|
+
<div className="absolute left-0 top-full z-[9999] mt-1 w-full rounded border border-semantic-border-layout bg-semantic-bg-primary shadow-md animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200">
|
|
1649
|
+
{/* Creatable hint */}
|
|
1650
|
+
<div className="flex items-center justify-between px-4 py-2 border-b border-semantic-border-layout">
|
|
1651
|
+
<span className="text-sm text-semantic-text-muted">
|
|
1652
|
+
{creatableHint}
|
|
1653
|
+
</span>
|
|
1654
|
+
<kbd className="inline-flex items-center gap-0.5 rounded border border-semantic-border-layout bg-semantic-bg-ui px-1.5 py-0.5 text-[10px] text-semantic-text-muted font-medium">
|
|
1655
|
+
Enter \u21B5
|
|
1656
|
+
</kbd>
|
|
1657
|
+
</div>
|
|
1658
|
+
|
|
1659
|
+
{/* Options list */}
|
|
1660
|
+
<div
|
|
1661
|
+
ref={listRef}
|
|
1662
|
+
role="listbox"
|
|
1663
|
+
className="max-h-60 overflow-y-auto p-1"
|
|
1664
|
+
>
|
|
1665
|
+
{filtered.length === 0 && !isCustom && (
|
|
1666
|
+
<div className="px-4 py-2 text-sm text-semantic-text-muted">
|
|
1667
|
+
No options found
|
|
1668
|
+
</div>
|
|
1669
|
+
)}
|
|
1670
|
+
{filtered.map((opt, i) => (
|
|
1671
|
+
<button
|
|
1672
|
+
key={opt.value}
|
|
1673
|
+
type="button"
|
|
1674
|
+
role="option"
|
|
1675
|
+
aria-selected={opt.value === value}
|
|
1676
|
+
disabled={opt.disabled}
|
|
1677
|
+
onClick={() => !opt.disabled && handleSelect(opt.value)}
|
|
1678
|
+
onMouseEnter={() => setHighlightIndex(i)}
|
|
1679
|
+
className={cn(
|
|
1680
|
+
"relative flex w-full items-center rounded-sm py-2 pl-4 pr-8 text-base text-semantic-text-primary outline-none cursor-pointer select-none",
|
|
1681
|
+
"hover:bg-semantic-bg-ui",
|
|
1682
|
+
highlightIndex === i && "bg-semantic-bg-ui",
|
|
1683
|
+
opt.disabled &&
|
|
1684
|
+
"pointer-events-none opacity-50 cursor-not-allowed"
|
|
1685
|
+
)}
|
|
1686
|
+
>
|
|
1687
|
+
{opt.label}
|
|
1688
|
+
{opt.value === value && (
|
|
1689
|
+
<span className="absolute right-2 flex size-4 items-center justify-center">
|
|
1690
|
+
<Check className="size-4 text-semantic-brand" />
|
|
1691
|
+
</span>
|
|
1692
|
+
)}
|
|
1693
|
+
</button>
|
|
1694
|
+
))}
|
|
1695
|
+
|
|
1696
|
+
{/* Show custom creation option */}
|
|
1697
|
+
{isCustom && (
|
|
1698
|
+
<button
|
|
1699
|
+
type="button"
|
|
1700
|
+
role="option"
|
|
1701
|
+
aria-selected={false}
|
|
1702
|
+
onClick={handleCreate}
|
|
1703
|
+
onMouseEnter={() => setHighlightIndex(filtered.length)}
|
|
1704
|
+
className={cn(
|
|
1705
|
+
"flex w-full items-center gap-2 rounded-sm py-2 pl-4 pr-8 text-base outline-none cursor-pointer select-none",
|
|
1706
|
+
"text-semantic-text-link hover:bg-semantic-bg-ui",
|
|
1707
|
+
highlightIndex === filtered.length && "bg-semantic-bg-ui"
|
|
1708
|
+
)}
|
|
1709
|
+
>
|
|
1710
|
+
Create “{search.trim()}”
|
|
1711
|
+
</button>
|
|
1712
|
+
)}
|
|
1713
|
+
</div>
|
|
1714
|
+
</div>
|
|
1715
|
+
)}
|
|
1716
|
+
</div>
|
|
1717
|
+
)
|
|
1718
|
+
}
|
|
1719
|
+
)
|
|
1720
|
+
CreatableSelect.displayName = "CreatableSelect"
|
|
1721
|
+
|
|
1722
|
+
export { CreatableSelect, creatableSelectTriggerVariants }
|
|
1139
1723
|
`,
|
|
1140
1724
|
"delete-confirmation-modal": `import * as React from "react";
|
|
1141
1725
|
|
|
@@ -1888,7 +2472,7 @@ import { cn } from "@/lib/utils";
|
|
|
1888
2472
|
* Input variants for different visual states
|
|
1889
2473
|
*/
|
|
1890
2474
|
const inputVariants = cva(
|
|
1891
|
-
"h-
|
|
2475
|
+
"h-[42px] w-full rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-base file:font-medium file:text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
|
|
1892
2476
|
{
|
|
1893
2477
|
variants: {
|
|
1894
2478
|
state: {
|
|
@@ -1982,7 +2566,7 @@ import { cn } from "@/lib/utils";
|
|
|
1982
2566
|
* MultiSelect trigger variants matching TextField styling
|
|
1983
2567
|
*/
|
|
1984
2568
|
const multiSelectTriggerVariants = cva(
|
|
1985
|
-
"flex min-h-
|
|
2569
|
+
"flex min-h-[42px] w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
|
|
1986
2570
|
{
|
|
1987
2571
|
variants: {
|
|
1988
2572
|
state: {
|
|
@@ -2352,7 +2936,7 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
2352
2936
|
disabled={isDisabled}
|
|
2353
2937
|
onClick={() => !isDisabled && toggleOption(option.value)}
|
|
2354
2938
|
className={cn(
|
|
2355
|
-
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-
|
|
2939
|
+
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-base text-semantic-text-primary outline-none",
|
|
2356
2940
|
"hover:bg-semantic-bg-ui focus:bg-semantic-bg-ui",
|
|
2357
2941
|
isSelected && "bg-semantic-bg-ui",
|
|
2358
2942
|
isDisabled && "pointer-events-none opacity-50"
|
|
@@ -2472,6 +3056,8 @@ export interface PageHeaderProps
|
|
|
2472
3056
|
showBackButton?: boolean;
|
|
2473
3057
|
/** Callback when back button is clicked */
|
|
2474
3058
|
onBackClick?: () => void;
|
|
3059
|
+
/** Optional badge/tag displayed next to the title (e.g., status or type indicator) */
|
|
3060
|
+
badge?: React.ReactNode;
|
|
2475
3061
|
/** Optional info icon displayed next to the title (e.g., tooltip trigger) */
|
|
2476
3062
|
infoIcon?: React.ReactNode;
|
|
2477
3063
|
/** Action buttons/elements rendered on the right side */
|
|
@@ -2493,6 +3079,7 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
|
|
|
2493
3079
|
icon,
|
|
2494
3080
|
showBackButton = false,
|
|
2495
3081
|
onBackClick,
|
|
3082
|
+
badge,
|
|
2496
3083
|
infoIcon,
|
|
2497
3084
|
actions,
|
|
2498
3085
|
showBorder = true,
|
|
@@ -2682,6 +3269,9 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
|
|
|
2682
3269
|
<h1 className="m-0 text-lg font-semibold text-semantic-text-primary truncate">
|
|
2683
3270
|
{title}
|
|
2684
3271
|
</h1>
|
|
3272
|
+
{badge && (
|
|
3273
|
+
<span className="flex-shrink-0">{badge}</span>
|
|
3274
|
+
)}
|
|
2685
3275
|
{infoIcon && (
|
|
2686
3276
|
<span className="flex-shrink-0 [&_svg]:w-4 [&_svg]:h-4 text-semantic-text-muted">
|
|
2687
3277
|
{infoIcon}
|
|
@@ -3559,7 +4149,7 @@ import { cn } from "@/lib/utils";
|
|
|
3559
4149
|
* SelectTrigger variants matching TextField styling
|
|
3560
4150
|
*/
|
|
3561
4151
|
const selectTriggerVariants = cva(
|
|
3562
|
-
"flex h-
|
|
4152
|
+
"flex h-[42px] w-full items-center justify-between rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)] [&>span]:line-clamp-1",
|
|
3563
4153
|
{
|
|
3564
4154
|
variants: {
|
|
3565
4155
|
state: {
|
|
@@ -3579,7 +4169,17 @@ const Select = SelectPrimitive.Root;
|
|
|
3579
4169
|
|
|
3580
4170
|
const SelectGroup = SelectPrimitive.Group;
|
|
3581
4171
|
|
|
3582
|
-
const SelectValue =
|
|
4172
|
+
const SelectValue = React.forwardRef<
|
|
4173
|
+
React.ElementRef<typeof SelectPrimitive.Value>,
|
|
4174
|
+
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>
|
|
4175
|
+
>(({ className, ...props }, ref) => (
|
|
4176
|
+
<SelectPrimitive.Value
|
|
4177
|
+
ref={ref}
|
|
4178
|
+
className={cn("[&[data-placeholder]]:text-semantic-text-muted", className)}
|
|
4179
|
+
{...props}
|
|
4180
|
+
/>
|
|
4181
|
+
));
|
|
4182
|
+
SelectValue.displayName = SelectPrimitive.Value.displayName;
|
|
3583
4183
|
|
|
3584
4184
|
export interface SelectTriggerProps
|
|
3585
4185
|
extends
|
|
@@ -3697,7 +4297,7 @@ const SelectItem = React.forwardRef<
|
|
|
3697
4297
|
<SelectPrimitive.Item
|
|
3698
4298
|
ref={ref}
|
|
3699
4299
|
className={cn(
|
|
3700
|
-
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-
|
|
4300
|
+
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-base text-semantic-text-primary outline-none",
|
|
3701
4301
|
"hover:bg-semantic-bg-ui focus:bg-semantic-bg-ui",
|
|
3702
4302
|
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
3703
4303
|
className
|
|
@@ -4588,7 +5188,7 @@ const textFieldContainerVariants = cva(
|
|
|
4588
5188
|
* TextField input variants (standalone without container)
|
|
4589
5189
|
*/
|
|
4590
5190
|
const textFieldInputVariants = cva(
|
|
4591
|
-
"h-
|
|
5191
|
+
"h-[42px] w-full rounded bg-semantic-bg-primary px-4 py-2 text-base text-semantic-text-primary outline-none transition-all file:border-0 file:bg-transparent file:text-base file:font-medium file:text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
|
|
4592
5192
|
{
|
|
4593
5193
|
variants: {
|
|
4594
5194
|
state: {
|
|
@@ -4719,7 +5319,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
4719
5319
|
type={type}
|
|
4720
5320
|
className={cn(
|
|
4721
5321
|
hasAddons
|
|
4722
|
-
? "flex-1 bg-transparent border-0 outline-none focus:ring-0 px-0 h-full text-
|
|
5322
|
+
? "flex-1 bg-transparent border-0 outline-none focus:ring-0 px-0 h-full text-base text-semantic-text-primary placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed"
|
|
4723
5323
|
: textFieldInputVariants({ state: derivedState, className }),
|
|
4724
5324
|
type === "number" &&
|
|
4725
5325
|
"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
|
@@ -4769,7 +5369,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
4769
5369
|
state: derivedState,
|
|
4770
5370
|
disabled: disabled || loading,
|
|
4771
5371
|
}),
|
|
4772
|
-
"h-
|
|
5372
|
+
"h-[42px] px-4",
|
|
4773
5373
|
inputContainerClassName
|
|
4774
5374
|
)}
|
|
4775
5375
|
>
|
|
@@ -4866,19 +5466,19 @@ const ToastViewport = React.forwardRef<
|
|
|
4866
5466
|
ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
|
|
4867
5467
|
|
|
4868
5468
|
const toastVariants = cva(
|
|
4869
|
-
"group pointer-events-auto relative flex w-full items-center justify-between
|
|
5469
|
+
"group pointer-events-auto relative flex w-full items-center justify-between gap-4 overflow-hidden rounded-[5px] border p-3 shadow-md transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
|
|
4870
5470
|
{
|
|
4871
5471
|
variants: {
|
|
4872
5472
|
variant: {
|
|
4873
5473
|
default:
|
|
4874
5474
|
"border-semantic-border-layout bg-semantic-bg-primary text-semantic-text-primary",
|
|
4875
5475
|
success:
|
|
4876
|
-
"border-
|
|
5476
|
+
"border-transparent bg-semantic-success-surface text-semantic-text-primary",
|
|
4877
5477
|
error:
|
|
4878
|
-
"border-
|
|
5478
|
+
"border-transparent bg-semantic-error-surface text-semantic-text-primary",
|
|
4879
5479
|
warning:
|
|
4880
|
-
"border-
|
|
4881
|
-
info: "border-
|
|
5480
|
+
"border-transparent bg-semantic-warning-surface text-semantic-text-primary",
|
|
5481
|
+
info: "border-transparent bg-semantic-info-surface text-semantic-text-primary",
|
|
4882
5482
|
},
|
|
4883
5483
|
},
|
|
4884
5484
|
defaultVariants: {
|
|
@@ -4928,17 +5528,13 @@ const ToastClose = React.forwardRef<
|
|
|
4928
5528
|
<ToastPrimitives.Close
|
|
4929
5529
|
ref={ref}
|
|
4930
5530
|
className={cn(
|
|
4931
|
-
"
|
|
4932
|
-
"group-[.success]:text-semantic-success-hover group-[.success]:hover:text-semantic-success-hover",
|
|
4933
|
-
"group-[.error]:text-semantic-error-hover group-[.error]:hover:text-semantic-error-hover",
|
|
4934
|
-
"group-[.warning]:text-semantic-warning-hover group-[.warning]:hover:text-semantic-warning-hover",
|
|
4935
|
-
"group-[.info]:text-semantic-info-hover group-[.info]:hover:text-semantic-info-hover",
|
|
5531
|
+
"shrink-0 rounded p-0.5 text-semantic-text-muted transition-colors hover:text-semantic-text-primary focus:outline-none focus:ring-2 focus:ring-semantic-border-focus",
|
|
4936
5532
|
className
|
|
4937
5533
|
)}
|
|
4938
5534
|
toast-close=""
|
|
4939
5535
|
{...props}
|
|
4940
5536
|
>
|
|
4941
|
-
<X className="h-
|
|
5537
|
+
<X className="h-3 w-3" />
|
|
4942
5538
|
</ToastPrimitives.Close>
|
|
4943
5539
|
));
|
|
4944
5540
|
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
|
@@ -4949,7 +5545,7 @@ const ToastTitle = React.forwardRef<
|
|
|
4949
5545
|
>(({ className, ...props }, ref) => (
|
|
4950
5546
|
<ToastPrimitives.Title
|
|
4951
5547
|
ref={ref}
|
|
4952
|
-
className={cn("text-sm font-semibold", className)}
|
|
5548
|
+
className={cn("text-sm font-semibold tracking-[0.014px]", className)}
|
|
4953
5549
|
{...props}
|
|
4954
5550
|
/>
|
|
4955
5551
|
));
|
|
@@ -4961,7 +5557,7 @@ const ToastDescription = React.forwardRef<
|
|
|
4961
5557
|
>(({ className, ...props }, ref) => (
|
|
4962
5558
|
<ToastPrimitives.Description
|
|
4963
5559
|
ref={ref}
|
|
4964
|
-
className={cn("text-
|
|
5560
|
+
className={cn("text-xs tracking-[0.048px]", className)}
|
|
4965
5561
|
{...props}
|
|
4966
5562
|
/>
|
|
4967
5563
|
));
|
|
@@ -5240,11 +5836,11 @@ function Toaster() {
|
|
|
5240
5836
|
className={variant ?? undefined}
|
|
5241
5837
|
{...props}
|
|
5242
5838
|
>
|
|
5243
|
-
<div className="flex gap-
|
|
5839
|
+
<div className="flex items-center gap-4">
|
|
5244
5840
|
{Icon && (
|
|
5245
5841
|
<Icon
|
|
5246
5842
|
className={cn(
|
|
5247
|
-
"
|
|
5843
|
+
"size-6 shrink-0",
|
|
5248
5844
|
variant === "success" && "text-semantic-success-primary",
|
|
5249
5845
|
variant === "error" && "text-semantic-error-primary",
|
|
5250
5846
|
variant === "warning" && "text-semantic-warning-primary",
|
|
@@ -5252,7 +5848,7 @@ function Toaster() {
|
|
|
5252
5848
|
)}
|
|
5253
5849
|
/>
|
|
5254
5850
|
)}
|
|
5255
|
-
<div className="
|
|
5851
|
+
<div className="flex flex-col gap-0.5">
|
|
5256
5852
|
{title && <ToastTitle>{title}</ToastTitle>}
|
|
5257
5853
|
{description && (
|
|
5258
5854
|
<ToastDescription>{description}</ToastDescription>
|
|
@@ -5965,6 +6561,44 @@ var componentMetadata = {
|
|
|
5965
6561
|
}
|
|
5966
6562
|
]
|
|
5967
6563
|
},
|
|
6564
|
+
"creatable-multi-select": {
|
|
6565
|
+
"name": "CreatableMultiSelect",
|
|
6566
|
+
"description": "A creatable multi select component.",
|
|
6567
|
+
"dependencies": [
|
|
6568
|
+
"class-variance-authority",
|
|
6569
|
+
"clsx",
|
|
6570
|
+
"tailwind-merge",
|
|
6571
|
+
"lucide-react"
|
|
6572
|
+
],
|
|
6573
|
+
"props": [],
|
|
6574
|
+
"variants": [],
|
|
6575
|
+
"examples": [
|
|
6576
|
+
{
|
|
6577
|
+
"title": "Basic CreatableMultiSelect",
|
|
6578
|
+
"code": "<CreatableMultiSelect>Content</CreatableMultiSelect>",
|
|
6579
|
+
"description": "Simple creatable multi select usage"
|
|
6580
|
+
}
|
|
6581
|
+
]
|
|
6582
|
+
},
|
|
6583
|
+
"creatable-select": {
|
|
6584
|
+
"name": "CreatableSelect",
|
|
6585
|
+
"description": "A creatable select component.",
|
|
6586
|
+
"dependencies": [
|
|
6587
|
+
"class-variance-authority",
|
|
6588
|
+
"clsx",
|
|
6589
|
+
"tailwind-merge",
|
|
6590
|
+
"lucide-react"
|
|
6591
|
+
],
|
|
6592
|
+
"props": [],
|
|
6593
|
+
"variants": [],
|
|
6594
|
+
"examples": [
|
|
6595
|
+
{
|
|
6596
|
+
"title": "Basic CreatableSelect",
|
|
6597
|
+
"code": "<CreatableSelect>Content</CreatableSelect>",
|
|
6598
|
+
"description": "Simple creatable select usage"
|
|
6599
|
+
}
|
|
6600
|
+
]
|
|
6601
|
+
},
|
|
5968
6602
|
"delete-confirmation-modal": {
|
|
5969
6603
|
"name": "DeleteConfirmationModal",
|
|
5970
6604
|
"description": "A delete confirmation modal component.",
|
package/package.json
CHANGED