@memelabui/ui 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -3
- package/dist/index.cjs +434 -3
- package/dist/index.d.cts +62 -1
- package/dist/index.d.ts +62 -1
- package/dist/index.js +429 -4
- package/dist/styles/index.css +135 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ function App() {
|
|
|
51
51
|
}
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
## Components (
|
|
54
|
+
## Components (50+ exports)
|
|
55
55
|
|
|
56
56
|
### Form
|
|
57
57
|
|
|
@@ -63,7 +63,7 @@ function App() {
|
|
|
63
63
|
| `Textarea` | Multiline text input with label/error |
|
|
64
64
|
| `Checkbox` | Custom checkbox with indeterminate support |
|
|
65
65
|
| `RadioGroup` / `RadioItem` | Compound radio button group |
|
|
66
|
-
| `Toggle` | Switch toggle (sm/md sizes) |
|
|
66
|
+
| `Toggle` | Switch toggle (sm/md sizes) with `busy` spinner state |
|
|
67
67
|
| `Slider` | Range input with custom track/thumb and value display |
|
|
68
68
|
| `TagInput` | Tag input with Enter/comma/paste, dedup, maxTags |
|
|
69
69
|
| `ColorInput` | Hex color picker with swatch + text input |
|
|
@@ -82,6 +82,7 @@ function App() {
|
|
|
82
82
|
| Component | Description |
|
|
83
83
|
|-----------|-------------|
|
|
84
84
|
| `Card` | Surface or glass card container |
|
|
85
|
+
| `SectionCard` | Settings section card with title, description, right slot, overlay slot |
|
|
85
86
|
| `Badge` / `Pill` | Status badges (neutral, primary, success, danger, warning, accent) |
|
|
86
87
|
| `StatCard` | Dashboard stat card with value, label, icon, trend indicator |
|
|
87
88
|
| `Table` / `TableHeader` / `TableBody` / `TableRow` / `TableHead` / `TableCell` | Styled table primitives |
|
|
@@ -93,6 +94,16 @@ function App() {
|
|
|
93
94
|
| `DropZone` | Drag & drop file upload area with accept filter |
|
|
94
95
|
| `Avatar` | Circular avatar with image + initials fallback |
|
|
95
96
|
| `Divider` | Horizontal/vertical divider with optional label |
|
|
97
|
+
| `ActiveFilterPills` | Dismissible filter pill row with "Clear all" action |
|
|
98
|
+
| `DotIndicator` | Dot-based remaining count with urgency colors |
|
|
99
|
+
|
|
100
|
+
### Progress & Status
|
|
101
|
+
|
|
102
|
+
| Component | Description |
|
|
103
|
+
|-----------|-------------|
|
|
104
|
+
| `ProgressBar` | Horizontal progress bar with variants and sizes |
|
|
105
|
+
| `CooldownRing` | SVG circular countdown timer with color changes and pulse |
|
|
106
|
+
| `StageProgress` | Multi-stage process indicator with shimmer animation |
|
|
96
107
|
|
|
97
108
|
### Navigation
|
|
98
109
|
|
|
@@ -109,6 +120,7 @@ function App() {
|
|
|
109
120
|
| `ConfirmDialog` | Confirmation modal with cancel/confirm actions |
|
|
110
121
|
| `Tooltip` | Hover/focus tooltip with portal positioning |
|
|
111
122
|
| `Dropdown` | Compound menu (Trigger, Menu, Item, Separator) |
|
|
123
|
+
| `MutationOverlay` | Saving/saved/error status overlay for cards |
|
|
112
124
|
|
|
113
125
|
### Layout
|
|
114
126
|
|
|
@@ -126,7 +138,6 @@ function App() {
|
|
|
126
138
|
| `ToastProvider` / `useToast` | Toast notification system with variants |
|
|
127
139
|
| `Alert` | Inline notification banner (info, success, warning, error) |
|
|
128
140
|
| `CopyField` | Read-only field with copy button and optional masking |
|
|
129
|
-
| `ProgressBar` | Horizontal progress bar with variants and sizes |
|
|
130
141
|
|
|
131
142
|
### Hooks
|
|
132
143
|
|
package/dist/index.cjs
CHANGED
|
@@ -558,7 +558,7 @@ var thumbSize = {
|
|
|
558
558
|
sm: { base: "w-4 h-4", translate: "translate-x-4" },
|
|
559
559
|
md: { base: "w-5 h-5", translate: "translate-x-5" }
|
|
560
560
|
};
|
|
561
|
-
var Toggle = React.forwardRef(function Toggle2({ checked, onChange, disabled, label, size = "md", id: externalId, "aria-label": ariaLabel }, ref) {
|
|
561
|
+
var Toggle = React.forwardRef(function Toggle2({ checked, onChange, disabled, busy, label, size = "md", id: externalId, "aria-label": ariaLabel }, ref) {
|
|
562
562
|
const generatedId = React.useId();
|
|
563
563
|
const toggleId = externalId || generatedId;
|
|
564
564
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
@@ -571,7 +571,8 @@ var Toggle = React.forwardRef(function Toggle2({ checked, onChange, disabled, la
|
|
|
571
571
|
role: "switch",
|
|
572
572
|
"aria-checked": checked,
|
|
573
573
|
"aria-label": ariaLabel || label,
|
|
574
|
-
disabled,
|
|
574
|
+
disabled: disabled || busy,
|
|
575
|
+
"aria-busy": busy || void 0,
|
|
575
576
|
onClick: () => onChange(!checked),
|
|
576
577
|
className: cn(
|
|
577
578
|
"relative rounded-full transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-surface",
|
|
@@ -583,9 +584,18 @@ var Toggle = React.forwardRef(function Toggle2({ checked, onChange, disabled, la
|
|
|
583
584
|
"span",
|
|
584
585
|
{
|
|
585
586
|
className: cn(
|
|
586
|
-
"absolute top-0.5 left-0.5 rounded-full bg-white transition-transform duration-200",
|
|
587
|
+
"absolute top-0.5 left-0.5 rounded-full bg-white transition-transform duration-200 flex items-center justify-center",
|
|
587
588
|
thumbSize[size].base,
|
|
588
589
|
checked ? thumbSize[size].translate : "translate-x-0"
|
|
590
|
+
),
|
|
591
|
+
children: busy && /* @__PURE__ */ jsxRuntime.jsx(
|
|
592
|
+
"span",
|
|
593
|
+
{
|
|
594
|
+
className: cn(
|
|
595
|
+
"border-2 border-primary/30 border-t-primary rounded-full animate-spin",
|
|
596
|
+
size === "sm" ? "w-2.5 h-2.5" : "w-3 h-3"
|
|
597
|
+
)
|
|
598
|
+
}
|
|
589
599
|
)
|
|
590
600
|
}
|
|
591
601
|
)
|
|
@@ -2257,6 +2267,309 @@ function ProgressBar({
|
|
|
2257
2267
|
)
|
|
2258
2268
|
] });
|
|
2259
2269
|
}
|
|
2270
|
+
var sizeMap = {
|
|
2271
|
+
sm: "w-8 h-8 text-xs",
|
|
2272
|
+
md: "w-12 h-12 text-sm",
|
|
2273
|
+
lg: "w-16 h-16 text-base"
|
|
2274
|
+
};
|
|
2275
|
+
var strokeWidthMap = {
|
|
2276
|
+
sm: 3,
|
|
2277
|
+
md: 3.5,
|
|
2278
|
+
lg: 4
|
|
2279
|
+
};
|
|
2280
|
+
var RADIUS = 15.9155;
|
|
2281
|
+
var CIRCUMFERENCE = 2 * Math.PI * RADIUS;
|
|
2282
|
+
function CooldownRing({
|
|
2283
|
+
duration,
|
|
2284
|
+
remaining,
|
|
2285
|
+
size = "md",
|
|
2286
|
+
className
|
|
2287
|
+
}) {
|
|
2288
|
+
const fraction = duration > 0 ? Math.max(0, Math.min(1, remaining / duration)) : 0;
|
|
2289
|
+
const offset = CIRCUMFERENCE * (1 - fraction);
|
|
2290
|
+
const color = fraction > 0.5 ? "text-primary" : fraction > 0.25 ? "text-amber-500" : "text-rose-500";
|
|
2291
|
+
const pulse = remaining <= 10 && remaining > 0;
|
|
2292
|
+
const strokeWidth = strokeWidthMap[size];
|
|
2293
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative inline-flex items-center justify-center", sizeMap[size], className), children: [
|
|
2294
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2295
|
+
"svg",
|
|
2296
|
+
{
|
|
2297
|
+
viewBox: "0 0 36 36",
|
|
2298
|
+
className: cn("w-full h-full -rotate-90", color, pulse && "animate-pulse"),
|
|
2299
|
+
"aria-label": `Cooldown: ${remaining} seconds remaining`,
|
|
2300
|
+
role: "img",
|
|
2301
|
+
children: [
|
|
2302
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2303
|
+
"circle",
|
|
2304
|
+
{
|
|
2305
|
+
cx: "18",
|
|
2306
|
+
cy: "18",
|
|
2307
|
+
r: RADIUS,
|
|
2308
|
+
fill: "none",
|
|
2309
|
+
stroke: "currentColor",
|
|
2310
|
+
strokeWidth,
|
|
2311
|
+
className: "text-white/10"
|
|
2312
|
+
}
|
|
2313
|
+
),
|
|
2314
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2315
|
+
"circle",
|
|
2316
|
+
{
|
|
2317
|
+
cx: "18",
|
|
2318
|
+
cy: "18",
|
|
2319
|
+
r: RADIUS,
|
|
2320
|
+
fill: "none",
|
|
2321
|
+
stroke: "currentColor",
|
|
2322
|
+
strokeWidth,
|
|
2323
|
+
strokeDasharray: `${CIRCUMFERENCE} ${CIRCUMFERENCE}`,
|
|
2324
|
+
strokeDashoffset: offset,
|
|
2325
|
+
strokeLinecap: "round",
|
|
2326
|
+
style: { transition: "stroke-dashoffset 0.6s ease" }
|
|
2327
|
+
}
|
|
2328
|
+
)
|
|
2329
|
+
]
|
|
2330
|
+
}
|
|
2331
|
+
),
|
|
2332
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2333
|
+
"span",
|
|
2334
|
+
{
|
|
2335
|
+
className: "absolute font-semibold tabular-nums text-white select-none",
|
|
2336
|
+
style: { lineHeight: 1 },
|
|
2337
|
+
children: Math.max(0, Math.ceil(remaining))
|
|
2338
|
+
}
|
|
2339
|
+
)
|
|
2340
|
+
] });
|
|
2341
|
+
}
|
|
2342
|
+
function StageProgress({ stages, activeStage, className }) {
|
|
2343
|
+
const clampedActive = Math.max(0, Math.min(activeStage, stages.length - 1));
|
|
2344
|
+
const fillPercent = stages.length <= 1 ? 100 : clampedActive / (stages.length - 1) * 100;
|
|
2345
|
+
const isComplete = clampedActive >= stages.length - 1;
|
|
2346
|
+
const isAnimating = !isComplete;
|
|
2347
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full", className), children: [
|
|
2348
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-between", children: stages.map((stage, index) => {
|
|
2349
|
+
const isCompleted = index < clampedActive;
|
|
2350
|
+
const isActive = index === clampedActive;
|
|
2351
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2352
|
+
"div",
|
|
2353
|
+
{
|
|
2354
|
+
className: cn(
|
|
2355
|
+
"flex items-center gap-1.5 text-xs font-medium transition-colors duration-300",
|
|
2356
|
+
isCompleted && "text-emerald-400",
|
|
2357
|
+
isActive && "text-white",
|
|
2358
|
+
!isCompleted && !isActive && "text-white/40"
|
|
2359
|
+
),
|
|
2360
|
+
children: [
|
|
2361
|
+
isCompleted ? (
|
|
2362
|
+
// Completed: emerald check circle
|
|
2363
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-3.5 w-3.5 items-center justify-center rounded-full bg-emerald-400/20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2364
|
+
"svg",
|
|
2365
|
+
{
|
|
2366
|
+
className: "h-2.5 w-2.5 text-emerald-400",
|
|
2367
|
+
viewBox: "0 0 10 10",
|
|
2368
|
+
fill: "none",
|
|
2369
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2370
|
+
"aria-hidden": "true",
|
|
2371
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2372
|
+
"path",
|
|
2373
|
+
{
|
|
2374
|
+
d: "M2 5.5L4 7.5L8 3",
|
|
2375
|
+
stroke: "currentColor",
|
|
2376
|
+
strokeWidth: "1.5",
|
|
2377
|
+
strokeLinecap: "round",
|
|
2378
|
+
strokeLinejoin: "round"
|
|
2379
|
+
}
|
|
2380
|
+
)
|
|
2381
|
+
}
|
|
2382
|
+
) })
|
|
2383
|
+
) : isActive ? (
|
|
2384
|
+
// Active: primary dot with ring
|
|
2385
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-3.5 w-3.5 items-center justify-center rounded-full ring-2 ring-[var(--ml-primary)] ring-offset-1 ring-offset-black/50", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-[var(--ml-primary)]" }) })
|
|
2386
|
+
) : (
|
|
2387
|
+
// Upcoming: hollow dim dot
|
|
2388
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-3.5 w-3.5 rounded-full border border-white/20 bg-transparent" })
|
|
2389
|
+
),
|
|
2390
|
+
stage
|
|
2391
|
+
]
|
|
2392
|
+
},
|
|
2393
|
+
stage
|
|
2394
|
+
);
|
|
2395
|
+
}) }),
|
|
2396
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2397
|
+
"div",
|
|
2398
|
+
{
|
|
2399
|
+
className: "relative mt-3 h-1.5 w-full overflow-hidden rounded-full bg-white/10",
|
|
2400
|
+
role: "progressbar",
|
|
2401
|
+
"aria-valuenow": clampedActive,
|
|
2402
|
+
"aria-valuemin": 0,
|
|
2403
|
+
"aria-valuemax": stages.length - 1,
|
|
2404
|
+
"aria-label": `Stage ${clampedActive + 1} of ${stages.length}: ${stages[clampedActive]}`,
|
|
2405
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2406
|
+
"div",
|
|
2407
|
+
{
|
|
2408
|
+
className: "h-full rounded-full bg-gradient-to-r from-[var(--ml-accent)] to-[var(--ml-primary)] transition-[width] duration-500 ease-in-out",
|
|
2409
|
+
style: { width: `${fillPercent}%` },
|
|
2410
|
+
children: isAnimating && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2411
|
+
"span",
|
|
2412
|
+
{
|
|
2413
|
+
className: "pointer-events-none absolute inset-0 -translate-x-full animate-[ml-shimmer_2s_ease-in-out_infinite] bg-gradient-to-r from-transparent via-white/30 to-transparent",
|
|
2414
|
+
"aria-hidden": "true"
|
|
2415
|
+
}
|
|
2416
|
+
)
|
|
2417
|
+
}
|
|
2418
|
+
)
|
|
2419
|
+
}
|
|
2420
|
+
)
|
|
2421
|
+
] });
|
|
2422
|
+
}
|
|
2423
|
+
function getUrgencyClasses(remaining, max) {
|
|
2424
|
+
const ratio = max > 0 ? remaining / max : 0;
|
|
2425
|
+
if (ratio > 0.5) {
|
|
2426
|
+
return {
|
|
2427
|
+
filled: "bg-emerald-400",
|
|
2428
|
+
empty: "bg-emerald-400/30",
|
|
2429
|
+
label: "text-emerald-400"
|
|
2430
|
+
};
|
|
2431
|
+
}
|
|
2432
|
+
if (ratio > 0.25) {
|
|
2433
|
+
return {
|
|
2434
|
+
filled: "bg-amber-400",
|
|
2435
|
+
empty: "bg-amber-400/30",
|
|
2436
|
+
label: "text-amber-400"
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2439
|
+
return {
|
|
2440
|
+
filled: "bg-rose-400",
|
|
2441
|
+
empty: "bg-rose-400/30",
|
|
2442
|
+
label: "text-rose-400"
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
function DotIndicator({
|
|
2446
|
+
remaining,
|
|
2447
|
+
max,
|
|
2448
|
+
showLabel = false,
|
|
2449
|
+
labelFormat,
|
|
2450
|
+
className
|
|
2451
|
+
}) {
|
|
2452
|
+
const clampedRemaining = Math.max(0, Math.min(remaining, max));
|
|
2453
|
+
const used = max - clampedRemaining;
|
|
2454
|
+
const urgency = getUrgencyClasses(clampedRemaining, max);
|
|
2455
|
+
const defaultLabel = `${clampedRemaining}/${max}`;
|
|
2456
|
+
const label = labelFormat ? labelFormat(clampedRemaining, max) : defaultLabel;
|
|
2457
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex items-center gap-2", className), children: [
|
|
2458
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2459
|
+
"div",
|
|
2460
|
+
{
|
|
2461
|
+
className: "flex items-center gap-1",
|
|
2462
|
+
role: "meter",
|
|
2463
|
+
"aria-valuenow": clampedRemaining,
|
|
2464
|
+
"aria-valuemin": 0,
|
|
2465
|
+
"aria-valuemax": max,
|
|
2466
|
+
"aria-label": label,
|
|
2467
|
+
children: Array.from({ length: max }, (_, index) => {
|
|
2468
|
+
const isFilled = index < used;
|
|
2469
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2470
|
+
"span",
|
|
2471
|
+
{
|
|
2472
|
+
className: cn(
|
|
2473
|
+
"h-2 w-2 rounded-full transition-colors duration-300",
|
|
2474
|
+
isFilled ? urgency.filled : urgency.empty
|
|
2475
|
+
),
|
|
2476
|
+
"aria-hidden": "true"
|
|
2477
|
+
},
|
|
2478
|
+
index
|
|
2479
|
+
);
|
|
2480
|
+
})
|
|
2481
|
+
}
|
|
2482
|
+
),
|
|
2483
|
+
showLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs font-medium tabular-nums", urgency.label), children: label })
|
|
2484
|
+
] });
|
|
2485
|
+
}
|
|
2486
|
+
function ActiveFilterPills({
|
|
2487
|
+
filters,
|
|
2488
|
+
onRemove,
|
|
2489
|
+
onClearAll,
|
|
2490
|
+
clearAllLabel = "Clear all",
|
|
2491
|
+
className
|
|
2492
|
+
}) {
|
|
2493
|
+
if (filters.length === 0) return null;
|
|
2494
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap items-center gap-1.5", className), children: [
|
|
2495
|
+
filters.map((filter) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2496
|
+
"span",
|
|
2497
|
+
{
|
|
2498
|
+
className: "inline-flex items-center gap-1 rounded-full bg-white/10 px-2.5 py-1 text-xs text-white/80 ring-1 ring-white/10",
|
|
2499
|
+
children: [
|
|
2500
|
+
filter.label,
|
|
2501
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2502
|
+
"button",
|
|
2503
|
+
{
|
|
2504
|
+
type: "button",
|
|
2505
|
+
onClick: () => onRemove(filter.key),
|
|
2506
|
+
className: "ml-0.5 text-white/50 transition-colors duration-150 hover:text-white focus:outline-none focus-visible:text-white",
|
|
2507
|
+
"aria-label": `Remove filter: ${filter.label}`,
|
|
2508
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2509
|
+
"svg",
|
|
2510
|
+
{
|
|
2511
|
+
className: "h-3 w-3",
|
|
2512
|
+
viewBox: "0 0 12 12",
|
|
2513
|
+
fill: "none",
|
|
2514
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2515
|
+
"aria-hidden": "true",
|
|
2516
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2517
|
+
"path",
|
|
2518
|
+
{
|
|
2519
|
+
d: "M9 3L3 9M3 3L9 9",
|
|
2520
|
+
stroke: "currentColor",
|
|
2521
|
+
strokeWidth: "1.5",
|
|
2522
|
+
strokeLinecap: "round"
|
|
2523
|
+
}
|
|
2524
|
+
)
|
|
2525
|
+
}
|
|
2526
|
+
)
|
|
2527
|
+
}
|
|
2528
|
+
)
|
|
2529
|
+
]
|
|
2530
|
+
},
|
|
2531
|
+
filter.key
|
|
2532
|
+
)),
|
|
2533
|
+
filters.length > 1 && onClearAll && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2534
|
+
"button",
|
|
2535
|
+
{
|
|
2536
|
+
type: "button",
|
|
2537
|
+
onClick: onClearAll,
|
|
2538
|
+
className: "text-xs text-white/40 underline-offset-2 transition-colors duration-150 hover:text-white/70 focus:outline-none focus-visible:text-white/70",
|
|
2539
|
+
children: clearAllLabel
|
|
2540
|
+
}
|
|
2541
|
+
)
|
|
2542
|
+
] });
|
|
2543
|
+
}
|
|
2544
|
+
function SectionCard({
|
|
2545
|
+
title,
|
|
2546
|
+
description,
|
|
2547
|
+
right,
|
|
2548
|
+
overlay,
|
|
2549
|
+
children,
|
|
2550
|
+
className
|
|
2551
|
+
}) {
|
|
2552
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2553
|
+
"div",
|
|
2554
|
+
{
|
|
2555
|
+
className: cn(
|
|
2556
|
+
"relative bg-white/5 ring-1 ring-white/10 rounded-xl overflow-hidden",
|
|
2557
|
+
className
|
|
2558
|
+
),
|
|
2559
|
+
children: [
|
|
2560
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3 px-5 py-4 border-b border-white/[0.06]", children: [
|
|
2561
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
2562
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-white", children: title }),
|
|
2563
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-white/40 mt-0.5", children: description })
|
|
2564
|
+
] }),
|
|
2565
|
+
right && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: right })
|
|
2566
|
+
] }),
|
|
2567
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 py-4", children }),
|
|
2568
|
+
overlay
|
|
2569
|
+
]
|
|
2570
|
+
}
|
|
2571
|
+
);
|
|
2572
|
+
}
|
|
2260
2573
|
var maxWidthClass = {
|
|
2261
2574
|
sm: "max-w-2xl",
|
|
2262
2575
|
md: "max-w-4xl",
|
|
@@ -2905,7 +3218,120 @@ function useToast() {
|
|
|
2905
3218
|
}
|
|
2906
3219
|
return ctx;
|
|
2907
3220
|
}
|
|
3221
|
+
function SavingIcon() {
|
|
3222
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3223
|
+
"svg",
|
|
3224
|
+
{
|
|
3225
|
+
className: "h-5 w-5 animate-spin text-white/70",
|
|
3226
|
+
viewBox: "0 0 24 24",
|
|
3227
|
+
fill: "none",
|
|
3228
|
+
"aria-hidden": "true",
|
|
3229
|
+
children: [
|
|
3230
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3231
|
+
"circle",
|
|
3232
|
+
{
|
|
3233
|
+
className: "opacity-25",
|
|
3234
|
+
cx: "12",
|
|
3235
|
+
cy: "12",
|
|
3236
|
+
r: "10",
|
|
3237
|
+
stroke: "currentColor",
|
|
3238
|
+
strokeWidth: "4"
|
|
3239
|
+
}
|
|
3240
|
+
),
|
|
3241
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3242
|
+
"path",
|
|
3243
|
+
{
|
|
3244
|
+
className: "opacity-75",
|
|
3245
|
+
fill: "currentColor",
|
|
3246
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
3247
|
+
}
|
|
3248
|
+
)
|
|
3249
|
+
]
|
|
3250
|
+
}
|
|
3251
|
+
);
|
|
3252
|
+
}
|
|
3253
|
+
function SavedIcon() {
|
|
3254
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3255
|
+
"svg",
|
|
3256
|
+
{
|
|
3257
|
+
className: "h-5 w-5 text-green-400",
|
|
3258
|
+
viewBox: "0 0 24 24",
|
|
3259
|
+
fill: "none",
|
|
3260
|
+
stroke: "currentColor",
|
|
3261
|
+
strokeWidth: 2,
|
|
3262
|
+
"aria-hidden": "true",
|
|
3263
|
+
children: [
|
|
3264
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10", strokeOpacity: 0.4 }),
|
|
3265
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l2 2 4-4" })
|
|
3266
|
+
]
|
|
3267
|
+
}
|
|
3268
|
+
);
|
|
3269
|
+
}
|
|
3270
|
+
function ErrorIcon2() {
|
|
3271
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3272
|
+
"svg",
|
|
3273
|
+
{
|
|
3274
|
+
className: "h-5 w-5 text-red-400",
|
|
3275
|
+
viewBox: "0 0 24 24",
|
|
3276
|
+
fill: "none",
|
|
3277
|
+
stroke: "currentColor",
|
|
3278
|
+
strokeWidth: 2,
|
|
3279
|
+
"aria-hidden": "true",
|
|
3280
|
+
children: [
|
|
3281
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10", strokeOpacity: 0.4 }),
|
|
3282
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 9l-6 6M9 9l6 6" })
|
|
3283
|
+
]
|
|
3284
|
+
}
|
|
3285
|
+
);
|
|
3286
|
+
}
|
|
3287
|
+
var statusConfig = {
|
|
3288
|
+
saving: {
|
|
3289
|
+
icon: SavingIcon,
|
|
3290
|
+
defaultText: "Saving...",
|
|
3291
|
+
textClass: "text-white/70"
|
|
3292
|
+
},
|
|
3293
|
+
saved: {
|
|
3294
|
+
icon: SavedIcon,
|
|
3295
|
+
defaultText: "Saved",
|
|
3296
|
+
textClass: "text-green-400"
|
|
3297
|
+
},
|
|
3298
|
+
error: {
|
|
3299
|
+
icon: ErrorIcon2,
|
|
3300
|
+
defaultText: "Error",
|
|
3301
|
+
textClass: "text-red-400"
|
|
3302
|
+
}
|
|
3303
|
+
};
|
|
3304
|
+
function MutationOverlay({
|
|
3305
|
+
status,
|
|
3306
|
+
savingText,
|
|
3307
|
+
savedText,
|
|
3308
|
+
errorText,
|
|
3309
|
+
className
|
|
3310
|
+
}) {
|
|
3311
|
+
if (status === "idle") return null;
|
|
3312
|
+
const config = statusConfig[status];
|
|
3313
|
+
const Icon = config.icon;
|
|
3314
|
+
const text = status === "saving" ? savingText ?? config.defaultText : status === "saved" ? savedText ?? config.defaultText : errorText ?? config.defaultText;
|
|
3315
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3316
|
+
"div",
|
|
3317
|
+
{
|
|
3318
|
+
className: cn(
|
|
3319
|
+
"absolute inset-0 z-10 flex items-center justify-center",
|
|
3320
|
+
"bg-surface-50/80 backdrop-blur-sm",
|
|
3321
|
+
"transition-opacity duration-200",
|
|
3322
|
+
className
|
|
3323
|
+
),
|
|
3324
|
+
role: "status",
|
|
3325
|
+
"aria-live": "polite",
|
|
3326
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3327
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, {}),
|
|
3328
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-medium", config.textClass), children: text })
|
|
3329
|
+
] })
|
|
3330
|
+
}
|
|
3331
|
+
);
|
|
3332
|
+
}
|
|
2908
3333
|
|
|
3334
|
+
exports.ActiveFilterPills = ActiveFilterPills;
|
|
2909
3335
|
exports.Alert = Alert;
|
|
2910
3336
|
exports.Avatar = Avatar;
|
|
2911
3337
|
exports.Badge = Badge;
|
|
@@ -2915,9 +3341,11 @@ exports.Checkbox = Checkbox;
|
|
|
2915
3341
|
exports.CollapsibleSection = CollapsibleSection;
|
|
2916
3342
|
exports.ColorInput = ColorInput;
|
|
2917
3343
|
exports.ConfirmDialog = ConfirmDialog;
|
|
3344
|
+
exports.CooldownRing = CooldownRing;
|
|
2918
3345
|
exports.CopyField = CopyField;
|
|
2919
3346
|
exports.DashboardLayout = DashboardLayout;
|
|
2920
3347
|
exports.Divider = Divider;
|
|
3348
|
+
exports.DotIndicator = DotIndicator;
|
|
2921
3349
|
exports.DropZone = DropZone;
|
|
2922
3350
|
exports.Dropdown = Dropdown;
|
|
2923
3351
|
exports.DropdownItem = DropdownItem;
|
|
@@ -2929,6 +3357,7 @@ exports.FormField = FormField;
|
|
|
2929
3357
|
exports.IconButton = IconButton;
|
|
2930
3358
|
exports.Input = Input;
|
|
2931
3359
|
exports.Modal = Modal;
|
|
3360
|
+
exports.MutationOverlay = MutationOverlay;
|
|
2932
3361
|
exports.Navbar = Navbar;
|
|
2933
3362
|
exports.PageShell = PageShell;
|
|
2934
3363
|
exports.Pagination = Pagination;
|
|
@@ -2938,11 +3367,13 @@ exports.ProgressButton = ProgressButton;
|
|
|
2938
3367
|
exports.RadioGroup = RadioGroup;
|
|
2939
3368
|
exports.RadioItem = RadioItem;
|
|
2940
3369
|
exports.SearchInput = SearchInput;
|
|
3370
|
+
exports.SectionCard = SectionCard;
|
|
2941
3371
|
exports.Select = Select;
|
|
2942
3372
|
exports.Sidebar = Sidebar;
|
|
2943
3373
|
exports.Skeleton = Skeleton;
|
|
2944
3374
|
exports.Slider = Slider;
|
|
2945
3375
|
exports.Spinner = Spinner;
|
|
3376
|
+
exports.StageProgress = StageProgress;
|
|
2946
3377
|
exports.StatCard = StatCard;
|
|
2947
3378
|
exports.Stepper = Stepper;
|
|
2948
3379
|
exports.Tab = Tab;
|
package/dist/index.d.cts
CHANGED
|
@@ -158,6 +158,7 @@ type ToggleProps = {
|
|
|
158
158
|
checked: boolean;
|
|
159
159
|
onChange: (checked: boolean) => void;
|
|
160
160
|
disabled?: boolean;
|
|
161
|
+
busy?: boolean;
|
|
161
162
|
label?: string;
|
|
162
163
|
size?: ToggleSize;
|
|
163
164
|
id?: string;
|
|
@@ -473,6 +474,56 @@ type ProgressBarProps = {
|
|
|
473
474
|
};
|
|
474
475
|
declare function ProgressBar({ value, max, variant, label, showValue, size, className, }: ProgressBarProps): react_jsx_runtime.JSX.Element;
|
|
475
476
|
|
|
477
|
+
type CooldownRingSize = 'sm' | 'md' | 'lg';
|
|
478
|
+
type CooldownRingProps = {
|
|
479
|
+
duration: number;
|
|
480
|
+
remaining: number;
|
|
481
|
+
onTick?: () => void;
|
|
482
|
+
onComplete?: () => void;
|
|
483
|
+
size?: CooldownRingSize;
|
|
484
|
+
className?: string;
|
|
485
|
+
};
|
|
486
|
+
declare function CooldownRing({ duration, remaining, size, className, }: CooldownRingProps): react_jsx_runtime.JSX.Element;
|
|
487
|
+
|
|
488
|
+
type StageProgressProps = {
|
|
489
|
+
stages: string[];
|
|
490
|
+
activeStage: number;
|
|
491
|
+
className?: string;
|
|
492
|
+
};
|
|
493
|
+
declare function StageProgress({ stages, activeStage, className }: StageProgressProps): react_jsx_runtime.JSX.Element;
|
|
494
|
+
|
|
495
|
+
type DotIndicatorProps = {
|
|
496
|
+
remaining: number;
|
|
497
|
+
max: number;
|
|
498
|
+
showLabel?: boolean;
|
|
499
|
+
labelFormat?: (remaining: number, max: number) => string;
|
|
500
|
+
className?: string;
|
|
501
|
+
};
|
|
502
|
+
declare function DotIndicator({ remaining, max, showLabel, labelFormat, className, }: DotIndicatorProps): react_jsx_runtime.JSX.Element;
|
|
503
|
+
|
|
504
|
+
type FilterPill = {
|
|
505
|
+
key: string;
|
|
506
|
+
label: string;
|
|
507
|
+
};
|
|
508
|
+
type ActiveFilterPillsProps = {
|
|
509
|
+
filters: FilterPill[];
|
|
510
|
+
onRemove: (key: string) => void;
|
|
511
|
+
onClearAll?: () => void;
|
|
512
|
+
clearAllLabel?: string;
|
|
513
|
+
className?: string;
|
|
514
|
+
};
|
|
515
|
+
declare function ActiveFilterPills({ filters, onRemove, onClearAll, clearAllLabel, className, }: ActiveFilterPillsProps): react_jsx_runtime.JSX.Element | null;
|
|
516
|
+
|
|
517
|
+
type SectionCardProps = {
|
|
518
|
+
title: string;
|
|
519
|
+
description?: string;
|
|
520
|
+
right?: ReactNode;
|
|
521
|
+
overlay?: ReactNode;
|
|
522
|
+
children: ReactNode;
|
|
523
|
+
className?: string;
|
|
524
|
+
};
|
|
525
|
+
declare function SectionCard({ title, description, right, overlay, children, className, }: SectionCardProps): react_jsx_runtime.JSX.Element;
|
|
526
|
+
|
|
476
527
|
type PageShellVariant = 'plain' | 'glass' | 'minimal';
|
|
477
528
|
type PageShellProps = {
|
|
478
529
|
header?: ReactNode;
|
|
@@ -569,4 +620,14 @@ type ToastContextValue = {
|
|
|
569
620
|
declare function ToastProvider({ children, position, maxToasts }: ToastProviderProps): react_jsx_runtime.JSX.Element;
|
|
570
621
|
declare function useToast(): ToastContextValue;
|
|
571
622
|
|
|
572
|
-
|
|
623
|
+
type MutationOverlayStatus = 'idle' | 'saving' | 'saved' | 'error';
|
|
624
|
+
type MutationOverlayProps = {
|
|
625
|
+
status: MutationOverlayStatus;
|
|
626
|
+
savingText?: string;
|
|
627
|
+
savedText?: string;
|
|
628
|
+
errorText?: string;
|
|
629
|
+
className?: string;
|
|
630
|
+
};
|
|
631
|
+
declare function MutationOverlay({ status, savingText, savedText, errorText, className, }: MutationOverlayProps): react_jsx_runtime.JSX.Element | null;
|
|
632
|
+
|
|
633
|
+
export { ActiveFilterPills, type ActiveFilterPillsProps, Alert, type AlertProps, type AlertVariant, Avatar, type AvatarProps, type AvatarSize, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Card, type CardProps, type CardVariant, Checkbox, type CheckboxProps, CollapsibleSection, type CollapsibleSectionProps, ColorInput, type ColorInputProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmDialogVariant, CooldownRing, type CooldownRingProps, type CooldownRingSize, CopyField, type CopyFieldProps, DashboardLayout, type DashboardLayoutProps, Divider, type DividerProps, DotIndicator, type DotIndicatorProps, DropZone, type DropZoneProps, Dropdown, DropdownItem, type DropdownItemProps, DropdownMenu, type DropdownMenuProps, type DropdownProps, DropdownSeparator, type DropdownSeparatorProps, DropdownTrigger, type DropdownTriggerProps, EmptyState, type EmptyStateProps, type FilterPill, FormField, type FormFieldProps, IconButton, type IconButtonProps, Input, type InputProps, Modal, type ModalProps, MutationOverlay, type MutationOverlayProps, type MutationOverlayStatus, Navbar, type NavbarProps, PageShell, type PageShellProps, type PageShellVariant, Pagination, type PaginationProps, Pill, ProgressBar, type ProgressBarProps, type ProgressBarVariant, ProgressButton, type ProgressButtonProps, RadioGroup, type RadioGroupProps, RadioItem, type RadioItemProps, SearchInput, type SearchInputProps, SectionCard, type SectionCardProps, Select, type SelectProps, Sidebar, type SidebarProps, type Size, Skeleton, type SkeletonProps, Slider, type SliderProps, Spinner, type SpinnerProps, type SpinnerSize, StageProgress, type StageProgressProps, StatCard, type StatCardProps, type StatCardTrend, type Step, Stepper, type StepperProps, Tab, TabList, type TabListProps, TabPanel, type TabPanelProps, type TabProps, Table, TableBody, type TableBodyProps, TableCell, type TableCellProps, TableHead, type TableHeadProps, TableHeader, type TableHeaderProps, type TableProps, TableRow, type TableRowProps, Tabs, type TabsProps, type TabsVariant, TagInput, type TagInputProps, Textarea, type TextareaProps, type ToastData, type ToastPosition, ToastProvider, type ToastProviderProps, type ToastVariant, Toggle, type ToggleProps, type ToggleSize, Tooltip, type TooltipPlacement, type TooltipProps, type UseClipboardReturn, type UseDisclosureReturn, cn, focusSafely, getFocusableElements, useClipboard, useDebounce, useDisclosure, useMediaQuery, useToast };
|