velloo 0.0.0 → 0.2.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/BUN-LICENSE.md +91 -0
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +288 -2
- package/THIRD-PARTY-NOTICES.md +467 -0
- package/assets/elsewhere-alps-9fqhv029.jpg +0 -0
- package/assets/elsewhere-bali-vp60g115.jpg +0 -0
- package/assets/elsewhere-forest-xgn23zrj.jpg +0 -0
- package/assets/elsewhere-japan-qs7qkbr2.jpg +0 -0
- package/assets/elsewhere-kyoto-map-n2bvkrya.svg +1 -0
- package/assets/elsewhere-kyoto-qemtn6nk.jpg +0 -0
- package/assets/elsewhere-room-g1gaw7cs.jpg +0 -0
- package/canvas/apple-touch-icon.png +0 -0
- package/canvas/assets/index-BCvDZiBo.css +2 -0
- package/canvas/assets/index-ClaBqcaS.js +28 -0
- package/canvas/assets/lucide-all-iIF-pmzN.js +1 -0
- package/canvas/assets/radix-C3HaOB-d.js +41 -0
- package/canvas/assets/react-D0Ec-185.js +9 -0
- package/canvas/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/canvas/assets/vendor-CKmQ-Zst.js +53 -0
- package/canvas/favicon.ico +0 -0
- package/canvas/favicon.svg +12 -0
- package/canvas/fonts/OFL-1.1.txt +93 -0
- package/canvas/fonts/poppins-700.woff2 +0 -0
- package/canvas/icon-192.png +0 -0
- package/canvas/icon-512.png +0 -0
- package/canvas/index.html +22 -0
- package/canvas/site.webmanifest +11 -0
- package/chunk-08sv3k41.js +4 -0
- package/chunk-0fe83yzt.js +2 -0
- package/chunk-0t68szgr.js +3 -0
- package/chunk-1h55s5he.js +2 -0
- package/chunk-2c7jbx46.js +2 -0
- package/chunk-2smsg2ct.js +7 -0
- package/chunk-308ynsxd.js +2 -0
- package/chunk-3e8vez4d.js +1229 -0
- package/chunk-40xgcth8.js +63 -0
- package/chunk-4dn75m6t.js +3 -0
- package/chunk-4fj5tahv.js +3 -0
- package/chunk-6nqghjda.js +3 -0
- package/chunk-6tx68d90.js +3 -0
- package/chunk-6w6ch4ce.js +2 -0
- package/chunk-735ezz23.js +86 -0
- package/chunk-7eq7nx37.js +7 -0
- package/chunk-7eyb8yrf.js +6 -0
- package/chunk-80fjfyha.js +86 -0
- package/chunk-80r93t2e.js +4 -0
- package/chunk-94vx1yb0.js +3 -0
- package/chunk-9vg3yafz.js +3 -0
- package/chunk-a84n72m2.js +4 -0
- package/chunk-ampmdzz4.js +10 -0
- package/chunk-avns4dbf.js +2 -0
- package/chunk-ayrb3qnm.js +3 -0
- package/chunk-bwnvcncx.js +3 -0
- package/chunk-ccszg02q.js +5 -0
- package/chunk-cvn689d5.js +3 -0
- package/chunk-cxe6jjwj.js +3 -0
- package/chunk-dg6z4vdd.js +3 -0
- package/chunk-dgwjpbp9.js +3 -0
- package/chunk-dy41n60j.js +52 -0
- package/chunk-ek71z2fv.js +226 -0
- package/chunk-er1fxb7d.js +2 -0
- package/chunk-eyr8hrzf.js +2 -0
- package/chunk-fjbzk4sw.js +3 -0
- package/chunk-fsbsksga.js +3 -0
- package/chunk-h6gchare.js +3 -0
- package/chunk-hcb68zt7.js +85 -0
- package/chunk-hggap8fq.js +3 -0
- package/chunk-j11fyeqh.js +2 -0
- package/chunk-jb21jkp1.js +8 -0
- package/chunk-jfx9xjmr.js +18 -0
- package/chunk-jr0ss0mm.js +303 -0
- package/chunk-jrsknzjt.js +3 -0
- package/chunk-jv0xggh0.js +2 -0
- package/chunk-k17gfwq3.js +2 -0
- package/chunk-mh2pr7cq.js +5 -0
- package/chunk-mnapdp1y.js +2 -0
- package/chunk-mzhdrawd.js +3 -0
- package/chunk-n9gs6yx9.js +2 -0
- package/chunk-ngnymg2q.js +3 -0
- package/chunk-nwx5700b.js +3 -0
- package/chunk-pjtg3wnm.js +4 -0
- package/chunk-pp86v6m6.js +3 -0
- package/chunk-r22epxz2.js +3 -0
- package/chunk-rgasy862.js +5 -0
- package/chunk-rpwpeph5.js +3 -0
- package/chunk-s23gtejf.js +3 -0
- package/chunk-sjgqnykd.js +6 -0
- package/chunk-sn3x2m0m.js +6 -0
- package/chunk-t448rrfr.js +2 -0
- package/chunk-tdsk5wxa.js +451 -0
- package/chunk-v40fn08f.js +442 -0
- package/chunk-vbk1qhdz.js +3 -0
- package/chunk-vdkrbzh1.js +2 -0
- package/chunk-vgmr98cv.js +40 -0
- package/chunk-vsv8z729.js +6 -0
- package/chunk-x4f4k9pp.js +26 -0
- package/chunk-xt5ayg7g.js +4 -0
- package/chunk-ydhwv29b.js +244 -0
- package/chunk-zb6hc1y0.js +2 -0
- package/cli.js +3 -0
- package/launcher.cjs +97 -0
- package/package.json +58 -5
- package/pkgs/helpers/src/box.tsx +21 -0
- package/pkgs/helpers/src/cn.ts +32 -0
- package/pkgs/helpers/src/descriptors.ts +270 -0
- package/pkgs/helpers/src/divider.tsx +123 -0
- package/pkgs/helpers/src/gradient.tsx +90 -0
- package/pkgs/helpers/src/heading.tsx +20 -0
- package/pkgs/helpers/src/icon-data.ts +8009 -0
- package/pkgs/helpers/src/icon.tsx +53 -0
- package/pkgs/helpers/src/image.tsx +111 -0
- package/pkgs/helpers/src/index.ts +29 -0
- package/pkgs/helpers/src/layer.tsx +61 -0
- package/pkgs/helpers/src/lowering.ts +53 -0
- package/pkgs/helpers/src/paths.ts +47 -0
- package/pkgs/helpers/src/placeholder.tsx +88 -0
- package/pkgs/helpers/src/prose.tsx +42 -0
- package/pkgs/helpers/src/registry.ts +41 -0
- package/pkgs/helpers/src/svg.tsx +62 -0
- package/pkgs/helpers/src/text.tsx +16 -0
- package/pkgs/provider-antd/src/index.ts +78 -0
- package/pkgs/provider-antd/src/intro.ts +14 -0
- package/pkgs/provider-antd/src/manifest.ts +439 -0
- package/pkgs/provider-antd/src/overlays.ts +176 -0
- package/pkgs/provider-antd/src/registry.ts +104 -0
- package/pkgs/provider-antd/src/render-pass.ts +43 -0
- package/pkgs/provider-antd/src/tailwind-entry.css +21 -0
- package/pkgs/provider-antd/src/theme.ts +132 -0
- package/pkgs/provider-antd/src/version.ts +8 -0
- package/pkgs/provider-chakra/src/index.ts +80 -0
- package/pkgs/provider-chakra/src/intro.ts +14 -0
- package/pkgs/provider-chakra/src/manifest.ts +421 -0
- package/pkgs/provider-chakra/src/overlays.ts +246 -0
- package/pkgs/provider-chakra/src/registry.ts +227 -0
- package/pkgs/provider-chakra/src/render-pass.ts +55 -0
- package/pkgs/provider-chakra/src/tailwind-entry.css +21 -0
- package/pkgs/provider-chakra/src/theme.ts +180 -0
- package/pkgs/provider-chakra/src/version.ts +8 -0
- package/pkgs/provider-mui/src/index.ts +117 -0
- package/pkgs/provider-mui/src/intro.ts +12 -0
- package/pkgs/provider-mui/src/manifest.ts +263 -0
- package/pkgs/provider-mui/src/overlays.ts +124 -0
- package/pkgs/provider-mui/src/registry.ts +120 -0
- package/pkgs/provider-mui/src/render-pass.ts +36 -0
- package/pkgs/provider-mui/src/tailwind-entry.css +21 -0
- package/pkgs/provider-mui/src/theme.ts +129 -0
- package/pkgs/provider-mui/src/version.ts +8 -0
- package/pkgs/provider-none/src/components-inline.tsx +204 -0
- package/pkgs/provider-none/src/components.tsx +155 -0
- package/pkgs/provider-none/src/index.ts +57 -0
- package/pkgs/provider-none/src/intro.ts +18 -0
- package/pkgs/provider-none/src/manifest.ts +163 -0
- package/pkgs/provider-none/src/registry-inline.ts +36 -0
- package/pkgs/provider-none/src/registry.ts +39 -0
- package/pkgs/provider-none/src/tailwind-entry.css +57 -0
- package/pkgs/provider-none/src/version.ts +10 -0
- package/pkgs/schema/src/annotation.ts +120 -0
- package/pkgs/schema/src/asset.ts +66 -0
- package/pkgs/schema/src/board.ts +71 -0
- package/pkgs/schema/src/comment.ts +107 -0
- package/pkgs/schema/src/config.ts +185 -0
- package/pkgs/schema/src/css-sanitize.ts +56 -0
- package/pkgs/schema/src/extension.ts +105 -0
- package/pkgs/schema/src/fonts.ts +690 -0
- package/pkgs/schema/src/frame.ts +40 -0
- package/pkgs/schema/src/icon-name.ts +21 -0
- package/pkgs/schema/src/ids.ts +14 -0
- package/pkgs/schema/src/index.ts +169 -0
- package/pkgs/schema/src/migrate.ts +297 -0
- package/pkgs/schema/src/node.ts +229 -0
- package/pkgs/schema/src/paths.ts +28 -0
- package/pkgs/schema/src/repo.ts +134 -0
- package/pkgs/schema/src/screen.ts +30 -0
- package/pkgs/schema/src/snippet-resolve.ts +193 -0
- package/pkgs/schema/src/snippet.ts +104 -0
- package/pkgs/schema/src/svg-sanitize.ts +487 -0
- package/pkgs/schema/src/theme.ts +218 -0
- package/pkgs/schema/src/typeset.ts +693 -0
- package/pkgs/schema/src/validate-ids.ts +46 -0
- package/pkgs/schema/src/viewport.ts +8 -0
- package/pkgs/shadcn-snapshot/dist/manifest.json +8109 -0
- package/pkgs/shadcn-snapshot/src/components/canvas-portal.tsx +55 -0
- package/pkgs/shadcn-snapshot/src/components/ui/accordion.tsx +122 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert-dialog.tsx +164 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +74 -0
- package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +13 -0
- package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +197 -0
- package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +100 -0
- package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +50 -0
- package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +109 -0
- package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +130 -0
- package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +82 -0
- package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +72 -0
- package/pkgs/shadcn-snapshot/src/components/ui/calendar.tsx +229 -0
- package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +92 -0
- package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +235 -0
- package/pkgs/shadcn-snapshot/src/components/ui/chart-option.ts +250 -0
- package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +177 -0
- package/pkgs/shadcn-snapshot/src/components/ui/checkbox.tsx +41 -0
- package/pkgs/shadcn-snapshot/src/components/ui/collapsible.tsx +32 -0
- package/pkgs/shadcn-snapshot/src/components/ui/combobox.tsx +196 -0
- package/pkgs/shadcn-snapshot/src/components/ui/context-menu.tsx +227 -0
- package/pkgs/shadcn-snapshot/src/components/ui/dialog.tsx +131 -0
- package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +24 -0
- package/pkgs/shadcn-snapshot/src/components/ui/drawer.tsx +112 -0
- package/pkgs/shadcn-snapshot/src/components/ui/dropdown-menu.tsx +205 -0
- package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +98 -0
- package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +228 -0
- package/pkgs/shadcn-snapshot/src/components/ui/hover-card.tsx +51 -0
- package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +148 -0
- package/pkgs/shadcn-snapshot/src/components/ui/input.tsx +43 -0
- package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +187 -0
- package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +30 -0
- package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +25 -0
- package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +71 -0
- package/pkgs/shadcn-snapshot/src/components/ui/menubar.tsx +243 -0
- package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +89 -0
- package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +60 -0
- package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +165 -0
- package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +117 -0
- package/pkgs/shadcn-snapshot/src/components/ui/popover.tsx +66 -0
- package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +35 -0
- package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +48 -0
- package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +59 -0
- package/pkgs/shadcn-snapshot/src/components/ui/select.tsx +180 -0
- package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +32 -0
- package/pkgs/shadcn-snapshot/src/components/ui/sheet.tsx +107 -0
- package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +17 -0
- package/pkgs/shadcn-snapshot/src/components/ui/slider.tsx +68 -0
- package/pkgs/shadcn-snapshot/src/components/ui/sonner.tsx +91 -0
- package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +21 -0
- package/pkgs/shadcn-snapshot/src/components/ui/switch.tsx +41 -0
- package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +93 -0
- package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +84 -0
- package/pkgs/shadcn-snapshot/src/components/ui/textarea.tsx +24 -0
- package/pkgs/shadcn-snapshot/src/components/ui/toggle-group.tsx +94 -0
- package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +50 -0
- package/pkgs/shadcn-snapshot/src/components/ui/tooltip.tsx +47 -0
- package/pkgs/shadcn-snapshot/src/examples.ts +36 -0
- package/pkgs/shadcn-snapshot/src/groups.ts +87 -0
- package/pkgs/shadcn-snapshot/src/index.ts +43 -0
- package/pkgs/shadcn-snapshot/src/lib/utils.ts +4 -0
- package/pkgs/shadcn-snapshot/src/manifest.ts +12 -0
- package/pkgs/shadcn-snapshot/src/notes.ts +97 -0
- package/pkgs/shadcn-snapshot/src/paths.ts +47 -0
- package/pkgs/shadcn-snapshot/src/registry-files.ts +293 -0
- package/pkgs/shadcn-snapshot/src/registry.ts +631 -0
- package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +632 -0
- package/pkgs/shadcn-snapshot/src/tailwind-entry.css +159 -0
- package/pkgs/shadcn-snapshot/src/version.ts +8 -0
- package/plugins/claude/velloo/.claude-plugin/plugin.json +6 -0
- package/plugins/claude/velloo/agents/velloo-design-reviewer.md +33 -0
- package/plugins/claude/velloo/agents/velloo-designer.md +39 -0
- package/plugins/claude/velloo/commands/design.md +11 -0
- package/plugins/claude/velloo/commands/implement.md +10 -0
- package/plugins/claude/velloo/commands/review.md +8 -0
- package/plugins/gemini/GEMINI.md +31 -0
- package/plugins/gemini/commands/velloo/design.toml +10 -0
- package/plugins/gemini/commands/velloo/implement.toml +9 -0
- package/plugins/gemini/gemini-extension.json +9 -0
- package/skills/velloo-brand/SKILL.md +124 -0
- package/skills/velloo-design/SKILL.md +144 -0
- package/skills/velloo-design-system/SKILL.md +90 -0
- package/skills/velloo-implement/SKILL.md +101 -0
- package/skills/velloo-logo/SKILL.md +93 -0
- package/skills/velloo-setup/SKILL.md +156 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/select).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: see ../canvas-portal.tsx. Select is the most divergent shim.
|
|
4
|
+
// Radix drives the trigger label and the item check mark through a context
|
|
5
|
+
// that Portal/Content set up, so once the popup renders inline that channel is
|
|
6
|
+
// dead — the label is authored on `SelectValue` and the check on `SelectItem`'s
|
|
7
|
+
// `selected`, which also puts both under inspector control. Classes track
|
|
8
|
+
// upstream minus the ones keyed to Radix's runtime vars
|
|
9
|
+
// (`--radix-select-*`) or to the open animation, which would fire on every
|
|
10
|
+
// render and leave screenshots catching a mid-transition frame.
|
|
11
|
+
"use client";
|
|
12
|
+
|
|
13
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|
14
|
+
import { Select as SelectPrimitive } from "radix-ui";
|
|
15
|
+
import type * as React from "react";
|
|
16
|
+
import { cn } from "../../lib/utils.ts";
|
|
17
|
+
import { inlineOpenAttrs, pinOpenInDesignMode } from "../canvas-portal.tsx";
|
|
18
|
+
|
|
19
|
+
const SCROLL_BUTTON =
|
|
20
|
+
"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4";
|
|
21
|
+
|
|
22
|
+
export function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
|
23
|
+
return <SelectPrimitive.Root data-slot="select" {...pinOpenInDesignMode(props)} />;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A plain button, not `SelectPrimitive.Trigger`: the rest of this file already
|
|
28
|
+
* bypasses Radix (Content, Item and Value are inline elements), so the root's
|
|
29
|
+
* context has nothing left to give a trigger — while Radix's own trigger
|
|
30
|
+
* *throws* when it can't find that context. Designs compose nodes freely, so a
|
|
31
|
+
* trigger sitting on its own under a Box is a shape the canvas has to render,
|
|
32
|
+
* not a crash that takes the whole screen down with it.
|
|
33
|
+
*/
|
|
34
|
+
export function SelectTrigger({
|
|
35
|
+
className,
|
|
36
|
+
size = "default",
|
|
37
|
+
children,
|
|
38
|
+
...props
|
|
39
|
+
}: React.ComponentProps<"button"> & {
|
|
40
|
+
size?: "sm" | "default";
|
|
41
|
+
}) {
|
|
42
|
+
return (
|
|
43
|
+
<button
|
|
44
|
+
type="button"
|
|
45
|
+
data-slot="select-trigger"
|
|
46
|
+
data-size={size}
|
|
47
|
+
className={cn(
|
|
48
|
+
"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
<ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
|
|
55
|
+
</button>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Static value display. Radix reads the label off the selected item, which
|
|
61
|
+
* only exists inside the portal it owns; design mode renders whatever the
|
|
62
|
+
* user typed so the trigger reads "Pro plan" next to the chevron. Pass
|
|
63
|
+
* `placeholder` alone for the empty state — it takes upstream's muted styling
|
|
64
|
+
* here rather than through the trigger's `data-placeholder`.
|
|
65
|
+
*/
|
|
66
|
+
export function SelectValue({
|
|
67
|
+
className,
|
|
68
|
+
placeholder,
|
|
69
|
+
children,
|
|
70
|
+
...props
|
|
71
|
+
}: React.ComponentProps<"span"> & { placeholder?: string }) {
|
|
72
|
+
return (
|
|
73
|
+
<span
|
|
74
|
+
data-slot="select-value"
|
|
75
|
+
className={children === undefined ? cn("text-muted-foreground", className) : className}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
{children ?? placeholder ?? ""}
|
|
79
|
+
</span>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function SelectContent({
|
|
84
|
+
className,
|
|
85
|
+
position: _position,
|
|
86
|
+
align: _align,
|
|
87
|
+
side: _side,
|
|
88
|
+
sideOffset: _sideOffset,
|
|
89
|
+
collisionPadding: _collisionPadding,
|
|
90
|
+
...props
|
|
91
|
+
}: React.ComponentProps<"div"> & {
|
|
92
|
+
position?: "popper" | "item-aligned";
|
|
93
|
+
align?: string;
|
|
94
|
+
side?: string;
|
|
95
|
+
sideOffset?: number;
|
|
96
|
+
collisionPadding?: number;
|
|
97
|
+
}) {
|
|
98
|
+
return (
|
|
99
|
+
<div
|
|
100
|
+
data-slot="select-content"
|
|
101
|
+
{...inlineOpenAttrs()}
|
|
102
|
+
className={cn(
|
|
103
|
+
"cn-menu-target cn-menu-translucent relative z-50 min-w-36 overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10",
|
|
104
|
+
className,
|
|
105
|
+
)}
|
|
106
|
+
{...props}
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function SelectGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
112
|
+
return <div data-slot="select-group" className={cn("scroll-my-1 p-1", className)} {...props} />;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function SelectLabel({ className, ...props }: React.ComponentProps<"div">) {
|
|
116
|
+
return (
|
|
117
|
+
<div
|
|
118
|
+
data-slot="select-label"
|
|
119
|
+
className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
|
|
120
|
+
{...props}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function SelectItem({
|
|
126
|
+
className,
|
|
127
|
+
children,
|
|
128
|
+
value,
|
|
129
|
+
selected,
|
|
130
|
+
...props
|
|
131
|
+
}: React.ComponentProps<"div"> & { value?: string; selected?: boolean }) {
|
|
132
|
+
return (
|
|
133
|
+
<div
|
|
134
|
+
data-slot="select-item"
|
|
135
|
+
data-value={value}
|
|
136
|
+
data-state={selected ? "checked" : "unchecked"}
|
|
137
|
+
className={cn(
|
|
138
|
+
"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
139
|
+
className,
|
|
140
|
+
)}
|
|
141
|
+
{...props}
|
|
142
|
+
>
|
|
143
|
+
<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
|
|
144
|
+
{selected ? <CheckIcon className="pointer-events-none" /> : null}
|
|
145
|
+
</span>
|
|
146
|
+
<span>{children}</span>
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function SelectSeparator({ className, ...props }: React.ComponentProps<"div">) {
|
|
152
|
+
return (
|
|
153
|
+
<div
|
|
154
|
+
data-slot="select-separator"
|
|
155
|
+
className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
|
|
156
|
+
{...props}
|
|
157
|
+
/>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Upstream renders both scroll buttons inside Content and lets Radix hide them
|
|
163
|
+
* until the list actually overflows. A static render can't measure that, so
|
|
164
|
+
* they stay opt-in children rather than always-on chrome.
|
|
165
|
+
*/
|
|
166
|
+
export function SelectScrollUpButton({ className, ...props }: React.ComponentProps<"div">) {
|
|
167
|
+
return (
|
|
168
|
+
<div data-slot="select-scroll-up-button" className={cn(SCROLL_BUTTON, className)} {...props}>
|
|
169
|
+
<ChevronUpIcon />
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function SelectScrollDownButton({ className, ...props }: React.ComponentProps<"div">) {
|
|
175
|
+
return (
|
|
176
|
+
<div data-slot="select-scroll-down-button" className={cn(SCROLL_BUTTON, className)} {...props}>
|
|
177
|
+
<ChevronDownIcon />
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/separator).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Regenerate with `bun run vendor` — do not hand-edit unless you are adding a
|
|
4
|
+
// canvas adaptation, in which case add the id to vendor.ts's ADAPTED set.
|
|
5
|
+
"use client";
|
|
6
|
+
|
|
7
|
+
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
8
|
+
import type * as React from "react";
|
|
9
|
+
|
|
10
|
+
import { cn } from "../../lib/utils.ts";
|
|
11
|
+
|
|
12
|
+
function Separator({
|
|
13
|
+
className,
|
|
14
|
+
orientation = "horizontal",
|
|
15
|
+
decorative = true,
|
|
16
|
+
...props
|
|
17
|
+
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
|
|
18
|
+
return (
|
|
19
|
+
<SeparatorPrimitive.Root
|
|
20
|
+
data-slot="separator"
|
|
21
|
+
decorative={decorative}
|
|
22
|
+
orientation={orientation}
|
|
23
|
+
className={cn(
|
|
24
|
+
"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { Separator };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/sheet).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: see ../canvas-portal.tsx. Content is a plain panel in the page
|
|
4
|
+
// flow, so upstream's viewport-edge anchoring goes away while `data-side` keeps
|
|
5
|
+
// driving the per-side size and border — a fixed panel would pin itself to the
|
|
6
|
+
// canvas viewport instead of the frame it belongs to. The close button is a
|
|
7
|
+
// plain Button rather than Radix Close, so a Content placed on the canvas
|
|
8
|
+
// without its Root still renders. Classes track upstream minus the slide/fade
|
|
9
|
+
// transitions: we pin `data-state="open"`, so those would replay on every
|
|
10
|
+
// render and screenshots would catch a mid-transition frame.
|
|
11
|
+
"use client";
|
|
12
|
+
|
|
13
|
+
import { XIcon } from "lucide-react";
|
|
14
|
+
import { Dialog as SheetPrimitive } from "radix-ui";
|
|
15
|
+
import type * as React from "react";
|
|
16
|
+
import { cn } from "../../lib/utils.ts";
|
|
17
|
+
import { inlineOpenAttrs, pinOpenInDesignMode } from "../canvas-portal.tsx";
|
|
18
|
+
import { Button } from "./button.tsx";
|
|
19
|
+
|
|
20
|
+
export function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
|
|
21
|
+
return <SheetPrimitive.Root data-slot="sheet" {...pinOpenInDesignMode(props)} />;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function SheetTrigger({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
|
|
25
|
+
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.Close>) {
|
|
29
|
+
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function SheetContent({
|
|
33
|
+
className,
|
|
34
|
+
children,
|
|
35
|
+
side = "right",
|
|
36
|
+
showCloseButton = true,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<"div"> & {
|
|
39
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
40
|
+
showCloseButton?: boolean;
|
|
41
|
+
}) {
|
|
42
|
+
return (
|
|
43
|
+
<div
|
|
44
|
+
data-slot="sheet-content"
|
|
45
|
+
data-side={side}
|
|
46
|
+
{...inlineOpenAttrs()}
|
|
47
|
+
className={cn(
|
|
48
|
+
"relative z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
{showCloseButton && (
|
|
55
|
+
<Button
|
|
56
|
+
data-slot="sheet-close"
|
|
57
|
+
variant="ghost"
|
|
58
|
+
className="absolute top-3 right-3"
|
|
59
|
+
size="icon-sm"
|
|
60
|
+
>
|
|
61
|
+
<XIcon />
|
|
62
|
+
<span className="sr-only">Close</span>
|
|
63
|
+
</Button>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
70
|
+
return (
|
|
71
|
+
<div
|
|
72
|
+
data-slot="sheet-header"
|
|
73
|
+
className={cn("flex flex-col gap-0.5 p-4", className)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
80
|
+
return (
|
|
81
|
+
<div
|
|
82
|
+
data-slot="sheet-footer"
|
|
83
|
+
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function SheetTitle({ className, ...props }: React.ComponentProps<"h2">) {
|
|
90
|
+
return (
|
|
91
|
+
<h2
|
|
92
|
+
data-slot="sheet-title"
|
|
93
|
+
className={cn("cn-font-heading text-base font-medium text-foreground", className)}
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function SheetDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
100
|
+
return (
|
|
101
|
+
<p
|
|
102
|
+
data-slot="sheet-description"
|
|
103
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
104
|
+
{...props}
|
|
105
|
+
/>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/skeleton).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Regenerate with `bun run vendor` — do not hand-edit unless you are adding a
|
|
4
|
+
// canvas adaptation, in which case add the id to vendor.ts's ADAPTED set.
|
|
5
|
+
import { cn } from "../../lib/utils.ts";
|
|
6
|
+
|
|
7
|
+
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
|
|
8
|
+
return (
|
|
9
|
+
<div
|
|
10
|
+
data-slot="skeleton"
|
|
11
|
+
className={cn("animate-pulse rounded-md bg-muted", className)}
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { Skeleton };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/slider).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: a design ships `value` to position the thumb, with no handler
|
|
4
|
+
// because nothing on the canvas is interactive. Radix would pin the thumb and
|
|
5
|
+
// React would warn about the missing handler, so a handlerless `value` becomes
|
|
6
|
+
// `defaultValue`.
|
|
7
|
+
"use client";
|
|
8
|
+
|
|
9
|
+
import { Slider as SliderPrimitive } from "radix-ui";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
|
|
12
|
+
import { cn } from "../../lib/utils.ts";
|
|
13
|
+
|
|
14
|
+
export function Slider({
|
|
15
|
+
className,
|
|
16
|
+
defaultValue,
|
|
17
|
+
value,
|
|
18
|
+
min = 0,
|
|
19
|
+
max = 100,
|
|
20
|
+
...props
|
|
21
|
+
}: React.ComponentProps<typeof SliderPrimitive.Root>) {
|
|
22
|
+
const isStaticControlled = value !== undefined && props.onValueChange === undefined;
|
|
23
|
+
// Only the keys that are actually set — an explicit `value: undefined` reads
|
|
24
|
+
// to Radix as a controlled slider with no value, which is not what "unset"
|
|
25
|
+
// means.
|
|
26
|
+
const resolved: { value?: typeof value; defaultValue?: typeof defaultValue } = isStaticControlled
|
|
27
|
+
? { defaultValue: value }
|
|
28
|
+
: {
|
|
29
|
+
...(value === undefined ? {} : { value }),
|
|
30
|
+
...(defaultValue === undefined ? {} : { defaultValue }),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const _values = React.useMemo(
|
|
34
|
+
() => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]),
|
|
35
|
+
[value, defaultValue, min, max],
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<SliderPrimitive.Root
|
|
40
|
+
data-slot="slider"
|
|
41
|
+
{...resolved}
|
|
42
|
+
min={min}
|
|
43
|
+
max={max}
|
|
44
|
+
className={cn(
|
|
45
|
+
"relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col",
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
<SliderPrimitive.Track
|
|
51
|
+
data-slot="slider-track"
|
|
52
|
+
className="relative grow overflow-hidden rounded-full bg-muted data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1"
|
|
53
|
+
>
|
|
54
|
+
<SliderPrimitive.Range
|
|
55
|
+
data-slot="slider-range"
|
|
56
|
+
className="absolute bg-primary select-none data-horizontal:h-full data-vertical:w-full"
|
|
57
|
+
/>
|
|
58
|
+
</SliderPrimitive.Track>
|
|
59
|
+
{Array.from({ length: _values.length }, (_, index) => (
|
|
60
|
+
<SliderPrimitive.Thumb
|
|
61
|
+
data-slot="slider-thumb"
|
|
62
|
+
key={index}
|
|
63
|
+
className="relative block size-3 shrink-0 rounded-full border border-ring bg-white ring-ring/50 transition-[color,box-shadow] select-none after:absolute after:-inset-2 hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3 disabled:pointer-events-none disabled:opacity-50"
|
|
64
|
+
/>
|
|
65
|
+
))}
|
|
66
|
+
</SliderPrimitive.Root>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/sonner).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
//
|
|
4
|
+
// Canvas-safe: real apps render sonner's <Toaster />, which mounts an
|
|
5
|
+
// imperative queue plus a portal at the document root. Nothing calls toast()
|
|
6
|
+
// in design mode, so that queue only ever paints an empty region — we render a
|
|
7
|
+
// single sample toast pinned to the configured corner instead, so a user who
|
|
8
|
+
// drops a <Toaster /> onto a screen sees what it will look like at runtime.
|
|
9
|
+
// Upstream reads next-themes to hand sonner a theme; the canvas is already
|
|
10
|
+
// themed by the design folder's tokens, so the sample is painted from the same
|
|
11
|
+
// CSS vars upstream passes down rather than taking that dependency.
|
|
12
|
+
"use client";
|
|
13
|
+
|
|
14
|
+
import { CircleCheckIcon } from "lucide-react";
|
|
15
|
+
import type * as React from "react";
|
|
16
|
+
import { cn } from "../../lib/utils.ts";
|
|
17
|
+
|
|
18
|
+
export interface ToasterProps extends React.ComponentProps<"div"> {
|
|
19
|
+
position?:
|
|
20
|
+
| "top-left"
|
|
21
|
+
| "top-center"
|
|
22
|
+
| "top-right"
|
|
23
|
+
| "bottom-left"
|
|
24
|
+
| "bottom-center"
|
|
25
|
+
| "bottom-right";
|
|
26
|
+
richColors?: boolean;
|
|
27
|
+
expand?: boolean;
|
|
28
|
+
closeButton?: boolean;
|
|
29
|
+
theme?: "light" | "dark" | "system";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const POSITION_CLASS: Record<NonNullable<ToasterProps["position"]>, string> = {
|
|
33
|
+
"top-left": "top-4 left-4 items-start",
|
|
34
|
+
"top-center": "top-4 left-1/2 -translate-x-1/2 items-center",
|
|
35
|
+
"top-right": "top-4 right-4 items-end",
|
|
36
|
+
"bottom-left": "bottom-4 left-4 items-start",
|
|
37
|
+
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2 items-center",
|
|
38
|
+
"bottom-right": "bottom-4 right-4 items-end",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const TOAST_VARS = {
|
|
42
|
+
"--normal-bg": "var(--popover)",
|
|
43
|
+
"--normal-text": "var(--popover-foreground)",
|
|
44
|
+
"--normal-border": "var(--border)",
|
|
45
|
+
"--border-radius": "var(--radius)",
|
|
46
|
+
} as React.CSSProperties;
|
|
47
|
+
|
|
48
|
+
const TOAST_STYLE = {
|
|
49
|
+
background: "var(--normal-bg)",
|
|
50
|
+
color: "var(--normal-text)",
|
|
51
|
+
borderColor: "var(--normal-border)",
|
|
52
|
+
borderRadius: "var(--border-radius)",
|
|
53
|
+
} as React.CSSProperties;
|
|
54
|
+
|
|
55
|
+
export function Toaster({
|
|
56
|
+
className,
|
|
57
|
+
style,
|
|
58
|
+
position = "bottom-right",
|
|
59
|
+
richColors: _richColors,
|
|
60
|
+
expand: _expand,
|
|
61
|
+
closeButton: _closeButton,
|
|
62
|
+
theme: _theme,
|
|
63
|
+
...props
|
|
64
|
+
}: ToasterProps) {
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
data-slot="sonner-toaster"
|
|
68
|
+
data-velloo-inline="true"
|
|
69
|
+
className={cn(
|
|
70
|
+
"pointer-events-none fixed z-50 flex flex-col gap-2",
|
|
71
|
+
POSITION_CLASS[position],
|
|
72
|
+
className,
|
|
73
|
+
)}
|
|
74
|
+
style={{ ...TOAST_VARS, ...style }}
|
|
75
|
+
{...props}
|
|
76
|
+
>
|
|
77
|
+
<div
|
|
78
|
+
data-slot="sonner-toast"
|
|
79
|
+
data-state="open"
|
|
80
|
+
className="pointer-events-auto flex w-80 max-w-[calc(100vw-2rem)] items-start gap-2 border p-4 text-sm shadow-lg"
|
|
81
|
+
style={TOAST_STYLE}
|
|
82
|
+
>
|
|
83
|
+
<CircleCheckIcon className="mt-0.5 size-4 shrink-0" aria-hidden="true" />
|
|
84
|
+
<div className="flex-1">
|
|
85
|
+
<div className="font-medium">Toast</div>
|
|
86
|
+
<div className="text-muted-foreground">Sample toast preview.</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/spinner).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Regenerate with `bun run vendor` — do not hand-edit unless you are adding a
|
|
4
|
+
// canvas adaptation, in which case add the id to vendor.ts's ADAPTED set.
|
|
5
|
+
|
|
6
|
+
import { Loader2Icon } from "lucide-react";
|
|
7
|
+
import { cn } from "../../lib/utils.ts";
|
|
8
|
+
|
|
9
|
+
function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
|
|
10
|
+
return (
|
|
11
|
+
<Loader2Icon
|
|
12
|
+
data-slot="spinner"
|
|
13
|
+
role="status"
|
|
14
|
+
aria-label="Loading"
|
|
15
|
+
className={cn("size-4 animate-spin", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { Spinner };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/switch).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: same contract as Checkbox — a design ships `checked` to show an
|
|
4
|
+
// on state with no handler to change it, so it becomes `defaultChecked` rather
|
|
5
|
+
// than a controlled switch React warns about.
|
|
6
|
+
"use client";
|
|
7
|
+
|
|
8
|
+
import { Switch as SwitchPrimitive } from "radix-ui";
|
|
9
|
+
import type * as React from "react";
|
|
10
|
+
|
|
11
|
+
import { cn } from "../../lib/utils.ts";
|
|
12
|
+
|
|
13
|
+
export function Switch({
|
|
14
|
+
className,
|
|
15
|
+
size = "default",
|
|
16
|
+
...props
|
|
17
|
+
}: React.ComponentProps<typeof SwitchPrimitive.Root> & {
|
|
18
|
+
size?: "sm" | "default";
|
|
19
|
+
}) {
|
|
20
|
+
const { checked, ...rest } = props;
|
|
21
|
+
const isStaticControlled = checked !== undefined && props.onCheckedChange === undefined;
|
|
22
|
+
// Drop `checked` by omitting it, not by setting it to undefined: Radix reads
|
|
23
|
+
// "present but undefined" as a controlled component with no value.
|
|
24
|
+
const finalProps = isStaticControlled ? { ...rest, defaultChecked: checked } : props;
|
|
25
|
+
return (
|
|
26
|
+
<SwitchPrimitive.Root
|
|
27
|
+
data-slot="switch"
|
|
28
|
+
data-size={size}
|
|
29
|
+
className={cn(
|
|
30
|
+
"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
31
|
+
className,
|
|
32
|
+
)}
|
|
33
|
+
{...finalProps}
|
|
34
|
+
>
|
|
35
|
+
<SwitchPrimitive.Thumb
|
|
36
|
+
data-slot="switch-thumb"
|
|
37
|
+
className="pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"
|
|
38
|
+
/>
|
|
39
|
+
</SwitchPrimitive.Root>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/table).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Regenerate with `bun run vendor` — do not hand-edit unless you are adding a
|
|
4
|
+
// canvas adaptation, in which case add the id to vendor.ts's ADAPTED set.
|
|
5
|
+
"use client";
|
|
6
|
+
|
|
7
|
+
import type * as React from "react";
|
|
8
|
+
|
|
9
|
+
import { cn } from "../../lib/utils.ts";
|
|
10
|
+
|
|
11
|
+
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
12
|
+
return (
|
|
13
|
+
<div data-slot="table-container" className="relative w-full overflow-x-auto">
|
|
14
|
+
<table
|
|
15
|
+
data-slot="table"
|
|
16
|
+
className={cn("w-full caption-bottom text-sm", className)}
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
|
|
24
|
+
return <thead data-slot="table-header" className={cn("[&_tr]:border-b", className)} {...props} />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
28
|
+
return (
|
|
29
|
+
<tbody
|
|
30
|
+
data-slot="table-body"
|
|
31
|
+
className={cn("[&_tr:last-child]:border-0", className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
38
|
+
return (
|
|
39
|
+
<tfoot
|
|
40
|
+
data-slot="table-footer"
|
|
41
|
+
className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
48
|
+
return (
|
|
49
|
+
<tr
|
|
50
|
+
data-slot="table-row"
|
|
51
|
+
className={cn(
|
|
52
|
+
"border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
|
|
53
|
+
className,
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
61
|
+
return (
|
|
62
|
+
<th
|
|
63
|
+
data-slot="table-head"
|
|
64
|
+
className={cn(
|
|
65
|
+
"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
|
|
66
|
+
className,
|
|
67
|
+
)}
|
|
68
|
+
{...props}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
74
|
+
return (
|
|
75
|
+
<td
|
|
76
|
+
data-slot="table-cell"
|
|
77
|
+
className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)}
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
|
|
84
|
+
return (
|
|
85
|
+
<caption
|
|
86
|
+
data-slot="table-caption"
|
|
87
|
+
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
|