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,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canvas-safe portal contract — the heart of the adapter pattern.
|
|
3
|
+
*
|
|
4
|
+
* Radix primitives portal their "open" content to `document.body` so it
|
|
5
|
+
* stacks above page chrome. Inside Velloo's canvas iframes, a portal to
|
|
6
|
+
* the body is invisible (the iframe's body has nothing for the design
|
|
7
|
+
* to attach to), and any styling pinned to a transformed ancestor breaks
|
|
8
|
+
* the math.
|
|
9
|
+
*
|
|
10
|
+
* The Velloo contract: render the content **inline** under the
|
|
11
|
+
* component itself, never through a portal. We don't actually want users
|
|
12
|
+
* clicking the dropdown shut in design mode — they want to see the
|
|
13
|
+
* styled state at all times. So:
|
|
14
|
+
*
|
|
15
|
+
* <Dialog>
|
|
16
|
+
* <DialogTrigger>Open</DialogTrigger>
|
|
17
|
+
* <DialogContent>...</DialogContent> ← rendered inline, always visible
|
|
18
|
+
* </Dialog>
|
|
19
|
+
*
|
|
20
|
+
* Implementation:
|
|
21
|
+
*
|
|
22
|
+
* 1. The Velloo Root for each Radix-shaped component forces
|
|
23
|
+
* `open={true}` / `defaultOpen={true}` in design mode so Radix
|
|
24
|
+
* mounts Content (otherwise Content is conditional on open state).
|
|
25
|
+
* 2. The Velloo `Content` ditches Radix's `Portal` wrapper — it
|
|
26
|
+
* renders the styled card with the same data-slot attribute that
|
|
27
|
+
* shadcn ships, so user-app CSS still targets it normally.
|
|
28
|
+
*
|
|
29
|
+
* The user's real app imports unmodified shadcn from their own
|
|
30
|
+
* `components/ui/<name>.tsx` (fetched at `velloo init` from upstream)
|
|
31
|
+
* and gets the actual modal behavior. The canvas-only adapter is what
|
|
32
|
+
* lets the *canvas* render those modals inline.
|
|
33
|
+
*
|
|
34
|
+
* The snapshot stays design-mode only; the upstream provider + adapter
|
|
35
|
+
* layer drive real app behavior.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Decide whether a Radix root should pin `open=true` in design mode.
|
|
39
|
+
* If the consumer explicitly set `open` or `defaultOpen`, respect it.
|
|
40
|
+
* Otherwise pin open so Content renders.
|
|
41
|
+
*/
|
|
42
|
+
export function pinOpenInDesignMode<Props extends { open?: boolean; defaultOpen?: boolean }>(
|
|
43
|
+
props: Props,
|
|
44
|
+
): Props {
|
|
45
|
+
if (props.open !== undefined || props.defaultOpen !== undefined) return props;
|
|
46
|
+
return { ...props, open: true };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Helper: spread the relevant `data-state` / aria attributes onto an
|
|
51
|
+
* inline-rendered Content so user-app shadcn CSS still styles it.
|
|
52
|
+
*/
|
|
53
|
+
export function inlineOpenAttrs(): { "data-state": "open"; "data-velloo-inline": "true" } {
|
|
54
|
+
return { "data-state": "open", "data-velloo-inline": "true" };
|
|
55
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/accordion).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: an accordion with no `value`/`defaultValue` opens itself, so a
|
|
4
|
+
// design that never receives a click still shows its content styling. Designs
|
|
5
|
+
// that set either prop keep their explicit state.
|
|
6
|
+
"use client";
|
|
7
|
+
|
|
8
|
+
import { ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|
9
|
+
import { Accordion as AccordionPrimitive } from "radix-ui";
|
|
10
|
+
import type * as React from "react";
|
|
11
|
+
import { Children, isValidElement, type ReactNode } from "react";
|
|
12
|
+
|
|
13
|
+
import { cn } from "../../lib/utils.ts";
|
|
14
|
+
|
|
15
|
+
function itemValues(children: ReactNode): string[] {
|
|
16
|
+
const values: string[] = [];
|
|
17
|
+
for (const child of Children.toArray(children)) {
|
|
18
|
+
if (!isValidElement<{ value?: unknown }>(child)) continue;
|
|
19
|
+
const { value } = child.props;
|
|
20
|
+
if (typeof value === "string") values.push(value);
|
|
21
|
+
}
|
|
22
|
+
return values;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Radix's `type: "single" | "multiple"` discriminates the whole props union —
|
|
27
|
+
* `value` changes shape with it — which is user-hostile to thread through MCP.
|
|
28
|
+
* The wrapper takes a permissive passthrough instead: a design-mode accordion
|
|
29
|
+
* only has to render.
|
|
30
|
+
*/
|
|
31
|
+
// biome-ignore lint/suspicious/noExplicitAny: discriminated radix props are user-hostile in design mode
|
|
32
|
+
export function Accordion({ className, type, ...props }: any) {
|
|
33
|
+
const classes = cn("flex w-full flex-col", className);
|
|
34
|
+
const resolvedType = type === "multiple" ? "multiple" : "single";
|
|
35
|
+
|
|
36
|
+
// Nothing on the canvas is clickable, so an accordion left in its initial
|
|
37
|
+
// state would show every item collapsed and none of the content styling. Open
|
|
38
|
+
// what the type allows — every item when multiple, the first when single.
|
|
39
|
+
const values = props.value || props.defaultValue ? undefined : itemValues(props.children);
|
|
40
|
+
const defaultValue =
|
|
41
|
+
values === undefined || values.length === 0
|
|
42
|
+
? undefined
|
|
43
|
+
: resolvedType === "multiple"
|
|
44
|
+
? values
|
|
45
|
+
: values[0];
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<AccordionPrimitive.Root
|
|
49
|
+
type={resolvedType}
|
|
50
|
+
{...(resolvedType === "single" ? { collapsible: true } : {})}
|
|
51
|
+
data-slot="accordion"
|
|
52
|
+
className={classes}
|
|
53
|
+
{...props}
|
|
54
|
+
{...(defaultValue === undefined ? {} : { defaultValue })}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function AccordionItem({
|
|
60
|
+
className,
|
|
61
|
+
...props
|
|
62
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Item>) {
|
|
63
|
+
return (
|
|
64
|
+
<AccordionPrimitive.Item
|
|
65
|
+
data-slot="accordion-item"
|
|
66
|
+
className={cn("not-last:border-b", className)}
|
|
67
|
+
{...props}
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function AccordionTrigger({
|
|
73
|
+
className,
|
|
74
|
+
children,
|
|
75
|
+
...props
|
|
76
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
|
|
77
|
+
return (
|
|
78
|
+
<AccordionPrimitive.Header className="flex">
|
|
79
|
+
<AccordionPrimitive.Trigger
|
|
80
|
+
data-slot="accordion-trigger"
|
|
81
|
+
className={cn(
|
|
82
|
+
"group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
|
|
83
|
+
className,
|
|
84
|
+
)}
|
|
85
|
+
{...props}
|
|
86
|
+
>
|
|
87
|
+
{children}
|
|
88
|
+
<ChevronDownIcon
|
|
89
|
+
data-slot="accordion-trigger-icon"
|
|
90
|
+
className="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
|
|
91
|
+
/>
|
|
92
|
+
<ChevronUpIcon
|
|
93
|
+
data-slot="accordion-trigger-icon"
|
|
94
|
+
className="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
|
|
95
|
+
/>
|
|
96
|
+
</AccordionPrimitive.Trigger>
|
|
97
|
+
</AccordionPrimitive.Header>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function AccordionContent({
|
|
102
|
+
className,
|
|
103
|
+
children,
|
|
104
|
+
...props
|
|
105
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Content>) {
|
|
106
|
+
return (
|
|
107
|
+
<AccordionPrimitive.Content
|
|
108
|
+
data-slot="accordion-content"
|
|
109
|
+
className="overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
|
|
110
|
+
{...props}
|
|
111
|
+
>
|
|
112
|
+
<div
|
|
113
|
+
className={cn(
|
|
114
|
+
"h-(--radix-accordion-content-height) pt-0 pb-2.5 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
|
|
115
|
+
className,
|
|
116
|
+
)}
|
|
117
|
+
>
|
|
118
|
+
{children}
|
|
119
|
+
</div>
|
|
120
|
+
</AccordionPrimitive.Content>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/alert-dialog).
|
|
2
|
+
// Snapshot version: see packages/shadcn-snapshot/package.json#snapshotVersion.
|
|
3
|
+
// Canvas-safe: see ../canvas-portal.tsx. Content is a plain card in the page
|
|
4
|
+
// flow — not a portaled, viewport-centered layer — and it doesn't pull the
|
|
5
|
+
// Overlay in with it, because a full-bleed backdrop would dim the whole design
|
|
6
|
+
// surface. Action/Cancel render the Button directly instead of wrapping a Radix
|
|
7
|
+
// primitive, so a Content placed on the canvas without its Root still renders.
|
|
8
|
+
// Classes track upstream minus the open/close animations: we pin
|
|
9
|
+
// `data-state="open"`, so those would replay on every render and screenshots
|
|
10
|
+
// would catch a mid-transition frame.
|
|
11
|
+
"use client";
|
|
12
|
+
|
|
13
|
+
import { AlertDialog as AlertDialogPrimitive } from "radix-ui";
|
|
14
|
+
import type * as React from "react";
|
|
15
|
+
import { cn } from "../../lib/utils.ts";
|
|
16
|
+
import { inlineOpenAttrs, pinOpenInDesignMode } from "../canvas-portal.tsx";
|
|
17
|
+
import { Button } from "./button.tsx";
|
|
18
|
+
|
|
19
|
+
export function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
|
|
20
|
+
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...pinOpenInDesignMode(props)} />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function AlertDialogTrigger({
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
|
|
26
|
+
return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Upstream's Portal, neutralized: children render where they sit. */
|
|
30
|
+
export function AlertDialogPortal({ children }: React.ComponentProps<"div">) {
|
|
31
|
+
return <>{children}</>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function AlertDialogOverlay({ className, ...props }: React.ComponentProps<"div">) {
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
data-slot="alert-dialog-overlay"
|
|
38
|
+
{...inlineOpenAttrs()}
|
|
39
|
+
className={cn(
|
|
40
|
+
"fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs",
|
|
41
|
+
className,
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function AlertDialogContent({
|
|
49
|
+
className,
|
|
50
|
+
size = "default",
|
|
51
|
+
...props
|
|
52
|
+
}: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
data-slot="alert-dialog-content"
|
|
56
|
+
data-size={size}
|
|
57
|
+
{...inlineOpenAttrs()}
|
|
58
|
+
className={cn(
|
|
59
|
+
"group/alert-dialog-content z-50 grid w-full gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm",
|
|
60
|
+
className,
|
|
61
|
+
)}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
data-slot="alert-dialog-header"
|
|
71
|
+
className={cn(
|
|
72
|
+
"grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
|
|
73
|
+
className,
|
|
74
|
+
)}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
81
|
+
return (
|
|
82
|
+
<div
|
|
83
|
+
data-slot="alert-dialog-footer"
|
|
84
|
+
className={cn(
|
|
85
|
+
"-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
|
|
86
|
+
className,
|
|
87
|
+
)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">) {
|
|
94
|
+
return (
|
|
95
|
+
<div
|
|
96
|
+
data-slot="alert-dialog-media"
|
|
97
|
+
className={cn(
|
|
98
|
+
"mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6",
|
|
99
|
+
className,
|
|
100
|
+
)}
|
|
101
|
+
{...props}
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function AlertDialogTitle({ className, ...props }: React.ComponentProps<"h2">) {
|
|
107
|
+
return (
|
|
108
|
+
<h2
|
|
109
|
+
data-slot="alert-dialog-title"
|
|
110
|
+
className={cn(
|
|
111
|
+
"cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
|
|
112
|
+
className,
|
|
113
|
+
)}
|
|
114
|
+
{...props}
|
|
115
|
+
/>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function AlertDialogDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
120
|
+
return (
|
|
121
|
+
<p
|
|
122
|
+
data-slot="alert-dialog-description"
|
|
123
|
+
className={cn(
|
|
124
|
+
"text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
|
|
125
|
+
className,
|
|
126
|
+
)}
|
|
127
|
+
{...props}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function AlertDialogAction({
|
|
133
|
+
className,
|
|
134
|
+
variant = "default",
|
|
135
|
+
size = "default",
|
|
136
|
+
...props
|
|
137
|
+
}: React.ComponentProps<"button"> & Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
|
|
138
|
+
return (
|
|
139
|
+
<Button
|
|
140
|
+
data-slot="alert-dialog-action"
|
|
141
|
+
variant={variant}
|
|
142
|
+
size={size}
|
|
143
|
+
className={cn(className)}
|
|
144
|
+
{...props}
|
|
145
|
+
/>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function AlertDialogCancel({
|
|
150
|
+
className,
|
|
151
|
+
variant = "outline",
|
|
152
|
+
size = "default",
|
|
153
|
+
...props
|
|
154
|
+
}: React.ComponentProps<"button"> & Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
|
|
155
|
+
return (
|
|
156
|
+
<Button
|
|
157
|
+
data-slot="alert-dialog-cancel"
|
|
158
|
+
variant={variant}
|
|
159
|
+
size={size}
|
|
160
|
+
className={cn(className)}
|
|
161
|
+
{...props}
|
|
162
|
+
/>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/alert).
|
|
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 { cva, type VariantProps } from "class-variance-authority";
|
|
7
|
+
import type * as React from "react";
|
|
8
|
+
|
|
9
|
+
import { cn } from "../../lib/utils.ts";
|
|
10
|
+
|
|
11
|
+
const alertVariants = cva(
|
|
12
|
+
"group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
|
|
13
|
+
{
|
|
14
|
+
variants: {
|
|
15
|
+
variant: {
|
|
16
|
+
default: "bg-card text-card-foreground",
|
|
17
|
+
destructive:
|
|
18
|
+
"bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
variant: "default",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
function Alert({
|
|
28
|
+
className,
|
|
29
|
+
variant,
|
|
30
|
+
...props
|
|
31
|
+
}: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
data-slot="alert"
|
|
35
|
+
role="alert"
|
|
36
|
+
className={cn(alertVariants({ variant }), className)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
43
|
+
return (
|
|
44
|
+
<div
|
|
45
|
+
data-slot="alert-title"
|
|
46
|
+
className={cn(
|
|
47
|
+
"font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
|
|
48
|
+
className,
|
|
49
|
+
)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function AlertDescription({ className, ...props }: React.ComponentProps<"div">) {
|
|
56
|
+
return (
|
|
57
|
+
<div
|
|
58
|
+
data-slot="alert-description"
|
|
59
|
+
className={cn(
|
|
60
|
+
"text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
|
|
61
|
+
className,
|
|
62
|
+
)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
|
|
69
|
+
return (
|
|
70
|
+
<div data-slot="alert-action" className={cn("absolute top-2 right-2", className)} {...props} />
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { Alert, AlertAction, AlertDescription, AlertTitle };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/aspect-ratio).
|
|
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 { AspectRatio as AspectRatioPrimitive } from "radix-ui";
|
|
8
|
+
|
|
9
|
+
function AspectRatio({ ...props }: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
|
|
10
|
+
return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { AspectRatio };
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// Vendored from shadcn-ui (https://ui.shadcn.com/docs/components/radix/attachment).
|
|
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 { cva, type VariantProps } from "class-variance-authority";
|
|
7
|
+
import { Slot } from "radix-ui";
|
|
8
|
+
import type * as React from "react";
|
|
9
|
+
|
|
10
|
+
import { cn } from "../../lib/utils.ts";
|
|
11
|
+
import { Button } from "./button.tsx";
|
|
12
|
+
|
|
13
|
+
const attachmentVariants = cva(
|
|
14
|
+
"group/attachment relative flex w-fit max-w-full min-w-0 shrink-0 flex-wrap rounded-xl border bg-card text-card-foreground transition-colors focus-within:ring-1 focus-within:ring-ring/50 has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed",
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
size: {
|
|
18
|
+
default:
|
|
19
|
+
"gap-2 text-sm has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2",
|
|
20
|
+
sm: "gap-2.5 text-xs has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5",
|
|
21
|
+
xs: "gap-1.5 rounded-lg text-xs has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1",
|
|
22
|
+
},
|
|
23
|
+
orientation: {
|
|
24
|
+
horizontal: "min-w-40 items-center",
|
|
25
|
+
vertical: "w-24 flex-col has-data-[slot=attachment-content]:w-30",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
function Attachment({
|
|
32
|
+
className,
|
|
33
|
+
state = "done",
|
|
34
|
+
size = "default",
|
|
35
|
+
orientation = "horizontal",
|
|
36
|
+
...props
|
|
37
|
+
}: React.ComponentProps<"div"> &
|
|
38
|
+
VariantProps<typeof attachmentVariants> & {
|
|
39
|
+
state?: "idle" | "uploading" | "processing" | "error" | "done";
|
|
40
|
+
}) {
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
data-slot="attachment"
|
|
44
|
+
data-state={state}
|
|
45
|
+
data-size={size}
|
|
46
|
+
data-orientation={orientation}
|
|
47
|
+
className={cn(attachmentVariants({ size, orientation }), className)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const attachmentMediaVariants = cva(
|
|
54
|
+
"relative flex aspect-square w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted text-foreground group-data-[orientation=vertical]/attachment:w-full group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-md group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5",
|
|
55
|
+
{
|
|
56
|
+
variants: {
|
|
57
|
+
variant: {
|
|
58
|
+
icon: "",
|
|
59
|
+
image:
|
|
60
|
+
"opacity-60 group-data-[state=done]/attachment:opacity-100 group-data-[state=idle]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
defaultVariants: {
|
|
64
|
+
variant: "icon",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
function AttachmentMedia({
|
|
70
|
+
className,
|
|
71
|
+
variant = "icon",
|
|
72
|
+
...props
|
|
73
|
+
}: React.ComponentProps<"div"> & VariantProps<typeof attachmentMediaVariants>) {
|
|
74
|
+
return (
|
|
75
|
+
<div
|
|
76
|
+
data-slot="attachment-media"
|
|
77
|
+
data-variant={variant}
|
|
78
|
+
className={cn(attachmentMediaVariants({ variant }), className)}
|
|
79
|
+
{...props}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function AttachmentContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
85
|
+
return (
|
|
86
|
+
<div
|
|
87
|
+
data-slot="attachment-content"
|
|
88
|
+
className={cn(
|
|
89
|
+
"max-w-full min-w-0 flex-1 leading-tight group-data-[orientation=vertical]/attachment:px-1",
|
|
90
|
+
className,
|
|
91
|
+
)}
|
|
92
|
+
{...props}
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function AttachmentTitle({ className, ...props }: React.ComponentProps<"span">) {
|
|
98
|
+
return (
|
|
99
|
+
<span
|
|
100
|
+
data-slot="attachment-title"
|
|
101
|
+
className={cn(
|
|
102
|
+
"block max-w-full min-w-0 truncate font-medium group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer",
|
|
103
|
+
className,
|
|
104
|
+
)}
|
|
105
|
+
{...props}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function AttachmentDescription({ className, ...props }: React.ComponentProps<"span">) {
|
|
111
|
+
return (
|
|
112
|
+
<span
|
|
113
|
+
data-slot="attachment-description"
|
|
114
|
+
className={cn(
|
|
115
|
+
"mt-0.5 block min-w-0 truncate text-xs text-muted-foreground group-data-[state=error]/attachment:text-destructive/80",
|
|
116
|
+
"max-w-full",
|
|
117
|
+
className,
|
|
118
|
+
)}
|
|
119
|
+
{...props}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function AttachmentActions({ className, ...props }: React.ComponentProps<"div">) {
|
|
125
|
+
return (
|
|
126
|
+
<div
|
|
127
|
+
data-slot="attachment-actions"
|
|
128
|
+
className={cn(
|
|
129
|
+
"relative z-20 flex shrink-0 items-center group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 group-data-[orientation=vertical]/attachment:gap-1",
|
|
130
|
+
className,
|
|
131
|
+
)}
|
|
132
|
+
{...props}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function AttachmentAction({
|
|
138
|
+
className,
|
|
139
|
+
variant,
|
|
140
|
+
size = "icon-xs",
|
|
141
|
+
...props
|
|
142
|
+
}: React.ComponentProps<typeof Button>) {
|
|
143
|
+
return (
|
|
144
|
+
<Button
|
|
145
|
+
data-slot="attachment-action"
|
|
146
|
+
variant={variant ?? "ghost"}
|
|
147
|
+
size={size}
|
|
148
|
+
className={cn(className)}
|
|
149
|
+
{...props}
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function AttachmentTrigger({
|
|
155
|
+
className,
|
|
156
|
+
asChild = false,
|
|
157
|
+
type,
|
|
158
|
+
...props
|
|
159
|
+
}: React.ComponentProps<"button"> & {
|
|
160
|
+
asChild?: boolean;
|
|
161
|
+
}) {
|
|
162
|
+
const Comp = asChild ? Slot.Root : "button";
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<Comp
|
|
166
|
+
data-slot="attachment-trigger"
|
|
167
|
+
type={asChild ? undefined : (type ?? "button")}
|
|
168
|
+
className={cn("absolute inset-0 z-10 outline-none", className)}
|
|
169
|
+
{...props}
|
|
170
|
+
/>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function AttachmentGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
175
|
+
return (
|
|
176
|
+
<div
|
|
177
|
+
data-slot="attachment-group"
|
|
178
|
+
className={cn(
|
|
179
|
+
"flex min-w-0 scroll-fade-x snap-x snap-mandatory scroll-px-1 scrollbar-none gap-3 overflow-x-auto overscroll-x-contain py-1 *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start",
|
|
180
|
+
className,
|
|
181
|
+
)}
|
|
182
|
+
{...props}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export {
|
|
188
|
+
Attachment,
|
|
189
|
+
AttachmentAction,
|
|
190
|
+
AttachmentActions,
|
|
191
|
+
AttachmentContent,
|
|
192
|
+
AttachmentDescription,
|
|
193
|
+
AttachmentGroup,
|
|
194
|
+
AttachmentMedia,
|
|
195
|
+
AttachmentTitle,
|
|
196
|
+
AttachmentTrigger,
|
|
197
|
+
};
|