@tollerud/ui 1.1.4 → 3.0.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/AGENTS.md +34 -11
- package/CHANGELOG.md +376 -0
- package/COMPONENTS.md +951 -0
- package/GETTING_STARTED.md +159 -0
- package/README.md +51 -43
- package/SKILL.md +55 -19
- package/components.json +18 -0
- package/dist/accordion.d.ts +20 -0
- package/dist/accordion.js +5 -0
- package/dist/accordion.js.map +1 -0
- package/dist/action-diff.d.ts +26 -0
- package/dist/action-diff.js +5 -0
- package/dist/action-diff.js.map +1 -0
- package/dist/action-row.d.ts +36 -0
- package/dist/action-row.js +6 -0
- package/dist/action-row.js.map +1 -0
- package/dist/alert-inbox.d.ts +23 -0
- package/dist/alert-inbox.js +6 -0
- package/dist/alert-inbox.js.map +1 -0
- package/dist/alert.d.ts +33 -0
- package/dist/alert.js +5 -0
- package/dist/alert.js.map +1 -0
- package/dist/approval-card.d.ts +27 -0
- package/dist/approval-card.js +5 -0
- package/dist/approval-card.js.map +1 -0
- package/dist/area-chart.d.ts +10 -0
- package/dist/area-chart.js +5 -0
- package/dist/area-chart.js.map +1 -0
- package/dist/avatar.d.ts +27 -0
- package/dist/avatar.js +5 -0
- package/dist/avatar.js.map +1 -0
- package/dist/backup-status-panel.d.ts +25 -0
- package/dist/backup-status-panel.js +6 -0
- package/dist/backup-status-panel.js.map +1 -0
- package/dist/badge.d.ts +17 -0
- package/dist/badge.js +5 -0
- package/dist/badge.js.map +1 -0
- package/dist/bar-chart.d.ts +15 -0
- package/dist/bar-chart.js +5 -0
- package/dist/bar-chart.js.map +1 -0
- package/dist/bento-dashboard.d.ts +30 -0
- package/dist/bento-dashboard.js +5 -0
- package/dist/bento-dashboard.js.map +1 -0
- package/dist/breadcrumb.d.ts +16 -0
- package/dist/breadcrumb.js +5 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/button.d.ts +29 -0
- package/dist/button.js +5 -0
- package/dist/button.js.map +1 -0
- package/dist/card.d.ts +10 -0
- package/dist/card.js +5 -0
- package/dist/card.js.map +1 -0
- package/dist/checkbox.d.ts +9 -0
- package/dist/checkbox.js +5 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/chunk-2QWKOCWF.js +79 -0
- package/dist/chunk-2QWKOCWF.js.map +1 -0
- package/dist/chunk-3TGMGBKM.js +393 -0
- package/dist/chunk-3TGMGBKM.js.map +1 -0
- package/dist/chunk-3XTZPDNV.js +94 -0
- package/dist/chunk-3XTZPDNV.js.map +1 -0
- package/dist/chunk-435JHF7G.js +65 -0
- package/dist/chunk-435JHF7G.js.map +1 -0
- package/dist/chunk-4PA2ACNF.js +52 -0
- package/dist/chunk-4PA2ACNF.js.map +1 -0
- package/dist/chunk-5GWHUJ5D.js +29 -0
- package/dist/chunk-5GWHUJ5D.js.map +1 -0
- package/dist/chunk-6FUKJD3W.js +123 -0
- package/dist/chunk-6FUKJD3W.js.map +1 -0
- package/dist/chunk-6IS2AYYG.js +106 -0
- package/dist/chunk-6IS2AYYG.js.map +1 -0
- package/dist/chunk-6PZKU6ZL.js +78 -0
- package/dist/chunk-6PZKU6ZL.js.map +1 -0
- package/dist/chunk-6SKTH45H.js +75 -0
- package/dist/chunk-6SKTH45H.js.map +1 -0
- package/dist/chunk-6UXW5YUC.js +77 -0
- package/dist/chunk-6UXW5YUC.js.map +1 -0
- package/dist/chunk-7EP2T3OW.js +52 -0
- package/dist/chunk-7EP2T3OW.js.map +1 -0
- package/dist/chunk-7J5QXUQN.js +38 -0
- package/dist/chunk-7J5QXUQN.js.map +1 -0
- package/dist/chunk-7TOT5ME3.js +53 -0
- package/dist/chunk-7TOT5ME3.js.map +1 -0
- package/dist/chunk-A6L5C3IJ.js +47 -0
- package/dist/chunk-A6L5C3IJ.js.map +1 -0
- package/dist/chunk-ANW6J6PV.js +42 -0
- package/dist/chunk-ANW6J6PV.js.map +1 -0
- package/dist/chunk-APFFKNPS.js +80 -0
- package/dist/chunk-APFFKNPS.js.map +1 -0
- package/dist/chunk-AZADSX4Z.js +85 -0
- package/dist/chunk-AZADSX4Z.js.map +1 -0
- package/dist/chunk-BPCH5LJ3.js +36 -0
- package/dist/chunk-BPCH5LJ3.js.map +1 -0
- package/dist/chunk-CBQ63EBL.js +85 -0
- package/dist/chunk-CBQ63EBL.js.map +1 -0
- package/dist/chunk-CDI7353B.js +40 -0
- package/dist/chunk-CDI7353B.js.map +1 -0
- package/dist/chunk-CKNWXYMA.js +53 -0
- package/dist/chunk-CKNWXYMA.js.map +1 -0
- package/dist/chunk-DFM7UUKB.js +79 -0
- package/dist/chunk-DFM7UUKB.js.map +1 -0
- package/dist/chunk-DGCRHVWW.js +84 -0
- package/dist/chunk-DGCRHVWW.js.map +1 -0
- package/dist/chunk-DNJI65VQ.js +22 -0
- package/dist/chunk-DNJI65VQ.js.map +1 -0
- package/dist/chunk-DOUDJU4P.js +63 -0
- package/dist/chunk-DOUDJU4P.js.map +1 -0
- package/dist/chunk-DRCMGIQ6.js +64 -0
- package/dist/chunk-DRCMGIQ6.js.map +1 -0
- package/dist/chunk-DZOBXK2S.js +28 -0
- package/dist/chunk-DZOBXK2S.js.map +1 -0
- package/dist/chunk-EN4OJCEF.js +54 -0
- package/dist/chunk-EN4OJCEF.js.map +1 -0
- package/dist/chunk-EVHZFYWX.js +33 -0
- package/dist/chunk-EVHZFYWX.js.map +1 -0
- package/dist/chunk-FGXOV2QH.js +23 -0
- package/dist/chunk-FGXOV2QH.js.map +1 -0
- package/dist/chunk-G2VKWNZA.js +53 -0
- package/dist/chunk-G2VKWNZA.js.map +1 -0
- package/dist/chunk-GTM2DE4C.js +156 -0
- package/dist/chunk-GTM2DE4C.js.map +1 -0
- package/dist/chunk-H3ZVGTJM.js +165 -0
- package/dist/chunk-H3ZVGTJM.js.map +1 -0
- package/dist/chunk-HWAWUEHC.js +28 -0
- package/dist/chunk-HWAWUEHC.js.map +1 -0
- package/dist/chunk-HWJVRTWO.js +36 -0
- package/dist/chunk-HWJVRTWO.js.map +1 -0
- package/dist/chunk-HYQGOC2E.js +79 -0
- package/dist/chunk-HYQGOC2E.js.map +1 -0
- package/dist/chunk-ILADNTUB.js +77 -0
- package/dist/chunk-ILADNTUB.js.map +1 -0
- package/dist/chunk-ISHZ6ZPJ.js +31 -0
- package/dist/chunk-ISHZ6ZPJ.js.map +1 -0
- package/dist/chunk-JRFSUVSO.js +66 -0
- package/dist/chunk-JRFSUVSO.js.map +1 -0
- package/dist/chunk-KI6OTVID.js +91 -0
- package/dist/chunk-KI6OTVID.js.map +1 -0
- package/dist/chunk-LUM2YJBH.js +73 -0
- package/dist/chunk-LUM2YJBH.js.map +1 -0
- package/dist/chunk-NHPISZWS.js +71 -0
- package/dist/chunk-NHPISZWS.js.map +1 -0
- package/dist/chunk-NOLWJJHT.js +52 -0
- package/dist/chunk-NOLWJJHT.js.map +1 -0
- package/dist/chunk-NPVINX3Q.js +20 -0
- package/dist/chunk-NPVINX3Q.js.map +1 -0
- package/dist/chunk-NSMU66ZX.js +47 -0
- package/dist/chunk-NSMU66ZX.js.map +1 -0
- package/dist/chunk-O57QMLNI.js +68 -0
- package/dist/chunk-O57QMLNI.js.map +1 -0
- package/dist/chunk-O5SWPHUQ.js +79 -0
- package/dist/chunk-O5SWPHUQ.js.map +1 -0
- package/dist/chunk-OGVSZ7NV.js +53 -0
- package/dist/chunk-OGVSZ7NV.js.map +1 -0
- package/dist/chunk-OONIUDST.js +48 -0
- package/dist/chunk-OONIUDST.js.map +1 -0
- package/dist/chunk-PLF3BBQI.js +139 -0
- package/dist/chunk-PLF3BBQI.js.map +1 -0
- package/dist/chunk-Q74VRQEX.js +26 -0
- package/dist/chunk-Q74VRQEX.js.map +1 -0
- package/dist/chunk-QEHTPQHL.js +35 -0
- package/dist/chunk-QEHTPQHL.js.map +1 -0
- package/dist/chunk-RJTDQOT2.js +73 -0
- package/dist/chunk-RJTDQOT2.js.map +1 -0
- package/dist/chunk-RQ3RXKAZ.js +203 -0
- package/dist/chunk-RQ3RXKAZ.js.map +1 -0
- package/dist/chunk-RWJELAS6.js +46 -0
- package/dist/chunk-RWJELAS6.js.map +1 -0
- package/dist/chunk-RZK2S2OO.js +126 -0
- package/dist/chunk-RZK2S2OO.js.map +1 -0
- package/dist/chunk-SAP7JSSO.js +106 -0
- package/dist/chunk-SAP7JSSO.js.map +1 -0
- package/dist/chunk-T3TQPOVM.js +79 -0
- package/dist/chunk-T3TQPOVM.js.map +1 -0
- package/dist/chunk-T56TTOI6.js +53 -0
- package/dist/chunk-T56TTOI6.js.map +1 -0
- package/dist/chunk-T7EFDE2L.js +36 -0
- package/dist/chunk-T7EFDE2L.js.map +1 -0
- package/dist/chunk-V3P5QLLX.js +154 -0
- package/dist/chunk-V3P5QLLX.js.map +1 -0
- package/dist/chunk-VTRUUT5K.js +31 -0
- package/dist/chunk-VTRUUT5K.js.map +1 -0
- package/dist/chunk-WDANALHD.js +95 -0
- package/dist/chunk-WDANALHD.js.map +1 -0
- package/dist/chunk-WSQNPRGN.js +12 -0
- package/dist/chunk-WSQNPRGN.js.map +1 -0
- package/dist/chunk-XR5QBVEV.js +56 -0
- package/dist/chunk-XR5QBVEV.js.map +1 -0
- package/dist/chunk-YYWODLER.js +111 -0
- package/dist/chunk-YYWODLER.js.map +1 -0
- package/dist/chunk-ZOXO3G3I.js +50 -0
- package/dist/chunk-ZOXO3G3I.js.map +1 -0
- package/dist/code-block.d.ts +14 -0
- package/dist/code-block.js +5 -0
- package/dist/code-block.js.map +1 -0
- package/dist/combobox.d.ts +26 -0
- package/dist/combobox.js +5 -0
- package/dist/combobox.js.map +1 -0
- package/dist/command-menu.d.ts +52 -0
- package/dist/command-menu.js +7 -0
- package/dist/command-menu.js.map +1 -0
- package/dist/container.d.ts +9 -0
- package/dist/container.js +5 -0
- package/dist/container.js.map +1 -0
- package/dist/cta-band.d.ts +12 -0
- package/dist/cta-band.js +5 -0
- package/dist/cta-band.js.map +1 -0
- package/dist/data-table.d.ts +58 -0
- package/dist/data-table.js +12 -0
- package/dist/data-table.js.map +1 -0
- package/dist/date-picker.d.ts +20 -0
- package/dist/date-picker.js +5 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/dialog.d.ts +21 -0
- package/dist/dialog.js +5 -0
- package/dist/dialog.js.map +1 -0
- package/dist/divider.d.ts +12 -0
- package/dist/divider.js +5 -0
- package/dist/divider.js.map +1 -0
- package/dist/docker-stack-card.d.ts +21 -0
- package/dist/docker-stack-card.js +6 -0
- package/dist/docker-stack-card.js.map +1 -0
- package/dist/donut.d.ts +15 -0
- package/dist/donut.js +5 -0
- package/dist/donut.js.map +1 -0
- package/dist/dropdown-menu.d.ts +15 -0
- package/dist/dropdown-menu.js +5 -0
- package/dist/dropdown-menu.js.map +1 -0
- package/dist/empty.d.ts +12 -0
- package/dist/empty.js +5 -0
- package/dist/empty.js.map +1 -0
- package/dist/feature-card.d.ts +11 -0
- package/dist/feature-card.js +6 -0
- package/dist/feature-card.js.map +1 -0
- package/dist/file-upload.d.ts +20 -0
- package/dist/file-upload.js +5 -0
- package/dist/file-upload.js.map +1 -0
- package/dist/footer.d.ts +35 -0
- package/dist/footer.js +5 -0
- package/dist/footer.js.map +1 -0
- package/dist/form-row.d.ts +15 -0
- package/dist/form-row.js +5 -0
- package/dist/form-row.js.map +1 -0
- package/dist/glow-card.d.ts +14 -0
- package/dist/glow-card.js +5 -0
- package/dist/glow-card.js.map +1 -0
- package/dist/hero-block.d.ts +16 -0
- package/dist/hero-block.js +7 -0
- package/dist/hero-block.js.map +1 -0
- package/dist/host-card.d.ts +27 -0
- package/dist/host-card.js +6 -0
- package/dist/host-card.js.map +1 -0
- package/dist/incident-card.d.ts +23 -0
- package/dist/incident-card.js +5 -0
- package/dist/incident-card.js.map +1 -0
- package/dist/index.d.ts +76 -960
- package/dist/index.js +68 -3812
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +10 -0
- package/dist/input.js +5 -0
- package/dist/input.js.map +1 -0
- package/dist/kbd.d.ts +24 -0
- package/dist/kbd.js +5 -0
- package/dist/kbd.js.map +1 -0
- package/dist/log-viewer.d.ts +35 -0
- package/dist/log-viewer.js +5 -0
- package/dist/log-viewer.js.map +1 -0
- package/dist/meter.d.ts +23 -0
- package/dist/meter.js +5 -0
- package/dist/meter.js.map +1 -0
- package/dist/noir-glow-background.d.ts +50 -0
- package/dist/noir-glow-background.js +4 -0
- package/dist/noir-glow-background.js.map +1 -0
- package/dist/pagination.d.ts +16 -0
- package/dist/pagination.js +5 -0
- package/dist/pagination.js.map +1 -0
- package/dist/panel.d.ts +12 -0
- package/dist/panel.js +5 -0
- package/dist/panel.js.map +1 -0
- package/dist/password-input.d.ts +10 -0
- package/dist/password-input.js +5 -0
- package/dist/password-input.js.map +1 -0
- package/dist/pill.d.ts +14 -0
- package/dist/pill.js +5 -0
- package/dist/pill.js.map +1 -0
- package/dist/pricing-card.d.ts +20 -0
- package/dist/pricing-card.js +6 -0
- package/dist/pricing-card.js.map +1 -0
- package/dist/progress.d.ts +6 -0
- package/dist/progress.js +5 -0
- package/dist/progress.js.map +1 -0
- package/dist/radio-group.d.ts +18 -0
- package/dist/radio-group.js +5 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/rollback-plan.d.ts +23 -0
- package/dist/rollback-plan.js +5 -0
- package/dist/rollback-plan.js.map +1 -0
- package/dist/segmented.d.ts +17 -0
- package/dist/segmented.js +5 -0
- package/dist/segmented.js.map +1 -0
- package/dist/select.d.ts +18 -0
- package/dist/select.js +5 -0
- package/dist/select.js.map +1 -0
- package/dist/service-health-card.d.ts +21 -0
- package/dist/service-health-card.js +6 -0
- package/dist/service-health-card.js.map +1 -0
- package/dist/sheet.d.ts +25 -0
- package/dist/sheet.js +5 -0
- package/dist/sheet.js.map +1 -0
- package/dist/skeleton.d.ts +5 -0
- package/dist/skeleton.js +5 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/slider.d.ts +12 -0
- package/dist/slider.js +5 -0
- package/dist/slider.js.map +1 -0
- package/dist/sparkline.d.ts +16 -0
- package/dist/sparkline.js +5 -0
- package/dist/sparkline.js.map +1 -0
- package/dist/stat-card.d.ts +15 -0
- package/dist/stat-card.js +5 -0
- package/dist/stat-card.js.map +1 -0
- package/dist/status-dot.d.ts +13 -0
- package/dist/status-dot.js +5 -0
- package/dist/status-dot.js.map +1 -0
- package/dist/stepper.d.ts +16 -0
- package/dist/stepper.js +5 -0
- package/dist/stepper.js.map +1 -0
- package/dist/switch.d.ts +9 -0
- package/dist/switch.js +5 -0
- package/dist/switch.js.map +1 -0
- package/dist/tabs.d.ts +9 -0
- package/dist/tabs.js +5 -0
- package/dist/tabs.js.map +1 -0
- package/dist/tag-input.d.ts +20 -0
- package/dist/tag-input.js +5 -0
- package/dist/tag-input.js.map +1 -0
- package/dist/textarea.d.ts +10 -0
- package/dist/textarea.js +5 -0
- package/dist/textarea.js.map +1 -0
- package/dist/timeline.d.ts +30 -0
- package/dist/timeline.js +5 -0
- package/dist/timeline.js.map +1 -0
- package/dist/toaster.d.ts +10 -0
- package/dist/toaster.js +4 -0
- package/dist/toaster.js.map +1 -0
- package/dist/tooltip.d.ts +12 -0
- package/dist/tooltip.js +5 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +4 -0
- package/dist/utils.js.map +1 -0
- package/globals-layers.css +935 -0
- package/globals-v3.css +17 -0
- package/globals-v4.css +2 -0
- package/globals.css +12 -939
- package/package.json +82 -17
- package/registry.json +920 -0
- package/tailwind.css +9 -0
- package/tollerud-preset.js +55 -50
- package/dist/index.cjs +0 -3938
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -960
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
8
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
9
|
+
var DropdownMenuContent = forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
10
|
+
DropdownMenuPrimitive.Content,
|
|
11
|
+
{
|
|
12
|
+
ref,
|
|
13
|
+
sideOffset,
|
|
14
|
+
className: cn(
|
|
15
|
+
"z-50 min-w-[9rem] overflow-hidden rounded-lg border p-1 shadow-md",
|
|
16
|
+
"bg-tollerud-noir-850 border-tollerud-border/30 text-tollerud-text-primary",
|
|
17
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
18
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
19
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
20
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
|
|
21
|
+
"data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
22
|
+
className
|
|
23
|
+
),
|
|
24
|
+
...props
|
|
25
|
+
}
|
|
26
|
+
) }));
|
|
27
|
+
DropdownMenuContent.displayName = "DropdownMenuContent";
|
|
28
|
+
var DropdownMenuItem = forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
29
|
+
DropdownMenuPrimitive.Item,
|
|
30
|
+
{
|
|
31
|
+
ref,
|
|
32
|
+
className: cn(
|
|
33
|
+
"relative flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-none",
|
|
34
|
+
"text-tollerud-text-secondary data-[highlighted]:text-tollerud-text-primary",
|
|
35
|
+
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
36
|
+
"data-[highlighted]:bg-tollerud-surface-raised",
|
|
37
|
+
inset && "pl-8",
|
|
38
|
+
className
|
|
39
|
+
),
|
|
40
|
+
...props
|
|
41
|
+
}
|
|
42
|
+
));
|
|
43
|
+
DropdownMenuItem.displayName = "DropdownMenuItem";
|
|
44
|
+
var DropdownMenuSeparator = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
45
|
+
DropdownMenuPrimitive.Separator,
|
|
46
|
+
{
|
|
47
|
+
ref,
|
|
48
|
+
className: cn("-mx-1 my-1 h-px bg-tollerud-border/30", className),
|
|
49
|
+
...props
|
|
50
|
+
}
|
|
51
|
+
));
|
|
52
|
+
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
|
53
|
+
var DropdownMenuLabel = forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
54
|
+
DropdownMenuPrimitive.Label,
|
|
55
|
+
{
|
|
56
|
+
ref,
|
|
57
|
+
className: cn("px-2 py-1.5 text-xs font-semibold text-tollerud-text-muted", inset && "pl-8", className),
|
|
58
|
+
...props
|
|
59
|
+
}
|
|
60
|
+
));
|
|
61
|
+
DropdownMenuLabel.displayName = "DropdownMenuLabel";
|
|
62
|
+
|
|
63
|
+
export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger };
|
|
64
|
+
//# sourceMappingURL=chunk-435JHF7G.js.map
|
|
65
|
+
//# sourceMappingURL=chunk-435JHF7G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/DropdownMenu.tsx"],"names":[],"mappings":";;;;;AAQA,IAAM,YAAA,GAAqC,qBAAA,CAAA;AAC3C,IAAM,mBAAA,GAA4C,qBAAA,CAAA;AAElD,IAAM,mBAAA,GAAsB,UAAA,CAG1B,CAAC,EAAE,SAAA,EAAW,UAAA,GAAa,CAAA,EAAG,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1C,GAAA,CAAuB,8BAAtB,EACC,QAAA,kBAAA,GAAA;AAAA,EAAuB,qBAAA,CAAA,OAAA;AAAA,EAAtB;AAAA,IACC,GAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,mEAAA;AAAA,MACA,2EAAA;AAAA,MACA,8DAAA;AAAA,MACA,4DAAA;AAAA,MACA,8DAAA;AAAA,MACA,+EAAA;AAAA,MACA,+EAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG;AAAA;AACN,CAAA,EACF,CACD;AACD,mBAAA,CAAoB,WAAA,GAAc,qBAAA;AAElC,IAAM,gBAAA,GAAmB,WAKvB,CAAC,EAAE,WAAW,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,qBACjC,GAAA;AAAA,EAAuB,qBAAA,CAAA,IAAA;AAAA,EAAtB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,mGAAA;AAAA,MACA,4EAAA;AAAA,MACA,gEAAA;AAAA,MACA,+CAAA;AAAA,MACA,KAAA,IAAS,MAAA;AAAA,MACT;AAAA,KACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,gBAAA,CAAiB,WAAA,GAAc,kBAAA;AAE/B,IAAM,qBAAA,GAAwB,WAG5B,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC1B,GAAA;AAAA,EAAuB,qBAAA,CAAA,SAAA;AAAA,EAAtB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,uCAAA,EAAyC,SAAS,CAAA;AAAA,IAC/D,GAAG;AAAA;AACN,CACD;AACD,qBAAA,CAAsB,WAAA,GAAc,uBAAA;AAEpC,IAAM,iBAAA,GAAoB,WAKxB,CAAC,EAAE,WAAW,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,qBACjC,GAAA;AAAA,EAAuB,qBAAA,CAAA,KAAA;AAAA,EAAtB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,4DAAA,EAA8D,KAAA,IAAS,QAAQ,SAAS,CAAA;AAAA,IACrG,GAAG;AAAA;AACN,CACD;AACD,iBAAA,CAAkB,WAAA,GAAc,mBAAA","file":"chunk-435JHF7G.js","sourcesContent":["'use client'\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\n/* ──────────────────── DropdownMenu ──────────────────── */\n\nconst DropdownMenu = DropdownMenuPrimitive.Root\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownMenuContent = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 min-w-[9rem] overflow-hidden rounded-lg border p-1 shadow-md',\n 'bg-tollerud-noir-850 border-tollerud-border/30 text-tollerud-text-primary',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',\n 'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n))\nDropdownMenuContent.displayName = 'DropdownMenuContent'\n\nconst DropdownMenuItem = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-none',\n 'text-tollerud-text-secondary data-[highlighted]:text-tollerud-text-primary',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n 'data-[highlighted]:bg-tollerud-surface-raised',\n inset && 'pl-8',\n className\n )}\n {...props}\n />\n))\nDropdownMenuItem.displayName = 'DropdownMenuItem'\n\nconst DropdownMenuSeparator = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn('-mx-1 my-1 h-px bg-tollerud-border/30', className)}\n {...props}\n />\n))\nDropdownMenuSeparator.displayName = 'DropdownMenuSeparator'\n\nconst DropdownMenuLabel = forwardRef<\n React.ComponentRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn('px-2 py-1.5 text-xs font-semibold text-tollerud-text-muted', inset && 'pl-8', className)}\n {...props}\n />\n))\nDropdownMenuLabel.displayName = 'DropdownMenuLabel'\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuLabel,\n}"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var BarChart = forwardRef(
|
|
7
|
+
({ className, data, height = 180, ...props }, ref) => {
|
|
8
|
+
const max = Math.max(...data.map((d) => d.value), 1);
|
|
9
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), ...props, children: [
|
|
10
|
+
/* @__PURE__ */ jsx(
|
|
11
|
+
"div",
|
|
12
|
+
{
|
|
13
|
+
className: "flex items-end gap-2.5 px-1",
|
|
14
|
+
style: { height, borderBottom: "1px solid var(--chart-grid)" },
|
|
15
|
+
children: data.map((d, i) => /* @__PURE__ */ jsxs(
|
|
16
|
+
"div",
|
|
17
|
+
{
|
|
18
|
+
className: "flex flex-1 flex-col items-center justify-end h-full",
|
|
19
|
+
children: [
|
|
20
|
+
/* @__PURE__ */ jsx("span", { className: "mb-1.5 font-mono text-[11px] text-tollerud-text-secondary", children: d.value }),
|
|
21
|
+
/* @__PURE__ */ jsx(
|
|
22
|
+
"div",
|
|
23
|
+
{
|
|
24
|
+
className: cn(
|
|
25
|
+
"w-full max-w-[38px] rounded-t-[3px] transition-[height] duration-500 ease-out",
|
|
26
|
+
d.accent ? "bg-tollerud-yellow" : "bg-tollerud-noir-600"
|
|
27
|
+
),
|
|
28
|
+
style: { height: `${d.value / max * 100}%` }
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
i
|
|
34
|
+
))
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2.5 px-1 pt-2", children: data.map((d, i) => /* @__PURE__ */ jsx(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
className: "flex-1 text-center text-[11px] text-tollerud-text-muted",
|
|
41
|
+
children: d.label
|
|
42
|
+
},
|
|
43
|
+
i
|
|
44
|
+
)) })
|
|
45
|
+
] });
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
BarChart.displayName = "BarChart";
|
|
49
|
+
|
|
50
|
+
export { BarChart };
|
|
51
|
+
//# sourceMappingURL=chunk-4PA2ACNF.js.map
|
|
52
|
+
//# sourceMappingURL=chunk-4PA2ACNF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/BarChart.tsx"],"names":[],"mappings":";;;;AAcA,IAAM,QAAA,GAAW,UAAA;AAAA,EACf,CAAC,EAAE,SAAA,EAAW,IAAA,EAAM,SAAS,GAAA,EAAK,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACpD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAA,EAAG,CAAC,CAAA;AAEnD,IAAA,uBACE,IAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,QAAA,EAAU,SAAS,CAAA,EAAI,GAAG,KAAA,EACrD,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,6BAAA;AAAA,UACV,KAAA,EAAO,EAAE,MAAA,EAAQ,YAAA,EAAc,6BAAA,EAA8B;AAAA,UAE5D,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBACZ,IAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEC,SAAA,EAAU,sDAAA;AAAA,cAEV,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2DAAA,EACb,QAAA,EAAA,CAAA,CAAE,KAAA,EACL,CAAA;AAAA,gCACA,GAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,EAAA;AAAA,sBACT,+EAAA;AAAA,sBACA,CAAA,CAAE,SAAS,oBAAA,GAAuB;AAAA,qBACpC;AAAA,oBACA,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA,EAAI,EAAE,KAAA,GAAQ,GAAA,GAAO,GAAG,CAAA,CAAA,CAAA;AAAI;AAAA;AAC/C;AAAA,aAAA;AAAA,YAZK;AAAA,WAcR;AAAA;AAAA,OACH;AAAA,sBACA,GAAA,CAAC,SAAI,SAAA,EAAU,wBAAA,EACZ,eAAK,GAAA,CAAI,CAAC,GAAG,CAAA,qBACZ,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEC,SAAA,EAAU,yDAAA;AAAA,UAET,QAAA,EAAA,CAAA,CAAE;AAAA,SAAA;AAAA,QAHE;AAAA,OAKR,CAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AACF;AACA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-4PA2ACNF.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface BarChartDatum {\n label: string\n value: number\n accent?: boolean\n}\n\nexport interface BarChartProps extends HTMLAttributes<HTMLDivElement> {\n data: BarChartDatum[]\n height?: number\n}\n\nconst BarChart = forwardRef<HTMLDivElement, BarChartProps>(\n ({ className, data, height = 180, ...props }, ref) => {\n const max = Math.max(...data.map((d) => d.value), 1)\n\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n <div\n className=\"flex items-end gap-2.5 px-1\"\n style={{ height, borderBottom: '1px solid var(--chart-grid)' }}\n >\n {data.map((d, i) => (\n <div\n key={i}\n className=\"flex flex-1 flex-col items-center justify-end h-full\"\n >\n <span className=\"mb-1.5 font-mono text-[11px] text-tollerud-text-secondary\">\n {d.value}\n </span>\n <div\n className={cn(\n 'w-full max-w-[38px] rounded-t-[3px] transition-[height] duration-500 ease-out',\n d.accent ? 'bg-tollerud-yellow' : 'bg-tollerud-noir-600'\n )}\n style={{ height: `${(d.value / max) * 100}%` }}\n />\n </div>\n ))}\n </div>\n <div className=\"flex gap-2.5 px-1 pt-2\">\n {data.map((d, i) => (\n <div\n key={i}\n className=\"flex-1 text-center text-[11px] text-tollerud-text-muted\"\n >\n {d.label}\n </div>\n ))}\n </div>\n </div>\n )\n }\n)\nBarChart.displayName = 'BarChart'\n\nexport { BarChart }\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var Progress = React.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8
|
+
ProgressPrimitive.Root,
|
|
9
|
+
{
|
|
10
|
+
ref,
|
|
11
|
+
className: cn(
|
|
12
|
+
"relative h-2 w-full overflow-hidden rounded-full bg-tollerud-noir-800",
|
|
13
|
+
className
|
|
14
|
+
),
|
|
15
|
+
...props,
|
|
16
|
+
children: /* @__PURE__ */ jsx(
|
|
17
|
+
ProgressPrimitive.Indicator,
|
|
18
|
+
{
|
|
19
|
+
className: "h-full w-full flex-1 rounded-full bg-tollerud-yellow transition-all duration-300 ease-in-out",
|
|
20
|
+
style: { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
));
|
|
25
|
+
Progress.displayName = "Progress";
|
|
26
|
+
|
|
27
|
+
export { Progress };
|
|
28
|
+
//# sourceMappingURL=chunk-5GWHUJ5D.js.map
|
|
29
|
+
//# sourceMappingURL=chunk-5GWHUJ5D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/Progress.tsx"],"names":[],"mappings":";;;;;AAMA,IAAM,QAAA,GAAiB,iBAGrB,CAAC,EAAE,WAAW,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,qBACjC,GAAA;AAAA,EAAmB,iBAAA,CAAA,IAAA;AAAA,EAAlB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,uEAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG,KAAA;AAAA,IAEJ,QAAA,kBAAA,GAAA;AAAA,MAAmB,iBAAA,CAAA,SAAA;AAAA,MAAlB;AAAA,QACC,SAAA,EAAU,8FAAA;AAAA,QACV,OAAO,EAAE,SAAA,EAAW,eAAe,GAAA,IAAO,KAAA,IAAS,EAAE,CAAA,EAAA,CAAA;AAAK;AAAA;AAC5D;AACF,CACD;AACD,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-5GWHUJ5D.js","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as ProgressPrimitive from '@radix-ui/react-progress'\nimport { cn } from '@/lib/utils'\n\nconst Progress = React.forwardRef<\n React.ComponentRef<typeof ProgressPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n <ProgressPrimitive.Root\n ref={ref}\n className={cn(\n 'relative h-2 w-full overflow-hidden rounded-full bg-tollerud-noir-800',\n className\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n className=\"h-full w-full flex-1 rounded-full bg-tollerud-yellow transition-all duration-300 ease-in-out\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n))\nProgress.displayName = 'Progress'\n\nexport { Progress }"]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { useId, useRef, useState } from 'react';
|
|
4
|
+
import { Upload, File, X } from 'lucide-react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function formatBytes(bytes) {
|
|
8
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
9
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
10
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
11
|
+
}
|
|
12
|
+
function FileUpload({
|
|
13
|
+
label,
|
|
14
|
+
description,
|
|
15
|
+
error,
|
|
16
|
+
accept,
|
|
17
|
+
multiple,
|
|
18
|
+
onFilesChange,
|
|
19
|
+
className,
|
|
20
|
+
disabled
|
|
21
|
+
}) {
|
|
22
|
+
const id = useId();
|
|
23
|
+
const inputRef = useRef(null);
|
|
24
|
+
const [files, setFiles] = useState([]);
|
|
25
|
+
const [dragging, setDragging] = useState(false);
|
|
26
|
+
const setAndNotify = (next) => {
|
|
27
|
+
setFiles(next);
|
|
28
|
+
onFilesChange?.(next);
|
|
29
|
+
};
|
|
30
|
+
const addFiles = (incoming) => {
|
|
31
|
+
if (!incoming || incoming.length === 0) return;
|
|
32
|
+
const incomingArr = Array.from(incoming);
|
|
33
|
+
setAndNotify(multiple ? [...files, ...incomingArr] : [incomingArr[0]]);
|
|
34
|
+
};
|
|
35
|
+
const removeAt = (index) => {
|
|
36
|
+
setAndNotify(files.filter((_, i) => i !== index));
|
|
37
|
+
};
|
|
38
|
+
const onDrop = (e) => {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
setDragging(false);
|
|
41
|
+
if (disabled) return;
|
|
42
|
+
addFiles(e.dataTransfer.files);
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
45
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "text-xs font-medium text-tollerud-text-muted", children: label }),
|
|
46
|
+
/* @__PURE__ */ jsxs(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
role: "button",
|
|
50
|
+
tabIndex: disabled ? -1 : 0,
|
|
51
|
+
"aria-disabled": disabled,
|
|
52
|
+
onClick: () => !disabled && inputRef.current?.click(),
|
|
53
|
+
onKeyDown: (e) => {
|
|
54
|
+
if (!disabled && (e.key === "Enter" || e.key === " ")) {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
inputRef.current?.click();
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
onDragOver: (e) => {
|
|
60
|
+
e.preventDefault();
|
|
61
|
+
if (!disabled) setDragging(true);
|
|
62
|
+
},
|
|
63
|
+
onDragLeave: () => setDragging(false),
|
|
64
|
+
onDrop,
|
|
65
|
+
className: cn(
|
|
66
|
+
"flex flex-col items-center justify-center gap-2 rounded-lg border border-dashed px-6 py-8 text-center cursor-pointer transition-colors duration-[150ms]",
|
|
67
|
+
dragging ? "border-tollerud-yellow bg-tollerud-yellow/[0.06]" : "border-tollerud-border bg-tollerud-surface-raised hover:border-tollerud-text-secondary",
|
|
68
|
+
error && "border-tollerud-error",
|
|
69
|
+
disabled && "opacity-50 pointer-events-none"
|
|
70
|
+
),
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx(Upload, { size: 20, className: "text-tollerud-text-muted" }),
|
|
73
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-tollerud-text-secondary", children: [
|
|
74
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-tollerud-yellow", children: "Click to upload" }),
|
|
75
|
+
" or drag and drop"
|
|
76
|
+
] }),
|
|
77
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-text-muted", children: description }),
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
"input",
|
|
80
|
+
{
|
|
81
|
+
ref: inputRef,
|
|
82
|
+
id,
|
|
83
|
+
type: "file",
|
|
84
|
+
accept,
|
|
85
|
+
multiple,
|
|
86
|
+
disabled,
|
|
87
|
+
onChange: (e) => addFiles(e.target.files),
|
|
88
|
+
className: "sr-only"
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
files.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-1.5", children: files.map((file, i) => /* @__PURE__ */ jsxs(
|
|
95
|
+
"li",
|
|
96
|
+
{
|
|
97
|
+
className: "flex items-center gap-2.5 rounded-md border border-tollerud-border bg-tollerud-surface-raised px-3 py-2 text-sm",
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsx(File, { size: 15, className: "shrink-0 text-tollerud-text-muted" }),
|
|
100
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-tollerud-text-primary", children: file.name }),
|
|
101
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs text-tollerud-text-muted", children: formatBytes(file.size) }),
|
|
102
|
+
/* @__PURE__ */ jsx(
|
|
103
|
+
"button",
|
|
104
|
+
{
|
|
105
|
+
type: "button",
|
|
106
|
+
"aria-label": `Remove ${file.name}`,
|
|
107
|
+
onClick: () => removeAt(i),
|
|
108
|
+
className: "shrink-0 text-tollerud-text-muted hover:text-tollerud-text-primary transition-colors duration-[150ms]",
|
|
109
|
+
children: /* @__PURE__ */ jsx(X, { size: 14 })
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
`${file.name}-${i}`
|
|
115
|
+
)) }),
|
|
116
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-error", children: error })
|
|
117
|
+
] });
|
|
118
|
+
}
|
|
119
|
+
FileUpload.displayName = "FileUpload";
|
|
120
|
+
|
|
121
|
+
export { FileUpload };
|
|
122
|
+
//# sourceMappingURL=chunk-6FUKJD3W.js.map
|
|
123
|
+
//# sourceMappingURL=chunk-6FUKJD3W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/FileUpload.tsx"],"names":["FileIcon"],"mappings":"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","file":"chunk-6FUKJD3W.js","sourcesContent":["'use client'\n\nimport { type DragEvent, useId, useRef, useState } from 'react'\nimport { Upload, X, File as FileIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface FileUploadProps {\n label?: string\n description?: React.ReactNode\n error?: string\n /** Forwarded to the underlying `<input accept>` */\n accept?: string\n multiple?: boolean\n /** Called whenever the selected file list changes */\n onFilesChange?: (files: File[]) => void\n className?: string\n disabled?: boolean\n}\n\nfunction formatBytes(bytes: number) {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction FileUpload({\n label,\n description,\n error,\n accept,\n multiple,\n onFilesChange,\n className,\n disabled,\n}: FileUploadProps) {\n const id = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const [files, setFiles] = useState<File[]>([])\n const [dragging, setDragging] = useState(false)\n\n const setAndNotify = (next: File[]) => {\n setFiles(next)\n onFilesChange?.(next)\n }\n\n const addFiles = (incoming: FileList | null) => {\n if (!incoming || incoming.length === 0) return\n const incomingArr = Array.from(incoming)\n setAndNotify(multiple ? [...files, ...incomingArr] : [incomingArr[0]!])\n }\n\n const removeAt = (index: number) => {\n setAndNotify(files.filter((_, i) => i !== index))\n }\n\n const onDrop = (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n setDragging(false)\n if (disabled) return\n addFiles(e.dataTransfer.files)\n }\n\n return (\n <div className={cn('flex flex-col gap-1.5', className)}>\n {label && (\n <label htmlFor={id} className=\"text-xs font-medium text-tollerud-text-muted\">\n {label}\n </label>\n )}\n\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n onClick={() => !disabled && inputRef.current?.click()}\n onKeyDown={(e) => {\n if (!disabled && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault()\n inputRef.current?.click()\n }\n }}\n onDragOver={(e) => {\n e.preventDefault()\n if (!disabled) setDragging(true)\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={onDrop}\n className={cn(\n 'flex flex-col items-center justify-center gap-2 rounded-lg border border-dashed px-6 py-8 text-center cursor-pointer transition-colors duration-[150ms]',\n dragging\n ? 'border-tollerud-yellow bg-tollerud-yellow/[0.06]'\n : 'border-tollerud-border bg-tollerud-surface-raised hover:border-tollerud-text-secondary',\n error && 'border-tollerud-error',\n disabled && 'opacity-50 pointer-events-none'\n )}\n >\n <Upload size={20} className=\"text-tollerud-text-muted\" />\n <div className=\"text-sm text-tollerud-text-secondary\">\n <span className=\"font-medium text-tollerud-yellow\">Click to upload</span> or drag and drop\n </div>\n {description && <p className=\"text-xs text-tollerud-text-muted\">{description}</p>}\n <input\n ref={inputRef}\n id={id}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n onChange={(e) => addFiles(e.target.files)}\n className=\"sr-only\"\n />\n </div>\n\n {files.length > 0 && (\n <ul className=\"flex flex-col gap-1.5\">\n {files.map((file, i) => (\n <li\n key={`${file.name}-${i}`}\n className=\"flex items-center gap-2.5 rounded-md border border-tollerud-border bg-tollerud-surface-raised px-3 py-2 text-sm\"\n >\n <FileIcon size={15} className=\"shrink-0 text-tollerud-text-muted\" />\n <span className=\"flex-1 truncate text-tollerud-text-primary\">{file.name}</span>\n <span className=\"shrink-0 text-xs text-tollerud-text-muted\">{formatBytes(file.size)}</span>\n <button\n type=\"button\"\n aria-label={`Remove ${file.name}`}\n onClick={() => removeAt(i)}\n className=\"shrink-0 text-tollerud-text-muted hover:text-tollerud-text-primary transition-colors duration-[150ms]\"\n >\n <X size={14} />\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {error && <p className=\"text-xs text-tollerud-error\">{error}</p>}\n </div>\n )\n}\nFileUpload.displayName = 'FileUpload'\n\nexport { FileUpload }\n"]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { useId, useState } from 'react';
|
|
4
|
+
import { X } from 'lucide-react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function TagInput({
|
|
8
|
+
value: valueProp,
|
|
9
|
+
defaultValue = [],
|
|
10
|
+
onChange,
|
|
11
|
+
label,
|
|
12
|
+
error,
|
|
13
|
+
placeholder = "Add a tag\u2026",
|
|
14
|
+
max,
|
|
15
|
+
className,
|
|
16
|
+
disabled
|
|
17
|
+
}) {
|
|
18
|
+
const id = useId();
|
|
19
|
+
const isControlled = valueProp !== void 0;
|
|
20
|
+
const [internalTags, setInternalTags] = useState(defaultValue);
|
|
21
|
+
const tags = isControlled ? valueProp : internalTags;
|
|
22
|
+
const [draft, setDraft] = useState("");
|
|
23
|
+
const setAndNotify = (next) => {
|
|
24
|
+
if (!isControlled) setInternalTags(next);
|
|
25
|
+
onChange?.(next);
|
|
26
|
+
};
|
|
27
|
+
const addTag = (raw) => {
|
|
28
|
+
const tag = raw.trim();
|
|
29
|
+
if (!tag || tags.includes(tag)) return;
|
|
30
|
+
if (max && tags.length >= max) return;
|
|
31
|
+
setAndNotify([...tags, tag]);
|
|
32
|
+
setDraft("");
|
|
33
|
+
};
|
|
34
|
+
const removeTag = (index) => {
|
|
35
|
+
setAndNotify(tags.filter((_, i) => i !== index));
|
|
36
|
+
};
|
|
37
|
+
const onKeyDown = (e) => {
|
|
38
|
+
if (e.key === "Enter" || e.key === ",") {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
addTag(draft);
|
|
41
|
+
} else if (e.key === "Backspace" && draft === "" && tags.length > 0) {
|
|
42
|
+
removeTag(tags.length - 1);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const atMax = max ? tags.length >= max : false;
|
|
46
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1", className), children: [
|
|
47
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "text-xs font-medium text-tollerud-text-muted", children: label }),
|
|
48
|
+
/* @__PURE__ */ jsxs(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
className: cn(
|
|
52
|
+
"flex flex-wrap items-center gap-1.5 rounded px-2.5 py-1.5",
|
|
53
|
+
"bg-tollerud-surface-raised border",
|
|
54
|
+
"transition-[border-color] duration-[150ms]",
|
|
55
|
+
"focus-within:border-tollerud-yellow focus-within:shadow-[0_0_0_1px_#E8D500]",
|
|
56
|
+
error ? "border-tollerud-error" : "border-tollerud-border",
|
|
57
|
+
disabled && "opacity-50 pointer-events-none"
|
|
58
|
+
),
|
|
59
|
+
children: [
|
|
60
|
+
tags.map((tag, i) => /* @__PURE__ */ jsxs(
|
|
61
|
+
"span",
|
|
62
|
+
{
|
|
63
|
+
className: "inline-flex items-center gap-1 rounded-full bg-tollerud-surface-hover px-2.5 py-0.5 text-xs font-medium text-tollerud-text-primary",
|
|
64
|
+
children: [
|
|
65
|
+
tag,
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
"button",
|
|
68
|
+
{
|
|
69
|
+
type: "button",
|
|
70
|
+
"aria-label": `Remove ${tag}`,
|
|
71
|
+
onClick: () => removeTag(i),
|
|
72
|
+
className: "text-tollerud-text-muted hover:text-tollerud-text-primary transition-colors duration-[150ms]",
|
|
73
|
+
children: /* @__PURE__ */ jsx(X, { size: 12 })
|
|
74
|
+
}
|
|
75
|
+
)
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
`${tag}-${i}`
|
|
79
|
+
)),
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
"input",
|
|
82
|
+
{
|
|
83
|
+
id,
|
|
84
|
+
value: draft,
|
|
85
|
+
disabled: disabled || atMax,
|
|
86
|
+
onChange: (e) => setDraft(e.target.value),
|
|
87
|
+
onKeyDown,
|
|
88
|
+
onBlur: () => addTag(draft),
|
|
89
|
+
placeholder: atMax ? "" : placeholder,
|
|
90
|
+
className: cn(
|
|
91
|
+
"min-w-[6rem] flex-1 bg-transparent py-0.5 text-sm text-tollerud-text-primary",
|
|
92
|
+
"placeholder:text-tollerud-text-muted focus:outline-none"
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-error mt-0.5", children: error })
|
|
100
|
+
] });
|
|
101
|
+
}
|
|
102
|
+
TagInput.displayName = "TagInput";
|
|
103
|
+
|
|
104
|
+
export { TagInput };
|
|
105
|
+
//# sourceMappingURL=chunk-6IS2AYYG.js.map
|
|
106
|
+
//# sourceMappingURL=chunk-6IS2AYYG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/TagInput.tsx"],"names":[],"mappings":"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","file":"chunk-6IS2AYYG.js","sourcesContent":["'use client'\n\nimport { type KeyboardEvent, useId, useState } from 'react'\nimport { X } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface TagInputProps {\n value?: string[]\n defaultValue?: string[]\n onChange?: (tags: string[]) => void\n label?: string\n error?: string\n placeholder?: string\n /** Maximum number of tags allowed */\n max?: number\n className?: string\n disabled?: boolean\n}\n\nfunction TagInput({\n value: valueProp,\n defaultValue = [],\n onChange,\n label,\n error,\n placeholder = 'Add a tag…',\n max,\n className,\n disabled,\n}: TagInputProps) {\n const id = useId()\n const isControlled = valueProp !== undefined\n const [internalTags, setInternalTags] = useState<string[]>(defaultValue)\n const tags = isControlled ? valueProp : internalTags\n const [draft, setDraft] = useState('')\n\n const setAndNotify = (next: string[]) => {\n if (!isControlled) setInternalTags(next)\n onChange?.(next)\n }\n\n const addTag = (raw: string) => {\n const tag = raw.trim()\n if (!tag || tags.includes(tag)) return\n if (max && tags.length >= max) return\n setAndNotify([...tags, tag])\n setDraft('')\n }\n\n const removeTag = (index: number) => {\n setAndNotify(tags.filter((_, i) => i !== index))\n }\n\n const onKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' || e.key === ',') {\n e.preventDefault()\n addTag(draft)\n } else if (e.key === 'Backspace' && draft === '' && tags.length > 0) {\n removeTag(tags.length - 1)\n }\n }\n\n const atMax = max ? tags.length >= max : false\n\n return (\n <div className={cn('flex flex-col gap-1', className)}>\n {label && (\n <label htmlFor={id} className=\"text-xs font-medium text-tollerud-text-muted\">\n {label}\n </label>\n )}\n <div\n className={cn(\n 'flex flex-wrap items-center gap-1.5 rounded px-2.5 py-1.5',\n 'bg-tollerud-surface-raised border',\n 'transition-[border-color] duration-[150ms]',\n 'focus-within:border-tollerud-yellow focus-within:shadow-[0_0_0_1px_#E8D500]',\n error ? 'border-tollerud-error' : 'border-tollerud-border',\n disabled && 'opacity-50 pointer-events-none'\n )}\n >\n {tags.map((tag, i) => (\n <span\n key={`${tag}-${i}`}\n className=\"inline-flex items-center gap-1 rounded-full bg-tollerud-surface-hover px-2.5 py-0.5 text-xs font-medium text-tollerud-text-primary\"\n >\n {tag}\n <button\n type=\"button\"\n aria-label={`Remove ${tag}`}\n onClick={() => removeTag(i)}\n className=\"text-tollerud-text-muted hover:text-tollerud-text-primary transition-colors duration-[150ms]\"\n >\n <X size={12} />\n </button>\n </span>\n ))}\n <input\n id={id}\n value={draft}\n disabled={disabled || atMax}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={onKeyDown}\n onBlur={() => addTag(draft)}\n placeholder={atMax ? '' : placeholder}\n className={cn(\n 'min-w-[6rem] flex-1 bg-transparent py-0.5 text-sm text-tollerud-text-primary',\n 'placeholder:text-tollerud-text-muted focus:outline-none'\n )}\n />\n </div>\n {error && <p className=\"text-xs text-tollerud-error mt-0.5\">{error}</p>}\n </div>\n )\n}\nTagInput.displayName = 'TagInput'\n\nexport { TagInput }\n"]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { forwardRef, useId } from 'react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var AreaChart = forwardRef(
|
|
7
|
+
({ className, data, height = 180, ...props }, ref) => {
|
|
8
|
+
const gradientId = useId().replace(/:/g, "");
|
|
9
|
+
const w = 520;
|
|
10
|
+
const h = height;
|
|
11
|
+
const pad = 8;
|
|
12
|
+
const max = Math.max(...data) * 1.1;
|
|
13
|
+
const min = Math.min(...data, 0);
|
|
14
|
+
const span = Math.max(data.length - 1, 1);
|
|
15
|
+
const x = (i) => pad + i / span * (w - pad * 2);
|
|
16
|
+
const y = (v) => h - pad - (v - min) / (max - min || 1) * (h - pad * 2);
|
|
17
|
+
const line = data.map((v, i) => `${x(i)},${y(v)}`).join(" ");
|
|
18
|
+
const area = `${pad},${h - pad} ${line} ${w - pad},${h - pad}`;
|
|
19
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn("w-full", className), ...props, children: /* @__PURE__ */ jsxs(
|
|
20
|
+
"svg",
|
|
21
|
+
{
|
|
22
|
+
viewBox: `0 0 ${w} ${h}`,
|
|
23
|
+
className: "w-full",
|
|
24
|
+
style: { height },
|
|
25
|
+
preserveAspectRatio: "none",
|
|
26
|
+
role: "img",
|
|
27
|
+
"aria-hidden": "true",
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
30
|
+
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#E8D500", stopOpacity: "0.30" }),
|
|
31
|
+
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#E8D500", stopOpacity: "0" })
|
|
32
|
+
] }) }),
|
|
33
|
+
[0.25, 0.5, 0.75].map((g, i) => /* @__PURE__ */ jsx(
|
|
34
|
+
"line",
|
|
35
|
+
{
|
|
36
|
+
x1: pad,
|
|
37
|
+
x2: w - pad,
|
|
38
|
+
y1: h * g,
|
|
39
|
+
y2: h * g,
|
|
40
|
+
stroke: "var(--chart-grid)",
|
|
41
|
+
strokeWidth: "1"
|
|
42
|
+
},
|
|
43
|
+
i
|
|
44
|
+
)),
|
|
45
|
+
/* @__PURE__ */ jsx("polygon", { points: area, fill: `url(#${gradientId})` }),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"polyline",
|
|
48
|
+
{
|
|
49
|
+
points: line,
|
|
50
|
+
fill: "none",
|
|
51
|
+
stroke: "#E8D500",
|
|
52
|
+
strokeWidth: "2",
|
|
53
|
+
strokeLinecap: "round",
|
|
54
|
+
strokeLinejoin: "round"
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
data.map((v, i) => /* @__PURE__ */ jsx(
|
|
58
|
+
"circle",
|
|
59
|
+
{
|
|
60
|
+
cx: x(i),
|
|
61
|
+
cy: y(v),
|
|
62
|
+
r: "2.5",
|
|
63
|
+
fill: "var(--card)",
|
|
64
|
+
stroke: "#E8D500",
|
|
65
|
+
strokeWidth: "1.5"
|
|
66
|
+
},
|
|
67
|
+
i
|
|
68
|
+
))
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
) });
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
AreaChart.displayName = "AreaChart";
|
|
75
|
+
|
|
76
|
+
export { AreaChart };
|
|
77
|
+
//# sourceMappingURL=chunk-6PZKU6ZL.js.map
|
|
78
|
+
//# sourceMappingURL=chunk-6PZKU6ZL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/AreaChart.tsx"],"names":[],"mappings":"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","file":"chunk-6PZKU6ZL.js","sourcesContent":["import { type HTMLAttributes, forwardRef, useId } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface AreaChartProps extends HTMLAttributes<HTMLDivElement> {\n data: number[]\n height?: number\n}\n\nconst AreaChart = forwardRef<HTMLDivElement, AreaChartProps>(\n ({ className, data, height = 180, ...props }, ref) => {\n const gradientId = useId().replace(/:/g, '')\n const w = 520\n const h = height\n const pad = 8\n const max = Math.max(...data) * 1.1\n const min = Math.min(...data, 0)\n const span = Math.max(data.length - 1, 1)\n const x = (i: number) => pad + (i / span) * (w - pad * 2)\n const y = (v: number) => h - pad - ((v - min) / (max - min || 1)) * (h - pad * 2)\n const line = data.map((v, i) => `${x(i)},${y(v)}`).join(' ')\n const area = `${pad},${h - pad} ${line} ${w - pad},${h - pad}`\n\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n <svg\n viewBox={`0 0 ${w} ${h}`}\n className=\"w-full\"\n style={{ height }}\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-hidden=\"true\"\n >\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor=\"#E8D500\" stopOpacity=\"0.30\" />\n <stop offset=\"100%\" stopColor=\"#E8D500\" stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n {[0.25, 0.5, 0.75].map((g, i) => (\n <line\n key={i}\n x1={pad}\n x2={w - pad}\n y1={h * g}\n y2={h * g}\n stroke=\"var(--chart-grid)\"\n strokeWidth=\"1\"\n />\n ))}\n <polygon points={area} fill={`url(#${gradientId})`} />\n <polyline\n points={line}\n fill=\"none\"\n stroke=\"#E8D500\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n {data.map((v, i) => (\n <circle\n key={i}\n cx={x(i)}\n cy={y(v)}\n r=\"2.5\"\n fill=\"var(--card)\"\n stroke=\"#E8D500\"\n strokeWidth=\"1.5\"\n />\n ))}\n </svg>\n </div>\n )\n }\n)\nAreaChart.displayName = 'AreaChart'\n\nexport { AreaChart }\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { forwardRef, useId } from 'react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var RadioGroup = forwardRef(
|
|
7
|
+
({ label, error, children, className }, ref) => {
|
|
8
|
+
return /* @__PURE__ */ jsxs("fieldset", { ref, className: cn("flex flex-col gap-1", className), children: [
|
|
9
|
+
label && /* @__PURE__ */ jsx("legend", { className: "text-xs font-medium text-tollerud-text-muted mb-1", children: label }),
|
|
10
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children }),
|
|
11
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-error mt-0.5", children: error })
|
|
12
|
+
] });
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
RadioGroup.displayName = "RadioGroup";
|
|
16
|
+
var Radio = forwardRef(
|
|
17
|
+
({ className, label, id: idProp, ...props }, ref) => {
|
|
18
|
+
const autoId = useId();
|
|
19
|
+
const id = idProp ?? autoId;
|
|
20
|
+
return /* @__PURE__ */ jsxs(
|
|
21
|
+
"label",
|
|
22
|
+
{
|
|
23
|
+
htmlFor: id,
|
|
24
|
+
className: cn(
|
|
25
|
+
"inline-flex items-center gap-2 cursor-pointer select-none group",
|
|
26
|
+
"text-sm text-tollerud-text-primary",
|
|
27
|
+
props.disabled && "opacity-50 pointer-events-none",
|
|
28
|
+
className
|
|
29
|
+
),
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ jsxs("span", { className: "relative flex items-center justify-center", children: [
|
|
32
|
+
/* @__PURE__ */ jsx(
|
|
33
|
+
"input",
|
|
34
|
+
{
|
|
35
|
+
ref,
|
|
36
|
+
id,
|
|
37
|
+
type: "radio",
|
|
38
|
+
className: "peer sr-only",
|
|
39
|
+
...props
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
"span",
|
|
44
|
+
{
|
|
45
|
+
className: cn(
|
|
46
|
+
"h-4 w-4 rounded-full border transition-all duration-[150ms]",
|
|
47
|
+
"bg-tollerud-surface-raised border-tollerud-border",
|
|
48
|
+
"peer-focus-visible:outline-2 peer-focus-visible:outline-tollerud-yellow",
|
|
49
|
+
"peer-checked:border-tollerud-yellow",
|
|
50
|
+
"group-hover:border-tollerud-text-secondary",
|
|
51
|
+
"flex items-center justify-center"
|
|
52
|
+
),
|
|
53
|
+
children: /* @__PURE__ */ jsx(
|
|
54
|
+
"span",
|
|
55
|
+
{
|
|
56
|
+
className: cn(
|
|
57
|
+
"h-2 w-2 rounded-full bg-tollerud-yellow transition-opacity duration-[150ms]",
|
|
58
|
+
props.checked ? "opacity-100" : "opacity-0"
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
] }),
|
|
65
|
+
label && /* @__PURE__ */ jsx("span", { children: label })
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
Radio.displayName = "Radio";
|
|
72
|
+
|
|
73
|
+
export { Radio, RadioGroup };
|
|
74
|
+
//# sourceMappingURL=chunk-6SKTH45H.js.map
|
|
75
|
+
//# sourceMappingURL=chunk-6SKTH45H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/RadioGroup.tsx"],"names":[],"mappings":";;;;AAcA,IAAM,UAAA,GAAa,UAAA;AAAA,EACjB,CAAC,EAAE,KAAA,EAAO,OAAO,QAAA,EAAU,SAAA,IAAa,GAAA,KAAQ;AAC9C,IAAA,4BACG,UAAA,EAAA,EAAS,GAAA,EAAU,WAAW,EAAA,CAAG,qBAAA,EAAuB,SAAS,CAAA,EAC/D,QAAA,EAAA;AAAA,MAAA,KAAA,oBACC,GAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAU,mDAAA,EACf,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,sBAEF,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAAuB,QAAA,EAAS,CAAA;AAAA,MAC9C,KAAA,oBACC,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCAAsC,QAAA,EAAA,KAAA,EAAM;AAAA,KAAA,EAE7D,CAAA;AAAA,EAEJ;AACF;AACA,UAAA,CAAW,WAAA,GAAc,YAAA;AAMzB,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,IAAI,MAAA,EAAQ,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACnD,IAAA,MAAM,SAAS,KAAA,EAAM;AACrB,IAAA,MAAM,KAAK,MAAA,IAAU,MAAA;AAErB,IAAA,uBACE,IAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,EAAA;AAAA,QACT,SAAA,EAAW,EAAA;AAAA,UACT,iEAAA;AAAA,UACA,oCAAA;AAAA,UACA,MAAM,QAAA,IAAY,gCAAA;AAAA,UAClB;AAAA,SACF;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,2CAAA,EACd,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,GAAA;AAAA,gBACA,EAAA;AAAA,gBACA,IAAA,EAAK,OAAA;AAAA,gBACL,SAAA,EAAU,cAAA;AAAA,gBACT,GAAG;AAAA;AAAA,aACN;AAAA,4BAEA,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,SAAA,EAAW,EAAA;AAAA,kBACT,6DAAA;AAAA,kBACA,mDAAA;AAAA,kBACA,yEAAA;AAAA,kBACA,qCAAA;AAAA,kBACA,4CAAA;AAAA,kBACA;AAAA,iBACF;AAAA,gBAGA,QAAA,kBAAA,GAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAW,EAAA;AAAA,sBACT,6EAAA;AAAA,sBACA,KAAA,CAAM,UAAU,aAAA,GAAgB;AAAA;AAClC;AAAA;AACF;AAAA;AACF,WAAA,EACF,CAAA;AAAA,UACC,KAAA,oBAAS,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA;AAAA,KACzB;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-6SKTH45H.js","sourcesContent":["'use client'\n\nimport { type InputHTMLAttributes, forwardRef, useId } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface RadioGroupProps {\n /** Group label */\n label?: string\n /** Error message */\n error?: string\n children?: React.ReactNode\n className?: string\n}\n\nconst RadioGroup = forwardRef<HTMLFieldSetElement, RadioGroupProps>(\n ({ label, error, children, className }, ref) => {\n return (\n <fieldset ref={ref} className={cn('flex flex-col gap-1', className)}>\n {label && (\n <legend className=\"text-xs font-medium text-tollerud-text-muted mb-1\">\n {label}\n </legend>\n )}\n <div className=\"flex flex-col gap-2\">{children}</div>\n {error && (\n <p className=\"text-xs text-tollerud-error mt-0.5\">{error}</p>\n )}\n </fieldset>\n )\n }\n)\nRadioGroup.displayName = 'RadioGroup'\n\nexport interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label?: string\n}\n\nconst Radio = forwardRef<HTMLInputElement, RadioProps>(\n ({ className, label, id: idProp, ...props }, ref) => {\n const autoId = useId()\n const id = idProp ?? autoId\n\n return (\n <label\n htmlFor={id}\n className={cn(\n 'inline-flex items-center gap-2 cursor-pointer select-none group',\n 'text-sm text-tollerud-text-primary',\n props.disabled && 'opacity-50 pointer-events-none',\n className\n )}\n >\n <span className=\"relative flex items-center justify-center\">\n <input\n ref={ref}\n id={id}\n type=\"radio\"\n className=\"peer sr-only\"\n {...props}\n />\n {/* Custom radio circle */}\n <span\n className={cn(\n 'h-4 w-4 rounded-full border transition-all duration-[150ms]',\n 'bg-tollerud-surface-raised border-tollerud-border',\n 'peer-focus-visible:outline-2 peer-focus-visible:outline-tollerud-yellow',\n 'peer-checked:border-tollerud-yellow',\n 'group-hover:border-tollerud-text-secondary',\n 'flex items-center justify-center'\n )}\n >\n {/* Inner dot */}\n <span\n className={cn(\n 'h-2 w-2 rounded-full bg-tollerud-yellow transition-opacity duration-[150ms]',\n props.checked ? 'opacity-100' : 'opacity-0'\n )}\n />\n </span>\n </span>\n {label && <span>{label}</span>}\n </label>\n )\n }\n)\nRadio.displayName = 'Radio'\n\nexport { RadioGroup, Radio }"]}
|