@kznlabs/labsui 0.1.1 → 0.1.2
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 +540 -344
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2805,6 +2805,7 @@ import {
|
|
|
2805
2805
|
type ComponentProps,
|
|
2806
2806
|
type KeyboardEvent,
|
|
2807
2807
|
type PointerEvent,
|
|
2808
|
+
type ReactNode,
|
|
2808
2809
|
useCallback,
|
|
2809
2810
|
useState,
|
|
2810
2811
|
} from "react";
|
|
@@ -2874,6 +2875,48 @@ function niceTicks(min: number, max: number) {
|
|
|
2874
2875
|
return ticks;
|
|
2875
2876
|
}
|
|
2876
2877
|
|
|
2878
|
+
// Chart and table differ in height: the box springs between them while one fades into the other.
|
|
2879
|
+
// Clips only while it moves, so the tooltip and focus ring can spill out at rest.
|
|
2880
|
+
function ViewSwap({ view, children }: { view: string; children: ReactNode }) {
|
|
2881
|
+
const [height, setHeight] = useState<number>();
|
|
2882
|
+
const [moving, setMoving] = useState(false);
|
|
2883
|
+
|
|
2884
|
+
const measure = useCallback((element: HTMLDivElement | null) => {
|
|
2885
|
+
if (!element) return;
|
|
2886
|
+
|
|
2887
|
+
const observer = new ResizeObserver(() => setHeight(element.offsetHeight));
|
|
2888
|
+
|
|
2889
|
+
observer.observe(element);
|
|
2890
|
+
|
|
2891
|
+
return () => observer.disconnect();
|
|
2892
|
+
}, []);
|
|
2893
|
+
|
|
2894
|
+
return (
|
|
2895
|
+
<motion.div
|
|
2896
|
+
initial={false}
|
|
2897
|
+
animate={{ height: height ?? "auto" }}
|
|
2898
|
+
transition={spring}
|
|
2899
|
+
onAnimationStart={() => setMoving(true)}
|
|
2900
|
+
onAnimationComplete={() => setMoving(false)}
|
|
2901
|
+
className={cn("relative", moving && "overflow-hidden")}
|
|
2902
|
+
>
|
|
2903
|
+
<div ref={measure}>
|
|
2904
|
+
<AnimatePresence mode="popLayout" initial={false}>
|
|
2905
|
+
<motion.div
|
|
2906
|
+
key={view}
|
|
2907
|
+
initial={{ opacity: 0 }}
|
|
2908
|
+
animate={{ opacity: 1 }}
|
|
2909
|
+
exit={{ opacity: 0 }}
|
|
2910
|
+
transition={spring}
|
|
2911
|
+
>
|
|
2912
|
+
{children}
|
|
2913
|
+
</motion.div>
|
|
2914
|
+
</AnimatePresence>
|
|
2915
|
+
</div>
|
|
2916
|
+
</motion.div>
|
|
2917
|
+
);
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2877
2920
|
/**
|
|
2878
2921
|
* 4px rounded data end, square at the baseline. Same path commands every time so motion can morph
|
|
2879
2922
|
* between any two bars (a flat one on mount too).
|
|
@@ -3177,215 +3220,217 @@ export function Chart({
|
|
|
3177
3220
|
</Button>
|
|
3178
3221
|
</div>
|
|
3179
3222
|
|
|
3180
|
-
{view
|
|
3181
|
-
table
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
<
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
{data.map((row, i) =>
|
|
3231
|
-
i % every === 0 ? (
|
|
3232
|
-
<text
|
|
3233
|
-
key={String(row[index])}
|
|
3234
|
-
x={cx(i)}
|
|
3235
|
-
y={height - 8}
|
|
3236
|
-
textAnchor="middle"
|
|
3237
|
-
className="fill-muted-foreground text-[11px]"
|
|
3238
|
-
>
|
|
3239
|
-
{row[index]}
|
|
3240
|
-
</text>
|
|
3241
|
-
) : null,
|
|
3242
|
-
)}
|
|
3243
|
-
|
|
3244
|
-
{active !== null &&
|
|
3245
|
-
(type === "bar" ? (
|
|
3246
|
-
<rect
|
|
3247
|
-
x={cx(active) - band / 2}
|
|
3248
|
-
y={margin.top}
|
|
3249
|
-
width={band}
|
|
3250
|
-
height={plotH}
|
|
3251
|
-
rx={6}
|
|
3252
|
-
className="fill-foreground/[0.04]"
|
|
3253
|
-
/>
|
|
3254
|
-
) : (
|
|
3255
|
-
<line
|
|
3256
|
-
x1={Math.round(cx(active)) + 0.5}
|
|
3257
|
-
x2={Math.round(cx(active)) + 0.5}
|
|
3258
|
-
y1={margin.top}
|
|
3259
|
-
y2={margin.top + plotH}
|
|
3260
|
-
className="stroke-foreground/25"
|
|
3261
|
-
shapeRendering="crispEdges"
|
|
3262
|
-
/>
|
|
3223
|
+
<ViewSwap view={view}>
|
|
3224
|
+
{view === "table" ? (
|
|
3225
|
+
table
|
|
3226
|
+
) : (
|
|
3227
|
+
<>
|
|
3228
|
+
<div
|
|
3229
|
+
ref={box}
|
|
3230
|
+
role="img"
|
|
3231
|
+
aria-roledescription="chart"
|
|
3232
|
+
aria-label={\`\${label}. Arrow keys read values.\`}
|
|
3233
|
+
// biome-ignore lint/a11y/noNoninteractiveTabindex: focus lets arrow keys walk the data
|
|
3234
|
+
tabIndex={0}
|
|
3235
|
+
onKeyDown={onKey}
|
|
3236
|
+
onFocus={(event) => {
|
|
3237
|
+
if (event.currentTarget.matches(":focus-visible") && active === null)
|
|
3238
|
+
setActive(rowCount - 1);
|
|
3239
|
+
}}
|
|
3240
|
+
onBlur={() => setActive(null)}
|
|
3241
|
+
className="relative rounded-lg outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
|
3242
|
+
style={{ height }}
|
|
3243
|
+
>
|
|
3244
|
+
{width > 0 && (
|
|
3245
|
+
// Out of flow, otherwise the fixed-width svg holds the box and the chart can grow but
|
|
3246
|
+
// never shrink.
|
|
3247
|
+
<svg
|
|
3248
|
+
width={width}
|
|
3249
|
+
height={height}
|
|
3250
|
+
aria-hidden="true"
|
|
3251
|
+
className="absolute inset-0 block overflow-visible"
|
|
3252
|
+
>
|
|
3253
|
+
{ticks.map((tick) => (
|
|
3254
|
+
<g key={tick}>
|
|
3255
|
+
<line
|
|
3256
|
+
x1={margin.left}
|
|
3257
|
+
x2={width - margin.right}
|
|
3258
|
+
y1={Math.round(y(tick)) + 0.5}
|
|
3259
|
+
y2={Math.round(y(tick)) + 0.5}
|
|
3260
|
+
className={tick === 0 ? "stroke-foreground/25" : "stroke-border"}
|
|
3261
|
+
shapeRendering="crispEdges"
|
|
3262
|
+
/>
|
|
3263
|
+
<text
|
|
3264
|
+
x={margin.left - 8}
|
|
3265
|
+
y={y(tick)}
|
|
3266
|
+
textAnchor="end"
|
|
3267
|
+
dominantBaseline="middle"
|
|
3268
|
+
className="fill-muted-foreground text-[11px] tabular-nums"
|
|
3269
|
+
>
|
|
3270
|
+
{tickFmt.format(tick)}
|
|
3271
|
+
</text>
|
|
3272
|
+
</g>
|
|
3263
3273
|
))}
|
|
3274
|
+
{data.map((row, i) =>
|
|
3275
|
+
i % every === 0 ? (
|
|
3276
|
+
<text
|
|
3277
|
+
key={String(row[index])}
|
|
3278
|
+
x={cx(i)}
|
|
3279
|
+
y={height - 8}
|
|
3280
|
+
textAnchor="middle"
|
|
3281
|
+
className="fill-muted-foreground text-[11px]"
|
|
3282
|
+
>
|
|
3283
|
+
{row[index]}
|
|
3284
|
+
</text>
|
|
3285
|
+
) : null,
|
|
3286
|
+
)}
|
|
3264
3287
|
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
<
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3288
|
+
{active !== null &&
|
|
3289
|
+
(type === "bar" ? (
|
|
3290
|
+
<rect
|
|
3291
|
+
x={cx(active) - band / 2}
|
|
3292
|
+
y={margin.top}
|
|
3293
|
+
width={band}
|
|
3294
|
+
height={plotH}
|
|
3295
|
+
rx={6}
|
|
3296
|
+
className="fill-foreground/[0.04]"
|
|
3273
3297
|
/>
|
|
3274
|
-
)
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
{
|
|
3301
|
-
|
|
3302
|
-
<motion.
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
animate={{ cx: pts[i][0], cy: pts[i][1] }}
|
|
3298
|
+
) : (
|
|
3299
|
+
<line
|
|
3300
|
+
x1={Math.round(cx(active)) + 0.5}
|
|
3301
|
+
x2={Math.round(cx(active)) + 0.5}
|
|
3302
|
+
y1={margin.top}
|
|
3303
|
+
y2={margin.top + plotH}
|
|
3304
|
+
className="stroke-foreground/25"
|
|
3305
|
+
shapeRendering="crispEdges"
|
|
3306
|
+
/>
|
|
3307
|
+
))}
|
|
3308
|
+
|
|
3309
|
+
{type === "bar"
|
|
3310
|
+
? bars().map((bar) => (
|
|
3311
|
+
<motion.path
|
|
3312
|
+
key={bar.key}
|
|
3313
|
+
initial={{ d: bar.flat }}
|
|
3314
|
+
animate={{ d: bar.d }}
|
|
3315
|
+
transition={spring}
|
|
3316
|
+
fill={bar.fill}
|
|
3317
|
+
/>
|
|
3318
|
+
))
|
|
3319
|
+
: shown.map((item) => {
|
|
3320
|
+
const pts = points(item.key);
|
|
3321
|
+
const fill = color(slots.get(item.key) ?? 1);
|
|
3322
|
+
|
|
3323
|
+
return (
|
|
3324
|
+
<g key={item.key}>
|
|
3325
|
+
{type === "area" && (
|
|
3326
|
+
<motion.path
|
|
3327
|
+
initial={{ d: areaPath(flat(pts)) }}
|
|
3328
|
+
animate={{ d: areaPath(pts) }}
|
|
3306
3329
|
transition={spring}
|
|
3307
|
-
r={4}
|
|
3308
3330
|
fill={fill}
|
|
3309
|
-
|
|
3310
|
-
className="stroke-card"
|
|
3331
|
+
fillOpacity={0.1}
|
|
3311
3332
|
/>
|
|
3312
|
-
)
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3333
|
+
)}
|
|
3334
|
+
<motion.path
|
|
3335
|
+
initial={{ d: linePath(flat(pts)) }}
|
|
3336
|
+
animate={{ d: linePath(pts) }}
|
|
3337
|
+
transition={spring}
|
|
3338
|
+
fill="none"
|
|
3339
|
+
stroke={fill}
|
|
3340
|
+
strokeWidth={2}
|
|
3341
|
+
strokeLinejoin="round"
|
|
3342
|
+
strokeLinecap="round"
|
|
3343
|
+
/>
|
|
3344
|
+
{(active === null ? [rowCount - 1] : [active]).map((i) =>
|
|
3345
|
+
pts[i] ? (
|
|
3346
|
+
<motion.circle
|
|
3347
|
+
key="dot"
|
|
3348
|
+
initial={false}
|
|
3349
|
+
animate={{ cx: pts[i][0], cy: pts[i][1] }}
|
|
3350
|
+
transition={spring}
|
|
3351
|
+
r={4}
|
|
3352
|
+
fill={fill}
|
|
3353
|
+
strokeWidth={2}
|
|
3354
|
+
className="stroke-card"
|
|
3355
|
+
/>
|
|
3356
|
+
) : null,
|
|
3357
|
+
)}
|
|
3358
|
+
</g>
|
|
3359
|
+
);
|
|
3360
|
+
})}
|
|
3361
|
+
|
|
3362
|
+
{endsFit &&
|
|
3363
|
+
ends.map((end) => (
|
|
3364
|
+
<text
|
|
3365
|
+
key={end.s.key}
|
|
3366
|
+
x={cx(rowCount - 1) + 10}
|
|
3367
|
+
y={end.y}
|
|
3368
|
+
dominantBaseline="middle"
|
|
3369
|
+
className="fill-muted-foreground text-[11px]"
|
|
3370
|
+
>
|
|
3371
|
+
{end.s.label}
|
|
3372
|
+
</text>
|
|
3373
|
+
))}
|
|
3330
3374
|
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3375
|
+
{/* Hit layer: the whole band answers, not just the painted mark. */}
|
|
3376
|
+
<rect
|
|
3377
|
+
x={margin.left}
|
|
3378
|
+
y={0}
|
|
3379
|
+
width={plotW}
|
|
3380
|
+
height={height}
|
|
3381
|
+
fill="transparent"
|
|
3382
|
+
onPointerMove={pick}
|
|
3383
|
+
onPointerLeave={() => setActive(null)}
|
|
3384
|
+
/>
|
|
3385
|
+
</svg>
|
|
3386
|
+
)}
|
|
3343
3387
|
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
>
|
|
3355
|
-
<div
|
|
3356
|
-
className={cn(
|
|
3357
|
-
"min-w-36 rounded-lg border px-2.5 py-2 text-popover-foreground text-xs shadow-md",
|
|
3358
|
-
material,
|
|
3359
|
-
flip ? "-translate-x-full -ml-3" : "ml-3",
|
|
3360
|
-
)}
|
|
3388
|
+
<AnimatePresence>
|
|
3389
|
+
{row && active !== null && (
|
|
3390
|
+
<motion.div
|
|
3391
|
+
key="tip"
|
|
3392
|
+
aria-hidden="true"
|
|
3393
|
+
initial={{ opacity: 0, x: cx(active), y: margin.top }}
|
|
3394
|
+
animate={{ opacity: 1, x: cx(active), y: margin.top }}
|
|
3395
|
+
exit={{ opacity: 0 }}
|
|
3396
|
+
transition={spring}
|
|
3397
|
+
className="pointer-events-none absolute top-0 left-0 z-10"
|
|
3361
3398
|
>
|
|
3362
|
-
<
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3399
|
+
<div
|
|
3400
|
+
className={cn(
|
|
3401
|
+
"min-w-36 rounded-lg border px-2.5 py-2 text-popover-foreground text-xs shadow-md",
|
|
3402
|
+
material,
|
|
3403
|
+
flip ? "-translate-x-full -ml-3" : "ml-3",
|
|
3404
|
+
)}
|
|
3405
|
+
>
|
|
3406
|
+
<p className="mb-1.5 text-muted-foreground">{row[index]}</p>
|
|
3407
|
+
<ul className="grid gap-1">
|
|
3408
|
+
{shown.map((item) => (
|
|
3409
|
+
<li key={item.key} className="flex items-center gap-2">
|
|
3410
|
+
<span
|
|
3411
|
+
className="h-0.5 w-2.5 shrink-0 rounded-full"
|
|
3412
|
+
style={{ background: color(slots.get(item.key) ?? 1) }}
|
|
3413
|
+
/>
|
|
3414
|
+
<span className="text-muted-foreground">{item.label}</span>
|
|
3415
|
+
<span className="ml-auto pl-3 font-medium tabular-nums">
|
|
3416
|
+
{fmt.format(num(row[item.key]))}
|
|
3417
|
+
</span>
|
|
3418
|
+
</li>
|
|
3419
|
+
))}
|
|
3420
|
+
</ul>
|
|
3421
|
+
</div>
|
|
3422
|
+
</motion.div>
|
|
3423
|
+
)}
|
|
3424
|
+
</AnimatePresence>
|
|
3425
|
+
</div>
|
|
3426
|
+
<p className="sr-only" aria-live="polite">
|
|
3427
|
+
{readout}
|
|
3428
|
+
</p>
|
|
3429
|
+
{/* The same numbers for screen readers, search engines and no-JS. */}
|
|
3430
|
+
<div className="sr-only">{table}</div>
|
|
3431
|
+
</>
|
|
3432
|
+
)}
|
|
3433
|
+
</ViewSwap>
|
|
3389
3434
|
</figure>
|
|
3390
3435
|
);
|
|
3391
3436
|
}
|
|
@@ -4004,7 +4049,7 @@ function CodeLines({
|
|
|
4004
4049
|
</span>
|
|
4005
4050
|
)}
|
|
4006
4051
|
{note ? (
|
|
4007
|
-
<Tooltip content={note} side="top" align="start" delay={150}>
|
|
4052
|
+
<Tooltip content={note} side="top" align="start" delay={150} touch="tap">
|
|
4008
4053
|
<span
|
|
4009
4054
|
// biome-ignore lint/a11y/noNoninteractiveTabindex: lets keyboard users reach the note
|
|
4010
4055
|
tabIndex={0}
|
|
@@ -4980,9 +5025,14 @@ export function CommandItem({
|
|
|
4980
5025
|
data-value={value}
|
|
4981
5026
|
aria-selected={selected}
|
|
4982
5027
|
aria-disabled={disabled || undefined}
|
|
4983
|
-
|
|
5028
|
+
// A finger moves across options while scrolling the list; only a tap should pick one.
|
|
5029
|
+
onPointerMove={(event) =>
|
|
5030
|
+
event.pointerType !== "touch" && !disabled && !selected && setActive(value)
|
|
5031
|
+
}
|
|
4984
5032
|
onClick={() => {
|
|
4985
5033
|
if (disabled) return;
|
|
5034
|
+
|
|
5035
|
+
setActive(value);
|
|
4986
5036
|
onSelect?.(value);
|
|
4987
5037
|
if (!keepOpen) close?.();
|
|
4988
5038
|
}}
|
|
@@ -5591,7 +5641,7 @@ export function MembersDataTable({
|
|
|
5591
5641
|
}` }], api: { entries: [{ kind: "component", name: "DataTable", props: [{ name: "columns", type: "DataTableColumn<T>[]", required: true, description: "Column definitions in display order." }, { name: "data", type: "T[]", required: true, description: "Rows; search, sort and paging happen on the client." }, { name: "getRowId", type: "(row: T) => string", required: true, description: "Stable id per row; selection is kept by it across pages." }, { name: "label", type: "string", required: true, description: `Names the table, the search box and each row's controls: "Members", "Select Jane".` }, { name: "rowLabel", type: "(row: T) => string", required: true, description: "Row name for screen readers, e.g. on its checkbox and ⋯ menu." }, { name: "defaultSort", type: "Sort", required: false, description: "Sort at first render." }, { name: "onSelectionChange", type: "(ids: string[]) => void", required: false, description: "Called with every selected row id." }, { name: "pageSize", type: "number", required: false, default: "10", description: "Rows per page." }, { name: "rowActions", type: "(row: T) => ReactNode", required: false, description: "Items for the row's ⋯ menu (DropdownMenuItem and friends)." }, { name: "searchable", type: "boolean", required: false, default: "true", description: "Show a search field that filters every column." }, { name: "searchPlaceholder", type: "string", required: false, default: '"Search…"', description: "Search field placeholder." }, { name: "selectable", type: "boolean", required: false, default: "false", description: "Checkbox column; selection survives search and paging." }, { name: "selection", type: "string[]", required: false, description: "Controlled selected row ids; pair with `onSelectionChange`." }, { name: "striped", type: "boolean", required: false, default: "false", description: "Alternate row backgrounds." }, { name: "toolbar", type: "(selected: T[]) => ReactNode", required: false, description: "Right side of the toolbar; receives the selected rows (bulk actions)." }], description: "Table with search, sortable columns, row selection, row actions and pagination, all on the\nclient. Columns are data: `{ id, header, accessor, cell?, sortable? }`. For server-driven\ndata, compose Table + Pagination yourself." }], types: { Sort: '{ id: string; dir: "ascending" | "descending" }', DataTableColumn: "{ id: string; header: ReactNode; accessor?: (row: T) => string | number; cell?: (row: T) => ReactNode; sortable?: boolean; className?: string; }" } }, dependencies: ["lucide-react@1.63.0"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/button.json", "https://kznlabs.github.io/labsUI/r/checkbox.json", "https://kznlabs.github.io/labsUI/r/dropdown-menu.json", "https://kznlabs.github.io/labsUI/r/empty.json", "https://kznlabs.github.io/labsUI/r/pagination.json", "https://kznlabs.github.io/labsUI/r/search-input.json", "https://kznlabs.github.io/labsUI/r/table.json", "https://kznlabs.github.io/labsUI/r/use-controllable-state.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/ui/data-table.tsx", type: "registry:ui", content: `"use client";
|
|
5592
5642
|
|
|
5593
5643
|
import { MoreHorizontal, SearchX } from "lucide-react";
|
|
5594
|
-
import { type ReactNode, useState } from "react";
|
|
5644
|
+
import { type ReactNode, useLayoutEffect, useRef, useState } from "react";
|
|
5595
5645
|
import { Button } from "@/components/ui/button";
|
|
5596
5646
|
import { Checkbox } from "@/components/ui/checkbox";
|
|
5597
5647
|
import {
|
|
@@ -5726,6 +5776,36 @@ export function DataTable<T>({
|
|
|
5726
5776
|
const allHere = filteredIds.length > 0 && selectedHere.length === filteredIds.length;
|
|
5727
5777
|
const span = columns.length + (selectable ? 1 : 0) + (rowActions ? 1 : 0);
|
|
5728
5778
|
|
|
5779
|
+
// Paging never makes the table shorter than the tallest page so far, so the footer stays put
|
|
5780
|
+
// (a short last page would pull the pagination up under your finger).
|
|
5781
|
+
const box = useRef<HTMLDivElement>(null);
|
|
5782
|
+
const layoutKey = \`\${query}|\${pageSize}|\${data.length}\`;
|
|
5783
|
+
const [tallest, setTallest] = useState({ key: "", height: 0 });
|
|
5784
|
+
const minHeight = tallest.key === layoutKey ? tallest.height : undefined;
|
|
5785
|
+
|
|
5786
|
+
useLayoutEffect(() => {
|
|
5787
|
+
const table = box.current?.firstElementChild as HTMLElement | null;
|
|
5788
|
+
|
|
5789
|
+
if (!table) return;
|
|
5790
|
+
|
|
5791
|
+
const observer = new ResizeObserver(() => {
|
|
5792
|
+
const height = table.offsetHeight;
|
|
5793
|
+
|
|
5794
|
+
setTallest((current) =>
|
|
5795
|
+
current.key === layoutKey && current.height >= height
|
|
5796
|
+
? current
|
|
5797
|
+
: {
|
|
5798
|
+
key: layoutKey,
|
|
5799
|
+
height: current.key === layoutKey ? Math.max(current.height, height) : height,
|
|
5800
|
+
},
|
|
5801
|
+
);
|
|
5802
|
+
});
|
|
5803
|
+
|
|
5804
|
+
observer.observe(table);
|
|
5805
|
+
|
|
5806
|
+
return () => observer.disconnect();
|
|
5807
|
+
}, [layoutKey]);
|
|
5808
|
+
|
|
5729
5809
|
return (
|
|
5730
5810
|
<div className={cn("grid w-full grid-cols-1 gap-3", className)}>
|
|
5731
5811
|
{(searchable || toolbar) && (
|
|
@@ -5750,119 +5830,122 @@ export function DataTable<T>({
|
|
|
5750
5830
|
</div>
|
|
5751
5831
|
)}
|
|
5752
5832
|
|
|
5753
|
-
<
|
|
5754
|
-
<
|
|
5755
|
-
<
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
<
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
/>
|
|
5771
|
-
</TableHead>
|
|
5772
|
-
)}
|
|
5773
|
-
{columns.map((column) => (
|
|
5774
|
-
<TableHead
|
|
5775
|
-
key={column.id}
|
|
5776
|
-
className={column.className}
|
|
5777
|
-
{...(column.sortable && column.accessor
|
|
5778
|
-
? {
|
|
5779
|
-
sort: sort?.id === column.id ? sort.dir : "none",
|
|
5780
|
-
onSort: () => {
|
|
5781
|
-
setSort((current) => ({
|
|
5782
|
-
id: column.id,
|
|
5783
|
-
dir:
|
|
5784
|
-
current?.id === column.id && current.dir === "ascending"
|
|
5785
|
-
? "descending"
|
|
5786
|
-
: "ascending",
|
|
5787
|
-
}));
|
|
5788
|
-
setPage(1);
|
|
5789
|
-
},
|
|
5833
|
+
<div ref={box} style={{ minHeight }}>
|
|
5834
|
+
<Table striped={striped} aria-label={label}>
|
|
5835
|
+
<TableHeader>
|
|
5836
|
+
<TableRow>
|
|
5837
|
+
{selectable && (
|
|
5838
|
+
<TableHead>
|
|
5839
|
+
<Checkbox
|
|
5840
|
+
aria-label={\`Select all \${sorted.length} \${label.toLowerCase()}\`}
|
|
5841
|
+
checked={allHere}
|
|
5842
|
+
indeterminate={selectedHere.length > 0 && !allHere}
|
|
5843
|
+
disabled={sorted.length === 0}
|
|
5844
|
+
onCheckedChange={(on) =>
|
|
5845
|
+
select(
|
|
5846
|
+
on
|
|
5847
|
+
? [...new Set([...selected, ...filteredIds])]
|
|
5848
|
+
: selected.filter((id) => !filteredIds.includes(id)),
|
|
5849
|
+
)
|
|
5790
5850
|
}
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5851
|
+
/>
|
|
5852
|
+
</TableHead>
|
|
5853
|
+
)}
|
|
5854
|
+
{columns.map((column) => (
|
|
5855
|
+
<TableHead
|
|
5856
|
+
key={column.id}
|
|
5857
|
+
className={column.className}
|
|
5858
|
+
{...(column.sortable && column.accessor
|
|
5859
|
+
? {
|
|
5860
|
+
sort: sort?.id === column.id ? sort.dir : "none",
|
|
5861
|
+
onSort: () => {
|
|
5862
|
+
setSort((current) => ({
|
|
5863
|
+
id: column.id,
|
|
5864
|
+
dir:
|
|
5865
|
+
current?.id === column.id && current.dir === "ascending"
|
|
5866
|
+
? "descending"
|
|
5867
|
+
: "ascending",
|
|
5868
|
+
}));
|
|
5869
|
+
setPage(1);
|
|
5870
|
+
},
|
|
5871
|
+
}
|
|
5872
|
+
: {})}
|
|
5811
5873
|
>
|
|
5812
|
-
{
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5874
|
+
{column.header}
|
|
5875
|
+
</TableHead>
|
|
5876
|
+
))}
|
|
5877
|
+
{rowActions && (
|
|
5878
|
+
<TableHead className="w-px">
|
|
5879
|
+
<span className="sr-only">Actions</span>
|
|
5880
|
+
</TableHead>
|
|
5881
|
+
)}
|
|
5819
5882
|
</TableRow>
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5883
|
+
</TableHeader>
|
|
5884
|
+
<TableBody>
|
|
5885
|
+
{rows.length === 0 ? (
|
|
5886
|
+
<TableRow className="hover:bg-transparent">
|
|
5887
|
+
<TableCell colSpan={span}>
|
|
5888
|
+
<Empty
|
|
5889
|
+
icon={<SearchX />}
|
|
5890
|
+
title={needle ? "No matches" : \`No \${label.toLowerCase()} yet\`}
|
|
5891
|
+
description={needle ? \`Nothing matches “\${query.trim()}”.\` : undefined}
|
|
5892
|
+
>
|
|
5893
|
+
{needle && (
|
|
5894
|
+
<Button size="sm" variant="outline" onClick={() => setQuery("")}>
|
|
5895
|
+
Clear search
|
|
5896
|
+
</Button>
|
|
5897
|
+
)}
|
|
5898
|
+
</Empty>
|
|
5899
|
+
</TableCell>
|
|
5900
|
+
</TableRow>
|
|
5901
|
+
) : (
|
|
5902
|
+
rows.map((row) => {
|
|
5903
|
+
const id = getRowId(row);
|
|
5904
|
+
const on = selected.includes(id);
|
|
5905
|
+
|
|
5906
|
+
return (
|
|
5907
|
+
<TableRow key={id} data-state={on ? "selected" : undefined}>
|
|
5908
|
+
{selectable && (
|
|
5909
|
+
<TableCell>
|
|
5910
|
+
<Checkbox
|
|
5911
|
+
aria-label={\`Select \${rowLabel(row)}\`}
|
|
5912
|
+
checked={on}
|
|
5913
|
+
onCheckedChange={(column) =>
|
|
5914
|
+
select(column ? [...selected, id] : selected.filter((x) => x !== id))
|
|
5915
|
+
}
|
|
5916
|
+
/>
|
|
5917
|
+
</TableCell>
|
|
5918
|
+
)}
|
|
5919
|
+
{columns.map((column) => (
|
|
5920
|
+
<TableCell key={column.id} className={column.className}>
|
|
5921
|
+
{column.cell ? column.cell(row) : column.accessor?.(row)}
|
|
5922
|
+
</TableCell>
|
|
5923
|
+
))}
|
|
5924
|
+
{rowActions && (
|
|
5925
|
+
<TableCell className="py-1 pr-2">
|
|
5926
|
+
<DropdownMenu>
|
|
5927
|
+
<DropdownMenuTrigger
|
|
5928
|
+
variant="ghost"
|
|
5929
|
+
size="icon"
|
|
5930
|
+
aria-label={\`Actions for \${rowLabel(row)}\`}
|
|
5931
|
+
className="size-8"
|
|
5932
|
+
>
|
|
5933
|
+
<MoreHorizontal />
|
|
5934
|
+
</DropdownMenuTrigger>
|
|
5935
|
+
<DropdownMenuContent align="end">{rowActions(row)}</DropdownMenuContent>
|
|
5936
|
+
</DropdownMenu>
|
|
5937
|
+
</TableCell>
|
|
5938
|
+
)}
|
|
5939
|
+
</TableRow>
|
|
5940
|
+
);
|
|
5941
|
+
})
|
|
5942
|
+
)}
|
|
5943
|
+
</TableBody>
|
|
5944
|
+
</Table>
|
|
5945
|
+
</div>
|
|
5864
5946
|
|
|
5865
|
-
|
|
5947
|
+
{/* Stacked on phones: side by side, a longer count (13–18 of 27) would push the pages to a new line. */}
|
|
5948
|
+
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
|
5866
5949
|
<p className="text-muted-foreground text-xs tabular-nums" aria-live="polite">
|
|
5867
5950
|
{selectable && selected.length > 0 && \`\${selected.length} selected · \`}
|
|
5868
5951
|
{sorted.length === 0
|
|
@@ -6042,9 +6125,13 @@ export function DatePicker(allProps: DatePickerProps) {
|
|
|
6042
6125
|
<CalendarDays />
|
|
6043
6126
|
<span className="truncate">{label ?? placeholder}</span>
|
|
6044
6127
|
</PopoverTrigger>
|
|
6045
|
-
<PopoverContent align="start" className="flex w-auto gap-3 p-3">
|
|
6128
|
+
<PopoverContent align="start" className="flex w-auto flex-col gap-3 p-3 sm:flex-row">
|
|
6046
6129
|
{presets && presets.length > 0 && (
|
|
6047
|
-
|
|
6130
|
+
// A row above the calendar on phones: a column beside it would not fit the screen.
|
|
6131
|
+
<ul
|
|
6132
|
+
className="flex flex-wrap gap-1.5 border-b pb-3 sm:min-w-32 sm:flex-col sm:flex-nowrap sm:gap-0.5 sm:border-r sm:border-b-0 sm:pr-3 sm:pb-0"
|
|
6133
|
+
aria-label="Presets"
|
|
6134
|
+
>
|
|
6048
6135
|
{presets.map((preset) => (
|
|
6049
6136
|
<li key={preset.label}>
|
|
6050
6137
|
<button
|
|
@@ -6053,7 +6140,7 @@ export function DatePicker(allProps: DatePickerProps) {
|
|
|
6053
6140
|
setShown((count) => count + 1);
|
|
6054
6141
|
commit(preset.value);
|
|
6055
6142
|
}}
|
|
6056
|
-
className="w-full cursor-default rounded-md px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
|
6143
|
+
className="min-h-6 w-full cursor-default rounded-md px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50 max-sm:rounded-full max-sm:border max-sm:px-2.5 max-sm:py-1 max-sm:text-xs"
|
|
6057
6144
|
>
|
|
6058
6145
|
{preset.label}
|
|
6059
6146
|
</button>
|
|
@@ -7372,13 +7459,15 @@ export function UserMention({ name, handle }: { name: string; handle: string })
|
|
|
7372
7459
|
<a href={"/u/" + handle}>@{handle}</a>
|
|
7373
7460
|
</HoverCard>
|
|
7374
7461
|
);
|
|
7375
|
-
}` }], api: { entries: [{ kind: "component", name: "HoverCard", props: [{ name: "children", type: "ReactNode", required: true, description: "Usually a link (profile, product, clip)." }, { name: "content", type: "ReactNode", required: true, description: "Rich preview: avatar, bio, stats. Supplementary only; the trigger must work without it." }, { name: "align", type: '"start" | "center" | "end"', required: false, default: '"center"', description: "Alignment with the trigger." }, { name: "closeDelay", type: "number", required: false, default: "200", description: "Time in ms before it closes once the pointer leaves." }, { name: "openDelay", type: "number", required: false, default: "600", description: "Hover or focus time in ms before it opens." }, { name: "side", type: '"top" | "bottom"', required: false, default: '"bottom"', description: "Preferred side; flips when there is no room." }], description:
|
|
7462
|
+
}` }], api: { entries: [{ kind: "component", name: "HoverCard", props: [{ name: "children", type: "ReactNode", required: true, description: "Usually a link (profile, product, clip)." }, { name: "content", type: "ReactNode", required: true, description: "Rich preview: avatar, bio, stats. Supplementary only; the trigger must work without it." }, { name: "align", type: '"start" | "center" | "end"', required: false, default: '"center"', description: "Alignment with the trigger." }, { name: "closeDelay", type: "number", required: false, default: "200", description: "Time in ms before it closes once the pointer leaves." }, { name: "openDelay", type: "number", required: false, default: "600", description: "Hover or focus time in ms before it opens." }, { name: "side", type: '"top" | "bottom"', required: false, default: '"bottom"', description: "Preferred side; flips when there is no room." }], description: `Preview card on hover or keyboard focus; the pointer can move into it. On touch the first tap
|
|
7463
|
+
on the trigger opens the card instead of acting, a second tap acts, a tap outside closes it.` }], types: {} }, dependencies: ["motion@14.7.1"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/platform.json", "https://kznlabs.github.io/labsUI/r/use-anchor.json", "https://kznlabs.github.io/labsUI/r/use-dismiss.json", "https://kznlabs.github.io/labsUI/r/use-hover-open.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/ui/hover-card.tsx", type: "registry:ui", content: `"use client";
|
|
7376
7464
|
|
|
7377
7465
|
import { AnimatePresence, motion } from "motion/react";
|
|
7378
|
-
import { type ReactNode, useRef } from "react";
|
|
7466
|
+
import { type FocusEvent, type MouseEvent, type PointerEvent, type ReactNode, useRef } from "react";
|
|
7379
7467
|
import { createPortal } from "react-dom";
|
|
7380
7468
|
import { useMounted } from "@/lib/platform";
|
|
7381
7469
|
import { useAnchor } from "@/lib/use-anchor";
|
|
7470
|
+
import { useDismiss } from "@/lib/use-dismiss";
|
|
7382
7471
|
import { useHoverOpen } from "@/lib/use-hover-open";
|
|
7383
7472
|
import { cn, material, spring } from "@/lib/utils";
|
|
7384
7473
|
|
|
@@ -7398,7 +7487,10 @@ type HoverCardProps = {
|
|
|
7398
7487
|
children: ReactNode;
|
|
7399
7488
|
};
|
|
7400
7489
|
|
|
7401
|
-
/**
|
|
7490
|
+
/**
|
|
7491
|
+
* Preview card on hover or keyboard focus; the pointer can move into it. On touch the first tap
|
|
7492
|
+
* on the trigger opens the card instead of acting, a second tap acts, a tap outside closes it.
|
|
7493
|
+
*/
|
|
7402
7494
|
export function HoverCard({
|
|
7403
7495
|
content,
|
|
7404
7496
|
side = "bottom",
|
|
@@ -7410,12 +7502,36 @@ export function HoverCard({
|
|
|
7410
7502
|
}: HoverCardProps) {
|
|
7411
7503
|
const wrap = useRef<HTMLSpanElement>(null);
|
|
7412
7504
|
const panel = useRef<HTMLDivElement>(null);
|
|
7413
|
-
const { open, trigger, floating } = useHoverOpen({ openDelay, closeDelay });
|
|
7505
|
+
const { open, close, schedule, trigger, floating } = useHoverOpen({ openDelay, closeDelay });
|
|
7414
7506
|
const pos = useAnchor(open, wrap, panel, { side, align, offset: 8 });
|
|
7415
7507
|
const mounted = useMounted();
|
|
7508
|
+
const touched = useRef(false);
|
|
7509
|
+
|
|
7510
|
+
useDismiss(open, [panel, wrap], close);
|
|
7416
7511
|
|
|
7417
7512
|
return (
|
|
7418
|
-
|
|
7513
|
+
// biome-ignore lint/a11y/noStaticElementInteractions: events bubble from the trigger inside
|
|
7514
|
+
<span
|
|
7515
|
+
ref={wrap}
|
|
7516
|
+
className="inline-flex"
|
|
7517
|
+
{...trigger}
|
|
7518
|
+
// Tab away closes it; a tap on the card moves focus into it or nowhere, and taps
|
|
7519
|
+
// outside are left to useDismiss.
|
|
7520
|
+
onBlur={(event: FocusEvent) => {
|
|
7521
|
+
if (event.relatedTarget && !panel.current?.contains(event.relatedTarget)) close();
|
|
7522
|
+
}}
|
|
7523
|
+
onPointerDown={(event: PointerEvent) => {
|
|
7524
|
+
touched.current = event.pointerType === "touch";
|
|
7525
|
+
}}
|
|
7526
|
+
onClickCapture={(event: MouseEvent) => {
|
|
7527
|
+
// Clicks inside the portaled card bubble here through React too.
|
|
7528
|
+
if (!touched.current || open || !wrap.current?.contains(event.target as Node)) return;
|
|
7529
|
+
|
|
7530
|
+
event.preventDefault();
|
|
7531
|
+
event.stopPropagation();
|
|
7532
|
+
schedule(true, 0);
|
|
7533
|
+
}}
|
|
7534
|
+
>
|
|
7419
7535
|
{children}
|
|
7420
7536
|
{mounted &&
|
|
7421
7537
|
createPortal(
|
|
@@ -9416,8 +9532,9 @@ export function ReleaseNotesSignup() {
|
|
|
9416
9532
|
}}
|
|
9417
9533
|
/>
|
|
9418
9534
|
);
|
|
9419
|
-
}` }], api: { entries: [{ kind: "component", name: "Newsletter", props: [{ name: "onSubscribe", type: "(email: string) => Promise<unknown>", required: true, description: "Resolves when the address is saved; a rejection shows its message in the toast." }, { name: "description", type: "ReactNode", required: false, description: "Supporting line under the heading." }, { name: "placeholder", type: "string", required: false, default: '"you@example.com"', description: "Email field placeholder." }, { name: "submitLabel", type: "string", required: false, default: '"Subscribe"', description: "Submit button text." }, { name: "successMessage", type: "ReactNode", required: false, default: '"Check your inbox to confirm"', description: 'Toast after success, e.g. "Check your inbox to confirm".' }, { name: "title", type: "ReactNode", required: false, description: "Heading above the form." }], description: `Email signup: InputGroup with a submit Button inside, native email validation, and a
|
|
9420
|
-
|
|
9535
|
+
}` }], api: { entries: [{ kind: "component", name: "Newsletter", props: [{ name: "onSubscribe", type: "(email: string) => Promise<unknown>", required: true, description: "Resolves when the address is saved; a rejection shows its message in the toast." }, { name: "description", type: "ReactNode", required: false, description: "Supporting line under the heading." }, { name: "placeholder", type: "string", required: false, default: '"you@example.com"', description: "Email field placeholder." }, { name: "submitLabel", type: "string", required: false, default: '"Subscribe"', description: "Submit button text." }, { name: "successMessage", type: "ReactNode", required: false, default: '"Check your inbox to confirm"', description: 'Toast after success, e.g. "Check your inbox to confirm".' }, { name: "title", type: "ReactNode", required: false, description: "Heading above the form." }], description: `Email signup: InputGroup with a submit Button inside, native email validation, and a loading
|
|
9536
|
+
toast that turns into a success toast. The button confirms in place, then resets for the next
|
|
9537
|
+
address.` }], types: {} }, dependencies: ["lucide-react@1.63.0"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/button.json", "https://kznlabs.github.io/labsUI/r/input.json", "https://kznlabs.github.io/labsUI/r/input-group.json", "https://kznlabs.github.io/labsUI/r/toast.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/blocks/newsletter.tsx", type: "registry:block", content: `"use client";
|
|
9421
9538
|
|
|
9422
9539
|
import { Mail } from "lucide-react";
|
|
9423
9540
|
import { type FormEvent, type ReactNode, useId, useState } from "react";
|
|
@@ -9444,8 +9561,9 @@ type NewsletterProps = {
|
|
|
9444
9561
|
};
|
|
9445
9562
|
|
|
9446
9563
|
/**
|
|
9447
|
-
* Email signup: InputGroup with a submit Button inside, native email validation, and a
|
|
9448
|
-
*
|
|
9564
|
+
* Email signup: InputGroup with a submit Button inside, native email validation, and a loading
|
|
9565
|
+
* toast that turns into a success toast. The button confirms in place, then resets for the next
|
|
9566
|
+
* address.
|
|
9449
9567
|
*/
|
|
9450
9568
|
export function Newsletter({
|
|
9451
9569
|
onSubscribe,
|
|
@@ -12101,10 +12219,11 @@ export function DeploysWindow({ onClose }: { onClose: () => void }) {
|
|
|
12101
12219
|
<h2 className="font-medium">{view}</h2>
|
|
12102
12220
|
</AppWindow>
|
|
12103
12221
|
);
|
|
12104
|
-
}` }], api: { entries: [{ kind: "component", name: "SegmentedTabs", props: [{ name: "items", type: "readonly string[]", required: true, description: "Labels, also used as values." }, { name: "label", type: "string", required: true, description: "Accessible name for the tab list." }, { name: "onChange", type: "(item: string) => void", required: true, description: "Called with the pressed item." }, { name: "value", type: "string", required: true, description: "Active item; marked `aria-current`." }], description: "Segmented tabs. One indicator slides under the active item on a spring, always behind the labels." }], types: {} }, dependencies: ["motion@14.7.1"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/use-indicator.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/ui/segmented-tabs.tsx", type: "registry:ui", content: `"use client";
|
|
12222
|
+
}` }], api: { entries: [{ kind: "component", name: "SegmentedTabs", props: [{ name: "items", type: "readonly string[]", required: true, description: "Labels, also used as values." }, { name: "label", type: "string", required: true, description: "Accessible name for the tab list." }, { name: "onChange", type: "(item: string) => void", required: true, description: "Called with the pressed item." }, { name: "value", type: "string", required: true, description: "Active item; marked `aria-current`." }], description: "Segmented tabs. One indicator slides under the active item on a spring, always behind the labels." }], types: {} }, dependencies: ["motion@14.7.1"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/overflow-focus.json", "https://kznlabs.github.io/labsUI/r/use-indicator.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/ui/segmented-tabs.tsx", type: "registry:ui", content: `"use client";
|
|
12105
12223
|
|
|
12106
12224
|
import { motion } from "motion/react";
|
|
12107
12225
|
import { useRef } from "react";
|
|
12226
|
+
import { OverflowFocus } from "@/lib/overflow-focus";
|
|
12108
12227
|
import { useIndicator } from "@/lib/use-indicator";
|
|
12109
12228
|
import { cn, spring } from "@/lib/utils";
|
|
12110
12229
|
|
|
@@ -12128,14 +12247,19 @@ export function SegmentedTabs({ label, items, value, onChange, className }: Segm
|
|
|
12128
12247
|
return (
|
|
12129
12248
|
<nav
|
|
12130
12249
|
aria-label={label}
|
|
12131
|
-
|
|
12250
|
+
// Scrolls sideways when the title bar is too narrow, instead of running under the actions.
|
|
12251
|
+
// The padding keeps the pill's ring and focus rings inside the scroller's clip.
|
|
12252
|
+
className={cn(
|
|
12253
|
+
"-mx-1 relative isolate flex min-w-0 items-center gap-1 overflow-x-auto px-1 py-1 outline-none [scrollbar-width:none] focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
12254
|
+
className,
|
|
12255
|
+
)}
|
|
12132
12256
|
>
|
|
12133
12257
|
<motion.span
|
|
12134
12258
|
aria-hidden="true"
|
|
12135
12259
|
initial={false}
|
|
12136
12260
|
animate={{ x: indicator.x, width: indicator.width }}
|
|
12137
12261
|
transition={spring}
|
|
12138
|
-
className="-z-10 absolute inset-y-
|
|
12262
|
+
className="-z-10 absolute inset-y-1 left-0 rounded-md bg-raised shadow-sm ring-[0.5px] ring-raised-ring"
|
|
12139
12263
|
/>
|
|
12140
12264
|
{items.map((item) => (
|
|
12141
12265
|
<button
|
|
@@ -12155,6 +12279,7 @@ export function SegmentedTabs({ label, items, value, onChange, className }: Segm
|
|
|
12155
12279
|
{item}
|
|
12156
12280
|
</button>
|
|
12157
12281
|
))}
|
|
12282
|
+
<OverflowFocus />
|
|
12158
12283
|
</nav>
|
|
12159
12284
|
);
|
|
12160
12285
|
}
|
|
@@ -12440,7 +12565,7 @@ export function Select(allProps: SelectProps) {
|
|
|
12440
12565
|
{option.icon}
|
|
12441
12566
|
{option.label}
|
|
12442
12567
|
{option.value === value && (
|
|
12443
|
-
<Check className="!text-current absolute
|
|
12568
|
+
<Check className="!text-current absolute right-2" aria-hidden="true" />
|
|
12444
12569
|
)}
|
|
12445
12570
|
</div>
|
|
12446
12571
|
))}
|
|
@@ -14256,8 +14381,8 @@ export function StepperFooter({
|
|
|
14256
14381
|
padding: 4px;
|
|
14257
14382
|
border: 1px solid var(--border);
|
|
14258
14383
|
border-radius: calc(var(--radius) + 4px);
|
|
14259
|
-
background: color-mix(in oklch, var(--popover)
|
|
14260
|
-
backdrop-filter: blur(
|
|
14384
|
+
background: color-mix(in oklch, var(--popover) 92%, transparent);
|
|
14385
|
+
backdrop-filter: blur(20px) saturate(1.25);
|
|
14261
14386
|
color: var(--popover-foreground);
|
|
14262
14387
|
box-shadow:
|
|
14263
14388
|
0 10px 30px -10px rgb(0 0 0 / 0.25),
|
|
@@ -15790,7 +15915,7 @@ export function notifySaved() {
|
|
|
15790
15915
|
description: "All changes synced",
|
|
15791
15916
|
action: { label: "Undo", onClick: undo },
|
|
15792
15917
|
});
|
|
15793
|
-
}` }], api: { entries: [{ kind: "function", name: "toast", signature: 'toast(title: ReactNode, opts?: Partial<Omit<ToastData, "id" | "title">>) => number', description: '`toast("Saved")`, `toast.success(title, { description, action, duration })`, `toast.loading(title)`, `toast.promise(p, { loading, success, error })`, `toast.dismiss(id?)`.' }, { kind: "component", name: "Toaster", props: [], description: "Mount once (root layout). Stacked toasts: hover
|
|
15918
|
+
}` }], api: { entries: [{ kind: "function", name: "toast", signature: 'toast(title: ReactNode, opts?: Partial<Omit<ToastData, "id" | "title">>) => number', description: '`toast("Saved")`, `toast.success(title, { description, action, duration })`, `toast.loading(title)`, `toast.promise(p, { loading, success, error })`, `toast.dismiss(id?)`.' }, { kind: "component", name: "Toaster", props: [], description: "Mount once (root layout). Stacked toasts: hover, focus or a tap expands, swipe dismisses." }], types: { ToastData: "{ id: number; title: ReactNode; description?: ReactNode; variant: Variant; duration: number; action?: { label: string; onClick: () => void }; }" } }, dependencies: ["lucide-react@1.63.0", "motion@14.7.1"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/use-dismiss.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/ui/toast.tsx", type: "registry:ui", content: `"use client";
|
|
15794
15919
|
|
|
15795
15920
|
import { CircleAlert, CircleCheck, Info, Loader2, X } from "lucide-react";
|
|
15796
15921
|
import { AnimatePresence, animate, motion, type PanInfo, useMotionValue } from "motion/react";
|
|
@@ -15802,6 +15927,7 @@ import {
|
|
|
15802
15927
|
useState,
|
|
15803
15928
|
useSyncExternalStore,
|
|
15804
15929
|
} from "react";
|
|
15930
|
+
import { useDismiss } from "@/lib/use-dismiss";
|
|
15805
15931
|
import { cn, material, spring } from "@/lib/utils";
|
|
15806
15932
|
|
|
15807
15933
|
/* ---------- store (module-level, no provider needed) ---------- */
|
|
@@ -15920,13 +16046,14 @@ const icons = {
|
|
|
15920
16046
|
loading: <Loader2 className="size-4 animate-spin text-muted-foreground" aria-hidden="true" />,
|
|
15921
16047
|
};
|
|
15922
16048
|
|
|
15923
|
-
/** Mount once (root layout). Stacked toasts: hover
|
|
16049
|
+
/** Mount once (root layout). Stacked toasts: hover, focus or a tap expands, swipe dismisses. */
|
|
15924
16050
|
export function Toaster({ className }: { className?: string }) {
|
|
15925
16051
|
const items = useSyncExternalStore(
|
|
15926
16052
|
subscribe,
|
|
15927
16053
|
() => toasts,
|
|
15928
16054
|
() => EMPTY,
|
|
15929
16055
|
);
|
|
16056
|
+
const section = useRef<HTMLElement>(null);
|
|
15930
16057
|
const [expanded, setExpanded] = useState(false);
|
|
15931
16058
|
const [heights, setHeights] = useState<Record<number, number>>({});
|
|
15932
16059
|
const onHeight = useCallback(
|
|
@@ -15939,15 +16066,21 @@ export function Toaster({ className }: { className?: string }) {
|
|
|
15939
16066
|
if (items.length === 0) setExpanded(false);
|
|
15940
16067
|
}, [items.length]);
|
|
15941
16068
|
|
|
16069
|
+
// A touch fires enter and leave around every tap, so phones expand on tap, collapse outside.
|
|
16070
|
+
useDismiss(expanded, [section], () => setExpanded(false));
|
|
16071
|
+
|
|
15942
16072
|
const frontH = heights[items[0]?.id ?? -1] ?? 0;
|
|
15943
16073
|
let offset = 0;
|
|
15944
16074
|
|
|
15945
16075
|
return (
|
|
16076
|
+
// biome-ignore lint/a11y/useKeyWithClickEvents: keyboard focus already expands the stack
|
|
15946
16077
|
<section
|
|
15947
16078
|
aria-label="Notifications"
|
|
15948
16079
|
className={cn("fixed right-4 bottom-4 z-[100] w-[min(360px,calc(100vw-2rem))]", className)}
|
|
15949
|
-
|
|
15950
|
-
|
|
16080
|
+
ref={section}
|
|
16081
|
+
onPointerEnter={(event) => event.pointerType !== "touch" && setExpanded(true)}
|
|
16082
|
+
onPointerLeave={(event) => event.pointerType !== "touch" && setExpanded(false)}
|
|
16083
|
+
onClick={() => setExpanded(true)}
|
|
15951
16084
|
onFocus={() => setExpanded(true)}
|
|
15952
16085
|
onBlur={(event) => {
|
|
15953
16086
|
if (!event.currentTarget.contains(event.relatedTarget)) setExpanded(false);
|
|
@@ -16305,14 +16438,21 @@ export function FormatToolbar() {
|
|
|
16305
16438
|
</Tooltip>
|
|
16306
16439
|
</div>
|
|
16307
16440
|
);
|
|
16308
|
-
}` }], api: { entries: [{ kind: "component", name: "Tooltip", props: [{ name: "children", type: "ReactNode", required: true, description: "One focusable element, e.g. an icon Button with an aria-label." }, { name: "content", type: "ReactNode", required: true, description: "Short text. Also becomes the trigger's accessible description." }, { name: "align", type: '"start" | "center" | "end"', required: false, default: '"center"', description: "Alignment with the trigger." }, { name: "delay", type: "number", required: false, default: "500", description: "Hover delay in ms before the first tooltip opens (default 500)." }, { name: "side", type: '"top" | "bottom"', required: false, default: '"top"', description: "Preferred side; flips when there is no room." }], description:
|
|
16309
|
-
1.4.13), Esc dismisses, mouse only: touch taps go straight to the trigger.` }], types: {} }, dependencies: ["motion@14.7.1"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/platform.json", "https://kznlabs.github.io/labsUI/r/use-anchor.json", "https://kznlabs.github.io/labsUI/r/use-hover-open.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/ui/tooltip.tsx", type: "registry:ui", content: `"use client";
|
|
16441
|
+
}` }], api: { entries: [{ kind: "component", name: "Tooltip", props: [{ name: "children", type: "ReactNode", required: true, description: "One focusable element, e.g. an icon Button with an aria-label." }, { name: "content", type: "ReactNode", required: true, description: "Short text. Also becomes the trigger's accessible description." }, { name: "align", type: '"start" | "center" | "end"', required: false, default: '"center"', description: "Alignment with the trigger." }, { name: "delay", type: "number", required: false, default: "500", description: "Hover delay in ms before the first tooltip opens (default 500)." }, { name: "side", type: '"top" | "bottom"', required: false, default: '"top"', description: "Preferred side; flips when there is no room." }, { name: "touch", type: '"press" | "tap"', required: false, default: '"press"', description: "How touch opens it: `press` (touch and hold; a tap still reaches the control) or `tap` (a tap\ntoggles it, for triggers with no action of their own)." }], description: 'Hover/keyboard-focus label for one element. Stays open while the pointer is on it (WCAG\n1.4.13), Esc dismisses. On touch: touch and hold shows it, or a tap with `touch="tap"`.' }], types: {} }, dependencies: ["motion@14.7.1"], registryDependencies: ["https://kznlabs.github.io/labsUI/r/platform.json", "https://kznlabs.github.io/labsUI/r/use-anchor.json", "https://kznlabs.github.io/labsUI/r/use-dismiss.json", "https://kznlabs.github.io/labsUI/r/use-hover-open.json", "https://kznlabs.github.io/labsUI/r/utils.json"], files: [{ path: "components/ui/tooltip.tsx", type: "registry:ui", content: `"use client";
|
|
16310
16442
|
|
|
16311
16443
|
import { AnimatePresence, motion } from "motion/react";
|
|
16312
|
-
import {
|
|
16444
|
+
import {
|
|
16445
|
+
type MouseEvent,
|
|
16446
|
+
type PointerEvent,
|
|
16447
|
+
type ReactNode,
|
|
16448
|
+
useEffect,
|
|
16449
|
+
useId,
|
|
16450
|
+
useRef,
|
|
16451
|
+
} from "react";
|
|
16313
16452
|
import { createPortal } from "react-dom";
|
|
16314
16453
|
import { useMounted } from "@/lib/platform";
|
|
16315
16454
|
import { useAnchor } from "@/lib/use-anchor";
|
|
16455
|
+
import { useDismiss } from "@/lib/use-dismiss";
|
|
16316
16456
|
import { useHoverOpen } from "@/lib/use-hover-open";
|
|
16317
16457
|
import { cn, material, spring } from "@/lib/utils";
|
|
16318
16458
|
|
|
@@ -16329,6 +16469,11 @@ type TooltipProps = {
|
|
|
16329
16469
|
align?: "start" | "center" | "end";
|
|
16330
16470
|
/** Hover delay in ms before the first tooltip opens (default 500). */
|
|
16331
16471
|
delay?: number;
|
|
16472
|
+
/**
|
|
16473
|
+
* How touch opens it: \`press\` (touch and hold; a tap still reaches the control) or \`tap\` (a tap
|
|
16474
|
+
* toggles it, for triggers with no action of their own).
|
|
16475
|
+
*/
|
|
16476
|
+
touch?: "press" | "tap";
|
|
16332
16477
|
className?: string;
|
|
16333
16478
|
/** One focusable element, e.g. an icon Button with an aria-label. */
|
|
16334
16479
|
children: ReactNode;
|
|
@@ -16336,20 +16481,21 @@ type TooltipProps = {
|
|
|
16336
16481
|
|
|
16337
16482
|
/**
|
|
16338
16483
|
* Hover/keyboard-focus label for one element. Stays open while the pointer is on it (WCAG
|
|
16339
|
-
* 1.4.13), Esc dismisses
|
|
16484
|
+
* 1.4.13), Esc dismisses. On touch: touch and hold shows it, or a tap with \`touch="tap"\`.
|
|
16340
16485
|
*/
|
|
16341
16486
|
export function Tooltip({
|
|
16342
16487
|
content,
|
|
16343
16488
|
side = "top",
|
|
16344
16489
|
align = "center",
|
|
16345
16490
|
delay = 500,
|
|
16491
|
+
touch = "press",
|
|
16346
16492
|
className,
|
|
16347
16493
|
children,
|
|
16348
16494
|
}: TooltipProps) {
|
|
16349
16495
|
const id = useId();
|
|
16350
16496
|
const wrap = useRef<HTMLSpanElement>(null);
|
|
16351
16497
|
const panel = useRef<HTMLDivElement>(null);
|
|
16352
|
-
const { open, close, trigger, floating } = useHoverOpen({
|
|
16498
|
+
const { open, close, schedule, trigger, floating } = useHoverOpen({
|
|
16353
16499
|
openDelay: delay,
|
|
16354
16500
|
closeDelay: 100,
|
|
16355
16501
|
instant: () => Date.now() - lastClosed < WARM,
|
|
@@ -16359,6 +16505,48 @@ export function Tooltip({
|
|
|
16359
16505
|
});
|
|
16360
16506
|
const pos = useAnchor(open, wrap, panel, { side, align, offset: 8 });
|
|
16361
16507
|
const mounted = useMounted();
|
|
16508
|
+
const press = useRef<{ timer?: ReturnType<typeof setTimeout>; held: boolean }>({ held: false });
|
|
16509
|
+
|
|
16510
|
+
useDismiss(open, [panel, wrap], close);
|
|
16511
|
+
useEffect(() => () => clearTimeout(press.current.timer), []);
|
|
16512
|
+
|
|
16513
|
+
const touchHandlers =
|
|
16514
|
+
touch === "tap"
|
|
16515
|
+
? {
|
|
16516
|
+
onPointerUp: (event: PointerEvent) => {
|
|
16517
|
+
if (event.pointerType === "touch") schedule(!open, 0);
|
|
16518
|
+
},
|
|
16519
|
+
}
|
|
16520
|
+
: {
|
|
16521
|
+
// Touch and hold opens it; letting go hides it a moment later. The tap that ends a
|
|
16522
|
+
// hold is swallowed, so holding a button to read its label doesn't press it.
|
|
16523
|
+
onPointerDown: (event: PointerEvent) => {
|
|
16524
|
+
if (event.pointerType !== "touch") return;
|
|
16525
|
+
|
|
16526
|
+
press.current.held = false;
|
|
16527
|
+
press.current.timer = setTimeout(() => {
|
|
16528
|
+
press.current.held = true;
|
|
16529
|
+
schedule(true, 0);
|
|
16530
|
+
}, 500);
|
|
16531
|
+
},
|
|
16532
|
+
onPointerUp: (event: PointerEvent) => {
|
|
16533
|
+
if (event.pointerType !== "touch") return;
|
|
16534
|
+
|
|
16535
|
+
clearTimeout(press.current.timer);
|
|
16536
|
+
if (press.current.held) schedule(false, 1500);
|
|
16537
|
+
},
|
|
16538
|
+
onPointerCancel: () => clearTimeout(press.current.timer),
|
|
16539
|
+
onContextMenu: (event: MouseEvent) => {
|
|
16540
|
+
if (press.current.held) event.preventDefault();
|
|
16541
|
+
},
|
|
16542
|
+
onClickCapture: (event: MouseEvent) => {
|
|
16543
|
+
if (!press.current.held) return;
|
|
16544
|
+
|
|
16545
|
+
press.current.held = false;
|
|
16546
|
+
event.preventDefault();
|
|
16547
|
+
event.stopPropagation();
|
|
16548
|
+
},
|
|
16549
|
+
};
|
|
16362
16550
|
|
|
16363
16551
|
// Describe the real control (not the wrapper) with an always-present hidden copy.
|
|
16364
16552
|
useEffect(() => {
|
|
@@ -16387,7 +16575,12 @@ export function Tooltip({
|
|
|
16387
16575
|
}, [open, close]);
|
|
16388
16576
|
|
|
16389
16577
|
return (
|
|
16390
|
-
<span
|
|
16578
|
+
<span
|
|
16579
|
+
ref={wrap}
|
|
16580
|
+
className="inline-flex [-webkit-touch-callout:none]"
|
|
16581
|
+
{...trigger}
|
|
16582
|
+
{...touchHandlers}
|
|
16583
|
+
>
|
|
16391
16584
|
{children}
|
|
16392
16585
|
<span id={id} hidden>
|
|
16393
16586
|
{content}
|
|
@@ -16828,6 +17021,7 @@ export function useHotkey(
|
|
|
16828
17021
|
}) => {
|
|
16829
17022
|
open: boolean;
|
|
16830
17023
|
close: () => void;
|
|
17024
|
+
schedule: (next: boolean, delay: number) => void;
|
|
16831
17025
|
trigger: {
|
|
16832
17026
|
onPointerEnter: (event: PointerEvent<Element>) => void | false;
|
|
16833
17027
|
onPointerLeave: (event: PointerEvent<Element>) => void | false;
|
|
@@ -16890,6 +17084,8 @@ export function useHoverOpen({
|
|
|
16890
17084
|
return {
|
|
16891
17085
|
open,
|
|
16892
17086
|
close: () => schedule(false, 0),
|
|
17087
|
+
/** Open (true) or close after \`delay\` ms, cancelling any pending change. */
|
|
17088
|
+
schedule,
|
|
16893
17089
|
trigger: {
|
|
16894
17090
|
onPointerEnter: (event: PointerEvent) => mouse(event) && show(),
|
|
16895
17091
|
onPointerLeave: (event: PointerEvent) => mouse(event) && hide(),
|
|
@@ -16951,7 +17147,7 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
16951
17147
|
}
|
|
16952
17148
|
|
|
16953
17149
|
/** Frosted material for floating surfaces (menus, popovers, tooltips, toasts): translucent + blur. */
|
|
16954
|
-
export const material = "bg-popover/
|
|
17150
|
+
export const material = "bg-popover/92 backdrop-blur-xl backdrop-saturate-125";
|
|
16955
17151
|
|
|
16956
17152
|
/** The one spring. Every interaction in the library uses it. */
|
|
16957
17153
|
export const spring = { type: "spring", stiffness: 400, damping: 30 } as const;
|
|
@@ -16959,9 +17155,9 @@ export const spring = { type: "spring", stiffness: 400, damping: 30 } as const;
|
|
|
16959
17155
|
export const clamp = (value: number, min: number, max: number) =>
|
|
16960
17156
|
Math.min(Math.max(value, min), max);
|
|
16961
17157
|
` }] } },
|
|
16962
|
-
index: [{ name: "accent-picker", type: "registry:ui", title: "Accent Picker", description: "Accent color row: eight swatches (red to slate) that retint primary, focus rings, selection, switches and checkboxes app-wide. Persisted, applied before paint, or set your own hue with --accent-hue.", exports: ["AccentPicker"], keywords: ["accent", "app", "color", "radio", "retint", "row", "setaccent", "swatches", "that", "the", "via", "whole"], registryDependencies: ["theme", "utils"] }, { name: "accordion", type: "registry:ui", title: "Accordion", description: "Single or multiple panels with spring height animation. Closed content stays in the DOM for SEO.", exports: ["Accordion", "AccordionItem", "AccordionTrigger", "AccordionContent"], keywords: ["accordion", "accordioncontent", "accordionitem", "accordiontrigger", "allow", "and", "called", "children", "closed", "closes", "closing", "collapsible", "content", "controlled", "crawlable", "default", "defaultvalue", "every", "first", "heading", "height", "html", "independent", "inert", "item", "items", "level", "match", "matched", "mounted", "multiple", "none", "one", "only", "onvaluechange", "open", "outline", "page", "panel", "panels", "question", "remains", "render", "single", "stays", "text", "the", "time", "type", "uncontrolled", "unique", "value", "when", "while", "with", "within", "wrapping"], registryDependencies: ["use-controllable-state", "utils"] }, { name: "alert", type: "registry:ui", title: "Alert", description: "Server-safe inline banner: tinted surface, colored icon, title, description and an optional action. Info, success, warning and destructive tones follow the accent and status tokens.", exports: ["Alert", "AlertTitle", "AlertDescription"], keywords: ["action", "add", "alert", "aligned", "and", "announced", "appears", "banner", "button", "colored", "default", "description", "did", "for", "icon", "inline", "live", "load", "none", "not", "null", "pass", "region", "replaces", "response", "right", "role", "sets", "should", "slot", "small", "something", "static", "surface", "the", "tint", "tinted", "title", "tone", "user", "variant", "when"], registryDependencies: ["utils"] }, { name: "app-window", type: "registry:ui", title: "AppWindow", description: "Window container with close / minimize / zoom controls, title, custom header slot and actions. SegmentedTabs is the compact view switcher for its title bar.", exports: ["AppWindow"], keywords: ["actions", "aligned", "area", "bar", "blurred", "bodyclassname", "button", "called", "centered", "classes", "content", "control", "custom", "dot", "for", "glass", "handler", "header", "into", "matching", "maximize", "minimize", "navbar", "onclose", "onmaximize", "onminimize", "passing", "pressed", "replaces", "right", "search", "shows", "slot", "surface", "tabs", "text", "the", "title", "titlebar", "translucent", "turns", "under", "when"], registryDependencies: ["utils"] }, { name: "aspect-ratio", type: "registry:ui", title: "Aspect Ratio", description: "Server-safe box locked to a ratio (16:9 thumbnails, 9:16 clips). A direct image or video child fills it with object-cover.", exports: ["AspectRatio"], keywords: ["box", "child", "cover", "direct", "fills", "height", "img", "locked", "object", "ratio", "video", "width"], registryDependencies: ["utils"] }, { name: "attachment", type: "registry:ui", title: "Attachment & Dropzone", description: "File chips with image thumbnails or type icons, size, a springing upload bar, error state and remove; the list springs chips in and closes the gap. FileDropzone wraps a real file input: click, keyboard and the native picker work, drop and paste are checked against accept and maxSize, and dropped files land in the input so forms and Server Actions receive them.", exports: ["formatBytes", "Attachment", "AttachmentList", "FileDropzone"], keywords: ["accept", "actions", "along", "and", "are", "area", "aria", "around", "attachments", "attribute", "back", "bar", "bcp", "blocks", "both", "bottom", "browse", "button", "bytes", "called", "child", "children", "chip", "click", "content", "createobjecturl", "default", "describedby", "disabled", "download", "drop", "dropped", "drops", "each", "edge", "enforced", "enter", "error", "failed", "field", "file", "files", "fills", "for", "form", "forms", "fresh", "from", "get", "given", "hint", "href", "icon", "ids", "image", "input", "into", "invalid", "key", "least", "line", "link", "locale", "makes", "maxsize", "mime", "more", "multiple", "name", "native", "needs", "one", "onfiles", "onreject", "onremove", "out", "passed", "paste", "pdf", "picked", "picker", "picks", "place", "plain", "pressed", "progress", "real", "reason", "red", "remove", "removed", "replaces", "required", "same", "server", "sets", "show", "shows", "size", "source", "space", "spring", "springs", "src", "styling", "submit", "syntax", "text", "than", "that", "the", "them", "thumbnail", "too", "turns", "type", "types", "upload", "uploading", "url", "when", "while", "with", "work", "written"], registryDependencies: ["field", "utils"] }, { name: "avatar", type: "registry:ui", title: "Avatar", description: "Image with initials fallback on error, three sizes and online/away/busy/offline dots.", exports: ["Avatar"], keywords: ["alt", "and", "announced", "corner", "diameter", "dot", "fails", "fallback", "for", "icon", "image", "initials", "loads", "name", "overrides", "person", "presence", "show", "size", "src", "status", "text", "the", "url", "used", "while", "with"], registryDependencies: ["utils"] }, { name: "avatar-group", type: "registry:ui", title: "AvatarGroup", description: "Overlapping avatars with a +N overflow chip. Hover gently enlarges the avatar on a spring, keeping stack order.", exports: ["AvatarGroup"], keywords: ["alt", "and", "avatar", "avatars", "before", "chip", "each", "enlarges", "every", "gently", "hover", "how", "many", "max", "name", "one", "order", "overflow", "overlapping", "people", "show", "size", "spring", "stack", "staying", "the", "users", "with"], registryDependencies: ["avatar", "utils"] }, { name: "badge", type: "registry:ui", title: "Badge & Pill", description: "Minimal status tags. Rounded badge or fully rounded pill, with optional dot. pulse adds an expanding live-status ring.", exports: ["Badge"], keywords: ["and", "color", "current", "dot", "emits", "expanding", "forever", "fully", "leading", "like", "live", "needs", "pill", "pulse", "ring", "rounded", "shape", "status", "surface", "tag", "text", "the", "variant"], registryDependencies: ["utils"] }, { name: "breadcrumb", type: "registry:ui", title: "Breadcrumb", description: "Navigation trail from a list of items: links up to the current page, which is marked for assistive tech. Server-safe, custom separator.", exports: ["Breadcrumb"], keywords: ["between", "chevron", "current", "default", "drawn", "ending", "first", "item", "items", "last", "links", "list", "outermost", "page", "safe", "separator", "server", "site", "sits", "the", "trail", "where"], registryDependencies: [] }, { name: "button", type: "registry:ui", title: "Button", description: "Five variants, four sizes, spring press feedback, an animated loading spinner and in-place success state, a two-step confirm that swaps the label on first click, and a configurable swap direction. Width stays fixed to the longest label.", exports: ["Button"], keywords: ["action", "also", "and", "aria", "armed", "before", "blur", "button", "check", "children", "click", "confirm", "confirmlabel", "confirmtimeout", "default", "defaults", "destructive", "disables", "done", "emphasis", "esc", "feedback", "fill", "first", "for", "give", "height", "icon", "irreversible", "its", "label", "left", "loading", "loadinglabel", "never", "old", "onclick", "one", "ones", "out", "padding", "per", "place", "primary", "reserved", "resets", "resize", "runs", "second", "shown", "shows", "size", "slides", "spinner", "spins", "square", "status", "step", "success", "successlabel", "swap", "swaps", "text", "the", "this", "two", "variant", "view", "where", "while", "width", "with"], registryDependencies: ["button-variants", "utils"] }, { name: "button-group", type: "registry:ui", title: "Button Group", description: "Joins buttons into one strip that shares borders, corners and active states. Horizontal or vertical.", exports: ["ButtonGroup"], keywords: ["and", "attached", "borders", "buttons", "connected", "control", "corners", "default", "fuse", "groups", "horizontal", "into", "orientation", "related", "single", "strip", "together", "toolbar", "true", "vertical"], registryDependencies: ["utils"] }, { name: "button-variants", type: "registry:ui", description: 'Button classes for non-button elements, e.g. `<a className={buttonVariants({ variant: "outline" })}>`.', exports: ["buttonVariants"], keywords: ["button", "buttonvariants", "classes", "classname", "elements", "for", "non", "outline", "variant"], registryDependencies: ["utils"] }, { name: "calendar", type: "registry:ui", title: "Calendar", description: "Month grid on the WAI-ARIA date-grid pattern: single date or range with a hover preview, min/max and custom disabled days, months that slide in from the direction of travel. Arrows, Home/End and PageUp/PageDown (+Shift for years). Hydration-safe: today is only marked in the browser.", exports: ["key", "Calendar"], keywords: ["and", "another", "any", "aria", "arrows", "autofocus", "bcp", "called", "client", "controlled", "current", "custom", "date", "datepicker", "dates", "day", "days", "default", "defaultmonth", "defaultvalue", "direction", "disabled", "displayed", "earliest", "end", "ends", "extra", "first", "focus", "for", "from", "function", "grid", "home", "hover", "into", "isdisabled", "iso", "keyboard", "latest", "like", "local", "locale", "max", "min", "mode", "monday", "month", "months", "mount", "names", "nothing", "null", "off", "one", "only", "onmonthchange", "onvaluechange", "pagedown", "pages", "pageup", "pattern", "pick", "picked", "preview", "range", "render", "rule", "saturday", "selectable", "sets", "shift", "shown", "single", "slide", "sorts", "start", "sunday", "the", "then", "this", "travel", "uncontrolled", "user", "value", "wai", "week", "weekday", "weekends", "weekstartson", "when", "with", "year", "yyyy"], registryDependencies: ["button", "use-controllable-state", "utils"] }, { name: "card", type: "registry:ui", title: "Card", description: "Composable surface: header, title, description, content and footer. Optional glass.", exports: ["Card", "CardHeader", "CardTitle", "CardDescription", "CardContent", "CardFooter"], keywords: ["backgrounds", "colored", "default", "directly", "fits", "follows", "glass", "heading", "level", "not", "outline", "over", "page", "place", "subtle", "textured", "that", "the", "translucency", "under", "when"], registryDependencies: ["utils"] }, { name: "carousel", type: "registry:ui", title: "Carousel", description: "Native scroll-snap row, so touch, trackpad and no-JS scrolling work, with spring-driven arrows, page dots, arrow keys and mouse drag that throws to the next snap point. APG carousel semantics: a labeled region of slides announced as 3 of 8.", exports: ["Carousel", "CarouselContent", "CarouselItem", "CarouselPrevious", "CarouselNext", "CarouselDots"], keywords: ["accessible", "all", "and", "announced", "any", "apg", "are", "arrow", "basis", "buttons", "carousel", "css", "default", "dot", "dots", "drag", "driven", "edge", "end", "fewer", "from", "gap", "hides", "keys", "label", "labeled", "left", "mouse", "name", "native", "not", "one", "overlaid", "page", "pages", "per", "projects", "region", "rem", "right", "row", "scroll", "scrolling", "semantics", "sized", "slide", "slides", "snap", "spring", "start", "the", "there", "total", "touch", "trackpad", "two", "variables", "view", "with", "work"], registryDependencies: ["button", "utils"] }, { name: "changelog", type: "registry:block", title: "Changelog", description: "Release notes on a Timeline: newest release highlighted, changes typed New / Improved / Fixed with Badges, and a Kbd shortcut to try the headline feature. Server-safe.", exports: ["Changelog"], keywords: ["are", "badges", "changes", "first", "highlighted", "how", "kbd", "newest", "notes", "one", "release", "releases", "shows", "the", "timeline", "try", "typed", "with"], registryDependencies: ["badge", "kbd", "timeline", "utils"] }, { name: "chart", type: "registry:ui", title: "Chart", description: "Line, area and bar (grouped or stacked) charts in SVG with a colorblind-validated eight-color palette that keeps each series' color. Crosshair tooltip listing every series, arrow-key readout, legend that hides series, direct end labels, a table view, and spring transitions between data.", exports: ["Chart"], keywords: ["add", "and", "are", "area", "areas", "arrow", "assistive", "axis", "bar", "bars", "bcp", "can", "captions", "categorical", "category", "chart", "charts", "compact", "crosshair", "currency", "data", "direct", "each", "eight", "end", "every", "filled", "fold", "for", "format", "grouping", "height", "hides", "index", "instead", "into", "key", "keys", "label", "labels", "legend", "line", "lines", "listing", "locale", "mark", "most", "names", "notation", "numbers", "object", "one", "only", "other", "pages", "palette", "past", "per", "plot", "plus", "props", "render", "row", "serializable", "series", "server", "split", "stack", "stacked", "style", "svg", "table", "tail", "tech", "that", "the", "them", "ticks", "too", "tooltip", "type", "usd", "value", "view", "with"], registryDependencies: ["button", "table", "utils"] }, { name: "checkbox", type: "registry:ui", title: "Checkbox", description: "Native checkbox with a spring-drawn check mark and an indeterminate state for select-all rows. Controlled or uncontrolled; submits with forms.", exports: ["Checkbox"], keywords: ["all", "called", "check", "checkbox", "checked", "controlled", "dash", "defaultchecked", "drawn", "field", "first", "indeterminate", "inside", "mixed", "native", "new", "oncheckedchange", "pair", "render", "rows", "select", "selected", "shows", "some", "spring", "state", "the", "uncontrolled", "with", "works"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "clip-card", type: "registry:block", title: "Clip Card", description: "Video tile: AspectRatio thumbnail (16:9 or 9:16), duration Badge, watched Progress along the bottom, and a ContextMenu of actions.", exports: ["ClipCard"], keywords: ["accessible", "actions", "ago", "along", "also", "and", "aspectratio", "badge", "bar", "bottom", "card", "click", "clip", "clips", "context", "contextmenuitem", "days", "duration", "f10", "film", "for", "glyph", "height", "how", "img", "items", "menu", "meta", "much", "name", "one", "opens", "print", "progress", "ratio", "right", "shift", "small", "stands", "the", "them", "thin", "thumbnail", "tile", "title", "under", "vertical", "video", "views", "was", "watched", "width", "without"], registryDependencies: ["aspect-ratio", "badge", "context-menu", "progress", "utils"] }, { name: "code", type: "registry:ui", title: "Code", description: "Shiki-highlighted code that follows light and dark through light-dark() token colors, as a block, an inline one-liner or a tabbed file panel. Line numbers (from any start line), tinted lines with an accent bar, <mark>ed words or column ranges, and per-line notes in a tooltip that keyboard users can tab to. Optional Prettier at display time; copy hands out exactly what is shown.", exports: ["CopyButton", "Code", "CodePanel"], keywords: ["accessible", "active", "add", "all", "and", "animates", "annotations", "bar", "bash", "before", "behind", "block", "body", "build", "button", "clipboard", "code", "collapse", "copied", "copy", "dark", "default", "dom", "each", "every", "excerpts", "file", "files", "first", "focus", "fold", "for", "format", "formatted", "from", "gets", "ghost", "gutter", "header", "highlight", "highlightcode", "highlighted", "highlighting", "hover", "ignored", "inline", "inside", "into", "its", "json", "keep", "label", "language", "least", "left", "light", "line", "linenumbers", "lines", "loads", "longer", "made", "many", "mark", "marks", "name", "never", "note", "notes", "number", "numbers", "one", "options", "own", "page", "paint", "panel", "per", "place", "prettier", "primary", "ranges", "refer", "registry", "remember", "renders", "run", "scrolling", "scrolls", "server", "sets", "shared", "shiki", "show", "source", "stays", "switching", "syntax", "tab", "terminal", "text", "than", "that", "the", "themes", "this", "time", "tint", "tokens", "too", "touch", "tsx", "turns", "variant", "vertically", "wheel", "with", "words", "wrapped", "written"], registryDependencies: ["button", "highlight", "overflow-focus", "tabs", "tooltip", "utils"] }, { name: "collapsible", type: "registry:ui", title: "Collapsible", description: "A single show/hide region with a spring height animation and rotating chevron. Controlled or uncontrolled; closed content stays in the DOM for SEO.", exports: ["Collapsible", "CollapsibleTrigger", "CollapsibleContent"], keywords: ["after", "and", "called", "chevron", "children", "closed", "collapsiblecontent", "collapsibletrigger", "content", "controlled", "crawlable", "default", "defaultopen", "first", "height", "hide", "html", "inert", "label", "mounted", "one", "onopenchange", "open", "pair", "region", "remains", "render", "rotating", "show", "springs", "state", "stays", "that", "the", "toggles", "trigger", "true", "uncontrolled", "when", "while", "with"], registryDependencies: ["use-controllable-state", "utils"] }, { name: "combobox", type: "registry:ui", title: "Combobox", description: "A Select you can type into: the query filters by label and keywords (prefix matches first), arrows move, Enter picks. multiple keeps the list open and shows picks as removable tags. Submits through hidden inputs.", exports: ["Combobox"], keywords: ["accessible", "and", "aria", "backspace", "blocks", "called", "can", "choices", "closes", "controlled", "defaultvalue", "describedby", "disabled", "down", "emptytext", "enter", "error", "esc", "every", "field", "fills", "filtered", "filters", "first", "form", "from", "hidden", "hint", "ids", "input", "inputs", "into", "invalid", "keeps", "label", "last", "list", "matches", "move", "multiple", "name", "needs", "nothing", "one", "onvaluechange", "open", "opening", "options", "pair", "per", "pick", "picked", "picks", "placeholder", "removable", "removes", "render", "required", "select", "sets", "show", "shown", "shows", "single", "stay", "styling", "submit", "submits", "tags", "text", "the", "there", "through", "type", "types", "typing", "uncontrolled", "user", "value", "values", "visible", "when", "with", "you"], registryDependencies: ["field", "list", "platform", "tag-input", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "command", type: "registry:ui", title: "Command", description: "⌘K palette: filterable groups, arrow-key highlight, Enter to run, keyword matching. Inline or as CommandDialog with a global shortcut; the first Esc clears, the second closes.", exports: ["Command", "CommandInput", "CommandList", "CommandEmpty", "CommandGroup", "CommandSeparator", "CommandItem", "CommandDialog"], keywords: ["accessible", "after", "against", "and", "arrows", "but", "called", "children", "click", "close", "closes", "collapse", "command", "commanddialog", "commandempty", "commandinput", "commanditem", "commandlist", "content", "controlled", "ctrl", "defaults", "dialog", "disable", "disabled", "driven", "elsewhere", "end", "enter", "esc", "extra", "false", "filterable", "filtering", "for", "global", "group", "groups", "heading", "hidden", "hides", "home", "icon", "inline", "input", "inside", "item", "items", "its", "itself", "keepopen", "keyboard", "keywords", "label", "list", "listbox", "mac", "match", "matched", "matches", "mod", "move", "name", "none", "not", "only", "onopenchange", "onselect", "open", "option", "outside", "own", "pair", "palette", "pass", "passes", "placeholder", "preferences", "query", "results", "scrollable", "search", "selectable", "selecting", "selection", "selects", "separators", "settings", "shortcut", "shown", "shows", "stack", "state", "stay", "terms", "text", "the", "title", "toggle", "toggled", "use", "used", "value", "visible", "visually", "when", "while", "with", "would"], registryDependencies: ["dialog", "list", "search-input", "separator", "use-controllable-state", "use-hotkey", "utils"] }, { name: "confirm", type: "registry:ui", title: "Confirm", description: "Promise-based confirm dialog called like toast: await confirm({ title, description, destructive }) resolves true or false. Built on Dialog's alert mode, Cancel takes the first focus, Esc cancels, one host mounted in the layout.", exports: ["confirm", "Confirmer"], keywords: ["acting", "asks", "await", "before", "cancel", "confirm", "confirmer", "delete", "destructive", "esc", "false", "for", "host", "layout", "mount", "mounted", "needs", "newer", "next", "once", "project", "remove", "resolves", "root", "title", "toaster", "true"], registryDependencies: ["button", "dialog"] }, { name: "context-menu", type: "registry:ui", title: "Context Menu", description: "Right-click menu for an area, opening at the pointer and flipping at screen edges. Shares Dropdown Menu's items, checkbox and radio items, keyboard and typeahead; Menu key or Shift+F10 opens it from the keyboard.", exports: ["ContextMenuContent", "ContextMenuItem", "ContextMenuCheckboxItem", "ContextMenuRadioGroup", "ContextMenuRadioItem", "ContextMenuLabel", "ContextMenuSeparator", "ContextMenu", "ContextMenuTrigger"], keywords: ["actions", "align", "aligned", "and", "area", "but", "called", "center", "check", "checked", "children", "click", "clickable", "closes", "contextmenucontent", "contextmenutrigger", "destructive", "disabled", "dropdownmenuradioitem", "edge", "enter", "equals", "f10", "first", "focus", "focusable", "for", "group", "groups", "hint", "icon", "irreversible", "item", "items", "its", "key", "keyboard", "label", "labels", "leading", "lines", "mark", "menu", "new", "not", "oncheckedchange", "onopenchange", "onselect", "onvaluechange", "opens", "optionally", "picked", "pointer", "press", "red", "right", "selectable", "separators", "shift", "shortcut", "shown", "shows", "state", "the", "then", "trigger", "value", "variant", "when", "with"], registryDependencies: ["dropdown-menu", "utils"] }, { name: "count-to", type: "registry:ui", title: "CountTo", description: "Springs a number up from a start value once it scrolls into view. Prefix, suffix, decimals and locale.", exports: ["CountTo"], keywords: ["after", "and", "bcp", "before", "decimal", "decimals", "digits", "dom", "final", "for", "from", "grouping", "into", "locale", "number", "once", "point", "prefix", "scrolls", "seo", "springs", "starting", "stays", "suffix", "text", "the", "value", "view"], registryDependencies: ["utils"] }, { name: "custom-cursor", type: "registry:ui", title: "Custom Cursor", description: "Optional spring cursor that expands over interactive elements. Off on touch and reduced motion.", exports: ["CustomCursor"], keywords: ["coarse", "cursor", "dot", "elements", "expands", "interactive", "motion", "mount", "nothing", "once", "opt", "over", "pointers", "reduced", "renders", "ring", "spring", "touch", "trailing", "with"], registryDependencies: ["platform", "utils"] }, { name: "data-table", type: "registry:ui", title: "Data Table", description: "Table with columns as data: search across every column, sortable headers, checkbox selection that survives paging, a ⋯ menu per row, bulk actions in the toolbar and pagination. Built from Table, SearchInput, Checkbox, DropdownMenu, Pagination and Empty.", exports: ["DataTable"], keywords: ["accessor", "across", "actions", "all", "alternate", "and", "are", "backgrounds", "box", "bulk", "called", "cell", "checkbox", "client", "column", "columns", "compose", "controlled", "controls", "data", "defaultsort", "definitions", "display", "driven", "dropdownmenuitem", "each", "every", "field", "filters", "first", "for", "friends", "getrowid", "happen", "header", "ids", "items", "its", "jane", "kept", "label", "members", "menu", "name", "names", "onselectionchange", "order", "page", "pages", "pagesize", "pagination", "paging", "pair", "per", "placeholder", "readers", "receives", "render", "right", "row", "rowactions", "rowlabel", "rows", "screen", "search", "searchable", "searchplaceholder", "select", "selectable", "selected", "selection", "server", "show", "side", "sort", "sortable", "stable", "striped", "survives", "table", "that", "the", "toolbar", "with", "yourself"], registryDependencies: ["button", "checkbox", "dropdown-menu", "empty", "pagination", "search-input", "table", "use-controllable-state", "utils"] }, { name: "date-picker", type: "registry:ui", title: "Date Picker", description: "Field-styled button that opens a Calendar in a Popover, focused on the picked day. Single or range, presets such as Last 7 days, closes once the pick is complete, and submits ISO dates through a hidden input. Works inside Field.", exports: ["DatePicker"], keywords: ["accessible", "and", "are", "aria", "bcp", "beside", "blocks", "both", "button", "calendar", "called", "client", "closes", "controlled", "date", "day", "days", "default", "defaultvalue", "describedby", "disabled", "earliest", "end", "ends", "error", "extra", "field", "fill", "fills", "first", "focused", "for", "form", "from", "function", "grid", "hidden", "hint", "htmlfor", "ids", "input", "invalid", "isdisabled", "iso", "label", "last", "latest", "let", "locale", "max", "min", "mode", "monday", "name", "needs", "nothing", "null", "off", "once", "one", "only", "onvaluechange", "opening", "opens", "optional", "pair", "pick", "picked", "placeholder", "popover", "presets", "range", "reach", "readers", "ready", "render", "required", "rule", "saturday", "selectable", "set", "sets", "shortcuts", "single", "start", "styled", "styling", "submit", "submits", "sunday", "text", "that", "the", "then", "there", "these", "through", "today", "uncontrolled", "value", "visible", "weekends", "weekstartson", "when", "with"], registryDependencies: ["calendar", "field", "input", "popover", "use-controllable-state", "utils"] }, { name: "dialog", type: "registry:ui", title: "Dialog", description: "Portal modal with blurred backdrop, spring scale-in, focus trap, Esc and scroll lock.", exports: ["useDialog", "Dialog", "DialogTrigger", "DialogClose", "useModal", "DialogContent", "DialogHeader", "DialogFooter", "DialogTitle", "DialogDescription"], keywords: ["action", "alert", "alertdialog", "also", "and", "aria", "armed", "attach", "backdrop", "before", "behavior", "blur", "blurred", "body", "button", "called", "check", "children", "click", "close", "confirm", "confirmlabel", "confirmtimeout", "controlled", "corner", "default", "defaultopen", "defaults", "destructive", "dialog", "dialogclose", "dialogcontent", "dialogs", "dialogtrigger", "disables", "does", "done", "drawer", "emphasis", "esc", "feedback", "field", "fill", "first", "focus", "footer", "for", "give", "header", "height", "icon", "irreversible", "its", "label", "left", "loading", "loadinglabel", "lock", "modal", "mode", "never", "not", "off", "old", "onclick", "one", "ones", "only", "onopenchange", "open", "out", "padding", "page", "pair", "panel", "per", "place", "portal", "primary", "ref", "render", "reserved", "resets", "resize", "restore", "returned", "role", "root", "runs", "scale", "scroll", "second", "shared", "showclose", "shown", "shows", "size", "slides", "spinner", "spins", "spring", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "tab", "text", "the", "this", "topmost", "trap", "trigger", "two", "uncontrolled", "variant", "view", "where", "while", "width", "with"], registryDependencies: ["button", "platform", "use-controllable-state", "utils"] }, { name: "drawer", type: "registry:ui", title: "Drawer", description: "Edge panel (left, right, top, bottom) that springs in and swipes away. Shares Dialog's focus trap, scroll lock and Esc handling. Sidebar uses it below md.", exports: ["Drawer", "DrawerTrigger", "DrawerClose", "DrawerTitle", "DrawerDescription", "DrawerContent", "DrawerHeader", "DrawerBody", "DrawerFooter"], keywords: ["action", "also", "and", "anywhere", "aria", "armed", "backdrop", "before", "blur", "body", "bottom", "button", "called", "can", "check", "children", "click", "close", "confirm", "confirmlabel", "confirmtimeout", "content", "controlled", "corner", "default", "defaultopen", "defaults", "destructive", "dialogclose", "dialogcontent", "dialogtrigger", "disables", "dismiss", "done", "drag", "drawer", "drawers", "edge", "emphasis", "esc", "feedback", "fill", "first", "footer", "for", "from", "give", "handle", "header", "height", "icon", "irreversible", "its", "label", "left", "loading", "loadinglabel", "never", "old", "onclick", "one", "ones", "onopenchange", "open", "out", "padding", "pair", "panel", "per", "place", "primary", "render", "reserved", "resets", "resize", "runs", "scroll", "scrolls", "second", "showclose", "shown", "shows", "side", "size", "slides", "spinner", "spins", "spring", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "swipe", "taller", "text", "than", "that", "the", "their", "this", "top", "toward", "trigger", "two", "uncontrolled", "variant", "view", "when", "where", "while", "width", "with"], registryDependencies: ["dialog", "platform", "utils"] }, { name: "dropdown-menu", type: "registry:ui", title: "Dropdown Menu", description: "Action menu anchored to a Button: items with icons and shortcuts, checkbox and radio items, labels, separators, destructive variant. Arrow keys, typeahead, focus follows the pointer, Esc returns focus.", exports: ["MenuContext", "DropdownMenu", "DropdownMenuTrigger", "DropdownMenuContent", "DropdownMenuItem", "DropdownMenuCheckboxItem", "DropdownMenuRadioGroup", "DropdownMenuRadioItem", "DropdownMenuLabel", "DropdownMenuSeparator"], keywords: ["action", "actions", "align", "aligned", "also", "anchored", "and", "aria", "armed", "before", "blur", "but", "button", "called", "check", "checked", "children", "choice", "click", "closes", "closing", "confirm", "confirmlabel", "confirmtimeout", "content", "controlled", "default", "defaultopen", "defaults", "destructive", "disabled", "disables", "done", "down", "dropdownmenuradioitem", "edge", "emphasis", "enter", "equals", "esc", "feedback", "fill", "first", "for", "give", "group", "groups", "height", "hint", "icon", "irreversible", "item", "items", "its", "keeps", "keyboard", "label", "labels", "last", "leading", "left", "lines", "loading", "loadinglabel", "mark", "menu", "never", "new", "not", "old", "oncheckedchange", "onclick", "one", "ones", "onopenchange", "onselect", "onvaluechange", "open", "opens", "optionally", "out", "outside", "padding", "pair", "per", "picked", "picking", "place", "primary", "radiogroup", "red", "render", "reserved", "resets", "resize", "right", "runs", "second", "selectable", "selection", "separators", "shortcut", "shown", "shows", "size", "slides", "space", "spinner", "spins", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "text", "the", "then", "this", "toggles", "trigger", "two", "uncontrolled", "value", "variant", "view", "when", "where", "while", "width", "with", "without"], registryDependencies: ["button", "list", "platform", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "empty", type: "registry:ui", title: "Empty", description: "Server-safe empty state: icon tile, title, one helpful sentence and the next action. Bordered variant for empty lists and drop zones.", exports: ["Empty"], keywords: ["about", "action", "and", "app", "area", "bordered", "children", "clips", "dashed", "description", "drop", "empty", "for", "helpful", "icon", "inside", "like", "list", "next", "one", "outline", "page", "rounded", "sentence", "shown", "state", "the", "tile", "title", "what", "yet", "zone"], registryDependencies: ["utils"] }, { name: "field", type: "registry:ui", title: "Field", description: "Label, control, description and error as one unit. Controls inside (Input, Textarea, Select, Checkbox, Switch, RadioGroup) get id, aria-describedby, aria-invalid and required automatically; errors spring in and are announced.", exports: ["useFieldControl", "Field"], keywords: ["and", "aria", "automatically", "beside", "checkbox", "children", "control", "controls", "describedby", "description", "dims", "disabled", "disables", "enclosing", "error", "explicit", "field", "fills", "first", "for", "form", "from", "hint", "horizontal", "ids", "invalid", "its", "label", "makes", "marks", "match", "must", "one", "orientation", "out", "outside", "own", "picks", "props", "renders", "required", "returns", "shown", "springs", "state", "switch", "the", "unchanged", "under", "unit", "use", "when", "win", "wired", "with"], registryDependencies: ["label", "utils"] }, { name: "highlight", type: "registry:lib", description: "Lines of colored tokens, with Shiki loaded on demand. Runs anywhere: Code calls it in the\nbrowser, and a Server Component or a build can call it ahead of time and pass the result as\n`tokens`, so the browser never loads Shiki. Null for unknown languages.", exports: ["highlightCode", "languageOf"], keywords: ["ahead", "and", "anywhere", "back", "browser", "build", "call", "calls", "can", "code", "colored", "component", "demand", "extension", "falls", "file", "for", "from", "language", "languages", "lines", "loaded", "loads", "name", "never", "null", "pass", "result", "runs", "server", "shiki", "the", "time", "tokens", "tsx", "unknown", "with"], registryDependencies: [] }, { name: "hover-card", type: "registry:ui", title: "Hover Card", description: "Rich preview (profile, product, clip) that opens after a hover delay or keyboard focus. The pointer can move into the card; supplementary only.", exports: ["HoverCard"], keywords: ["align", "alignment", "avatar", "before", "bio", "can", "card", "children", "clip", "closedelay", "closes", "content", "flips", "focus", "for", "hover", "into", "keyboard", "leaves", "link", "mouse", "move", "must", "once", "only", "opendelay", "opens", "pointer", "preferred", "preview", "product", "profile", "rich", "room", "side", "sighted", "stats", "supplementary", "the", "there", "time", "trigger", "users", "usually", "when", "with", "without", "work"], registryDependencies: ["platform", "use-anchor", "use-hover-open", "utils"] }, { name: "input", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["fieldClass", "Input"], keywords: ["and", "aria", "chrome", "field", "filled", "group", "handed", "inputgroup", "inside", "the", "works"], registryDependencies: ["field", "utils"] }, { name: "input-group", type: "registry:ui", title: "Input Group", description: "Server-safe wrapper that fuses an Input with icons, text (https://, USD) or buttons into one field with a shared border and focus ring. Clicking an addon focuses the input.", exports: ["InputGroup", "InputGroupAddon"], keywords: ["addons", "align", "and", "beside", "border", "button", "buttons", "clicking", "control", "data", "draws", "drops", "field", "focus", "focuses", "group", "https", "icon", "icons", "inner", "input", "its", "like", "made", "matched", "one", "own", "plain", "plus", "ring", "side", "sits", "slot", "text", "the"], registryDependencies: ["utils"] }, { name: "input-otp", type: "registry:ui", title: "Input OTP", description: "One-time code in separate slots, backed by one real input: paste and SMS autofill work, screen readers hear one field. Grouped slots, numeric or alphanumeric, characters spring in, onComplete to submit. verified turns each character into a check, then merges them into one mark.", exports: ["InputOTP"], keywords: ["accepted", "again", "allowed", "alphanumeric", "and", "announced", "are", "autocomplete", "autofill", "back", "beside", "between", "called", "change", "character", "characters", "charset", "check", "code", "controlled", "counts", "dash", "defaultvalue", "draws", "dropped", "each", "edit", "every", "false", "filled", "fires", "first", "for", "group", "groups", "input", "into", "label", "laid", "length", "mark", "merge", "merged", "number", "once", "oncomplete", "one", "only", "onvaluechange", "others", "over", "pair", "paste", "pasted", "per", "read", "readers", "real", "render", "screen", "set", "shown", "single", "sits", "slides", "slot", "slots", "sms", "submit", "the", "then", "time", "transparently", "turns", "typed", "uncontrolled", "uppercased", "value", "verified", "verifiedlabel", "via", "visual", "was", "with"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "kbd", type: "registry:ui", title: "Kbd", description: "Server-safe key caps for shortcut hints. KbdGroup nests keys per the HTML spec.", exports: ["Kbd", "KbdGroup"], keywords: ["cap", "html", "kbd", "kbdgroup", "key", "keys", "made", "nested", "one", "per", "several", "shortcut", "spec", "the"], registryDependencies: ["utils"] }, { name: "label", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["Label"], keywords: [], registryDependencies: ["utils"] }, { name: "list", type: "registry:lib", description: "The item a navigation key moves to in a list, from the item at `index` (-1: none active).\nUndefined when the key doesn't navigate.", exports: ["listKeyTarget", "scrollIntoList"], keywords: ["active", "box", "can", "doesn", "enough", "from", "index", "item", "just", "key", "list", "moves", "moving", "navigate", "navigation", "none", "page", "scrollintoview", "scrolls", "show", "the", "undefined", "way", "when", "without"], registryDependencies: ["utils"] }, { name: "marker", type: "registry:ui", title: "Marker", description: "Highlighter-pen <mark> in four tints that wraps cleanly across lines and can draw itself on, left to right, when it scrolls into view. Highlight marks every match of a search in a string, for transcripts and search results.", exports: ["Marker", "Highlight"], keywords: ["across", "before", "case", "cleanly", "color", "delay", "draw", "drawing", "draws", "every", "first", "full", "fully", "highlight", "highlighter", "insensitive", "inside", "instant", "into", "left", "lines", "mark", "markers", "marks", "match", "motion", "one", "paragraph", "pen", "query", "reduced", "right", "scrolls", "search", "seconds", "several", "shown", "stagger", "sweeps", "term", "terms", "text", "the", "time", "view", "with", "without", "wraps"], registryDependencies: ["utils"] }, { name: "menubar", type: "registry:ui", title: "Menubar", description: "Desktop-style menu bar on the WAI-ARIA menubar pattern: one menu open at a time, hovering the next title while one is open switches to it, ← → walk the bar with or without a menu open, one Tab stop. A single highlight springs between titles; menus reuse every DropdownMenu item.", exports: ["MenubarContent", "MenubarItem", "MenubarCheckboxItem", "MenubarRadioGroup", "MenubarRadioItem", "MenubarLabel", "MenubarSeparator", "Menubar", "MenubarMenu", "MenubarTrigger"], keywords: ["actions", "align", "aligned", "analytics", "and", "another", "apart", "bar", "between", "but", "called", "check", "checked", "children", "click", "closes", "desktop", "destructive", "disabled", "down", "dropdownmenuradioitem", "edge", "enter", "equals", "first", "for", "generated", "give", "group", "groups", "highlight", "hint", "hovering", "icon", "irreversible", "item", "items", "its", "label", "labels", "last", "leading", "left", "lines", "mark", "menu", "menubarcontent", "menubartrigger", "menus", "move", "new", "not", "omitted", "oncheckedchange", "one", "onselect", "onvaluechange", "open", "opens", "optional", "optionally", "picked", "red", "right", "selectable", "separators", "shortcut", "shown", "shows", "space", "springs", "stable", "state", "style", "switches", "tell", "tests", "the", "then", "time", "title", "titles", "toggles", "trigger", "value", "variant", "when", "while", "with"], registryDependencies: ["dropdown-menu", "list", "use-indicator", "utils"] }, { name: "message-bubble", type: "registry:ui", title: "Message Bubble", description: "User/assistant chat bubbles with avatar slot, streaming dots and copyable code blocks.", exports: ["MessageBubble"], keywords: ["above", "accent", "after", "and", "animated", "are", "assistant", "attachments", "avatar", "bubble", "chat", "children", "code", "content", "dots", "from", "inline", "left", "lists", "message", "name", "next", "rich", "right", "sender", "shown", "shows", "side", "size", "slot", "streaming", "surface", "text", "the", "time", "typing", "user"], registryDependencies: ["utils"] }, { name: "meter", type: "registry:ui", title: "Meter", description: "Server-safe gauge for a value in a known range (storage, quota, server load, password strength). Colors by <meter> thresholds, or stacked segments with a legend, like a storage bar.", exports: ["Meter"], keywords: ["above", "accessible", "also", "and", "away", "bar", "below", "between", "bound", "color", "colors", "decides", "defaults", "disk", "follow", "good", "green", "high", "known", "label", "legend", "like", "load", "low", "lower", "max", "measurement", "meter", "min", "name", "not", "one", "optimum", "orange", "overrides", "parts", "password", "progress", "quota", "range", "red", "region", "right", "segments", "server", "stacked", "storage", "strength", "sum", "task", "text", "the", "their", "this", "threshold", "thresholds", "total", "two", "upper", "use", "used", "value", "valuetext", "visible", "where", "with", "within"], registryDependencies: ["utils"] }, { name: "motion-provider", type: "registry:component", exports: ["MotionProvider"], keywords: [], registryDependencies: ["utils"] }, { name: "native-select", type: "registry:ui", title: "Native Select", description: "A real <select> with option groups: native picker on phones, no-JS forms, native required validation. Where customizable select is supported (appearance: base-select), the open list gets the menu look.", exports: ["NativeSelect", "NativeSelectGroup", "NativeSelectOption"], keywords: ["appearance", "base", "browser", "custom", "customizable", "elsewhere", "forms", "gets", "group", "heading", "icons", "instead", "invalid", "label", "labeled", "list", "look", "menu", "native", "need", "open", "optgroup", "options", "phones", "picker", "real", "rendering", "required", "select", "stays", "supports", "the", "use", "user", "validation", "when", "where", "without", "works"], registryDependencies: ["field", "input", "utils"] }, { name: "navigation-menu", type: "registry:ui", title: "Navigation Menu", description: "Website top navigation on the APG disclosure pattern: plain links and panels of rich links. Hover opens after a beat, then sliding along the bar switches panels at once; every panel shares one viewport that springs to the next panel's size and position while the content slides in from the side you moved toward. Click, Enter, ↓, ← → and Esc work; closed panels keep their links in the HTML for crawlers.", exports: ["NavigationMenu", "NavigationMenuList", "NavigationMenuItem", "NavigationMenuTrigger", "NavigationMenuContent", "NavigationMenuLink"], keywords: ["active", "after", "all", "along", "and", "aria", "bar", "beat", "bold", "called", "children", "classname", "click", "closed", "closes", "content", "controlled", "crawlers", "current", "defaultvalue", "description", "down", "enter", "entry", "esc", "find", "first", "focuses", "following", "for", "generated", "hidden", "hover", "html", "icon", "inset", "into", "item", "items", "its", "left", "level", "line", "link", "links", "look", "matched", "menu", "mouse", "muted", "navigation", "omitted", "once", "one", "onvaluechange", "open", "opened", "opens", "optional", "own", "padding", "page", "pair", "panel", "panels", "pill", "plain", "readers", "rem", "render", "rich", "right", "row", "selected", "single", "size", "sliding", "space", "springs", "stable", "stay", "still", "switches", "the", "them", "then", "tile", "title", "toggle", "top", "trigger", "uncontrolled", "under", "value", "viewport", "walk", "website", "while", "with", "your"], registryDependencies: ["use-controllable-state", "use-dismiss", "use-indicator", "utils"] }, { name: "newsletter", type: "registry:block", title: "Newsletter", description: "Email signup: InputGroup with the submit Button inside, native email validation, a loading → success toast and an in-place success state on the button.", exports: ["Newsletter"], keywords: ["above", "address", "after", "and", "button", "check", "confirm", "confirms", "description", "email", "field", "for", "form", "heading", "inbox", "inputgroup", "inside", "into", "its", "line", "loading", "message", "native", "next", "onsubscribe", "place", "placeholder", "rejection", "resets", "resolves", "saved", "shows", "signup", "submit", "submitlabel", "success", "successmessage", "supporting", "text", "that", "the", "then", "title", "toast", "turns", "under", "validation", "when", "with", "your"], registryDependencies: ["button", "input", "input-group", "toast", "utils"] }, { name: "number-input", type: "registry:ui", title: "Number Input", description: "Native number field with −/+ buttons: arrow keys, min/max/step validation and form submit from the platform; clamps on blur, rounds to the step's precision.", exports: ["NumberInput"], keywords: ["amount", "and", "are", "arrows", "arrowup", "buttons", "called", "cart", "change", "controlled", "defaultvalue", "down", "field", "first", "form", "helpers", "highest", "keyboard", "lowest", "max", "min", "native", "new", "number", "onvaluechange", "pair", "pointer", "quantity", "render", "step", "submit", "tabindex", "the", "uncontrolled", "use", "users", "validation", "value", "with"], registryDependencies: ["input", "input-group", "use-controllable-state", "utils"] }, { name: "overflow-focus", type: "registry:lib", description: `Drop inside a scroll container: while the container overflows it becomes keyboard-focusable
|
|
17158
|
+
index: [{ name: "accent-picker", type: "registry:ui", title: "Accent Picker", description: "Accent color row: eight swatches (red to slate) that retint primary, focus rings, selection, switches and checkboxes app-wide. Persisted, applied before paint, or set your own hue with --accent-hue.", exports: ["AccentPicker"], keywords: ["accent", "app", "color", "radio", "retint", "row", "setaccent", "swatches", "that", "the", "via", "whole"], registryDependencies: ["theme", "utils"] }, { name: "accordion", type: "registry:ui", title: "Accordion", description: "Single or multiple panels with spring height animation. Closed content stays in the DOM for SEO.", exports: ["Accordion", "AccordionItem", "AccordionTrigger", "AccordionContent"], keywords: ["accordion", "accordioncontent", "accordionitem", "accordiontrigger", "allow", "and", "called", "children", "closed", "closes", "closing", "collapsible", "content", "controlled", "crawlable", "default", "defaultvalue", "every", "first", "heading", "height", "html", "independent", "inert", "item", "items", "level", "match", "matched", "mounted", "multiple", "none", "one", "only", "onvaluechange", "open", "outline", "page", "panel", "panels", "question", "remains", "render", "single", "stays", "text", "the", "time", "type", "uncontrolled", "unique", "value", "when", "while", "with", "within", "wrapping"], registryDependencies: ["use-controllable-state", "utils"] }, { name: "alert", type: "registry:ui", title: "Alert", description: "Server-safe inline banner: tinted surface, colored icon, title, description and an optional action. Info, success, warning and destructive tones follow the accent and status tokens.", exports: ["Alert", "AlertTitle", "AlertDescription"], keywords: ["action", "add", "alert", "aligned", "and", "announced", "appears", "banner", "button", "colored", "default", "description", "did", "for", "icon", "inline", "live", "load", "none", "not", "null", "pass", "region", "replaces", "response", "right", "role", "sets", "should", "slot", "small", "something", "static", "surface", "the", "tint", "tinted", "title", "tone", "user", "variant", "when"], registryDependencies: ["utils"] }, { name: "app-window", type: "registry:ui", title: "AppWindow", description: "Window container with close / minimize / zoom controls, title, custom header slot and actions. SegmentedTabs is the compact view switcher for its title bar.", exports: ["AppWindow"], keywords: ["actions", "aligned", "area", "bar", "blurred", "bodyclassname", "button", "called", "centered", "classes", "content", "control", "custom", "dot", "for", "glass", "handler", "header", "into", "matching", "maximize", "minimize", "navbar", "onclose", "onmaximize", "onminimize", "passing", "pressed", "replaces", "right", "search", "shows", "slot", "surface", "tabs", "text", "the", "title", "titlebar", "translucent", "turns", "under", "when"], registryDependencies: ["utils"] }, { name: "aspect-ratio", type: "registry:ui", title: "Aspect Ratio", description: "Server-safe box locked to a ratio (16:9 thumbnails, 9:16 clips). A direct image or video child fills it with object-cover.", exports: ["AspectRatio"], keywords: ["box", "child", "cover", "direct", "fills", "height", "img", "locked", "object", "ratio", "video", "width"], registryDependencies: ["utils"] }, { name: "attachment", type: "registry:ui", title: "Attachment & Dropzone", description: "File chips with image thumbnails or type icons, size, a springing upload bar, error state and remove; the list springs chips in and closes the gap. FileDropzone wraps a real file input: click, keyboard and the native picker work, drop and paste are checked against accept and maxSize, and dropped files land in the input so forms and Server Actions receive them.", exports: ["formatBytes", "Attachment", "AttachmentList", "FileDropzone"], keywords: ["accept", "actions", "along", "and", "are", "area", "aria", "around", "attachments", "attribute", "back", "bar", "bcp", "blocks", "both", "bottom", "browse", "button", "bytes", "called", "child", "children", "chip", "click", "content", "createobjecturl", "default", "describedby", "disabled", "download", "drop", "dropped", "drops", "each", "edge", "enforced", "enter", "error", "failed", "field", "file", "files", "fills", "for", "form", "forms", "fresh", "from", "get", "given", "hint", "href", "icon", "ids", "image", "input", "into", "invalid", "key", "least", "line", "link", "locale", "makes", "maxsize", "mime", "more", "multiple", "name", "native", "needs", "one", "onfiles", "onreject", "onremove", "out", "passed", "paste", "pdf", "picked", "picker", "picks", "place", "plain", "pressed", "progress", "real", "reason", "red", "remove", "removed", "replaces", "required", "same", "server", "sets", "show", "shows", "size", "source", "space", "spring", "springs", "src", "styling", "submit", "syntax", "text", "than", "that", "the", "them", "thumbnail", "too", "turns", "type", "types", "upload", "uploading", "url", "when", "while", "with", "work", "written"], registryDependencies: ["field", "utils"] }, { name: "avatar", type: "registry:ui", title: "Avatar", description: "Image with initials fallback on error, three sizes and online/away/busy/offline dots.", exports: ["Avatar"], keywords: ["alt", "and", "announced", "corner", "diameter", "dot", "fails", "fallback", "for", "icon", "image", "initials", "loads", "name", "overrides", "person", "presence", "show", "size", "src", "status", "text", "the", "url", "used", "while", "with"], registryDependencies: ["utils"] }, { name: "avatar-group", type: "registry:ui", title: "AvatarGroup", description: "Overlapping avatars with a +N overflow chip. Hover gently enlarges the avatar on a spring, keeping stack order.", exports: ["AvatarGroup"], keywords: ["alt", "and", "avatar", "avatars", "before", "chip", "each", "enlarges", "every", "gently", "hover", "how", "many", "max", "name", "one", "order", "overflow", "overlapping", "people", "show", "size", "spring", "stack", "staying", "the", "users", "with"], registryDependencies: ["avatar", "utils"] }, { name: "badge", type: "registry:ui", title: "Badge & Pill", description: "Minimal status tags. Rounded badge or fully rounded pill, with optional dot. pulse adds an expanding live-status ring.", exports: ["Badge"], keywords: ["and", "color", "current", "dot", "emits", "expanding", "forever", "fully", "leading", "like", "live", "needs", "pill", "pulse", "ring", "rounded", "shape", "status", "surface", "tag", "text", "the", "variant"], registryDependencies: ["utils"] }, { name: "breadcrumb", type: "registry:ui", title: "Breadcrumb", description: "Navigation trail from a list of items: links up to the current page, which is marked for assistive tech. Server-safe, custom separator.", exports: ["Breadcrumb"], keywords: ["between", "chevron", "current", "default", "drawn", "ending", "first", "item", "items", "last", "links", "list", "outermost", "page", "safe", "separator", "server", "site", "sits", "the", "trail", "where"], registryDependencies: [] }, { name: "button", type: "registry:ui", title: "Button", description: "Five variants, four sizes, spring press feedback, an animated loading spinner and in-place success state, a two-step confirm that swaps the label on first click, and a configurable swap direction. Width stays fixed to the longest label.", exports: ["Button"], keywords: ["action", "also", "and", "aria", "armed", "before", "blur", "button", "check", "children", "click", "confirm", "confirmlabel", "confirmtimeout", "default", "defaults", "destructive", "disables", "done", "emphasis", "esc", "feedback", "fill", "first", "for", "give", "height", "icon", "irreversible", "its", "label", "left", "loading", "loadinglabel", "never", "old", "onclick", "one", "ones", "out", "padding", "per", "place", "primary", "reserved", "resets", "resize", "runs", "second", "shown", "shows", "size", "slides", "spinner", "spins", "square", "status", "step", "success", "successlabel", "swap", "swaps", "text", "the", "this", "two", "variant", "view", "where", "while", "width", "with"], registryDependencies: ["button-variants", "utils"] }, { name: "button-group", type: "registry:ui", title: "Button Group", description: "Joins buttons into one strip that shares borders, corners and active states. Horizontal or vertical.", exports: ["ButtonGroup"], keywords: ["and", "attached", "borders", "buttons", "connected", "control", "corners", "default", "fuse", "groups", "horizontal", "into", "orientation", "related", "single", "strip", "together", "toolbar", "true", "vertical"], registryDependencies: ["utils"] }, { name: "button-variants", type: "registry:ui", description: 'Button classes for non-button elements, e.g. `<a className={buttonVariants({ variant: "outline" })}>`.', exports: ["buttonVariants"], keywords: ["button", "buttonvariants", "classes", "classname", "elements", "for", "non", "outline", "variant"], registryDependencies: ["utils"] }, { name: "calendar", type: "registry:ui", title: "Calendar", description: "Month grid on the WAI-ARIA date-grid pattern: single date or range with a hover preview, min/max and custom disabled days, months that slide in from the direction of travel. Arrows, Home/End and PageUp/PageDown (+Shift for years). Hydration-safe: today is only marked in the browser.", exports: ["key", "Calendar"], keywords: ["and", "another", "any", "aria", "arrows", "autofocus", "bcp", "called", "client", "controlled", "current", "custom", "date", "datepicker", "dates", "day", "days", "default", "defaultmonth", "defaultvalue", "direction", "disabled", "displayed", "earliest", "end", "ends", "extra", "first", "focus", "for", "from", "function", "grid", "home", "hover", "into", "isdisabled", "iso", "keyboard", "latest", "like", "local", "locale", "max", "min", "mode", "monday", "month", "months", "mount", "names", "nothing", "null", "off", "one", "only", "onmonthchange", "onvaluechange", "pagedown", "pages", "pageup", "pattern", "pick", "picked", "preview", "range", "render", "rule", "saturday", "selectable", "sets", "shift", "shown", "single", "slide", "sorts", "start", "sunday", "the", "then", "this", "travel", "uncontrolled", "user", "value", "wai", "week", "weekday", "weekends", "weekstartson", "when", "with", "year", "yyyy"], registryDependencies: ["button", "use-controllable-state", "utils"] }, { name: "card", type: "registry:ui", title: "Card", description: "Composable surface: header, title, description, content and footer. Optional glass.", exports: ["Card", "CardHeader", "CardTitle", "CardDescription", "CardContent", "CardFooter"], keywords: ["backgrounds", "colored", "default", "directly", "fits", "follows", "glass", "heading", "level", "not", "outline", "over", "page", "place", "subtle", "textured", "that", "the", "translucency", "under", "when"], registryDependencies: ["utils"] }, { name: "carousel", type: "registry:ui", title: "Carousel", description: "Native scroll-snap row, so touch, trackpad and no-JS scrolling work, with spring-driven arrows, page dots, arrow keys and mouse drag that throws to the next snap point. APG carousel semantics: a labeled region of slides announced as 3 of 8.", exports: ["Carousel", "CarouselContent", "CarouselItem", "CarouselPrevious", "CarouselNext", "CarouselDots"], keywords: ["accessible", "all", "and", "announced", "any", "apg", "are", "arrow", "basis", "buttons", "carousel", "css", "default", "dot", "dots", "drag", "driven", "edge", "end", "fewer", "from", "gap", "hides", "keys", "label", "labeled", "left", "mouse", "name", "native", "not", "one", "overlaid", "page", "pages", "per", "projects", "region", "rem", "right", "row", "scroll", "scrolling", "semantics", "sized", "slide", "slides", "snap", "spring", "start", "the", "there", "total", "touch", "trackpad", "two", "variables", "view", "with", "work"], registryDependencies: ["button", "utils"] }, { name: "changelog", type: "registry:block", title: "Changelog", description: "Release notes on a Timeline: newest release highlighted, changes typed New / Improved / Fixed with Badges, and a Kbd shortcut to try the headline feature. Server-safe.", exports: ["Changelog"], keywords: ["are", "badges", "changes", "first", "highlighted", "how", "kbd", "newest", "notes", "one", "release", "releases", "shows", "the", "timeline", "try", "typed", "with"], registryDependencies: ["badge", "kbd", "timeline", "utils"] }, { name: "chart", type: "registry:ui", title: "Chart", description: "Line, area and bar (grouped or stacked) charts in SVG with a colorblind-validated eight-color palette that keeps each series' color. Crosshair tooltip listing every series, arrow-key readout, legend that hides series, direct end labels, a table view, and spring transitions between data.", exports: ["Chart"], keywords: ["add", "and", "are", "area", "areas", "arrow", "assistive", "axis", "bar", "bars", "bcp", "can", "captions", "categorical", "category", "chart", "charts", "compact", "crosshair", "currency", "data", "direct", "each", "eight", "end", "every", "filled", "fold", "for", "format", "grouping", "height", "hides", "index", "instead", "into", "key", "keys", "label", "labels", "legend", "line", "lines", "listing", "locale", "mark", "most", "names", "notation", "numbers", "object", "one", "only", "other", "pages", "palette", "past", "per", "plot", "plus", "props", "render", "row", "serializable", "series", "server", "split", "stack", "stacked", "style", "svg", "table", "tail", "tech", "that", "the", "them", "ticks", "too", "tooltip", "type", "usd", "value", "view", "with"], registryDependencies: ["button", "table", "utils"] }, { name: "checkbox", type: "registry:ui", title: "Checkbox", description: "Native checkbox with a spring-drawn check mark and an indeterminate state for select-all rows. Controlled or uncontrolled; submits with forms.", exports: ["Checkbox"], keywords: ["all", "called", "check", "checkbox", "checked", "controlled", "dash", "defaultchecked", "drawn", "field", "first", "indeterminate", "inside", "mixed", "native", "new", "oncheckedchange", "pair", "render", "rows", "select", "selected", "shows", "some", "spring", "state", "the", "uncontrolled", "with", "works"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "clip-card", type: "registry:block", title: "Clip Card", description: "Video tile: AspectRatio thumbnail (16:9 or 9:16), duration Badge, watched Progress along the bottom, and a ContextMenu of actions.", exports: ["ClipCard"], keywords: ["accessible", "actions", "ago", "along", "also", "and", "aspectratio", "badge", "bar", "bottom", "card", "click", "clip", "clips", "context", "contextmenuitem", "days", "duration", "f10", "film", "for", "glyph", "height", "how", "img", "items", "menu", "meta", "much", "name", "one", "opens", "print", "progress", "ratio", "right", "shift", "small", "stands", "the", "them", "thin", "thumbnail", "tile", "title", "under", "vertical", "video", "views", "was", "watched", "width", "without"], registryDependencies: ["aspect-ratio", "badge", "context-menu", "progress", "utils"] }, { name: "code", type: "registry:ui", title: "Code", description: "Shiki-highlighted code that follows light and dark through light-dark() token colors, as a block, an inline one-liner or a tabbed file panel. Line numbers (from any start line), tinted lines with an accent bar, <mark>ed words or column ranges, and per-line notes in a tooltip that keyboard users can tab to. Optional Prettier at display time; copy hands out exactly what is shown.", exports: ["CopyButton", "Code", "CodePanel"], keywords: ["accessible", "active", "add", "all", "and", "animates", "annotations", "bar", "bash", "before", "behind", "block", "body", "build", "button", "clipboard", "code", "collapse", "copied", "copy", "dark", "default", "dom", "each", "every", "excerpts", "file", "files", "first", "focus", "fold", "for", "format", "formatted", "from", "gets", "ghost", "gutter", "header", "highlight", "highlightcode", "highlighted", "highlighting", "hover", "ignored", "inline", "inside", "into", "its", "json", "keep", "label", "language", "least", "left", "light", "line", "linenumbers", "lines", "loads", "longer", "made", "many", "mark", "marks", "name", "never", "note", "notes", "number", "numbers", "one", "options", "own", "page", "paint", "panel", "per", "place", "prettier", "primary", "ranges", "refer", "registry", "remember", "renders", "run", "scrolling", "scrolls", "server", "sets", "shared", "shiki", "show", "source", "stays", "switching", "syntax", "tab", "terminal", "text", "than", "that", "the", "themes", "this", "time", "tint", "tokens", "too", "touch", "tsx", "turns", "variant", "vertically", "wheel", "with", "words", "wrapped", "written"], registryDependencies: ["button", "highlight", "overflow-focus", "tabs", "tooltip", "utils"] }, { name: "collapsible", type: "registry:ui", title: "Collapsible", description: "A single show/hide region with a spring height animation and rotating chevron. Controlled or uncontrolled; closed content stays in the DOM for SEO.", exports: ["Collapsible", "CollapsibleTrigger", "CollapsibleContent"], keywords: ["after", "and", "called", "chevron", "children", "closed", "collapsiblecontent", "collapsibletrigger", "content", "controlled", "crawlable", "default", "defaultopen", "first", "height", "hide", "html", "inert", "label", "mounted", "one", "onopenchange", "open", "pair", "region", "remains", "render", "rotating", "show", "springs", "state", "stays", "that", "the", "toggles", "trigger", "true", "uncontrolled", "when", "while", "with"], registryDependencies: ["use-controllable-state", "utils"] }, { name: "combobox", type: "registry:ui", title: "Combobox", description: "A Select you can type into: the query filters by label and keywords (prefix matches first), arrows move, Enter picks. multiple keeps the list open and shows picks as removable tags. Submits through hidden inputs.", exports: ["Combobox"], keywords: ["accessible", "and", "aria", "backspace", "blocks", "called", "can", "choices", "closes", "controlled", "defaultvalue", "describedby", "disabled", "down", "emptytext", "enter", "error", "esc", "every", "field", "fills", "filtered", "filters", "first", "form", "from", "hidden", "hint", "ids", "input", "inputs", "into", "invalid", "keeps", "label", "last", "list", "matches", "move", "multiple", "name", "needs", "nothing", "one", "onvaluechange", "open", "opening", "options", "pair", "per", "pick", "picked", "picks", "placeholder", "removable", "removes", "render", "required", "select", "sets", "show", "shown", "shows", "single", "stay", "styling", "submit", "submits", "tags", "text", "the", "there", "through", "type", "types", "typing", "uncontrolled", "user", "value", "values", "visible", "when", "with", "you"], registryDependencies: ["field", "list", "platform", "tag-input", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "command", type: "registry:ui", title: "Command", description: "⌘K palette: filterable groups, arrow-key highlight, Enter to run, keyword matching. Inline or as CommandDialog with a global shortcut; the first Esc clears, the second closes.", exports: ["Command", "CommandInput", "CommandList", "CommandEmpty", "CommandGroup", "CommandSeparator", "CommandItem", "CommandDialog"], keywords: ["accessible", "after", "against", "and", "arrows", "but", "called", "children", "click", "close", "closes", "collapse", "command", "commanddialog", "commandempty", "commandinput", "commanditem", "commandlist", "content", "controlled", "ctrl", "defaults", "dialog", "disable", "disabled", "driven", "elsewhere", "end", "enter", "esc", "extra", "false", "filterable", "filtering", "for", "global", "group", "groups", "heading", "hidden", "hides", "home", "icon", "inline", "input", "inside", "item", "items", "its", "itself", "keepopen", "keyboard", "keywords", "label", "list", "listbox", "mac", "match", "matched", "matches", "mod", "move", "name", "none", "not", "only", "onopenchange", "onselect", "open", "option", "outside", "own", "pair", "palette", "pass", "passes", "placeholder", "preferences", "query", "results", "scrollable", "search", "selectable", "selecting", "selection", "selects", "separators", "settings", "shortcut", "shown", "shows", "stack", "state", "stay", "terms", "text", "the", "title", "toggle", "toggled", "use", "used", "value", "visible", "visually", "when", "while", "with", "would"], registryDependencies: ["dialog", "list", "search-input", "separator", "use-controllable-state", "use-hotkey", "utils"] }, { name: "confirm", type: "registry:ui", title: "Confirm", description: "Promise-based confirm dialog called like toast: await confirm({ title, description, destructive }) resolves true or false. Built on Dialog's alert mode, Cancel takes the first focus, Esc cancels, one host mounted in the layout.", exports: ["confirm", "Confirmer"], keywords: ["acting", "asks", "await", "before", "cancel", "confirm", "confirmer", "delete", "destructive", "esc", "false", "for", "host", "layout", "mount", "mounted", "needs", "newer", "next", "once", "project", "remove", "resolves", "root", "title", "toaster", "true"], registryDependencies: ["button", "dialog"] }, { name: "context-menu", type: "registry:ui", title: "Context Menu", description: "Right-click menu for an area, opening at the pointer and flipping at screen edges. Shares Dropdown Menu's items, checkbox and radio items, keyboard and typeahead; Menu key or Shift+F10 opens it from the keyboard.", exports: ["ContextMenuContent", "ContextMenuItem", "ContextMenuCheckboxItem", "ContextMenuRadioGroup", "ContextMenuRadioItem", "ContextMenuLabel", "ContextMenuSeparator", "ContextMenu", "ContextMenuTrigger"], keywords: ["actions", "align", "aligned", "and", "area", "but", "called", "center", "check", "checked", "children", "click", "clickable", "closes", "contextmenucontent", "contextmenutrigger", "destructive", "disabled", "dropdownmenuradioitem", "edge", "enter", "equals", "f10", "first", "focus", "focusable", "for", "group", "groups", "hint", "icon", "irreversible", "item", "items", "its", "key", "keyboard", "label", "labels", "leading", "lines", "mark", "menu", "new", "not", "oncheckedchange", "onopenchange", "onselect", "onvaluechange", "opens", "optionally", "picked", "pointer", "press", "red", "right", "selectable", "separators", "shift", "shortcut", "shown", "shows", "state", "the", "then", "trigger", "value", "variant", "when", "with"], registryDependencies: ["dropdown-menu", "utils"] }, { name: "count-to", type: "registry:ui", title: "CountTo", description: "Springs a number up from a start value once it scrolls into view. Prefix, suffix, decimals and locale.", exports: ["CountTo"], keywords: ["after", "and", "bcp", "before", "decimal", "decimals", "digits", "dom", "final", "for", "from", "grouping", "into", "locale", "number", "once", "point", "prefix", "scrolls", "seo", "springs", "starting", "stays", "suffix", "text", "the", "value", "view"], registryDependencies: ["utils"] }, { name: "custom-cursor", type: "registry:ui", title: "Custom Cursor", description: "Optional spring cursor that expands over interactive elements. Off on touch and reduced motion.", exports: ["CustomCursor"], keywords: ["coarse", "cursor", "dot", "elements", "expands", "interactive", "motion", "mount", "nothing", "once", "opt", "over", "pointers", "reduced", "renders", "ring", "spring", "touch", "trailing", "with"], registryDependencies: ["platform", "utils"] }, { name: "data-table", type: "registry:ui", title: "Data Table", description: "Table with columns as data: search across every column, sortable headers, checkbox selection that survives paging, a ⋯ menu per row, bulk actions in the toolbar and pagination. Built from Table, SearchInput, Checkbox, DropdownMenu, Pagination and Empty.", exports: ["DataTable"], keywords: ["accessor", "across", "actions", "all", "alternate", "and", "are", "backgrounds", "box", "bulk", "called", "cell", "checkbox", "client", "column", "columns", "compose", "controlled", "controls", "data", "defaultsort", "definitions", "display", "driven", "dropdownmenuitem", "each", "every", "field", "filters", "first", "for", "friends", "getrowid", "happen", "header", "ids", "items", "its", "jane", "kept", "label", "members", "menu", "name", "names", "onselectionchange", "order", "page", "pages", "pagesize", "pagination", "paging", "pair", "per", "placeholder", "readers", "receives", "render", "right", "row", "rowactions", "rowlabel", "rows", "screen", "search", "searchable", "searchplaceholder", "select", "selectable", "selected", "selection", "server", "show", "side", "sort", "sortable", "stable", "striped", "survives", "table", "that", "the", "toolbar", "with", "yourself"], registryDependencies: ["button", "checkbox", "dropdown-menu", "empty", "pagination", "search-input", "table", "use-controllable-state", "utils"] }, { name: "date-picker", type: "registry:ui", title: "Date Picker", description: "Field-styled button that opens a Calendar in a Popover, focused on the picked day. Single or range, presets such as Last 7 days, closes once the pick is complete, and submits ISO dates through a hidden input. Works inside Field.", exports: ["DatePicker"], keywords: ["accessible", "and", "are", "aria", "bcp", "beside", "blocks", "both", "button", "calendar", "called", "client", "closes", "controlled", "date", "day", "days", "default", "defaultvalue", "describedby", "disabled", "earliest", "end", "ends", "error", "extra", "field", "fill", "fills", "first", "focused", "for", "form", "from", "function", "grid", "hidden", "hint", "htmlfor", "ids", "input", "invalid", "isdisabled", "iso", "label", "last", "latest", "let", "locale", "max", "min", "mode", "monday", "name", "needs", "nothing", "null", "off", "once", "one", "only", "onvaluechange", "opening", "opens", "optional", "pair", "pick", "picked", "placeholder", "popover", "presets", "range", "reach", "readers", "ready", "render", "required", "rule", "saturday", "selectable", "set", "sets", "shortcuts", "single", "start", "styled", "styling", "submit", "submits", "sunday", "text", "that", "the", "then", "there", "these", "through", "today", "uncontrolled", "value", "visible", "weekends", "weekstartson", "when", "with"], registryDependencies: ["calendar", "field", "input", "popover", "use-controllable-state", "utils"] }, { name: "dialog", type: "registry:ui", title: "Dialog", description: "Portal modal with blurred backdrop, spring scale-in, focus trap, Esc and scroll lock.", exports: ["useDialog", "Dialog", "DialogTrigger", "DialogClose", "useModal", "DialogContent", "DialogHeader", "DialogFooter", "DialogTitle", "DialogDescription"], keywords: ["action", "alert", "alertdialog", "also", "and", "aria", "armed", "attach", "backdrop", "before", "behavior", "blur", "blurred", "body", "button", "called", "check", "children", "click", "close", "confirm", "confirmlabel", "confirmtimeout", "controlled", "corner", "default", "defaultopen", "defaults", "destructive", "dialog", "dialogclose", "dialogcontent", "dialogs", "dialogtrigger", "disables", "does", "done", "drawer", "emphasis", "esc", "feedback", "field", "fill", "first", "focus", "footer", "for", "give", "header", "height", "icon", "irreversible", "its", "label", "left", "loading", "loadinglabel", "lock", "modal", "mode", "never", "not", "off", "old", "onclick", "one", "ones", "only", "onopenchange", "open", "out", "padding", "page", "pair", "panel", "per", "place", "portal", "primary", "ref", "render", "reserved", "resets", "resize", "restore", "returned", "role", "root", "runs", "scale", "scroll", "second", "shared", "showclose", "shown", "shows", "size", "slides", "spinner", "spins", "spring", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "tab", "text", "the", "this", "topmost", "trap", "trigger", "two", "uncontrolled", "variant", "view", "where", "while", "width", "with"], registryDependencies: ["button", "platform", "use-controllable-state", "utils"] }, { name: "drawer", type: "registry:ui", title: "Drawer", description: "Edge panel (left, right, top, bottom) that springs in and swipes away. Shares Dialog's focus trap, scroll lock and Esc handling. Sidebar uses it below md.", exports: ["Drawer", "DrawerTrigger", "DrawerClose", "DrawerTitle", "DrawerDescription", "DrawerContent", "DrawerHeader", "DrawerBody", "DrawerFooter"], keywords: ["action", "also", "and", "anywhere", "aria", "armed", "backdrop", "before", "blur", "body", "bottom", "button", "called", "can", "check", "children", "click", "close", "confirm", "confirmlabel", "confirmtimeout", "content", "controlled", "corner", "default", "defaultopen", "defaults", "destructive", "dialogclose", "dialogcontent", "dialogtrigger", "disables", "dismiss", "done", "drag", "drawer", "drawers", "edge", "emphasis", "esc", "feedback", "fill", "first", "footer", "for", "from", "give", "handle", "header", "height", "icon", "irreversible", "its", "label", "left", "loading", "loadinglabel", "never", "old", "onclick", "one", "ones", "onopenchange", "open", "out", "padding", "pair", "panel", "per", "place", "primary", "render", "reserved", "resets", "resize", "runs", "scroll", "scrolls", "second", "showclose", "shown", "shows", "side", "size", "slides", "spinner", "spins", "spring", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "swipe", "taller", "text", "than", "that", "the", "their", "this", "top", "toward", "trigger", "two", "uncontrolled", "variant", "view", "when", "where", "while", "width", "with"], registryDependencies: ["dialog", "platform", "utils"] }, { name: "dropdown-menu", type: "registry:ui", title: "Dropdown Menu", description: "Action menu anchored to a Button: items with icons and shortcuts, checkbox and radio items, labels, separators, destructive variant. Arrow keys, typeahead, focus follows the pointer, Esc returns focus.", exports: ["MenuContext", "DropdownMenu", "DropdownMenuTrigger", "DropdownMenuContent", "DropdownMenuItem", "DropdownMenuCheckboxItem", "DropdownMenuRadioGroup", "DropdownMenuRadioItem", "DropdownMenuLabel", "DropdownMenuSeparator"], keywords: ["action", "actions", "align", "aligned", "also", "anchored", "and", "aria", "armed", "before", "blur", "but", "button", "called", "check", "checked", "children", "choice", "click", "closes", "closing", "confirm", "confirmlabel", "confirmtimeout", "content", "controlled", "default", "defaultopen", "defaults", "destructive", "disabled", "disables", "done", "down", "dropdownmenuradioitem", "edge", "emphasis", "enter", "equals", "esc", "feedback", "fill", "first", "for", "give", "group", "groups", "height", "hint", "icon", "irreversible", "item", "items", "its", "keeps", "keyboard", "label", "labels", "last", "leading", "left", "lines", "loading", "loadinglabel", "mark", "menu", "never", "new", "not", "old", "oncheckedchange", "onclick", "one", "ones", "onopenchange", "onselect", "onvaluechange", "open", "opens", "optionally", "out", "outside", "padding", "pair", "per", "picked", "picking", "place", "primary", "radiogroup", "red", "render", "reserved", "resets", "resize", "right", "runs", "second", "selectable", "selection", "separators", "shortcut", "shown", "shows", "size", "slides", "space", "spinner", "spins", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "text", "the", "then", "this", "toggles", "trigger", "two", "uncontrolled", "value", "variant", "view", "when", "where", "while", "width", "with", "without"], registryDependencies: ["button", "list", "platform", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "empty", type: "registry:ui", title: "Empty", description: "Server-safe empty state: icon tile, title, one helpful sentence and the next action. Bordered variant for empty lists and drop zones.", exports: ["Empty"], keywords: ["about", "action", "and", "app", "area", "bordered", "children", "clips", "dashed", "description", "drop", "empty", "for", "helpful", "icon", "inside", "like", "list", "next", "one", "outline", "page", "rounded", "sentence", "shown", "state", "the", "tile", "title", "what", "yet", "zone"], registryDependencies: ["utils"] }, { name: "field", type: "registry:ui", title: "Field", description: "Label, control, description and error as one unit. Controls inside (Input, Textarea, Select, Checkbox, Switch, RadioGroup) get id, aria-describedby, aria-invalid and required automatically; errors spring in and are announced.", exports: ["useFieldControl", "Field"], keywords: ["and", "aria", "automatically", "beside", "checkbox", "children", "control", "controls", "describedby", "description", "dims", "disabled", "disables", "enclosing", "error", "explicit", "field", "fills", "first", "for", "form", "from", "hint", "horizontal", "ids", "invalid", "its", "label", "makes", "marks", "match", "must", "one", "orientation", "out", "outside", "own", "picks", "props", "renders", "required", "returns", "shown", "springs", "state", "switch", "the", "unchanged", "under", "unit", "use", "when", "win", "wired", "with"], registryDependencies: ["label", "utils"] }, { name: "highlight", type: "registry:lib", description: "Lines of colored tokens, with Shiki loaded on demand. Runs anywhere: Code calls it in the\nbrowser, and a Server Component or a build can call it ahead of time and pass the result as\n`tokens`, so the browser never loads Shiki. Null for unknown languages.", exports: ["highlightCode", "languageOf"], keywords: ["ahead", "and", "anywhere", "back", "browser", "build", "call", "calls", "can", "code", "colored", "component", "demand", "extension", "falls", "file", "for", "from", "language", "languages", "lines", "loaded", "loads", "name", "never", "null", "pass", "result", "runs", "server", "shiki", "the", "time", "tokens", "tsx", "unknown", "with"], registryDependencies: [] }, { name: "hover-card", type: "registry:ui", title: "Hover Card", description: "Rich preview (profile, product, clip) that opens after a hover delay or keyboard focus. The pointer can move into the card; supplementary only.", exports: ["HoverCard"], keywords: ["acting", "acts", "align", "alignment", "avatar", "before", "bio", "can", "card", "children", "clip", "closedelay", "closes", "content", "first", "flips", "focus", "hover", "instead", "into", "keyboard", "leaves", "link", "move", "must", "once", "only", "opendelay", "opens", "outside", "pointer", "preferred", "preview", "product", "profile", "rich", "room", "second", "side", "stats", "supplementary", "tap", "the", "there", "time", "touch", "trigger", "usually", "when", "with", "without", "work"], registryDependencies: ["platform", "use-anchor", "use-dismiss", "use-hover-open", "utils"] }, { name: "input", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["fieldClass", "Input"], keywords: ["and", "aria", "chrome", "field", "filled", "group", "handed", "inputgroup", "inside", "the", "works"], registryDependencies: ["field", "utils"] }, { name: "input-group", type: "registry:ui", title: "Input Group", description: "Server-safe wrapper that fuses an Input with icons, text (https://, USD) or buttons into one field with a shared border and focus ring. Clicking an addon focuses the input.", exports: ["InputGroup", "InputGroupAddon"], keywords: ["addons", "align", "and", "beside", "border", "button", "buttons", "clicking", "control", "data", "draws", "drops", "field", "focus", "focuses", "group", "https", "icon", "icons", "inner", "input", "its", "like", "made", "matched", "one", "own", "plain", "plus", "ring", "side", "sits", "slot", "text", "the"], registryDependencies: ["utils"] }, { name: "input-otp", type: "registry:ui", title: "Input OTP", description: "One-time code in separate slots, backed by one real input: paste and SMS autofill work, screen readers hear one field. Grouped slots, numeric or alphanumeric, characters spring in, onComplete to submit. verified turns each character into a check, then merges them into one mark.", exports: ["InputOTP"], keywords: ["accepted", "again", "allowed", "alphanumeric", "and", "announced", "are", "autocomplete", "autofill", "back", "beside", "between", "called", "change", "character", "characters", "charset", "check", "code", "controlled", "counts", "dash", "defaultvalue", "draws", "dropped", "each", "edit", "every", "false", "filled", "fires", "first", "for", "group", "groups", "input", "into", "label", "laid", "length", "mark", "merge", "merged", "number", "once", "oncomplete", "one", "only", "onvaluechange", "others", "over", "pair", "paste", "pasted", "per", "read", "readers", "real", "render", "screen", "set", "shown", "single", "sits", "slides", "slot", "slots", "sms", "submit", "the", "then", "time", "transparently", "turns", "typed", "uncontrolled", "uppercased", "value", "verified", "verifiedlabel", "via", "visual", "was", "with"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "kbd", type: "registry:ui", title: "Kbd", description: "Server-safe key caps for shortcut hints. KbdGroup nests keys per the HTML spec.", exports: ["Kbd", "KbdGroup"], keywords: ["cap", "html", "kbd", "kbdgroup", "key", "keys", "made", "nested", "one", "per", "several", "shortcut", "spec", "the"], registryDependencies: ["utils"] }, { name: "label", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["Label"], keywords: [], registryDependencies: ["utils"] }, { name: "list", type: "registry:lib", description: "The item a navigation key moves to in a list, from the item at `index` (-1: none active).\nUndefined when the key doesn't navigate.", exports: ["listKeyTarget", "scrollIntoList"], keywords: ["active", "box", "can", "doesn", "enough", "from", "index", "item", "just", "key", "list", "moves", "moving", "navigate", "navigation", "none", "page", "scrollintoview", "scrolls", "show", "the", "undefined", "way", "when", "without"], registryDependencies: ["utils"] }, { name: "marker", type: "registry:ui", title: "Marker", description: "Highlighter-pen <mark> in four tints that wraps cleanly across lines and can draw itself on, left to right, when it scrolls into view. Highlight marks every match of a search in a string, for transcripts and search results.", exports: ["Marker", "Highlight"], keywords: ["across", "before", "case", "cleanly", "color", "delay", "draw", "drawing", "draws", "every", "first", "full", "fully", "highlight", "highlighter", "insensitive", "inside", "instant", "into", "left", "lines", "mark", "markers", "marks", "match", "motion", "one", "paragraph", "pen", "query", "reduced", "right", "scrolls", "search", "seconds", "several", "shown", "stagger", "sweeps", "term", "terms", "text", "the", "time", "view", "with", "without", "wraps"], registryDependencies: ["utils"] }, { name: "menubar", type: "registry:ui", title: "Menubar", description: "Desktop-style menu bar on the WAI-ARIA menubar pattern: one menu open at a time, hovering the next title while one is open switches to it, ← → walk the bar with or without a menu open, one Tab stop. A single highlight springs between titles; menus reuse every DropdownMenu item.", exports: ["MenubarContent", "MenubarItem", "MenubarCheckboxItem", "MenubarRadioGroup", "MenubarRadioItem", "MenubarLabel", "MenubarSeparator", "Menubar", "MenubarMenu", "MenubarTrigger"], keywords: ["actions", "align", "aligned", "analytics", "and", "another", "apart", "bar", "between", "but", "called", "check", "checked", "children", "click", "closes", "desktop", "destructive", "disabled", "down", "dropdownmenuradioitem", "edge", "enter", "equals", "first", "for", "generated", "give", "group", "groups", "highlight", "hint", "hovering", "icon", "irreversible", "item", "items", "its", "label", "labels", "last", "leading", "left", "lines", "mark", "menu", "menubarcontent", "menubartrigger", "menus", "move", "new", "not", "omitted", "oncheckedchange", "one", "onselect", "onvaluechange", "open", "opens", "optional", "optionally", "picked", "red", "right", "selectable", "separators", "shortcut", "shown", "shows", "space", "springs", "stable", "state", "style", "switches", "tell", "tests", "the", "then", "time", "title", "titles", "toggles", "trigger", "value", "variant", "when", "while", "with"], registryDependencies: ["dropdown-menu", "list", "use-indicator", "utils"] }, { name: "message-bubble", type: "registry:ui", title: "Message Bubble", description: "User/assistant chat bubbles with avatar slot, streaming dots and copyable code blocks.", exports: ["MessageBubble"], keywords: ["above", "accent", "after", "and", "animated", "are", "assistant", "attachments", "avatar", "bubble", "chat", "children", "code", "content", "dots", "from", "inline", "left", "lists", "message", "name", "next", "rich", "right", "sender", "shown", "shows", "side", "size", "slot", "streaming", "surface", "text", "the", "time", "typing", "user"], registryDependencies: ["utils"] }, { name: "meter", type: "registry:ui", title: "Meter", description: "Server-safe gauge for a value in a known range (storage, quota, server load, password strength). Colors by <meter> thresholds, or stacked segments with a legend, like a storage bar.", exports: ["Meter"], keywords: ["above", "accessible", "also", "and", "away", "bar", "below", "between", "bound", "color", "colors", "decides", "defaults", "disk", "follow", "good", "green", "high", "known", "label", "legend", "like", "load", "low", "lower", "max", "measurement", "meter", "min", "name", "not", "one", "optimum", "orange", "overrides", "parts", "password", "progress", "quota", "range", "red", "region", "right", "segments", "server", "stacked", "storage", "strength", "sum", "task", "text", "the", "their", "this", "threshold", "thresholds", "total", "two", "upper", "use", "used", "value", "valuetext", "visible", "where", "with", "within"], registryDependencies: ["utils"] }, { name: "motion-provider", type: "registry:component", exports: ["MotionProvider"], keywords: [], registryDependencies: ["utils"] }, { name: "native-select", type: "registry:ui", title: "Native Select", description: "A real <select> with option groups: native picker on phones, no-JS forms, native required validation. Where customizable select is supported (appearance: base-select), the open list gets the menu look.", exports: ["NativeSelect", "NativeSelectGroup", "NativeSelectOption"], keywords: ["appearance", "base", "browser", "custom", "customizable", "elsewhere", "forms", "gets", "group", "heading", "icons", "instead", "invalid", "label", "labeled", "list", "look", "menu", "native", "need", "open", "optgroup", "options", "phones", "picker", "real", "rendering", "required", "select", "stays", "supports", "the", "use", "user", "validation", "when", "where", "without", "works"], registryDependencies: ["field", "input", "utils"] }, { name: "navigation-menu", type: "registry:ui", title: "Navigation Menu", description: "Website top navigation on the APG disclosure pattern: plain links and panels of rich links. Hover opens after a beat, then sliding along the bar switches panels at once; every panel shares one viewport that springs to the next panel's size and position while the content slides in from the side you moved toward. Click, Enter, ↓, ← → and Esc work; closed panels keep their links in the HTML for crawlers.", exports: ["NavigationMenu", "NavigationMenuList", "NavigationMenuItem", "NavigationMenuTrigger", "NavigationMenuContent", "NavigationMenuLink"], keywords: ["active", "after", "all", "along", "and", "aria", "bar", "beat", "bold", "called", "children", "classname", "click", "closed", "closes", "content", "controlled", "crawlers", "current", "defaultvalue", "description", "down", "enter", "entry", "esc", "find", "first", "focuses", "following", "for", "generated", "hidden", "hover", "html", "icon", "inset", "into", "item", "items", "its", "left", "level", "line", "link", "links", "look", "matched", "menu", "mouse", "muted", "navigation", "omitted", "once", "one", "onvaluechange", "open", "opened", "opens", "optional", "own", "padding", "page", "pair", "panel", "panels", "pill", "plain", "readers", "rem", "render", "rich", "right", "row", "selected", "single", "size", "sliding", "space", "springs", "stable", "stay", "still", "switches", "the", "them", "then", "tile", "title", "toggle", "top", "trigger", "uncontrolled", "under", "value", "viewport", "walk", "website", "while", "with", "your"], registryDependencies: ["use-controllable-state", "use-dismiss", "use-indicator", "utils"] }, { name: "newsletter", type: "registry:block", title: "Newsletter", description: "Email signup: InputGroup with the submit Button inside, native email validation, a loading → success toast and an in-place success state on the button.", exports: ["Newsletter"], keywords: ["above", "address", "after", "and", "button", "check", "confirm", "confirms", "description", "email", "field", "for", "form", "heading", "inbox", "inputgroup", "inside", "into", "its", "line", "loading", "message", "native", "next", "onsubscribe", "place", "placeholder", "rejection", "resets", "resolves", "saved", "shows", "signup", "submit", "submitlabel", "success", "successmessage", "supporting", "text", "that", "the", "then", "title", "toast", "turns", "under", "validation", "when", "with", "your"], registryDependencies: ["button", "input", "input-group", "toast", "utils"] }, { name: "number-input", type: "registry:ui", title: "Number Input", description: "Native number field with −/+ buttons: arrow keys, min/max/step validation and form submit from the platform; clamps on blur, rounds to the step's precision.", exports: ["NumberInput"], keywords: ["amount", "and", "are", "arrows", "arrowup", "buttons", "called", "cart", "change", "controlled", "defaultvalue", "down", "field", "first", "form", "helpers", "highest", "keyboard", "lowest", "max", "min", "native", "new", "number", "onvaluechange", "pair", "pointer", "quantity", "render", "step", "submit", "tabindex", "the", "uncontrolled", "use", "users", "validation", "value", "with"], registryDependencies: ["input", "input-group", "use-controllable-state", "utils"] }, { name: "overflow-focus", type: "registry:lib", description: `Drop inside a scroll container: while the container overflows it becomes keyboard-focusable
|
|
16963
17159
|
(tabIndex 0) so arrow keys can scroll it, and it leaves the tab order again once it fits.
|
|
16964
|
-
Renders a hidden span, so server components (Table) can use it as a child.`, exports: ["OverflowFocus"], keywords: ["again", "and", "arrow", "becomes", "can", "child", "components", "container", "drop", "fits", "focusable", "hidden", "inside", "keyboard", "keys", "leaves", "once", "order", "overflows", "renders", "scroll", "server", "span", "tab", "tabindex", "table", "the", "use", "while"], registryDependencies: [] }, { name: "pagination", type: "registry:ui", title: "Pagination", description: "Server-safe page links from page and total: previous/next, ellipsis gaps and a sliding active pill, with numbers that swipe the way you moved. Links by default; buttons with onPageChange. The row keeps a fixed width so it never jumps.", exports: ["Pagination", "pageRange"], keywords: ["active", "always", "and", "arrows", "bar", "become", "between", "buttons", "called", "changes", "client", "controls", "current", "default", "each", "ellipsis", "first", "for", "from", "gaps", "href", "index", "instead", "items", "its", "keeps", "kept", "key", "labels", "last", "length", "links", "mounted", "moved", "never", "next", "number", "numbers", "one", "only", "onpagechange", "page", "pagerange", "pages", "parents", "phones", "picked", "pill", "previous", "remounting", "render", "returns", "row", "same", "show", "siblings", "side", "slides", "slot", "stays", "swipe", "swipes", "text", "that", "the", "total", "unused", "url", "way", "width", "with", "without", "work", "you"], registryDependencies: ["button-variants", "pagination-motion", "utils"] }, { name: "pagination-motion", type: "registry:ui", description: "Scopes the active pill's `layoutId` so several paginations on a page don't share it.", exports: ["PaginationMotion", "PaginationActivePill", "PaginationNumber"], keywords: ["active", "behind", "changes", "children", "direction", "don", "from", "items", "its", "layoutid", "link", "moved", "next", "number", "outline", "page", "pagination", "paginations", "pill", "scopes", "several", "share", "side", "slot", "springs", "swipes", "that", "the", "toward", "travel", "value", "when"], registryDependencies: ["utils"] }, { name: "platform", type: "registry:lib", description: "False on the server and during hydration, true after: gates portals and other client-only output.", exports: ["useMounted", "useIsMac", "useMediaQuery"], keywords: ["after", "and", "assumes", "client", "corrects", "ctrl", "during", "false", "gates", "hydration", "live", "match", "media", "not", "only", "other", "output", "portals", "query", "render", "server", "shortcuts", "ssr", "the", "then", "true", "use", "where"], registryDependencies: [] }, { name: "popover", type: "registry:ui", title: "Popover", description: "Non-modal panel anchored to a Button for filters, pickers and quick edits. Focus moves in, Esc returns it, outside clicks close; Selects and menus opened inside don't count as outside.", exports: ["Popover", "PopoverTrigger", "PopoverContent"], keywords: ["action", "align", "alignment", "also", "anchored", "and", "any", "aria", "armed", "before", "blur", "button", "called", "check", "children", "click", "closes", "confirm", "confirmlabel", "confirmtimeout", "content", "controlled", "default", "defaultopen", "defaults", "destructive", "disables", "done", "edits", "emphasis", "end", "esc", "feedback", "fill", "filters", "first", "flips", "focus", "for", "give", "height", "icon", "irreversible", "its", "label", "left", "like", "loading", "loadinglabel", "modal", "moves", "never", "non", "not", "old", "onclick", "one", "ones", "onopenchange", "open", "out", "outside", "padding", "pair", "panel", "past", "per", "pickers", "place", "popovercontent", "popovertrigger", "popup", "preferred", "primary", "quick", "render", "reserved", "resets", "resize", "returns", "room", "runs", "second", "shown", "shows", "side", "size", "slides", "spinner", "spins", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "tab", "text", "the", "there", "this", "trap", "trigger", "two", "uncontrolled", "variant", "view", "when", "where", "while", "width", "with"], registryDependencies: ["button", "platform", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "pricing", type: "registry:block", title: "Pricing", description: "Plan cards with a monthly / yearly segmented switch. Prices roll on a spring in the direction they moved; the featured plan is outlined in the accent. Card, Badge, ToggleGroup, Button.", exports: ["Pricing"], keywords: ["and", "bcp", "billing", "cards", "code", "currency", "defaultperiod", "display", "down", "drop", "eur", "first", "for", "formatting", "iso", "locale", "monthly", "next", "number", "order", "period", "plan", "plans", "price", "prices", "render", "rise", "rolling", "segmented", "selected", "spring", "swap", "switch", "the", "they", "togglegroup", "when", "with", "yearly", "yearlynote"], registryDependencies: ["badge", "card", "toggle-group", "utils"] }, { name: "product-card", type: "registry:block", title: "Product Card", description: "Shop tile: photos in an AspectRatio (a swipeable Carousel with dots when there are several), sale price, Badge and add-to-cart Button.", exports: ["ProductCard"], keywords: ["add", "addlabel", "are", "aspectratio", "badge", "bcp", "become", "button", "called", "card", "carousel", "code", "compareat", "currency", "current", "dots", "for", "formatting", "heading", "height", "href", "img", "iso", "label", "link", "locale", "major", "media", "name", "new", "number", "onaddtocart", "one", "original", "over", "page", "per", "photos", "pressed", "price", "product", "ratio", "sale", "several", "shop", "shows", "slide", "small", "square", "struck", "swipeable", "text", "the", "there", "through", "tile", "units", "when", "width", "with"], registryDependencies: ["aspect-ratio", "badge", "button", "carousel", "utils"] }, { name: "progress", type: "registry:ui", title: "Progress", description: "Accent bar that springs to each new value, with an optional label and percentage. Leave out value for an indeterminate sweep (static under reduced motion).", exports: ["Progress"], keywords: ["above", "accent", "accessible", "across", "allowed", "also", "aria", "bar", "colored", "duration", "each", "for", "frame", "indeterminate", "infinite", "its", "label", "layout", "max", "motion", "name", "new", "next", "omit", "one", "per", "percentage", "reduced", "scalex", "segment", "show", "showvalue", "size", "springs", "static", "sweeps", "that", "the", "there", "thickness", "tween", "under", "unknown", "value", "visible", "when", "work"], registryDependencies: ["utils"] }, { name: "quote", type: "registry:ui", title: "Quote", description: "Semantic figure, blockquote and figcaption. Plain, card and large variants, with author, subtitle, avatar, lang, typewriter and textSwap.", exports: ["Quote"], keywords: ["accent", "alt", "and", "array", "author", "avatar", "blockquote", "card", "children", "correct", "custom", "cycles", "delay", "display", "doe", "effect", "enables", "fades", "figcaption", "figure", "for", "into", "jane", "job", "lang", "language", "large", "line", "mark", "options", "pass", "plain", "pronunciation", "quote", "quoted", "quotes", "reader", "said", "screen", "scrolls", "secondary", "semantic", "seo", "size", "slot", "speed", "spring", "string", "strings", "subtitle", "supports", "surface", "swap", "text", "textswap", "the", "through", "title", "transitions", "typewriter", "under", "variant", "view", "when", "who", "with", "work", "wrote"], registryDependencies: ["text-swap", "typewriter", "utils"] }, { name: "radio-group", type: "registry:ui", title: "Radio Group", description: "Native radios in a fieldset with a legend: browser arrow keys and form submit, a dot that springs in, optional per-option descriptions, vertical or horizontal.", exports: ["RadioGroup", "RadioGroupItem"], keywords: ["adds", "and", "application", "aria", "arrow", "browser", "but", "called", "children", "conform", "controlled", "defaultvalue", "description", "disabled", "does", "entered", "expected", "field", "fieldset", "first", "form", "format", "generated", "group", "indicates", "invalid", "item", "items", "its", "keys", "label", "labels", "lay", "legend", "line", "muted", "name", "native", "not", "omitted", "one", "onvaluechange", "option", "orientation", "pair", "picked", "radios", "render", "rendered", "row", "selectable", "shown", "stack", "submit", "submitted", "the", "them", "uncontrolled", "under", "value", "visible", "when", "with", "work"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "rating", type: "registry:ui", title: "Rating", description: "Star rating on native radios (arrow keys, forms) with hover preview, or readOnly display with fractional stars for averages.", exports: ["Rating"], keywords: ["and", "arrow", "called", "chosen", "controlled", "defaultvalue", "display", "field", "filled", "first", "for", "form", "forms", "fractions", "group", "hidden", "hover", "image", "included", "inputs", "interactive", "keys", "label", "lift", "max", "name", "native", "number", "only", "onvaluechange", "pair", "partially", "picked", "press", "preview", "radios", "rating", "readers", "readonly", "render", "renders", "score", "screen", "size", "spring", "star", "stars", "the", "uncontrolled", "value", "visually", "with"], registryDependencies: ["use-controllable-state", "utils"] }, { name: "relative-time", type: "registry:ui", title: "Relative Time", description: "Self-updating “5 minutes ago” in a semantic <time> with the full date as its title. Server renders the absolute date (no hydration mismatch); one shared ticker for the whole page.", exports: ["RelativeTime"], keywords: ["absolute", "ago", "and", "both", "client", "crawlers", "current", "date", "default", "differ", "full", "get", "hydration", "its", "itself", "keeps", "locale", "minutes", "mismatch", "not", "now", "one", "page", "pass", "real", "relative", "render", "renders", "semantic", "server", "shared", "stored", "text", "that", "the", "there", "ticker", "time", "timestamp", "title", "with", "would"], registryDependencies: ["utils"] }, { name: "resizable", type: "registry:ui", title: "Resizable", description: "Split panes for admin layouts, docs and editors. Hairline dividers with a wide grab area follow the pointer; collapsible panels snap shut past half their minimum. Dividers are APG window splitters: arrows step, Home/End jump to the limits, Enter or double-click collapses with a spring. Groups nest.", exports: ["ResizablePanelGroup", "ResizablePanel", "ResizableHandle"], keywords: ["adds", "admin", "after", "already", "and", "apg", "are", "arrow", "arrows", "basis", "between", "click", "collapsed", "collapsedsize", "collapses", "collapsible", "component", "cookie", "css", "default", "defaultsize", "direction", "divider", "docs", "dom", "double", "drag", "dragging", "each", "editors", "end", "enter", "evenly", "final", "find", "flex", "follows", "for", "grip", "group", "half", "handle", "handles", "home", "horizontal", "hydration", "icon", "jump", "key", "keyboardstep", "keys", "largest", "layout", "layouts", "left", "limits", "maxsize", "middle", "minimum", "minsize", "neighbor", "one", "onlayout", "order", "others", "panels", "panes", "parents", "past", "per", "plain", "pointer", "press", "rail", "rest", "save", "server", "share", "shows", "shut", "side", "size", "sizes", "smallest", "snaps", "split", "splitters", "spring", "ssr", "stacked", "starting", "step", "the", "their", "them", "toggle", "toggles", "two", "until", "vertical", "visible", "what", "when", "window", "withhandle", "without", "work", "wrappers"], registryDependencies: ["utils"] }, { name: "reveal", type: "registry:ui", title: "Reveal", description: "Scroll reveal: content fades and rises on a spring the first time it enters the viewport.", exports: ["Reveal"], keywords: ["after", "and", "content", "delay", "entering", "fades", "first", "into", "offset", "place", "rises", "scrolls", "seconds", "spring", "start", "stays", "the", "time", "view", "visible", "wait"], registryDependencies: ["utils"] }, { name: "scroll-area", type: "registry:ui", title: "Scroll Area", description: "Overlay scrollbars: thin thumbs that fade in while scrolling or on hover, widen under the pointer and drag. Scrolling stays native; the labeled region is keyboard-focusable.", exports: ["ScrollArea"], keywords: ["also", "and", "aria", "axes", "can", "classes", "drag", "fade", "focus", "for", "get", "give", "goes", "height", "here", "horizontal", "hover", "itself", "keyboard", "label", "mouse", "names", "native", "one", "orientation", "overlay", "padding", "region", "scroll", "scrollable", "scrollbars", "scrolling", "stays", "takes", "that", "the", "thin", "thumb", "thumbs", "touch", "users", "viewport", "viewportclassname", "wheel", "while", "widen"], registryDependencies: ["utils"] }, { name: "search-input", type: "registry:ui", title: "Search Input", description: 'Search field built on Input: leading icon, spring-in clear button, Esc to clear, and an optional focus shortcut ("/" or mod+k) with a Kbd hint.', exports: ["SearchInput"], keywords: ["accessible", "already", "and", "anywhere", "aside", "border", "browser", "button", "called", "change", "clear", "cleared", "clears", "command", "controlled", "ctrl", "default", "defaultvalue", "elsewhere", "embedded", "esc", "every", "field", "find", "first", "focus", "focused", "focuses", "for", "from", "ghost", "hidden", "hint", "htmlfor", "icon", "inputs", "kbd", "key", "label", "mac", "mod", "name", "onvaluechange", "opens", "optional", "own", "pair", "palette", "pass", "query", "render", "ring", "search", "second", "shadow", "shortcut", "single", "skipped", "spring", "steps", "still", "surface", "the", "uncontrolled", "value", "variant", "when", "while", "with", "you"], registryDependencies: ["input", "kbd", "platform", "use-controllable-state", "use-hotkey", "utils"] }, { name: "segmented-tabs", type: "registry:ui", title: "AppWindow", description: "Window container with close / minimize / zoom controls, title, custom header slot and actions. SegmentedTabs is the compact view switcher for its title bar.", exports: ["SegmentedTabs"], keywords: ["accessible", "active", "also", "always", "aria", "behind", "called", "current", "for", "indicator", "item", "items", "label", "labels", "list", "marked", "name", "onchange", "one", "pressed", "segmented", "slides", "spring", "tab", "tabs", "the", "under", "used", "value", "values", "with"], registryDependencies: ["use-indicator", "utils"] }, { name: "select", type: "registry:ui", title: "Select", description: "Single-choice listbox styled like Input, with groups, icons and disabled options. Native-select keyboard (arrows, typeahead even while closed), flips above the trigger near the viewport edge, submits via a hidden input.", exports: ["Select"], keywords: ["accessible", "also", "aria", "blocks", "called", "cancel", "choice", "closed", "controlled", "defaultvalue", "describedby", "disabled", "down", "end", "enter", "error", "esc", "field", "fill", "fills", "first", "flat", "form", "from", "groups", "hidden", "hint", "home", "htmlfor", "ids", "input", "invalid", "keyboard", "label", "labeled", "let", "like", "listbox", "matches", "name", "native", "needs", "nothing", "onvaluechange", "opening", "options", "pair", "pick", "picked", "placeholder", "render", "required", "select", "sets", "single", "space", "styled", "styling", "submit", "submits", "text", "the", "there", "through", "trigger", "typeahead", "uncontrolled", "value", "visible", "when", "while", "with"], registryDependencies: ["field", "input", "list", "platform", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "separator", type: "registry:ui", title: "Separator", description: 'Server-safe hairline, horizontal or vertical, decorative by default, with an optional centered label like "or".', exports: ["Separator"], keywords: ["assistive", "centered", "content", "decorative", "default", "direction", "false", "for", "horizontal", "label", "line", "only", "orientation", "purely", "separates", "set", "tech", "text", "the", "visual", "when"], registryDependencies: ["utils"] }, { name: "sidebar", type: "registry:ui", title: "Sidebar", description: "App navigation from data: header, groups (optionally foldable), badges and pinned footer entries. Collapses to an icon rail on a spring (⌘B / Ctrl+B) with labels kept for assistive tech; below md it is a left drawer.", exports: ["SidebarLayout", "Sidebar", "SidebarTrigger"], keywords: ["a11y", "accessible", "and", "aria", "below", "bottom", "but", "called", "client", "clip", "collapsed", "collapses", "controlled", "ctrl", "current", "data", "default", "defaultcollapsed", "drawer", "entries", "field", "footer", "for", "from", "groups", "header", "highlighted", "holds", "icon", "ignored", "item", "label", "labels", "landmark", "lays", "left", "links", "name", "navigation", "oncollapsedchange", "onselect", "page", "pair", "picked", "pinned", "rail", "routing", "settings", "shortcut", "side", "sidebar", "slot", "spring", "start", "state", "stay", "the", "toggle", "too", "top", "tree", "trigger", "true", "typing", "uncontrolled", "when", "while", "with", "workspace"], registryDependencies: ["button", "collapsible", "drawer", "platform", "use-controllable-state", "use-hotkey", "utils"] }, { name: "site-header", type: "registry:block", title: "Site Header", description: "Sticky, translucent site header from one nav array: brand, NavigationMenu panels from md up, a right Drawer with the same links below it, and your actions on the right. The hairline underneath appears only once content scrolls beneath it.", exports: ["SiteHeader"], keywords: ["accessible", "acme", "actions", "alike", "and", "appears", "aria", "below", "brand", "client", "close", "controls", "current", "demo", "desktop", "drawer", "every", "for", "from", "hairline", "hand", "header", "href", "label", "left", "level", "link", "links", "logo", "marks", "matching", "name", "nav", "navigation", "navigationmenu", "once", "onclick", "only", "onnavigate", "over", "page", "panels", "right", "routing", "same", "scrolls", "search", "shown", "sign", "site", "sticky", "stub", "the", "theme", "top", "under", "width", "with"], registryDependencies: ["button", "drawer", "navigation-menu", "use-disclosure", "utils"] }, { name: "skeleton", type: "registry:ui", title: "Skeleton", description: 'Server-safe loading placeholders that pulse (static under reduced motion). SkeletonGroup announces one "Loading" to screen readers.', exports: ["Skeleton", "SkeletonGroup"], keywords: ["announced", "block", "classes", "classname", "hear", "instead", "label", "loading", "nothing", "one", "placeholder", "readers", "screen", "shown", "size", "skeleton", "skeletons", "this", "while", "with", "wrap"], registryDependencies: ["utils"] }, { name: "slider", type: "registry:ui", title: "Slider", description: "Slider over native range inputs: thin accent track, white knob that lifts while held. One value or two for a range; keyboard, forms, touch and Field wiring come from the platform.", exports: ["Slider"], keywords: ["accent", "accessible", "and", "aria", "arrow", "blocks", "browser", "called", "defaults", "defaultvalue", "describedby", "disabled", "does", "drag", "dragging", "error", "every", "field", "fills", "filter", "first", "for", "forms", "from", "held", "highest", "hint", "ids", "increment", "inputs", "invalid", "keyboard", "keys", "knob", "labels", "lifts", "lowest", "max", "maximum", "min", "minimum", "name", "names", "native", "one", "onvaluechange", "over", "per", "price", "range", "readers", "render", "screen", "sets", "slider", "step", "styling", "submitted", "text", "that", "the", "thin", "thumb", "touch", "track", "twice", "two", "uncontrolled", "value", "values", "while", "white", "with", "work"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "spinner", type: "registry:ui", title: "Spinner", description: "Server-safe activity indicator: eight spokes in currentColor, three sizes, its own status label (or silent inside a parent that announces). Holds still under reduced motion.", exports: ["Spinner"], keywords: ["accessible", "activity", "already", "announces", "busy", "currentcolor", "diameter", "eight", "holds", "indicator", "label", "motion", "name", "parent", "pass", "reduced", "size", "spokes", "state", "still", "the", "under", "when"], registryDependencies: ["utils"] }, { name: "stat-tile", type: "registry:block", title: "Stat Tile", description: "Admin dashboard metric: value, a delta Badge that is green when the change is good news (invert for errors and latency), and an area Chart of the trend. Server-safe.", exports: ["StatTile"], keywords: ["admin", "and", "area", "axis", "badge", "below", "change", "chart", "dashboard", "data", "datakey", "delta", "down", "each", "errors", "for", "format", "formatted", "good", "green", "headline", "index", "intl", "invert", "key", "label", "last", "latency", "metric", "metrics", "month", "name", "news", "number", "period", "positive", "revenue", "row", "rows", "the", "tile", "tooltip", "trend", "unless", "value", "when", "where"], registryDependencies: ["badge", "card", "chart", "utils"] }, { name: "stats-strip", type: "registry:block", title: "Stats Strip", description: "Headline numbers, each card a <dl>: cards rise in turn with Reveal, then each number springs up with CountTo. Final values are in the HTML.", exports: ["StatsStrip"], keywords: ["card", "display", "each", "headline", "its", "number", "numbers", "order", "rises", "row", "springs", "stats", "then", "turn"], registryDependencies: ["card", "count-to", "reveal", "utils"] }, { name: "stepper", type: "registry:ui", title: "Stepper", description: "Multi-step form (questionnaire, checkout, setup wizard). Steps stay mounted so values survive Back and submit together; Continue checks only the current step's native constraints, plus an optional async onNext guard with a spinner. Progress header with springing connectors; works with onSubmit or a Server Action.", exports: ["Stepper", "StepperList", "StepperStep", "StepperFooter"], keywords: ["action", "after", "and", "are", "back", "backlabel", "button", "called", "check", "checks", "children", "connector", "constraints", "continue", "controlled", "current", "defaultvalue", "description", "every", "false", "fields", "fills", "finished", "first", "for", "form", "header", "hidden", "inactive", "its", "last", "links", "matches", "mounted", "multi", "native", "new", "nextlabel", "not", "one", "only", "onnext", "onsubmit", "onvaluechange", "optional", "order", "pass", "progress", "render", "resolve", "return", "runs", "server", "shown", "shows", "spinner", "spring", "start", "stay", "stays", "step", "steps", "submit", "submitlabel", "submits", "survive", "text", "the", "through", "title", "together", "uncontrolled", "unmounted", "value", "values", "while", "with"], registryDependencies: ["button", "use-controllable-state", "utils"] }, { name: "styles", type: "registry:file", exports: [], keywords: [], registryDependencies: [] }, { name: "switch", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["Switch"], keywords: ["called", "checkbox", "checked", "controlled", "defaultchecked", "first", "knob", "native", "new", "oncheckedchange", "pair", "render", "role", "spring", "state", "switch", "the", "uncontrolled", "with"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "table", type: "registry:ui", title: "Table", description: "Server-safe semantic <table> in a scrolling card: header, body, footer and caption, striped rows, tinted selected rows, and sortable headers that set aria-sort and flip their arrow.", exports: ["Table", "TableHeader", "TableBody", "TableFooter", "TableRow", "TableHead", "TableCell", "TableCaption"], keywords: ["alternating", "and", "aria", "around", "arrow", "button", "called", "card", "classes", "column", "containerclassname", "data", "direction", "for", "header", "keyboard", "makes", "narrow", "onsort", "pass", "pressed", "real", "requires", "row", "screens", "scrollable", "scrolling", "scrolls", "selected", "sets", "shading", "shows", "sideways", "sort", "sortable", "state", "striped", "table", "that", "the", "then", "tint", "when"], registryDependencies: ["overflow-focus", "utils"] }, { name: "tabs", type: "registry:ui", title: "Tabs", description: "WAI-ARIA tabs with arrow, Home and End keys. One indicator springs between tabs, segmented or underline. Inactive panels stay in the DOM for SEO; the active one fades in.", exports: ["Tabs", "TabsList", "TabsTrigger", "TabsContent"], keywords: ["activated", "active", "always", "and", "aria", "arrows", "bar", "behind", "called", "children", "content", "controlled", "crawlable", "defaultvalue", "dom", "end", "first", "focus", "hidden", "home", "html", "inactive", "indicator", "labels", "matches", "move", "muted", "one", "onvaluechange", "pair", "panel", "panels", "pill", "remains", "render", "segmented", "springs", "stay", "stays", "tab", "tabs", "tabscontent", "tabstrigger", "the", "their", "track", "uncontrolled", "under", "underline", "value", "variant", "wai", "while", "with"], registryDependencies: ["list", "use-controllable-state", "use-indicator", "utils"] }, { name: "tag-input", type: "registry:ui", title: "Tag Input", description: "Free-form tags: Enter or a separator adds, Backspace removes the last, pasting a list adds them all. Duplicates, a max and a validate function keep bad tags in the input. One hidden input per tag.", exports: ["tagFieldClass", "Tag", "TagInput"], keywords: ["accessible", "add", "after", "allowed", "and", "animatepresence", "backspace", "besides", "button", "called", "children", "chip", "commit", "controlled", "defaultvalue", "disabled", "empty", "enter", "every", "false", "first", "form", "free", "hidden", "hides", "input", "inside", "its", "keys", "last", "limit", "list", "many", "max", "mode", "most", "name", "one", "onremove", "onvaluechange", "out", "pair", "paste", "pasted", "per", "poplayout", "press", "reject", "removable", "remove", "removes", "render", "rendered", "return", "runs", "separator", "separators", "shows", "split", "springs", "stays", "stops", "submits", "tag", "tags", "text", "that", "the", "these", "too", "trimming", "type", "typed", "typing", "uncontrolled", "validate", "value", "when", "with"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "terminal", type: "registry:ui", title: "Terminal", description: "Terminal window. Snippet mode types install commands once scrolled into view, with the full transcript kept in the DOM for SEO and no-JS; log mode streams lines into a live region that follows the bottom unless you scroll up, then offers a jump back. Status lines carry glyphs, copy grabs the commands.", exports: ["Terminal"], keywords: ["and", "append", "arrives", "back", "before", "body", "bodyclassname", "bottom", "character", "clipboard", "commands", "copy", "copytext", "defaults", "dom", "false", "follows", "for", "full", "hides", "install", "jump", "lines", "live", "log", "mode", "new", "offering", "once", "order", "output", "per", "prompt", "puts", "read", "reveals", "role", "scroll", "scrolling", "seo", "size", "snippet", "snippets", "speed", "stays", "sticks", "stream", "streams", "symbol", "terminal", "text", "the", "title", "typed", "types", "typing", "unless", "view", "what", "when", "window", "you"], registryDependencies: ["app-window", "code", "platform", "utils"] }, { name: "testimonial", type: "registry:block", title: "Testimonial", description: "A large Quote with its author, and everyone else who agrees as an overlapping AvatarGroup. Server-safe.", exports: ["Testimonial"], keywords: ["agrees", "and", "author", "avatar", "avatargroup", "behind", "beside", "carried", "children", "company", "crowd", "else", "everyone", "few", "first", "fold", "initials", "into", "its", "lang", "language", "large", "line", "one", "others", "otherslabel", "photo", "quote", "rest", "role", "said", "show", "stack", "streamers", "subtitle", "the", "trusted", "under", "url", "who", "with", "without"], registryDependencies: ["avatar", "avatar-group", "quote", "utils"] }, { name: "text-swap", type: "registry:ui", title: "TextSwap", description: "Spring-powered text morphing and ticker. Auto-cycles phrases or animates whenever children change with blur and slide transitions.", exports: ["TextSwap"], keywords: ["active", "array", "automatically", "between", "changing", "child", "children", "controlling", "cycle", "cycling", "default", "direction", "externally", "hover", "index", "interval", "items", "milliseconds", "mouse", "new", "pass", "pause", "pauseonhover", "single", "string", "swap", "swaps", "text", "the", "through", "true", "when"], registryDependencies: ["utils"] }, { name: "textarea", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["Textarea"], keywords: ["auto", "cap", "content", "corner", "end", "field", "firefox", "grows", "max", "maxlength", "near", "needs", "red", "resizable", "show", "showcount", "sizing", "the", "then", "turns", "unsupported", "used", "warning", "where", "with"], registryDependencies: ["field", "input", "utils"] }, { name: "theme", type: "registry:lib", description: "Retints primary, focus rings, selection and switches app-wide. Persists like the theme.", exports: ["isDark", "setTheme", "subscribeTheme", "accents", "getAccent", "setAccent", "themeScript"], keywords: ["and", "app", "focus", "like", "persists", "primary", "retints", "rings", "selection", "switches", "the", "theme", "wide"], registryDependencies: [] }, { name: "theme-toggle", type: "registry:ui", title: "Theme Toggle", description: "Light/dark icon switch with spring rotate-swap; follows the OS until first use.", exports: ["ThemeToggle"], keywords: ["button", "click", "first", "follows", "icon", "moon", "rotate", "spring", "sun", "swap", "until"], registryDependencies: ["button", "theme", "utils"] }, { name: "timeline", type: "registry:ui", title: "Timeline", description: "Server-safe ordered list of events on a rail: icon or dot markers with status colors, machine-readable <time>, title and an optional body. For changelogs, experience and mod logs.", exports: ["Timeline", "TimelineItem"], keywords: ["above", "and", "body", "children", "color", "date", "datetime", "dot", "event", "events", "first", "for", "headline", "icon", "inside", "list", "machine", "marker", "newest", "oldest", "one", "optional", "order", "ordered", "pair", "rail", "readable", "render", "shown", "small", "the", "then", "time", "title", "variant", "with", "without", "yours"], registryDependencies: ["utils"] }, { name: "toast", type: "registry:ui", title: "Toast", description: "Stacked notifications. Hover to expand, swipe to dismiss, timers pause on hover.", exports: ["toast", "Toaster"], keywords: ["action", "description", "dismiss", "dismisses", "duration", "error", "expands", "focus", "hover", "layout", "loading", "mount", "once", "promise", "root", "saved", "stacked", "success", "swipe", "title", "toast", "toasts"], registryDependencies: ["utils"] }, { name: "toggle-group", type: "registry:ui", title: "Toggle Group", description: "Segmented control of toggle buttons. Single mode slides one pill to the pressed item (view mode, billing period); multiple mode toggles items independently (bold, italic). Arrow keys move between items.", exports: ["ToggleGroup", "ToggleGroupItem"], keywords: ["always", "and", "aria", "arrow", "behind", "between", "billing", "bold", "buttons", "called", "choice", "control", "controlled", "defaultvalue", "end", "every", "filters", "first", "height", "home", "icon", "independent", "italic", "item", "items", "keys", "label", "labels", "mode", "move", "multiple", "need", "one", "only", "onvaluechange", "pair", "period", "pill", "pressed", "render", "reported", "segment", "segmented", "set", "single", "size", "slides", "springs", "the", "time", "toggle", "toggles", "type", "uncontrolled", "value", "values", "view", "when", "with"], registryDependencies: ["list", "use-controllable-state", "use-indicator", "utils"] }, { name: "tooltip", type: "registry:ui", title: "Tooltip", description: "Short label on hover or keyboard focus, also wired as the trigger's aria-describedby. Warm-up: once one opens, neighbors open instantly. Hoverable, Esc dismisses, ignores touch.", exports: ["Tooltip"], keywords: ["accessible", "align", "alignment", "also", "aria", "becomes", "before", "button", "children", "content", "default", "delay", "description", "dismisses", "element", "esc", "first", "flips", "focus", "focusable", "for", "hover", "icon", "keyboard", "label", "mouse", "one", "only", "open", "opens", "pointer", "preferred", "room", "short", "side", "stays", "straight", "taps", "text", "the", "there", "tooltip", "touch", "trigger", "wcag", "when", "while", "with"], registryDependencies: ["platform", "use-anchor", "use-hover-open", "utils"] }, { name: "typewriter", type: "registry:ui", title: "Typewriter", description: "Types out text character-by-character with optional phrase cycling and pulsing cursor. Full copy stays in the DOM for SEO.", exports: ["Typewriter"], keywords: ["and", "array", "before", "blinking", "called", "character", "classes", "cursor", "cursorchar", "cursorclassname", "custom", "cycle", "default", "delay", "deletespeed", "deleting", "dom", "effect", "for", "full", "fully", "headers", "hero", "loop", "milliseconds", "once", "oncomplete", "pause", "pauseduration", "per", "phrase", "phrases", "quotes", "seo", "show", "speed", "starting", "stays", "text", "the", "through", "true", "type", "typed", "typewriter", "typing", "wait", "when", "whether", "while"], registryDependencies: ["platform", "utils"] }, { name: "use-anchor", type: "registry:hook", description: `Fixed-position coordinates for a floating panel next to its anchor: on the preferred side,
|
|
17160
|
+
Renders a hidden span, so server components (Table) can use it as a child.`, exports: ["OverflowFocus"], keywords: ["again", "and", "arrow", "becomes", "can", "child", "components", "container", "drop", "fits", "focusable", "hidden", "inside", "keyboard", "keys", "leaves", "once", "order", "overflows", "renders", "scroll", "server", "span", "tab", "tabindex", "table", "the", "use", "while"], registryDependencies: [] }, { name: "pagination", type: "registry:ui", title: "Pagination", description: "Server-safe page links from page and total: previous/next, ellipsis gaps and a sliding active pill, with numbers that swipe the way you moved. Links by default; buttons with onPageChange. The row keeps a fixed width so it never jumps.", exports: ["Pagination", "pageRange"], keywords: ["active", "always", "and", "arrows", "bar", "become", "between", "buttons", "called", "changes", "client", "controls", "current", "default", "each", "ellipsis", "first", "for", "from", "gaps", "href", "index", "instead", "items", "its", "keeps", "kept", "key", "labels", "last", "length", "links", "mounted", "moved", "never", "next", "number", "numbers", "one", "only", "onpagechange", "page", "pagerange", "pages", "parents", "phones", "picked", "pill", "previous", "remounting", "render", "returns", "row", "same", "show", "siblings", "side", "slides", "slot", "stays", "swipe", "swipes", "text", "that", "the", "total", "unused", "url", "way", "width", "with", "without", "work", "you"], registryDependencies: ["button-variants", "pagination-motion", "utils"] }, { name: "pagination-motion", type: "registry:ui", description: "Scopes the active pill's `layoutId` so several paginations on a page don't share it.", exports: ["PaginationMotion", "PaginationActivePill", "PaginationNumber"], keywords: ["active", "behind", "changes", "children", "direction", "don", "from", "items", "its", "layoutid", "link", "moved", "next", "number", "outline", "page", "pagination", "paginations", "pill", "scopes", "several", "share", "side", "slot", "springs", "swipes", "that", "the", "toward", "travel", "value", "when"], registryDependencies: ["utils"] }, { name: "platform", type: "registry:lib", description: "False on the server and during hydration, true after: gates portals and other client-only output.", exports: ["useMounted", "useIsMac", "useMediaQuery"], keywords: ["after", "and", "assumes", "client", "corrects", "ctrl", "during", "false", "gates", "hydration", "live", "match", "media", "not", "only", "other", "output", "portals", "query", "render", "server", "shortcuts", "ssr", "the", "then", "true", "use", "where"], registryDependencies: [] }, { name: "popover", type: "registry:ui", title: "Popover", description: "Non-modal panel anchored to a Button for filters, pickers and quick edits. Focus moves in, Esc returns it, outside clicks close; Selects and menus opened inside don't count as outside.", exports: ["Popover", "PopoverTrigger", "PopoverContent"], keywords: ["action", "align", "alignment", "also", "anchored", "and", "any", "aria", "armed", "before", "blur", "button", "called", "check", "children", "click", "closes", "confirm", "confirmlabel", "confirmtimeout", "content", "controlled", "default", "defaultopen", "defaults", "destructive", "disables", "done", "edits", "emphasis", "end", "esc", "feedback", "fill", "filters", "first", "flips", "focus", "for", "give", "height", "icon", "irreversible", "its", "label", "left", "like", "loading", "loadinglabel", "modal", "moves", "never", "non", "not", "old", "onclick", "one", "ones", "onopenchange", "open", "out", "outside", "padding", "pair", "panel", "past", "per", "pickers", "place", "popovercontent", "popovertrigger", "popup", "preferred", "primary", "quick", "render", "reserved", "resets", "resize", "returns", "room", "runs", "second", "shown", "shows", "side", "size", "slides", "spinner", "spins", "square", "state", "status", "step", "success", "successlabel", "swap", "swaps", "tab", "text", "the", "there", "this", "trap", "trigger", "two", "uncontrolled", "variant", "view", "when", "where", "while", "width", "with"], registryDependencies: ["button", "platform", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "pricing", type: "registry:block", title: "Pricing", description: "Plan cards with a monthly / yearly segmented switch. Prices roll on a spring in the direction they moved; the featured plan is outlined in the accent. Card, Badge, ToggleGroup, Button.", exports: ["Pricing"], keywords: ["and", "bcp", "billing", "cards", "code", "currency", "defaultperiod", "display", "down", "drop", "eur", "first", "for", "formatting", "iso", "locale", "monthly", "next", "number", "order", "period", "plan", "plans", "price", "prices", "render", "rise", "rolling", "segmented", "selected", "spring", "swap", "switch", "the", "they", "togglegroup", "when", "with", "yearly", "yearlynote"], registryDependencies: ["badge", "card", "toggle-group", "utils"] }, { name: "product-card", type: "registry:block", title: "Product Card", description: "Shop tile: photos in an AspectRatio (a swipeable Carousel with dots when there are several), sale price, Badge and add-to-cart Button.", exports: ["ProductCard"], keywords: ["add", "addlabel", "are", "aspectratio", "badge", "bcp", "become", "button", "called", "card", "carousel", "code", "compareat", "currency", "current", "dots", "for", "formatting", "heading", "height", "href", "img", "iso", "label", "link", "locale", "major", "media", "name", "new", "number", "onaddtocart", "one", "original", "over", "page", "per", "photos", "pressed", "price", "product", "ratio", "sale", "several", "shop", "shows", "slide", "small", "square", "struck", "swipeable", "text", "the", "there", "through", "tile", "units", "when", "width", "with"], registryDependencies: ["aspect-ratio", "badge", "button", "carousel", "utils"] }, { name: "progress", type: "registry:ui", title: "Progress", description: "Accent bar that springs to each new value, with an optional label and percentage. Leave out value for an indeterminate sweep (static under reduced motion).", exports: ["Progress"], keywords: ["above", "accent", "accessible", "across", "allowed", "also", "aria", "bar", "colored", "duration", "each", "for", "frame", "indeterminate", "infinite", "its", "label", "layout", "max", "motion", "name", "new", "next", "omit", "one", "per", "percentage", "reduced", "scalex", "segment", "show", "showvalue", "size", "springs", "static", "sweeps", "that", "the", "there", "thickness", "tween", "under", "unknown", "value", "visible", "when", "work"], registryDependencies: ["utils"] }, { name: "quote", type: "registry:ui", title: "Quote", description: "Semantic figure, blockquote and figcaption. Plain, card and large variants, with author, subtitle, avatar, lang, typewriter and textSwap.", exports: ["Quote"], keywords: ["accent", "alt", "and", "array", "author", "avatar", "blockquote", "card", "children", "correct", "custom", "cycles", "delay", "display", "doe", "effect", "enables", "fades", "figcaption", "figure", "for", "into", "jane", "job", "lang", "language", "large", "line", "mark", "options", "pass", "plain", "pronunciation", "quote", "quoted", "quotes", "reader", "said", "screen", "scrolls", "secondary", "semantic", "seo", "size", "slot", "speed", "spring", "string", "strings", "subtitle", "supports", "surface", "swap", "text", "textswap", "the", "through", "title", "transitions", "typewriter", "under", "variant", "view", "when", "who", "with", "work", "wrote"], registryDependencies: ["text-swap", "typewriter", "utils"] }, { name: "radio-group", type: "registry:ui", title: "Radio Group", description: "Native radios in a fieldset with a legend: browser arrow keys and form submit, a dot that springs in, optional per-option descriptions, vertical or horizontal.", exports: ["RadioGroup", "RadioGroupItem"], keywords: ["adds", "and", "application", "aria", "arrow", "browser", "but", "called", "children", "conform", "controlled", "defaultvalue", "description", "disabled", "does", "entered", "expected", "field", "fieldset", "first", "form", "format", "generated", "group", "indicates", "invalid", "item", "items", "its", "keys", "label", "labels", "lay", "legend", "line", "muted", "name", "native", "not", "omitted", "one", "onvaluechange", "option", "orientation", "pair", "picked", "radios", "render", "rendered", "row", "selectable", "shown", "stack", "submit", "submitted", "the", "them", "uncontrolled", "under", "value", "visible", "when", "with", "work"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "rating", type: "registry:ui", title: "Rating", description: "Star rating on native radios (arrow keys, forms) with hover preview, or readOnly display with fractional stars for averages.", exports: ["Rating"], keywords: ["and", "arrow", "called", "chosen", "controlled", "defaultvalue", "display", "field", "filled", "first", "for", "form", "forms", "fractions", "group", "hidden", "hover", "image", "included", "inputs", "interactive", "keys", "label", "lift", "max", "name", "native", "number", "only", "onvaluechange", "pair", "partially", "picked", "press", "preview", "radios", "rating", "readers", "readonly", "render", "renders", "score", "screen", "size", "spring", "star", "stars", "the", "uncontrolled", "value", "visually", "with"], registryDependencies: ["use-controllable-state", "utils"] }, { name: "relative-time", type: "registry:ui", title: "Relative Time", description: "Self-updating “5 minutes ago” in a semantic <time> with the full date as its title. Server renders the absolute date (no hydration mismatch); one shared ticker for the whole page.", exports: ["RelativeTime"], keywords: ["absolute", "ago", "and", "both", "client", "crawlers", "current", "date", "default", "differ", "full", "get", "hydration", "its", "itself", "keeps", "locale", "minutes", "mismatch", "not", "now", "one", "page", "pass", "real", "relative", "render", "renders", "semantic", "server", "shared", "stored", "text", "that", "the", "there", "ticker", "time", "timestamp", "title", "with", "would"], registryDependencies: ["utils"] }, { name: "resizable", type: "registry:ui", title: "Resizable", description: "Split panes for admin layouts, docs and editors. Hairline dividers with a wide grab area follow the pointer; collapsible panels snap shut past half their minimum. Dividers are APG window splitters: arrows step, Home/End jump to the limits, Enter or double-click collapses with a spring. Groups nest.", exports: ["ResizablePanelGroup", "ResizablePanel", "ResizableHandle"], keywords: ["adds", "admin", "after", "already", "and", "apg", "are", "arrow", "arrows", "basis", "between", "click", "collapsed", "collapsedsize", "collapses", "collapsible", "component", "cookie", "css", "default", "defaultsize", "direction", "divider", "docs", "dom", "double", "drag", "dragging", "each", "editors", "end", "enter", "evenly", "final", "find", "flex", "follows", "for", "grip", "group", "half", "handle", "handles", "home", "horizontal", "hydration", "icon", "jump", "key", "keyboardstep", "keys", "largest", "layout", "layouts", "left", "limits", "maxsize", "middle", "minimum", "minsize", "neighbor", "one", "onlayout", "order", "others", "panels", "panes", "parents", "past", "per", "plain", "pointer", "press", "rail", "rest", "save", "server", "share", "shows", "shut", "side", "size", "sizes", "smallest", "snaps", "split", "splitters", "spring", "ssr", "stacked", "starting", "step", "the", "their", "them", "toggle", "toggles", "two", "until", "vertical", "visible", "what", "when", "window", "withhandle", "without", "work", "wrappers"], registryDependencies: ["utils"] }, { name: "reveal", type: "registry:ui", title: "Reveal", description: "Scroll reveal: content fades and rises on a spring the first time it enters the viewport.", exports: ["Reveal"], keywords: ["after", "and", "content", "delay", "entering", "fades", "first", "into", "offset", "place", "rises", "scrolls", "seconds", "spring", "start", "stays", "the", "time", "view", "visible", "wait"], registryDependencies: ["utils"] }, { name: "scroll-area", type: "registry:ui", title: "Scroll Area", description: "Overlay scrollbars: thin thumbs that fade in while scrolling or on hover, widen under the pointer and drag. Scrolling stays native; the labeled region is keyboard-focusable.", exports: ["ScrollArea"], keywords: ["also", "and", "aria", "axes", "can", "classes", "drag", "fade", "focus", "for", "get", "give", "goes", "height", "here", "horizontal", "hover", "itself", "keyboard", "label", "mouse", "names", "native", "one", "orientation", "overlay", "padding", "region", "scroll", "scrollable", "scrollbars", "scrolling", "stays", "takes", "that", "the", "thin", "thumb", "thumbs", "touch", "users", "viewport", "viewportclassname", "wheel", "while", "widen"], registryDependencies: ["utils"] }, { name: "search-input", type: "registry:ui", title: "Search Input", description: 'Search field built on Input: leading icon, spring-in clear button, Esc to clear, and an optional focus shortcut ("/" or mod+k) with a Kbd hint.', exports: ["SearchInput"], keywords: ["accessible", "already", "and", "anywhere", "aside", "border", "browser", "button", "called", "change", "clear", "cleared", "clears", "command", "controlled", "ctrl", "default", "defaultvalue", "elsewhere", "embedded", "esc", "every", "field", "find", "first", "focus", "focused", "focuses", "for", "from", "ghost", "hidden", "hint", "htmlfor", "icon", "inputs", "kbd", "key", "label", "mac", "mod", "name", "onvaluechange", "opens", "optional", "own", "pair", "palette", "pass", "query", "render", "ring", "search", "second", "shadow", "shortcut", "single", "skipped", "spring", "steps", "still", "surface", "the", "uncontrolled", "value", "variant", "when", "while", "with", "you"], registryDependencies: ["input", "kbd", "platform", "use-controllable-state", "use-hotkey", "utils"] }, { name: "segmented-tabs", type: "registry:ui", title: "AppWindow", description: "Window container with close / minimize / zoom controls, title, custom header slot and actions. SegmentedTabs is the compact view switcher for its title bar.", exports: ["SegmentedTabs"], keywords: ["accessible", "active", "also", "always", "aria", "behind", "called", "current", "for", "indicator", "item", "items", "label", "labels", "list", "marked", "name", "onchange", "one", "pressed", "segmented", "slides", "spring", "tab", "tabs", "the", "under", "used", "value", "values", "with"], registryDependencies: ["overflow-focus", "use-indicator", "utils"] }, { name: "select", type: "registry:ui", title: "Select", description: "Single-choice listbox styled like Input, with groups, icons and disabled options. Native-select keyboard (arrows, typeahead even while closed), flips above the trigger near the viewport edge, submits via a hidden input.", exports: ["Select"], keywords: ["accessible", "also", "aria", "blocks", "called", "cancel", "choice", "closed", "controlled", "defaultvalue", "describedby", "disabled", "down", "end", "enter", "error", "esc", "field", "fill", "fills", "first", "flat", "form", "from", "groups", "hidden", "hint", "home", "htmlfor", "ids", "input", "invalid", "keyboard", "label", "labeled", "let", "like", "listbox", "matches", "name", "native", "needs", "nothing", "onvaluechange", "opening", "options", "pair", "pick", "picked", "placeholder", "render", "required", "select", "sets", "single", "space", "styled", "styling", "submit", "submits", "text", "the", "there", "through", "trigger", "typeahead", "uncontrolled", "value", "visible", "when", "while", "with"], registryDependencies: ["field", "input", "list", "platform", "use-anchor", "use-controllable-state", "use-dismiss", "utils"] }, { name: "separator", type: "registry:ui", title: "Separator", description: 'Server-safe hairline, horizontal or vertical, decorative by default, with an optional centered label like "or".', exports: ["Separator"], keywords: ["assistive", "centered", "content", "decorative", "default", "direction", "false", "for", "horizontal", "label", "line", "only", "orientation", "purely", "separates", "set", "tech", "text", "the", "visual", "when"], registryDependencies: ["utils"] }, { name: "sidebar", type: "registry:ui", title: "Sidebar", description: "App navigation from data: header, groups (optionally foldable), badges and pinned footer entries. Collapses to an icon rail on a spring (⌘B / Ctrl+B) with labels kept for assistive tech; below md it is a left drawer.", exports: ["SidebarLayout", "Sidebar", "SidebarTrigger"], keywords: ["a11y", "accessible", "and", "aria", "below", "bottom", "but", "called", "client", "clip", "collapsed", "collapses", "controlled", "ctrl", "current", "data", "default", "defaultcollapsed", "drawer", "entries", "field", "footer", "for", "from", "groups", "header", "highlighted", "holds", "icon", "ignored", "item", "label", "labels", "landmark", "lays", "left", "links", "name", "navigation", "oncollapsedchange", "onselect", "page", "pair", "picked", "pinned", "rail", "routing", "settings", "shortcut", "side", "sidebar", "slot", "spring", "start", "state", "stay", "the", "toggle", "too", "top", "tree", "trigger", "true", "typing", "uncontrolled", "when", "while", "with", "workspace"], registryDependencies: ["button", "collapsible", "drawer", "platform", "use-controllable-state", "use-hotkey", "utils"] }, { name: "site-header", type: "registry:block", title: "Site Header", description: "Sticky, translucent site header from one nav array: brand, NavigationMenu panels from md up, a right Drawer with the same links below it, and your actions on the right. The hairline underneath appears only once content scrolls beneath it.", exports: ["SiteHeader"], keywords: ["accessible", "acme", "actions", "alike", "and", "appears", "aria", "below", "brand", "client", "close", "controls", "current", "demo", "desktop", "drawer", "every", "for", "from", "hairline", "hand", "header", "href", "label", "left", "level", "link", "links", "logo", "marks", "matching", "name", "nav", "navigation", "navigationmenu", "once", "onclick", "only", "onnavigate", "over", "page", "panels", "right", "routing", "same", "scrolls", "search", "shown", "sign", "site", "sticky", "stub", "the", "theme", "top", "under", "width", "with"], registryDependencies: ["button", "drawer", "navigation-menu", "use-disclosure", "utils"] }, { name: "skeleton", type: "registry:ui", title: "Skeleton", description: 'Server-safe loading placeholders that pulse (static under reduced motion). SkeletonGroup announces one "Loading" to screen readers.', exports: ["Skeleton", "SkeletonGroup"], keywords: ["announced", "block", "classes", "classname", "hear", "instead", "label", "loading", "nothing", "one", "placeholder", "readers", "screen", "shown", "size", "skeleton", "skeletons", "this", "while", "with", "wrap"], registryDependencies: ["utils"] }, { name: "slider", type: "registry:ui", title: "Slider", description: "Slider over native range inputs: thin accent track, white knob that lifts while held. One value or two for a range; keyboard, forms, touch and Field wiring come from the platform.", exports: ["Slider"], keywords: ["accent", "accessible", "and", "aria", "arrow", "blocks", "browser", "called", "defaults", "defaultvalue", "describedby", "disabled", "does", "drag", "dragging", "error", "every", "field", "fills", "filter", "first", "for", "forms", "from", "held", "highest", "hint", "ids", "increment", "inputs", "invalid", "keyboard", "keys", "knob", "labels", "lifts", "lowest", "max", "maximum", "min", "minimum", "name", "names", "native", "one", "onvaluechange", "over", "per", "price", "range", "readers", "render", "screen", "sets", "slider", "step", "styling", "submitted", "text", "that", "the", "thin", "thumb", "touch", "track", "twice", "two", "uncontrolled", "value", "values", "while", "white", "with", "work"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "spinner", type: "registry:ui", title: "Spinner", description: "Server-safe activity indicator: eight spokes in currentColor, three sizes, its own status label (or silent inside a parent that announces). Holds still under reduced motion.", exports: ["Spinner"], keywords: ["accessible", "activity", "already", "announces", "busy", "currentcolor", "diameter", "eight", "holds", "indicator", "label", "motion", "name", "parent", "pass", "reduced", "size", "spokes", "state", "still", "the", "under", "when"], registryDependencies: ["utils"] }, { name: "stat-tile", type: "registry:block", title: "Stat Tile", description: "Admin dashboard metric: value, a delta Badge that is green when the change is good news (invert for errors and latency), and an area Chart of the trend. Server-safe.", exports: ["StatTile"], keywords: ["admin", "and", "area", "axis", "badge", "below", "change", "chart", "dashboard", "data", "datakey", "delta", "down", "each", "errors", "for", "format", "formatted", "good", "green", "headline", "index", "intl", "invert", "key", "label", "last", "latency", "metric", "metrics", "month", "name", "news", "number", "period", "positive", "revenue", "row", "rows", "the", "tile", "tooltip", "trend", "unless", "value", "when", "where"], registryDependencies: ["badge", "card", "chart", "utils"] }, { name: "stats-strip", type: "registry:block", title: "Stats Strip", description: "Headline numbers, each card a <dl>: cards rise in turn with Reveal, then each number springs up with CountTo. Final values are in the HTML.", exports: ["StatsStrip"], keywords: ["card", "display", "each", "headline", "its", "number", "numbers", "order", "rises", "row", "springs", "stats", "then", "turn"], registryDependencies: ["card", "count-to", "reveal", "utils"] }, { name: "stepper", type: "registry:ui", title: "Stepper", description: "Multi-step form (questionnaire, checkout, setup wizard). Steps stay mounted so values survive Back and submit together; Continue checks only the current step's native constraints, plus an optional async onNext guard with a spinner. Progress header with springing connectors; works with onSubmit or a Server Action.", exports: ["Stepper", "StepperList", "StepperStep", "StepperFooter"], keywords: ["action", "after", "and", "are", "back", "backlabel", "button", "called", "check", "checks", "children", "connector", "constraints", "continue", "controlled", "current", "defaultvalue", "description", "every", "false", "fields", "fills", "finished", "first", "for", "form", "header", "hidden", "inactive", "its", "last", "links", "matches", "mounted", "multi", "native", "new", "nextlabel", "not", "one", "only", "onnext", "onsubmit", "onvaluechange", "optional", "order", "pass", "progress", "render", "resolve", "return", "runs", "server", "shown", "shows", "spinner", "spring", "start", "stay", "stays", "step", "steps", "submit", "submitlabel", "submits", "survive", "text", "the", "through", "title", "together", "uncontrolled", "unmounted", "value", "values", "while", "with"], registryDependencies: ["button", "use-controllable-state", "utils"] }, { name: "styles", type: "registry:file", exports: [], keywords: [], registryDependencies: [] }, { name: "switch", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["Switch"], keywords: ["called", "checkbox", "checked", "controlled", "defaultchecked", "first", "knob", "native", "new", "oncheckedchange", "pair", "render", "role", "spring", "state", "switch", "the", "uncontrolled", "with"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "table", type: "registry:ui", title: "Table", description: "Server-safe semantic <table> in a scrolling card: header, body, footer and caption, striped rows, tinted selected rows, and sortable headers that set aria-sort and flip their arrow.", exports: ["Table", "TableHeader", "TableBody", "TableFooter", "TableRow", "TableHead", "TableCell", "TableCaption"], keywords: ["alternating", "and", "aria", "around", "arrow", "button", "called", "card", "classes", "column", "containerclassname", "data", "direction", "for", "header", "keyboard", "makes", "narrow", "onsort", "pass", "pressed", "real", "requires", "row", "screens", "scrollable", "scrolling", "scrolls", "selected", "sets", "shading", "shows", "sideways", "sort", "sortable", "state", "striped", "table", "that", "the", "then", "tint", "when"], registryDependencies: ["overflow-focus", "utils"] }, { name: "tabs", type: "registry:ui", title: "Tabs", description: "WAI-ARIA tabs with arrow, Home and End keys. One indicator springs between tabs, segmented or underline. Inactive panels stay in the DOM for SEO; the active one fades in.", exports: ["Tabs", "TabsList", "TabsTrigger", "TabsContent"], keywords: ["activated", "active", "always", "and", "aria", "arrows", "bar", "behind", "called", "children", "content", "controlled", "crawlable", "defaultvalue", "dom", "end", "first", "focus", "hidden", "home", "html", "inactive", "indicator", "labels", "matches", "move", "muted", "one", "onvaluechange", "pair", "panel", "panels", "pill", "remains", "render", "segmented", "springs", "stay", "stays", "tab", "tabs", "tabscontent", "tabstrigger", "the", "their", "track", "uncontrolled", "under", "underline", "value", "variant", "wai", "while", "with"], registryDependencies: ["list", "use-controllable-state", "use-indicator", "utils"] }, { name: "tag-input", type: "registry:ui", title: "Tag Input", description: "Free-form tags: Enter or a separator adds, Backspace removes the last, pasting a list adds them all. Duplicates, a max and a validate function keep bad tags in the input. One hidden input per tag.", exports: ["tagFieldClass", "Tag", "TagInput"], keywords: ["accessible", "add", "after", "allowed", "and", "animatepresence", "backspace", "besides", "button", "called", "children", "chip", "commit", "controlled", "defaultvalue", "disabled", "empty", "enter", "every", "false", "first", "form", "free", "hidden", "hides", "input", "inside", "its", "keys", "last", "limit", "list", "many", "max", "mode", "most", "name", "one", "onremove", "onvaluechange", "out", "pair", "paste", "pasted", "per", "poplayout", "press", "reject", "removable", "remove", "removes", "render", "rendered", "return", "runs", "separator", "separators", "shows", "split", "springs", "stays", "stops", "submits", "tag", "tags", "text", "that", "the", "these", "too", "trimming", "type", "typed", "typing", "uncontrolled", "validate", "value", "when", "with"], registryDependencies: ["field", "use-controllable-state", "utils"] }, { name: "terminal", type: "registry:ui", title: "Terminal", description: "Terminal window. Snippet mode types install commands once scrolled into view, with the full transcript kept in the DOM for SEO and no-JS; log mode streams lines into a live region that follows the bottom unless you scroll up, then offers a jump back. Status lines carry glyphs, copy grabs the commands.", exports: ["Terminal"], keywords: ["and", "append", "arrives", "back", "before", "body", "bodyclassname", "bottom", "character", "clipboard", "commands", "copy", "copytext", "defaults", "dom", "false", "follows", "for", "full", "hides", "install", "jump", "lines", "live", "log", "mode", "new", "offering", "once", "order", "output", "per", "prompt", "puts", "read", "reveals", "role", "scroll", "scrolling", "seo", "size", "snippet", "snippets", "speed", "stays", "sticks", "stream", "streams", "symbol", "terminal", "text", "the", "title", "typed", "types", "typing", "unless", "view", "what", "when", "window", "you"], registryDependencies: ["app-window", "code", "platform", "utils"] }, { name: "testimonial", type: "registry:block", title: "Testimonial", description: "A large Quote with its author, and everyone else who agrees as an overlapping AvatarGroup. Server-safe.", exports: ["Testimonial"], keywords: ["agrees", "and", "author", "avatar", "avatargroup", "behind", "beside", "carried", "children", "company", "crowd", "else", "everyone", "few", "first", "fold", "initials", "into", "its", "lang", "language", "large", "line", "one", "others", "otherslabel", "photo", "quote", "rest", "role", "said", "show", "stack", "streamers", "subtitle", "the", "trusted", "under", "url", "who", "with", "without"], registryDependencies: ["avatar", "avatar-group", "quote", "utils"] }, { name: "text-swap", type: "registry:ui", title: "TextSwap", description: "Spring-powered text morphing and ticker. Auto-cycles phrases or animates whenever children change with blur and slide transitions.", exports: ["TextSwap"], keywords: ["active", "array", "automatically", "between", "changing", "child", "children", "controlling", "cycle", "cycling", "default", "direction", "externally", "hover", "index", "interval", "items", "milliseconds", "mouse", "new", "pass", "pause", "pauseonhover", "single", "string", "swap", "swaps", "text", "the", "through", "true", "when"], registryDependencies: ["utils"] }, { name: "textarea", type: "registry:ui", title: "Forms", description: "Input, Textarea, Label and Switch: smooth focus rings, native :user-invalid validation (red only after interaction), aria-invalid, auto-growing textarea with an optional character count, and a spring switch.", exports: ["Textarea"], keywords: ["auto", "cap", "content", "corner", "end", "field", "firefox", "grows", "max", "maxlength", "near", "needs", "red", "resizable", "show", "showcount", "sizing", "the", "then", "turns", "unsupported", "used", "warning", "where", "with"], registryDependencies: ["field", "input", "utils"] }, { name: "theme", type: "registry:lib", description: "Retints primary, focus rings, selection and switches app-wide. Persists like the theme.", exports: ["isDark", "setTheme", "subscribeTheme", "accents", "getAccent", "setAccent", "themeScript"], keywords: ["and", "app", "focus", "like", "persists", "primary", "retints", "rings", "selection", "switches", "the", "theme", "wide"], registryDependencies: [] }, { name: "theme-toggle", type: "registry:ui", title: "Theme Toggle", description: "Light/dark icon switch with spring rotate-swap; follows the OS until first use.", exports: ["ThemeToggle"], keywords: ["button", "click", "first", "follows", "icon", "moon", "rotate", "spring", "sun", "swap", "until"], registryDependencies: ["button", "theme", "utils"] }, { name: "timeline", type: "registry:ui", title: "Timeline", description: "Server-safe ordered list of events on a rail: icon or dot markers with status colors, machine-readable <time>, title and an optional body. For changelogs, experience and mod logs.", exports: ["Timeline", "TimelineItem"], keywords: ["above", "and", "body", "children", "color", "date", "datetime", "dot", "event", "events", "first", "for", "headline", "icon", "inside", "list", "machine", "marker", "newest", "oldest", "one", "optional", "order", "ordered", "pair", "rail", "readable", "render", "shown", "small", "the", "then", "time", "title", "variant", "with", "without", "yours"], registryDependencies: ["utils"] }, { name: "toast", type: "registry:ui", title: "Toast", description: "Stacked notifications. Hover to expand, swipe to dismiss, timers pause on hover.", exports: ["toast", "Toaster"], keywords: ["action", "description", "dismiss", "dismisses", "duration", "error", "expands", "focus", "hover", "layout", "loading", "mount", "once", "promise", "root", "saved", "stacked", "success", "swipe", "tap", "title", "toast", "toasts"], registryDependencies: ["use-dismiss", "utils"] }, { name: "toggle-group", type: "registry:ui", title: "Toggle Group", description: "Segmented control of toggle buttons. Single mode slides one pill to the pressed item (view mode, billing period); multiple mode toggles items independently (bold, italic). Arrow keys move between items.", exports: ["ToggleGroup", "ToggleGroupItem"], keywords: ["always", "and", "aria", "arrow", "behind", "between", "billing", "bold", "buttons", "called", "choice", "control", "controlled", "defaultvalue", "end", "every", "filters", "first", "height", "home", "icon", "independent", "italic", "item", "items", "keys", "label", "labels", "mode", "move", "multiple", "need", "one", "only", "onvaluechange", "pair", "period", "pill", "pressed", "render", "reported", "segment", "segmented", "set", "single", "size", "slides", "springs", "the", "time", "toggle", "toggles", "type", "uncontrolled", "value", "values", "view", "when", "with"], registryDependencies: ["list", "use-controllable-state", "use-indicator", "utils"] }, { name: "tooltip", type: "registry:ui", title: "Tooltip", description: "Short label on hover or keyboard focus, also wired as the trigger's aria-describedby. Warm-up: once one opens, neighbors open instantly. Hoverable, Esc dismisses, ignores touch.", exports: ["Tooltip"], keywords: ["accessible", "action", "align", "alignment", "also", "and", "aria", "becomes", "before", "button", "children", "content", "control", "default", "delay", "description", "dismisses", "element", "esc", "first", "flips", "focus", "focusable", "for", "hold", "hover", "how", "icon", "keyboard", "label", "one", "open", "opens", "own", "pointer", "preferred", "press", "reaches", "room", "short", "shows", "side", "stays", "still", "tap", "text", "the", "their", "there", "toggles", "tooltip", "touch", "trigger", "triggers", "wcag", "when", "while", "with"], registryDependencies: ["platform", "use-anchor", "use-dismiss", "use-hover-open", "utils"] }, { name: "typewriter", type: "registry:ui", title: "Typewriter", description: "Types out text character-by-character with optional phrase cycling and pulsing cursor. Full copy stays in the DOM for SEO.", exports: ["Typewriter"], keywords: ["and", "array", "before", "blinking", "called", "character", "classes", "cursor", "cursorchar", "cursorclassname", "custom", "cycle", "default", "delay", "deletespeed", "deleting", "dom", "effect", "for", "full", "fully", "headers", "hero", "loop", "milliseconds", "once", "oncomplete", "pause", "pauseduration", "per", "phrase", "phrases", "quotes", "seo", "show", "speed", "starting", "stays", "text", "the", "through", "true", "type", "typed", "typewriter", "typing", "wait", "when", "whether", "while"], registryDependencies: ["platform", "utils"] }, { name: "use-anchor", type: "registry:hook", description: `Fixed-position coordinates for a floating panel next to its anchor: on the preferred side,
|
|
16965
17161
|
flipped when it doesn't fit, clamped to the viewport, kept in place on scroll and resize.
|
|
16966
17162
|
Measures before paint, so nothing jumps.`, exports: ["useAnchor"], keywords: ["anchor", "and", "before", "clamped", "coordinates", "doesn", "fit", "fixed", "flipped", "floating", "for", "its", "jumps", "kept", "measures", "next", "nothing", "paint", "panel", "place", "position", "preferred", "resize", "scroll", "side", "the", "viewport", "when"], registryDependencies: ["utils"] }, { name: "use-controllable-state", type: "registry:hook", description: "State a parent may own. Controlled while `value` is defined; otherwise kept here, seeded from\n`defaultValue`. The setter always reports through `onChange`, so both modes stay observable.", exports: ["useControllableState"], keywords: ["always", "both", "controlled", "defaultvalue", "defined", "from", "here", "kept", "may", "modes", "observable", "onchange", "otherwise", "own", "parent", "reports", "seeded", "setter", "state", "stay", "the", "through", "value", "while"], registryDependencies: [] }, { name: "use-disclosure", type: "registry:hook", description: "Open state for any overlay. Spread `props` onto Dialog, Drawer, Popover or DropdownMenu and\nopen it from anywhere: `const drawer = useDisclosure(); <Drawer {...drawer.props}>`, `drawer.show()`.", exports: ["useDisclosure"], keywords: ["and", "any", "anywhere", "const", "dialog", "drawer", "dropdownmenu", "for", "from", "onto", "open", "overlay", "popover", "props", "show", "spread", "state", "usedisclosure"], registryDependencies: [] }, { name: "use-dismiss", type: "registry:hook", description: "Inside one of `refs` (panel first, then its trigger), or inside a floating child opened from\nthe panel: a Select list or menu portals out, but it is marked `data-floating`.", exports: ["isWithin", "useDismiss"], keywords: ["and", "but", "child", "children", "closes", "data", "first", "floating", "from", "inside", "its", "list", "marked", "menu", "one", "opened", "out", "outside", "panel", "pointerdown", "portals", "refs", "select", "the", "then", "trigger"], registryDependencies: [] }, { name: "use-hotkey", type: "registry:hook", description: '`"mod+k"`: ⌘K on Mac, Ctrl+K elsewhere, without Alt. `"/"`: the key alone, no modifiers.', exports: ["matchesHotkey", "useHotkey"], keywords: ["alone", "alt", "browser", "ctrl", "disable", "elsewhere", "false", "handler", "key", "keyboard", "leave", "mac", "mod", "modifiers", "pass", "preventdefault", "returns", "shortcut", "the", "undefined", "wide", "window", "without"], registryDependencies: [] }, { name: "use-hover-open", type: "registry:hook", description: "Open-on-hover state with intent delays, shared by Tooltip and HoverCard. Mouse only (touch\ntaps go to the trigger's own action); keyboard focus opens it too. Spread `trigger` on the\nanchor and `floating` on the panel so moving between them keeps it open.", exports: ["useHoverOpen"], keywords: ["action", "anchor", "and", "between", "delays", "floating", "focus", "hover", "hovercard", "intent", "keeps", "keyboard", "mouse", "moving", "only", "open", "opens", "own", "panel", "shared", "spread", "state", "taps", "the", "them", "too", "tooltip", "touch", "trigger", "with"], registryDependencies: [] }, { name: "use-indicator", type: "registry:hook", description: `Offset and width of the active item, for one indicator that springs between items (Tabs,
|
|
16967
17163
|
ToggleGroup). Re-measures when the item or its row resizes (font swap, wrap), or the pill
|
|
@@ -17061,7 +17257,7 @@ async function fetchAllItems(source) {
|
|
|
17061
17257
|
// jsr.json
|
|
17062
17258
|
var jsr_default = {
|
|
17063
17259
|
name: "@kznlabs/labsui",
|
|
17064
|
-
version: "0.1.
|
|
17260
|
+
version: "0.1.2",
|
|
17065
17261
|
license: "MIT",
|
|
17066
17262
|
exports: "./src/index.ts",
|
|
17067
17263
|
publish: {
|