harebear-ui 0.1.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +14 -11
- package/dist/components/ai/chat.js +4 -0
- package/dist/components/ai/code-block.d.ts +13 -7
- package/dist/components/ai/code-block.js +23 -13
- package/dist/components/auth/auth.d.ts +85 -0
- package/dist/components/auth/auth.js +325 -0
- package/dist/components/theme/theme-toggle.js +1 -0
- package/dist/components/ui/attachment.d.ts +24 -0
- package/dist/components/ui/attachment.js +100 -0
- package/dist/components/ui/bubble.d.ts +17 -0
- package/dist/components/ui/bubble.js +71 -0
- package/dist/components/ui/code-block.d.ts +26 -0
- package/dist/components/ui/code-block.js +123 -0
- package/dist/components/ui/combobox.d.ts +24 -0
- package/dist/components/ui/combobox.js +162 -0
- package/dist/components/ui/direction.d.ts +7 -0
- package/dist/components/ui/direction.js +12 -0
- package/dist/components/ui/field.js +1 -1
- package/dist/components/ui/input-group.js +1 -1
- package/dist/components/ui/marker.d.ts +11 -0
- package/dist/components/ui/marker.js +39 -0
- package/dist/components/ui/message-scroller.d.ts +10 -0
- package/dist/components/ui/message-scroller.js +59 -0
- package/dist/components/ui/message.d.ts +10 -0
- package/dist/components/ui/message.js +48 -0
- package/dist/components/ui/native-select.d.ts +8 -0
- package/dist/components/ui/native-select.js +37 -0
- package/dist/components/ui/questionnaire.d.ts +19 -0
- package/dist/components/ui/questionnaire.js +168 -0
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/trace.d.ts +18 -0
- package/dist/components/ui/trace.js +74 -0
- package/dist/hooks/use-highlighted-code.d.ts +2 -0
- package/dist/hooks/use-highlighted-code.js +54 -0
- package/dist/index.d.ts +16 -2
- package/dist/index.js +16 -2
- package/dist/lib/highlighter.d.ts +9 -0
- package/dist/lib/highlighter.js +77 -0
- package/docs/COMPONENTS.md +115 -62
- package/llms.txt +6 -4
- package/package.json +8 -5
- package/skills/harebear-ui/SKILL.md +3 -2
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
import { Slot } from "radix-ui";
|
|
7
|
+
// src/components/ui/attachment.tsx
|
|
8
|
+
const attachmentVariants = cva("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", { variants: {
|
|
9
|
+
size: {
|
|
10
|
+
default: "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",
|
|
11
|
+
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",
|
|
12
|
+
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"
|
|
13
|
+
},
|
|
14
|
+
orientation: {
|
|
15
|
+
horizontal: "min-w-40 items-center",
|
|
16
|
+
vertical: "w-24 flex-col has-data-[slot=attachment-content]:w-30"
|
|
17
|
+
}
|
|
18
|
+
} });
|
|
19
|
+
function Attachment({ className, state = "done", size = "default", orientation = "horizontal", ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsx("div", {
|
|
21
|
+
"data-slot": "attachment",
|
|
22
|
+
"data-state": state,
|
|
23
|
+
"data-size": size,
|
|
24
|
+
"data-orientation": orientation,
|
|
25
|
+
className: cn(attachmentVariants({
|
|
26
|
+
size,
|
|
27
|
+
orientation
|
|
28
|
+
}), className),
|
|
29
|
+
...props
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const attachmentMediaVariants = cva("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", {
|
|
33
|
+
variants: { variant: {
|
|
34
|
+
icon: "",
|
|
35
|
+
image: "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"
|
|
36
|
+
} },
|
|
37
|
+
defaultVariants: { variant: "icon" }
|
|
38
|
+
});
|
|
39
|
+
function AttachmentMedia({ className, variant = "icon", ...props }) {
|
|
40
|
+
return /* @__PURE__ */ jsx("div", {
|
|
41
|
+
"data-slot": "attachment-media",
|
|
42
|
+
"data-variant": variant,
|
|
43
|
+
className: cn(attachmentMediaVariants({ variant }), className),
|
|
44
|
+
...props
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function AttachmentContent({ className, ...props }) {
|
|
48
|
+
return /* @__PURE__ */ jsx("div", {
|
|
49
|
+
"data-slot": "attachment-content",
|
|
50
|
+
className: cn("max-w-full min-w-0 flex-1 leading-tight group-data-[orientation=vertical]/attachment:px-1", className),
|
|
51
|
+
...props
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function AttachmentTitle({ className, ...props }) {
|
|
55
|
+
return /* @__PURE__ */ jsx("span", {
|
|
56
|
+
"data-slot": "attachment-title",
|
|
57
|
+
className: cn("block max-w-full min-w-0 truncate font-medium group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer", className),
|
|
58
|
+
...props
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function AttachmentDescription({ className, ...props }) {
|
|
62
|
+
return /* @__PURE__ */ jsx("span", {
|
|
63
|
+
"data-slot": "attachment-description",
|
|
64
|
+
className: cn("mt-0.5 block min-w-0 truncate text-xs text-muted-foreground group-data-[state=error]/attachment:text-destructive/80", "max-w-full", className),
|
|
65
|
+
...props
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function AttachmentActions({ className, ...props }) {
|
|
69
|
+
return /* @__PURE__ */ jsx("div", {
|
|
70
|
+
"data-slot": "attachment-actions",
|
|
71
|
+
className: cn("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", className),
|
|
72
|
+
...props
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function AttachmentAction({ className, variant, size = "icon-xs", ...props }) {
|
|
76
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
77
|
+
"data-slot": "attachment-action",
|
|
78
|
+
variant: variant ?? "ghost",
|
|
79
|
+
size,
|
|
80
|
+
className: cn(className),
|
|
81
|
+
...props
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function AttachmentTrigger({ className, asChild = false, type, ...props }) {
|
|
85
|
+
const Comp = asChild ? Slot.Root : "button";
|
|
86
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
87
|
+
"data-slot": "attachment-trigger",
|
|
88
|
+
type: asChild ? void 0 : type ?? "button",
|
|
89
|
+
className: cn("absolute inset-0 z-10 outline-none", className),
|
|
90
|
+
...props
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function AttachmentGroup({ className, ...props }) {
|
|
94
|
+
return /* @__PURE__ */ jsx("div", {
|
|
95
|
+
"data-slot": "attachment-group",
|
|
96
|
+
className: cn("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", className),
|
|
97
|
+
...props
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export { Attachment, AttachmentAction, AttachmentActions, AttachmentContent, AttachmentDescription, AttachmentGroup, AttachmentMedia, AttachmentTitle, AttachmentTrigger };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
declare function BubbleGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
4
|
+
declare const bubbleVariants: (props?: ({
|
|
5
|
+
variant?: "default" | "destructive" | "ghost" | "muted" | "outline" | "secondary" | "tinted" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
declare function Bubble({ variant, align, className, ...props }: React.ComponentProps<"div"> & VariantProps<typeof bubbleVariants> & {
|
|
8
|
+
align?: "start" | "end";
|
|
9
|
+
}): React.JSX.Element;
|
|
10
|
+
declare function BubbleContent({ asChild, className, ...props }: React.ComponentProps<"div"> & {
|
|
11
|
+
asChild?: boolean;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
declare function BubbleReactions({ side, align, className, ...props }: React.ComponentProps<"div"> & {
|
|
14
|
+
align?: "start" | "end";
|
|
15
|
+
side?: "top" | "bottom";
|
|
16
|
+
}): React.JSX.Element;
|
|
17
|
+
export { Bubble, BubbleContent, BubbleGroup, BubbleReactions };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import { Slot } from "radix-ui";
|
|
6
|
+
// src/components/ui/bubble.tsx
|
|
7
|
+
function BubbleGroup({ className, ...props }) {
|
|
8
|
+
return /* @__PURE__ */ jsx("div", {
|
|
9
|
+
"data-slot": "bubble-group",
|
|
10
|
+
className: cn("flex min-w-0 flex-col gap-2", className),
|
|
11
|
+
...props
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const bubbleVariants = cva("group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full", {
|
|
15
|
+
variants: { variant: {
|
|
16
|
+
default: "*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80",
|
|
17
|
+
secondary: "*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]",
|
|
18
|
+
muted: "*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]",
|
|
19
|
+
tinted: "*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]",
|
|
20
|
+
outline: "*:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30",
|
|
21
|
+
ghost: "border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50",
|
|
22
|
+
destructive: "*:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30"
|
|
23
|
+
} },
|
|
24
|
+
defaultVariants: { variant: "default" }
|
|
25
|
+
});
|
|
26
|
+
function Bubble({ variant = "default", align = "start", className, ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx("div", {
|
|
28
|
+
"data-slot": "bubble",
|
|
29
|
+
"data-variant": variant,
|
|
30
|
+
"data-align": align,
|
|
31
|
+
className: cn(bubbleVariants({ variant }), className),
|
|
32
|
+
...props
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function BubbleContent({ asChild = false, className, ...props }) {
|
|
36
|
+
const Comp = asChild ? Slot.Root : "div";
|
|
37
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
38
|
+
"data-slot": "bubble-content",
|
|
39
|
+
className: cn("w-fit max-w-full min-w-0 overflow-hidden rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed wrap-break-word group-data-[align=end]/bubble:self-end [button]:text-left [button,a]:transition-colors [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-3 [button,a]:focus-visible:ring-ring/50", className),
|
|
40
|
+
...props
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const bubbleReactionsVariants = cva("absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0", {
|
|
44
|
+
variants: {
|
|
45
|
+
side: {
|
|
46
|
+
top: "top-0 -translate-y-3/4",
|
|
47
|
+
bottom: "bottom-0 translate-y-3/4"
|
|
48
|
+
},
|
|
49
|
+
align: {
|
|
50
|
+
start: "left-3",
|
|
51
|
+
end: "right-3"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
defaultVariants: {
|
|
55
|
+
side: "bottom",
|
|
56
|
+
align: "end"
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
function BubbleReactions({ side = "bottom", align = "end", className, ...props }) {
|
|
60
|
+
return /* @__PURE__ */ jsx("div", {
|
|
61
|
+
"data-slot": "bubble-reactions",
|
|
62
|
+
"data-align": align,
|
|
63
|
+
"data-side": side,
|
|
64
|
+
className: cn(bubbleReactionsVariants({
|
|
65
|
+
side,
|
|
66
|
+
align
|
|
67
|
+
}), className),
|
|
68
|
+
...props
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export { Bubble, BubbleContent, BubbleGroup, BubbleReactions };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Button } from "./button.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { VariantProps } from "class-variance-authority";
|
|
4
|
+
declare const codeBlockVariants: (props?: ({
|
|
5
|
+
variant?: "default" | "destructive" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
declare function CodeBlock({ className, variant, size, ...props }: React.ComponentProps<"div"> & VariantProps<typeof codeBlockVariants> & {
|
|
8
|
+
size?: "default" | "sm";
|
|
9
|
+
}): React.JSX.Element;
|
|
10
|
+
declare function CodeBlockHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
11
|
+
declare function CodeBlockTitle({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
12
|
+
declare function CodeBlockActions({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
13
|
+
declare function CodeBlockCopyButton({ value, variant, size, type, className, onClick, ...props }: React.ComponentProps<typeof Button> & {
|
|
14
|
+
value: string;
|
|
15
|
+
}): React.JSX.Element;
|
|
16
|
+
declare function CodeBlockContent({ className, children, style, wrap, lineNumbers, startLine, ...props }: React.ComponentProps<"pre"> & {
|
|
17
|
+
wrap?: boolean;
|
|
18
|
+
lineNumbers?: boolean;
|
|
19
|
+
startLine?: number;
|
|
20
|
+
}): React.JSX.Element;
|
|
21
|
+
declare const codeBlockLineVariants: (props?: ({
|
|
22
|
+
variant?: "added" | "default" | "highlighted" | "removed" | null | undefined;
|
|
23
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
24
|
+
declare function CodeBlockLine({ className, variant, children, ...props }: React.ComponentProps<"span"> & VariantProps<typeof codeBlockLineVariants>): React.JSX.Element;
|
|
25
|
+
declare function CodeBlockFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
26
|
+
export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
7
|
+
import { cva } from "class-variance-authority";
|
|
8
|
+
// src/components/ui/code-block.tsx
|
|
9
|
+
const codeBlockVariants = cva("group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs", {
|
|
10
|
+
variants: { variant: {
|
|
11
|
+
default: "bg-muted text-foreground",
|
|
12
|
+
destructive: "border border-destructive/30 text-destructive dark:border-destructive/40"
|
|
13
|
+
} },
|
|
14
|
+
defaultVariants: { variant: "default" }
|
|
15
|
+
});
|
|
16
|
+
function CodeBlock({ className, variant = "default", size = "default", ...props }) {
|
|
17
|
+
return /* @__PURE__ */ jsx("div", {
|
|
18
|
+
"data-slot": "code-block",
|
|
19
|
+
"data-variant": variant,
|
|
20
|
+
"data-size": size,
|
|
21
|
+
className: cn(codeBlockVariants({ variant }), className),
|
|
22
|
+
...props
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function CodeBlockHeader({ className, ...props }) {
|
|
26
|
+
return /* @__PURE__ */ jsx("div", {
|
|
27
|
+
"data-slot": "code-block-header",
|
|
28
|
+
className: cn("flex min-w-0 shrink-0 items-center gap-2 pt-2 pr-2 pl-4.5 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0", className),
|
|
29
|
+
...props
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function CodeBlockTitle({ className, ...props }) {
|
|
33
|
+
return /* @__PURE__ */ jsx("div", {
|
|
34
|
+
"data-slot": "code-block-title",
|
|
35
|
+
className: cn("min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5", className),
|
|
36
|
+
...props
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function CodeBlockActions({ className, ...props }) {
|
|
40
|
+
return /* @__PURE__ */ jsx("div", {
|
|
41
|
+
"data-slot": "code-block-actions",
|
|
42
|
+
className: cn("-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-1.5 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-1.5 [[data-slot=code-block]>&]:pointer-coarse:opacity-100 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10", className),
|
|
43
|
+
...props
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function CodeBlockCopyButton({ value, variant = "ghost", size = "icon-xs", type = "button", className, onClick, ...props }) {
|
|
47
|
+
const [copied, setCopied] = React.useState(false);
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
if (!copied) return;
|
|
50
|
+
const timeout = setTimeout(() => setCopied(false), 2e3);
|
|
51
|
+
return () => clearTimeout(timeout);
|
|
52
|
+
}, [copied]);
|
|
53
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
|
|
54
|
+
"data-slot": "code-block-copy-button",
|
|
55
|
+
"data-copied": copied || void 0,
|
|
56
|
+
type,
|
|
57
|
+
variant,
|
|
58
|
+
size,
|
|
59
|
+
"aria-label": copied ? "Copied" : "Copy",
|
|
60
|
+
className: cn(className),
|
|
61
|
+
onClick: (event) => {
|
|
62
|
+
onClick?.(event);
|
|
63
|
+
navigator.clipboard.writeText(value).then(() => setCopied(true)).catch(() => {});
|
|
64
|
+
},
|
|
65
|
+
...props,
|
|
66
|
+
children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
|
|
67
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
68
|
+
"aria-live": "polite",
|
|
69
|
+
className: "sr-only",
|
|
70
|
+
children: copied ? "Copied" : ""
|
|
71
|
+
})] });
|
|
72
|
+
}
|
|
73
|
+
function CodeBlockContent({ className, children, style, wrap = false, lineNumbers = false, startLine = 1, ...props }) {
|
|
74
|
+
return /* @__PURE__ */ jsx("pre", {
|
|
75
|
+
"data-slot": "code-block-content",
|
|
76
|
+
"data-wrap": wrap || void 0,
|
|
77
|
+
"data-numbered": lineNumbers || void 0,
|
|
78
|
+
dir: "ltr",
|
|
79
|
+
tabIndex: 0,
|
|
80
|
+
style: {
|
|
81
|
+
counterReset: `line ${startLine - 1}`,
|
|
82
|
+
...style
|
|
83
|
+
},
|
|
84
|
+
className: cn("min-h-0 min-w-0 scroll-fade-x scrollbar-thin overflow-auto px-4.5 py-3 text-start font-mono text-[13px] leading-[1.7] outline-none group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 data-wrap:scroll-fade-y data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap", className),
|
|
85
|
+
...props,
|
|
86
|
+
children: /* @__PURE__ */ jsx("code", {
|
|
87
|
+
"data-slot": "code-block-code",
|
|
88
|
+
className: "grid min-h-lh min-w-max content-start in-data-numbered:grid-cols-[auto_1fr] in-data-wrap:min-w-0",
|
|
89
|
+
children: lineNumbers && typeof children === "string" ? children.replace(/\n$/, "").split("\n").map((line, index) => /* @__PURE__ */ jsx(CodeBlockLine, { children: line }, index)) : children
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const codeBlockLineVariants = cva("relative -mx-4.5 block min-h-lh px-4.5 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none in-data-numbered:supports-[content:counter(line)_/_'']:before:content-[counter(line)_/_'']", {
|
|
94
|
+
variants: { variant: {
|
|
95
|
+
default: "",
|
|
96
|
+
added: "bg-success/12 after:text-success after:content-['+']",
|
|
97
|
+
removed: "bg-destructive/10 after:text-destructive after:content-['−']",
|
|
98
|
+
highlighted: "bg-primary-soft"
|
|
99
|
+
} },
|
|
100
|
+
defaultVariants: { variant: "default" }
|
|
101
|
+
});
|
|
102
|
+
function CodeBlockLine({ className, variant = "default", children, ...props }) {
|
|
103
|
+
const empty = children === void 0 || children === null || children === "" || Array.isArray(children) && children.length === 0;
|
|
104
|
+
return /* @__PURE__ */ jsx("span", {
|
|
105
|
+
"data-slot": "code-block-line",
|
|
106
|
+
"data-variant": variant,
|
|
107
|
+
className: cn(codeBlockLineVariants({ variant }), className),
|
|
108
|
+
...props,
|
|
109
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
110
|
+
"data-slot": "code-block-line-content",
|
|
111
|
+
className: "min-w-0",
|
|
112
|
+
children: empty ? "\n" : children
|
|
113
|
+
})
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function CodeBlockFooter({ className, ...props }) {
|
|
117
|
+
return /* @__PURE__ */ jsx("div", {
|
|
118
|
+
"data-slot": "code-block-footer",
|
|
119
|
+
className: cn("flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5", className),
|
|
120
|
+
...props
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
export { CodeBlock, CodeBlockActions, CodeBlockContent, CodeBlockCopyButton, CodeBlockFooter, CodeBlockHeader, CodeBlockLine, CodeBlockTitle };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Combobox as Combobox$1 } from "@base-ui/react";
|
|
3
|
+
declare const Combobox: typeof Combobox$1.Root;
|
|
4
|
+
declare function ComboboxValue({ ...props }: Combobox$1.Value.Props): React.JSX.Element;
|
|
5
|
+
declare function ComboboxTrigger({ className, children, ...props }: Combobox$1.Trigger.Props): React.JSX.Element;
|
|
6
|
+
declare function ComboboxInput({ className, children, disabled, showTrigger, showClear, ...props }: Combobox$1.Input.Props & {
|
|
7
|
+
showTrigger?: boolean;
|
|
8
|
+
showClear?: boolean;
|
|
9
|
+
}): React.JSX.Element;
|
|
10
|
+
declare function ComboboxContent({ className, side, sideOffset, align, alignOffset, anchor, ...props }: Combobox$1.Popup.Props & Pick<Combobox$1.Positioner.Props, "side" | "align" | "sideOffset" | "alignOffset" | "anchor">): React.JSX.Element;
|
|
11
|
+
declare function ComboboxList({ className, ...props }: Combobox$1.List.Props): React.JSX.Element;
|
|
12
|
+
declare function ComboboxItem({ className, children, ...props }: Combobox$1.Item.Props): React.JSX.Element;
|
|
13
|
+
declare function ComboboxGroup({ className, ...props }: Combobox$1.Group.Props): React.JSX.Element;
|
|
14
|
+
declare function ComboboxLabel({ className, ...props }: Combobox$1.GroupLabel.Props): React.JSX.Element;
|
|
15
|
+
declare function ComboboxCollection({ ...props }: Combobox$1.Collection.Props): React.JSX.Element;
|
|
16
|
+
declare function ComboboxEmpty({ className, ...props }: Combobox$1.Empty.Props): React.JSX.Element;
|
|
17
|
+
declare function ComboboxSeparator({ className, ...props }: Combobox$1.Separator.Props): React.JSX.Element;
|
|
18
|
+
declare function ComboboxChips({ className, ...props }: React.ComponentPropsWithRef<typeof Combobox$1.Chips> & Combobox$1.Chips.Props): React.JSX.Element;
|
|
19
|
+
declare function ComboboxChip({ className, children, showRemove, ...props }: Combobox$1.Chip.Props & {
|
|
20
|
+
showRemove?: boolean;
|
|
21
|
+
}): React.JSX.Element;
|
|
22
|
+
declare function ComboboxChipsInput({ className, ...props }: Combobox$1.Input.Props): React.JSX.Element;
|
|
23
|
+
declare function useComboboxAnchor(): React.RefObject<HTMLDivElement | null>;
|
|
24
|
+
export { Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, useComboboxAnchor };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "./input-group.js";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { CheckIcon, ChevronDownIcon, XIcon } from "lucide-react";
|
|
8
|
+
import { Combobox as Combobox$1 } from "@base-ui/react";
|
|
9
|
+
// src/components/ui/combobox.tsx
|
|
10
|
+
const Combobox = Combobox$1.Root;
|
|
11
|
+
function ComboboxValue({ ...props }) {
|
|
12
|
+
return /* @__PURE__ */ jsx(Combobox$1.Value, {
|
|
13
|
+
"data-slot": "combobox-value",
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function ComboboxTrigger({ className, children, ...props }) {
|
|
18
|
+
return /* @__PURE__ */ jsxs(Combobox$1.Trigger, {
|
|
19
|
+
"data-slot": "combobox-trigger",
|
|
20
|
+
className: cn("[&_svg:not([class*='size-'])]:size-4", className),
|
|
21
|
+
...props,
|
|
22
|
+
children: [children, /* @__PURE__ */ jsx(ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" })]
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function ComboboxClear({ className, ...props }) {
|
|
26
|
+
return /* @__PURE__ */ jsx(Combobox$1.Clear, {
|
|
27
|
+
"data-slot": "combobox-clear",
|
|
28
|
+
render: /* @__PURE__ */ jsx(InputGroupButton, {
|
|
29
|
+
variant: "ghost",
|
|
30
|
+
size: "icon-xs"
|
|
31
|
+
}),
|
|
32
|
+
className: cn(className),
|
|
33
|
+
...props,
|
|
34
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "pointer-events-none" })
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function ComboboxInput({ className, children, disabled = false, showTrigger = true, showClear = false, ...props }) {
|
|
38
|
+
return /* @__PURE__ */ jsxs(InputGroup, {
|
|
39
|
+
className: cn("w-auto", className),
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Combobox$1.Input, {
|
|
42
|
+
render: /* @__PURE__ */ jsx(InputGroupInput, { disabled }),
|
|
43
|
+
...props
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ jsxs(InputGroupAddon, {
|
|
46
|
+
align: "inline-end",
|
|
47
|
+
children: [showTrigger && /* @__PURE__ */ jsx(InputGroupButton, {
|
|
48
|
+
size: "icon-xs",
|
|
49
|
+
variant: "ghost",
|
|
50
|
+
asChild: true,
|
|
51
|
+
"data-slot": "input-group-button",
|
|
52
|
+
className: "group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent",
|
|
53
|
+
disabled,
|
|
54
|
+
children: /* @__PURE__ */ jsx(ComboboxTrigger, {})
|
|
55
|
+
}), showClear && /* @__PURE__ */ jsx(ComboboxClear, { disabled })]
|
|
56
|
+
}),
|
|
57
|
+
children
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function ComboboxContent({ className, side = "bottom", sideOffset = 6, align = "start", alignOffset = 0, anchor, ...props }) {
|
|
62
|
+
return /* @__PURE__ */ jsx(Combobox$1.Portal, { children: /* @__PURE__ */ jsx(Combobox$1.Positioner, {
|
|
63
|
+
side,
|
|
64
|
+
sideOffset,
|
|
65
|
+
align,
|
|
66
|
+
alignOffset,
|
|
67
|
+
anchor,
|
|
68
|
+
className: "isolate z-50",
|
|
69
|
+
children: /* @__PURE__ */ jsx(Combobox$1.Popup, {
|
|
70
|
+
"data-slot": "combobox-content",
|
|
71
|
+
"data-chips": !!anchor,
|
|
72
|
+
className: cn("group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
|
|
73
|
+
...props
|
|
74
|
+
})
|
|
75
|
+
}) });
|
|
76
|
+
}
|
|
77
|
+
function ComboboxList({ className, ...props }) {
|
|
78
|
+
return /* @__PURE__ */ jsx(Combobox$1.List, {
|
|
79
|
+
"data-slot": "combobox-list",
|
|
80
|
+
className: cn("no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0", className),
|
|
81
|
+
...props
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function ComboboxItem({ className, children, ...props }) {
|
|
85
|
+
return /* @__PURE__ */ jsxs(Combobox$1.Item, {
|
|
86
|
+
"data-slot": "combobox-item",
|
|
87
|
+
className: cn("relative flex w-full cursor-default items-center gap-2 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**: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", className),
|
|
88
|
+
...props,
|
|
89
|
+
children: [children, /* @__PURE__ */ jsx(Combobox$1.ItemIndicator, {
|
|
90
|
+
render: /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }),
|
|
91
|
+
children: /* @__PURE__ */ jsx(CheckIcon, { className: "pointer-events-none" })
|
|
92
|
+
})]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function ComboboxGroup({ className, ...props }) {
|
|
96
|
+
return /* @__PURE__ */ jsx(Combobox$1.Group, {
|
|
97
|
+
"data-slot": "combobox-group",
|
|
98
|
+
className: cn(className),
|
|
99
|
+
...props
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function ComboboxLabel({ className, ...props }) {
|
|
103
|
+
return /* @__PURE__ */ jsx(Combobox$1.GroupLabel, {
|
|
104
|
+
"data-slot": "combobox-label",
|
|
105
|
+
className: cn("px-2 py-1.5 text-xs text-muted-foreground", className),
|
|
106
|
+
...props
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function ComboboxCollection({ ...props }) {
|
|
110
|
+
return /* @__PURE__ */ jsx(Combobox$1.Collection, {
|
|
111
|
+
"data-slot": "combobox-collection",
|
|
112
|
+
...props
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function ComboboxEmpty({ className, ...props }) {
|
|
116
|
+
return /* @__PURE__ */ jsx(Combobox$1.Empty, {
|
|
117
|
+
"data-slot": "combobox-empty",
|
|
118
|
+
className: cn("hidden w-full justify-center py-2 text-center text-sm text-muted-foreground group-data-empty/combobox-content:flex", className),
|
|
119
|
+
...props
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function ComboboxSeparator({ className, ...props }) {
|
|
123
|
+
return /* @__PURE__ */ jsx(Combobox$1.Separator, {
|
|
124
|
+
"data-slot": "combobox-separator",
|
|
125
|
+
className: cn("-mx-1 my-1 h-px bg-border", className),
|
|
126
|
+
...props
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function ComboboxChips({ className, ...props }) {
|
|
130
|
+
return /* @__PURE__ */ jsx(Combobox$1.Chips, {
|
|
131
|
+
"data-slot": "combobox-chips",
|
|
132
|
+
className: cn("flex min-h-10 flex-wrap items-center gap-1 rounded-md border border-transparent bg-muted bg-clip-padding px-3.5 py-1 text-sm transition-[border-color,box-shadow,background-color] focus-within:border-primary focus-within:bg-card focus-within:ring-4 focus-within:ring-primary/15 has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 has-data-[slot=combobox-chip]:px-1 dark:has-aria-invalid:border-destructive/50 dark:has-aria-invalid:ring-destructive/40", className),
|
|
133
|
+
...props
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function ComboboxChip({ className, children, showRemove = true, ...props }) {
|
|
137
|
+
return /* @__PURE__ */ jsxs(Combobox$1.Chip, {
|
|
138
|
+
"data-slot": "combobox-chip",
|
|
139
|
+
className: cn("flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0", className),
|
|
140
|
+
...props,
|
|
141
|
+
children: [children, showRemove && /* @__PURE__ */ jsx(Combobox$1.ChipRemove, {
|
|
142
|
+
render: /* @__PURE__ */ jsx(Button, {
|
|
143
|
+
variant: "ghost",
|
|
144
|
+
size: "icon-xs"
|
|
145
|
+
}),
|
|
146
|
+
className: "-ml-1 opacity-50 hover:opacity-100",
|
|
147
|
+
"data-slot": "combobox-chip-remove",
|
|
148
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "pointer-events-none" })
|
|
149
|
+
})]
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function ComboboxChipsInput({ className, ...props }) {
|
|
153
|
+
return /* @__PURE__ */ jsx(Combobox$1.Input, {
|
|
154
|
+
"data-slot": "combobox-chip-input",
|
|
155
|
+
className: cn("min-w-16 flex-1 outline-none", className),
|
|
156
|
+
...props
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function useComboboxAnchor() {
|
|
160
|
+
return React.useRef(null);
|
|
161
|
+
}
|
|
162
|
+
export { Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, useComboboxAnchor };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Direction } from "radix-ui";
|
|
3
|
+
declare function DirectionProvider({ dir, direction, children }: React.ComponentProps<typeof Direction.DirectionProvider> & {
|
|
4
|
+
direction?: React.ComponentProps<typeof Direction.DirectionProvider>["dir"];
|
|
5
|
+
}): React.JSX.Element;
|
|
6
|
+
declare const useDirection: typeof Direction.useDirection;
|
|
7
|
+
export { DirectionProvider, useDirection };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Direction } from "radix-ui";
|
|
4
|
+
// src/components/ui/direction.tsx
|
|
5
|
+
function DirectionProvider({ dir, direction, children }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(Direction.DirectionProvider, {
|
|
7
|
+
dir: direction ?? dir,
|
|
8
|
+
children
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const useDirection = Direction.useDirection;
|
|
12
|
+
export { DirectionProvider, useDirection };
|
|
@@ -80,7 +80,7 @@ function FieldSeparator({ children, className, ...props }) {
|
|
|
80
80
|
className: cn("relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2", className),
|
|
81
81
|
...props,
|
|
82
82
|
children: [/* @__PURE__ */ jsx(Separator, { className: "absolute inset-0 top-1/2" }), children && /* @__PURE__ */ jsx("span", {
|
|
83
|
-
className: "relative mx-auto block w-fit bg-background px-2 text-muted-foreground",
|
|
83
|
+
className: "relative mx-auto block w-fit bg-background px-2 text-muted-foreground in-data-[slot=card]:bg-card",
|
|
84
84
|
"data-slot": "field-separator-content",
|
|
85
85
|
children
|
|
86
86
|
})]
|
|
@@ -10,7 +10,7 @@ function InputGroup({ className, ...props }) {
|
|
|
10
10
|
return /* @__PURE__ */ jsx("div", {
|
|
11
11
|
"data-slot": "input-group",
|
|
12
12
|
role: "group",
|
|
13
|
-
className: cn("group/input-group relative flex h-
|
|
13
|
+
className: cn("group/input-group relative flex h-10 w-full min-w-0 items-center rounded-md border border-transparent bg-muted transition-[border-color,box-shadow,background-color] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-primary has-[[data-slot=input-group-control]:focus-visible]:bg-card has-[[data-slot=input-group-control]:focus-visible]:ring-4 has-[[data-slot=input-group-control]:focus-visible]:ring-primary/15 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className),
|
|
14
14
|
...props
|
|
15
15
|
});
|
|
16
16
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
declare const markerVariants: (props?: ({
|
|
4
|
+
variant?: "border" | "default" | "separator" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
declare function Marker({ className, variant, asChild, ...props }: React.ComponentProps<"div"> & VariantProps<typeof markerVariants> & {
|
|
7
|
+
asChild?: boolean;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
declare function MarkerIcon({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
|
|
10
|
+
declare function MarkerContent({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
|
|
11
|
+
export { Marker, MarkerContent, MarkerIcon, markerVariants };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import { Slot } from "radix-ui";
|
|
6
|
+
// src/components/ui/marker.tsx
|
|
7
|
+
const markerVariants = cva("group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground", { variants: { variant: {
|
|
8
|
+
default: "",
|
|
9
|
+
separator: "before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border",
|
|
10
|
+
border: "border-b border-border pb-2"
|
|
11
|
+
} } });
|
|
12
|
+
function Marker({ className, variant = "default", asChild = false, ...props }) {
|
|
13
|
+
const Comp = asChild ? Slot.Root : "div";
|
|
14
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
15
|
+
"data-slot": "marker",
|
|
16
|
+
"data-variant": variant,
|
|
17
|
+
className: cn(markerVariants({
|
|
18
|
+
variant,
|
|
19
|
+
className
|
|
20
|
+
})),
|
|
21
|
+
...props
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function MarkerIcon({ className, ...props }) {
|
|
25
|
+
return /* @__PURE__ */ jsx("span", {
|
|
26
|
+
"data-slot": "marker-icon",
|
|
27
|
+
"aria-hidden": "true",
|
|
28
|
+
className: cn("size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
|
|
29
|
+
...props
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function MarkerContent({ className, ...props }) {
|
|
33
|
+
return /* @__PURE__ */ jsx("span", {
|
|
34
|
+
"data-slot": "marker-content",
|
|
35
|
+
className: cn("min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className),
|
|
36
|
+
...props
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export { Marker, MarkerContent, MarkerIcon, markerVariants };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Button } from "./button.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { MessageScroller as MessageScroller$1, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility } from "@shadcn/react/message-scroller";
|
|
4
|
+
declare function MessageScrollerProvider(props: React.ComponentProps<typeof MessageScroller$1.Provider>): React.JSX.Element;
|
|
5
|
+
declare function MessageScroller({ className, ...props }: React.ComponentProps<typeof MessageScroller$1.Root>): React.JSX.Element;
|
|
6
|
+
declare function MessageScrollerViewport({ className, ...props }: React.ComponentProps<typeof MessageScroller$1.Viewport>): React.JSX.Element;
|
|
7
|
+
declare function MessageScrollerContent({ className, ...props }: React.ComponentProps<typeof MessageScroller$1.Content>): React.JSX.Element;
|
|
8
|
+
declare function MessageScrollerItem({ className, scrollAnchor, ...props }: React.ComponentProps<typeof MessageScroller$1.Item>): React.JSX.Element;
|
|
9
|
+
declare function MessageScrollerButton({ direction, className, children, render, variant, size, ...props }: React.ComponentProps<typeof MessageScroller$1.Button> & Pick<React.ComponentProps<typeof Button>, "variant" | "size">): React.JSX.Element;
|
|
10
|
+
export { MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility };
|