@rynx-ai/ui 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/components/alert-dialog.d.ts +16 -0
- package/dist/components/alert-dialog.js +34 -0
- package/dist/components/button.d.ts +11 -0
- package/dist/components/button.js +34 -0
- package/dist/components/dialog.d.ts +16 -0
- package/dist/components/dialog.js +30 -0
- package/dist/components/dropdown-menu.d.ts +8 -0
- package/dist/components/dropdown-menu.js +14 -0
- package/dist/components/input.d.ts +2 -0
- package/dist/components/input.js +5 -0
- package/dist/components/interaction-question.d.ts +42 -0
- package/dist/components/interaction-question.js +79 -0
- package/dist/components/native-select.d.ts +7 -0
- package/dist/components/native-select.js +12 -0
- package/dist/components/scroll-area.d.ts +9 -0
- package/dist/components/scroll-area.js +11 -0
- package/dist/components/select.d.ts +14 -0
- package/dist/components/select.js +28 -0
- package/dist/components/tabs.d.ts +6 -0
- package/dist/components/tabs.js +13 -0
- package/dist/components/textarea.d.ts +2 -0
- package/dist/components/textarea.js +5 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/package.json +68 -0
- package/src/components/alert-dialog.tsx +162 -0
- package/src/components/button.tsx +63 -0
- package/src/components/dialog.tsx +137 -0
- package/src/components/dropdown-menu.tsx +57 -0
- package/src/components/input.tsx +19 -0
- package/src/components/interaction-question.tsx +364 -0
- package/src/components/native-select.tsx +57 -0
- package/src/components/scroll-area.tsx +84 -0
- package/src/components/select.tsx +191 -0
- package/src/components/tabs.tsx +53 -0
- package/src/components/textarea.tsx +16 -0
- package/src/index.ts +12 -0
- package/src/lib/utils.ts +6 -0
- package/styles/tailwind.css +31 -0
- package/styles/tokens.css +55 -0
- package/styles/utilities.css +55 -0
- package/styles.css +4 -0
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @rynx-ai/ui
|
|
2
|
+
|
|
3
|
+
Shared Rynx Web design tokens and business-agnostic shadcn/Radix primitives.
|
|
4
|
+
`DESIGN.md` is the visual specification; this package is its Web implementation.
|
|
5
|
+
The component recipe is pinned to shadcn `radix-nova` in `components.json`.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
Button,
|
|
10
|
+
Select,
|
|
11
|
+
SelectContent,
|
|
12
|
+
SelectItem,
|
|
13
|
+
SelectTrigger,
|
|
14
|
+
SelectValue,
|
|
15
|
+
} from "@rynx-ai/ui";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Import the shared theme after Tailwind in the consuming application:
|
|
19
|
+
|
|
20
|
+
```css
|
|
21
|
+
@import "tailwindcss";
|
|
22
|
+
@import "@rynx-ai/ui/styles.css";
|
|
23
|
+
@source "../node_modules/@rynx-ai/ui/dist";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Monorepo applications scan `packages/ui/src` instead because their Vite aliases
|
|
27
|
+
consume source directly.
|
|
28
|
+
|
|
29
|
+
Run shadcn component commands from this package so the CLI uses the pinned
|
|
30
|
+
recipe and installs components under `src/components`:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
pnpm dlx shadcn@latest add <component>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The package must stay independent of application state, routing, APIs, protocol
|
|
37
|
+
types, and product-specific compositions. Those belong in the consuming app.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export declare function AlertDialog(props: React.ComponentProps<typeof AlertDialogPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
export declare const AlertDialogTrigger: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
export declare function AlertDialogPortal(props: React.ComponentProps<typeof AlertDialogPrimitive.Portal>): React.JSX.Element;
|
|
6
|
+
export declare const AlertDialogOverlay: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
export declare const AlertDialogContent: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
8
|
+
size?: "default" | "sm";
|
|
9
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
export declare function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
11
|
+
export declare function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
12
|
+
export declare function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
13
|
+
export declare const AlertDialogTitle: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
14
|
+
export declare const AlertDialogDescription: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
15
|
+
export declare const AlertDialogAction: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogActionProps & React.RefAttributes<HTMLButtonElement>, "ref"> & Pick<import("./button.js").ButtonProps & React.RefAttributes<HTMLButtonElement>, "variant" | "size"> & React.RefAttributes<HTMLButtonElement>>;
|
|
16
|
+
export declare const AlertDialogCancel: React.ForwardRefExoticComponent<Omit<AlertDialogPrimitive.AlertDialogCancelProps & React.RefAttributes<HTMLButtonElement>, "ref"> & Pick<import("./button.js").ButtonProps & React.RefAttributes<HTMLButtonElement>, "variant" | "size"> & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { Button } from "./button.js";
|
|
6
|
+
export function AlertDialog(props) {
|
|
7
|
+
return _jsx(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
|
|
8
|
+
}
|
|
9
|
+
export const AlertDialogTrigger = React.forwardRef((props, ref) => (_jsx(AlertDialogPrimitive.Trigger, { ref: ref, "data-slot": "alert-dialog-trigger", ...props })));
|
|
10
|
+
AlertDialogTrigger.displayName = AlertDialogPrimitive.Trigger.displayName;
|
|
11
|
+
export function AlertDialogPortal(props) {
|
|
12
|
+
return _jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
|
|
13
|
+
}
|
|
14
|
+
export const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(AlertDialogPrimitive.Overlay, { ref: ref, "data-slot": "alert-dialog-overlay", className: cn("fixed inset-0 z-50 bg-black/10 duration-100 supports-[backdrop-filter]:backdrop-blur-xs data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0", className), ...props })));
|
|
15
|
+
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
16
|
+
export const AlertDialogContent = React.forwardRef(({ className, size = "default", ...props }, ref) => (_jsxs(AlertDialogPortal, { children: [_jsx(AlertDialogOverlay, {}), _jsx(AlertDialogPrimitive.Content, { ref: ref, "data-slot": "alert-dialog-content", "data-size": size, className: cn("group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-[calc(100%-2rem)] min-w-0 -translate-x-1/2 -translate-y-1/2 grid-cols-1 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 [&>*]:min-w-0", className), ...props })] })));
|
|
17
|
+
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
|
|
18
|
+
export function AlertDialogHeader({ className, ...props }) {
|
|
19
|
+
return (_jsx("div", { "data-slot": "alert-dialog-header", className: cn("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]", className), ...props }));
|
|
20
|
+
}
|
|
21
|
+
export function AlertDialogFooter({ className, ...props }) {
|
|
22
|
+
return (_jsx("div", { "data-slot": "alert-dialog-footer", className: cn("-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", className), ...props }));
|
|
23
|
+
}
|
|
24
|
+
export function AlertDialogMedia({ className, ...props }) {
|
|
25
|
+
return (_jsx("div", { "data-slot": "alert-dialog-media", className: cn("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", className), ...props }));
|
|
26
|
+
}
|
|
27
|
+
export const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx(AlertDialogPrimitive.Title, { ref: ref, "data-slot": "alert-dialog-title", className: cn("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", className), ...props })));
|
|
28
|
+
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
29
|
+
export const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(AlertDialogPrimitive.Description, { ref: ref, "data-slot": "alert-dialog-description", className: cn("text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className), ...props })));
|
|
30
|
+
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
|
31
|
+
export const AlertDialogAction = React.forwardRef(({ className, variant = "default", size = "default", ...props }, ref) => (_jsx(Button, { variant: variant, size: size, asChild: true, children: _jsx(AlertDialogPrimitive.Action, { ref: ref, "data-slot": "alert-dialog-action", className: cn(className), ...props }) })));
|
|
32
|
+
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
33
|
+
export const AlertDialogCancel = React.forwardRef(({ className, variant = "outline", size = "default", ...props }, ref) => (_jsx(Button, { variant: variant, size: size, asChild: true, children: _jsx(AlertDialogPrimitive.Cancel, { ref: ref, "data-slot": "alert-dialog-cancel", className: cn(className), ...props }) })));
|
|
34
|
+
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
|
|
5
|
+
size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
11
|
+
export { buttonVariants };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { cn } from "../lib/utils.js";
|
|
6
|
+
const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-lg border border-transparent bg-clip-padding text-sm font-medium transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 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", {
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
10
|
+
destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
|
|
11
|
+
outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
12
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
13
|
+
ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
|
14
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
18
|
+
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
19
|
+
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
20
|
+
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
21
|
+
icon: "size-8",
|
|
22
|
+
"icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] [&_svg:not([class*='size-'])]:size-3",
|
|
23
|
+
"icon-sm": "size-7 rounded-[min(var(--radius-md),12px)]",
|
|
24
|
+
"icon-lg": "size-9",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: { variant: "default", size: "default" },
|
|
28
|
+
});
|
|
29
|
+
export const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
30
|
+
const Comp = asChild ? Slot : "button";
|
|
31
|
+
return (_jsx(Comp, { ref: ref, "data-slot": "button", "data-variant": variant ?? "default", "data-size": size ?? "default", className: cn(buttonVariants({ variant, size, className })), ...props }));
|
|
32
|
+
});
|
|
33
|
+
Button.displayName = "Button";
|
|
34
|
+
export { buttonVariants };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export declare function Dialog(props: React.ComponentProps<typeof DialogPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
export declare const DialogTrigger: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
export declare function DialogPortal(props: React.ComponentProps<typeof DialogPrimitive.Portal>): React.JSX.Element;
|
|
6
|
+
export declare const DialogClose: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
7
|
+
export declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
export declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
9
|
+
showCloseButton?: boolean;
|
|
10
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
11
|
+
export declare function DialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
12
|
+
export declare function DialogFooter({ className, showCloseButton, children, ...props }: React.ComponentProps<"div"> & {
|
|
13
|
+
showCloseButton?: boolean;
|
|
14
|
+
}): React.JSX.Element;
|
|
15
|
+
export declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
16
|
+
export declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
3
|
+
import { X } from "lucide-react";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { cn } from "../lib/utils.js";
|
|
6
|
+
import { Button } from "./button.js";
|
|
7
|
+
export function Dialog(props) {
|
|
8
|
+
return _jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
9
|
+
}
|
|
10
|
+
export const DialogTrigger = React.forwardRef((props, ref) => _jsx(DialogPrimitive.Trigger, { ref: ref, "data-slot": "dialog-trigger", ...props }));
|
|
11
|
+
DialogTrigger.displayName = DialogPrimitive.Trigger.displayName;
|
|
12
|
+
export function DialogPortal(props) {
|
|
13
|
+
return _jsx(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
14
|
+
}
|
|
15
|
+
export const DialogClose = React.forwardRef((props, ref) => _jsx(DialogPrimitive.Close, { ref: ref, "data-slot": "dialog-close", ...props }));
|
|
16
|
+
DialogClose.displayName = DialogPrimitive.Close.displayName;
|
|
17
|
+
export const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, "data-slot": "dialog-overlay", className: cn("fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-[backdrop-filter]:backdrop-blur-xs data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0", className), ...props })));
|
|
18
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
19
|
+
export const DialogContent = React.forwardRef(({ className, children, showCloseButton = true, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, "data-slot": "dialog-content", className: cn("fixed top-1/2 left-1/2 z-50 grid w-full min-w-0 max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 grid-cols-1 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 [&>*]:min-w-0", className), ...props, children: [children, showCloseButton && (_jsx(DialogPrimitive.Close, { "data-slot": "dialog-close", asChild: true, children: _jsxs(Button, { variant: "ghost", size: "icon-sm", className: "absolute top-2 right-2", children: [_jsx(X, { "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: "Close" })] }) }))] })] })));
|
|
20
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
21
|
+
export function DialogHeader({ className, ...props }) {
|
|
22
|
+
return (_jsx("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2", className), ...props }));
|
|
23
|
+
}
|
|
24
|
+
export function DialogFooter({ className, showCloseButton = false, children, ...props }) {
|
|
25
|
+
return (_jsxs("div", { "data-slot": "dialog-footer", className: cn("-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end", className), ...props, children: [children, showCloseButton && (_jsx(DialogPrimitive.Close, { asChild: true, children: _jsx(Button, { variant: "outline", children: "Close" }) }))] }));
|
|
26
|
+
}
|
|
27
|
+
export const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Title, { ref: ref, "data-slot": "dialog-title", className: cn("text-base leading-none font-medium", className), ...props })));
|
|
28
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
29
|
+
export const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Description, { ref: ref, "data-slot": "dialog-description", className: cn("text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className), ...props })));
|
|
30
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export declare function DropdownMenu(props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
export declare const DropdownMenuTrigger: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
export declare const DropdownMenuContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
6
|
+
export declare const DropdownMenuItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
7
|
+
variant?: "default" | "destructive";
|
|
8
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
export function DropdownMenu(props) {
|
|
6
|
+
return _jsx(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
7
|
+
}
|
|
8
|
+
export const DropdownMenuTrigger = React.forwardRef((props, ref) => (_jsx(DropdownMenuPrimitive.Trigger, { ref: ref, "data-slot": "dropdown-menu-trigger", ...props })));
|
|
9
|
+
DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName;
|
|
10
|
+
export const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, collisionPadding = 8, ...props }, ref) => (_jsx(DropdownMenuPrimitive.Portal, { children: _jsx(DropdownMenuPrimitive.Content, { ref: ref, "data-slot": "dropdown-menu-content", sideOffset: sideOffset, collisionPadding: collisionPadding, className: cn("cn-menu-translucent z-50 min-w-36 origin-[var(--radix-dropdown-menu-content-transform-origin)] overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-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", className), ...props }) })));
|
|
11
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
12
|
+
export const DropdownMenuItem = React.forwardRef(({ className, variant = "default", ...props }, ref) => (_jsx(DropdownMenuPrimitive.Item, { ref: ref, "data-slot": "dropdown-menu-item", "data-variant": variant, className: cn("relative flex cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent 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", variant === "destructive" &&
|
|
13
|
+
"text-destructive focus:bg-destructive/10 focus:text-destructive dark:focus:bg-destructive/20", className), ...props })));
|
|
14
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
export const Input = React.forwardRef(({ className, type, ...props }, ref) => (_jsx("input", { ref: ref, type: type, "data-slot": "input", className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className), ...props })));
|
|
5
|
+
Input.displayName = "Input";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface InteractionQuestionOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
}
|
|
7
|
+
export type InteractionQuestionField = {
|
|
8
|
+
id: string;
|
|
9
|
+
type: "text";
|
|
10
|
+
label: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
secret?: boolean;
|
|
14
|
+
multiline?: boolean;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
} | {
|
|
17
|
+
id: string;
|
|
18
|
+
type: "select";
|
|
19
|
+
label: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
required?: boolean;
|
|
22
|
+
multiple?: boolean;
|
|
23
|
+
allowOther?: boolean;
|
|
24
|
+
options: InteractionQuestionOption[];
|
|
25
|
+
};
|
|
26
|
+
export type InteractionQuestionAnswer = string | string[];
|
|
27
|
+
export interface InteractionQuestionProps {
|
|
28
|
+
idPrefix: string;
|
|
29
|
+
fields: readonly InteractionQuestionField[];
|
|
30
|
+
activeFieldId?: string;
|
|
31
|
+
answers: Record<string, InteractionQuestionAnswer>;
|
|
32
|
+
otherValues: Record<string, string>;
|
|
33
|
+
otherSelections: Record<string, boolean>;
|
|
34
|
+
errors?: Record<string, string | undefined>;
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
onNavigate: (fieldId: string) => void;
|
|
37
|
+
onAnswerChange: (fieldId: string, answer: InteractionQuestionAnswer) => void;
|
|
38
|
+
onOtherValueChange: (fieldId: string, value: string) => void;
|
|
39
|
+
onOtherSelectionChange: (fieldId: string, selected: boolean) => void;
|
|
40
|
+
}
|
|
41
|
+
/** Shared one-question-at-a-time editor used by every Rynx web surface. */
|
|
42
|
+
export declare function InteractionQuestion({ idPrefix, fields, activeFieldId, answers, otherValues, otherSelections, errors, disabled, onNavigate, onAnswerChange, onOtherValueChange, onOtherSelectionChange, }: InteractionQuestionProps): React.JSX.Element | null;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Check, ChevronLeft, ChevronRight } from "lucide-react";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Button } from "./button.js";
|
|
5
|
+
import { Input } from "./input.js";
|
|
6
|
+
import { Textarea } from "./textarea.js";
|
|
7
|
+
import { cn } from "../lib/utils.js";
|
|
8
|
+
/** Shared one-question-at-a-time editor used by every Rynx web surface. */
|
|
9
|
+
export function InteractionQuestion({ idPrefix, fields, activeFieldId, answers, otherValues, otherSelections, errors = {}, disabled = false, onNavigate, onAnswerChange, onOtherValueChange, onOtherSelectionChange, }) {
|
|
10
|
+
const questionRef = React.useRef(null);
|
|
11
|
+
const previousFieldIdRef = React.useRef(undefined);
|
|
12
|
+
const previousErrorRef = React.useRef(undefined);
|
|
13
|
+
const requestedIndex = fields.findIndex((candidate) => candidate.id === activeFieldId);
|
|
14
|
+
const index = requestedIndex >= 0 ? requestedIndex : 0;
|
|
15
|
+
const field = fields[index];
|
|
16
|
+
const error = field ? errors[field.id] : undefined;
|
|
17
|
+
const currentAnswer = field ? answers[field.id] : undefined;
|
|
18
|
+
React.useEffect(() => {
|
|
19
|
+
if (!field)
|
|
20
|
+
return;
|
|
21
|
+
const fieldChanged = previousFieldIdRef.current !== undefined
|
|
22
|
+
&& previousFieldIdRef.current !== field.id;
|
|
23
|
+
const errorAppeared = Boolean(error) && previousErrorRef.current !== error;
|
|
24
|
+
previousFieldIdRef.current = field.id;
|
|
25
|
+
previousErrorRef.current = error;
|
|
26
|
+
if (!fieldChanged && !errorAppeared)
|
|
27
|
+
return;
|
|
28
|
+
const container = questionRef.current;
|
|
29
|
+
const focusTarget = container?.querySelector('input[aria-invalid="true"]:not([disabled]), textarea[aria-invalid="true"]:not([disabled])') ?? container?.querySelector("input:checked:not([disabled])")
|
|
30
|
+
?? container?.querySelector("input:not([disabled]), textarea:not([disabled])");
|
|
31
|
+
focusTarget?.focus();
|
|
32
|
+
}, [error, field]);
|
|
33
|
+
if (!field)
|
|
34
|
+
return null;
|
|
35
|
+
const domId = `${idPrefix}-field-${index}`;
|
|
36
|
+
const descriptionId = field.description ? `${domId}-description` : undefined;
|
|
37
|
+
const errorId = error ? `${domId}-error` : undefined;
|
|
38
|
+
const describedBy = [descriptionId, errorId].filter(Boolean).join(" ") || undefined;
|
|
39
|
+
return (_jsxs("div", { className: "grid gap-3", children: [fields.length > 1 && (_jsxs("div", { className: "grid gap-1.5", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { "aria-live": "polite", className: "font-mono text-[10px] uppercase tracking-[0.14em] text-muted-foreground", children: ["Question ", index + 1, " of ", fields.length] }), _jsx("div", { className: "text-[11px] text-muted-foreground", children: field.required ? "Required" : "Optional" })] }), _jsx("div", { role: "progressbar", "aria-label": "Question progress", "aria-valuemin": 1, "aria-valuemax": fields.length, "aria-valuenow": index + 1, className: "h-1 overflow-hidden rounded-full bg-muted", children: _jsx("div", { className: "h-full rounded-full bg-primary transition-[width]", style: { width: `${((index + 1) / fields.length) * 100}%` } }) })] })), _jsx("div", { ref: questionRef, children: field.type === "text" ? (_jsxs("div", { className: "grid gap-1.5", children: [_jsxs("label", { htmlFor: domId, className: "text-xs font-medium text-foreground", children: [field.label, field.required && _jsx(RequiredIndicator, {})] }), field.description && (_jsx("p", { id: descriptionId, className: "text-[11px] leading-relaxed text-muted-foreground", children: field.description })), field.multiline && !field.secret ? (_jsx(Textarea, { id: domId, value: typeof currentAnswer === "string" ? currentAnswer : "", disabled: disabled, placeholder: field.placeholder, "aria-invalid": error ? true : undefined, "aria-describedby": describedBy, required: field.required, onChange: (event) => onAnswerChange(field.id, event.target.value) })) : (_jsx(Input, { id: domId, type: field.secret ? "password" : "text", autoComplete: "off", value: typeof currentAnswer === "string" ? currentAnswer : "", disabled: disabled, placeholder: field.placeholder, "aria-invalid": error ? true : undefined, "aria-describedby": describedBy, required: field.required, onChange: (event) => onAnswerChange(field.id, event.target.value) })), _jsx(FieldError, { id: errorId, error: error })] })) : (_jsxs("fieldset", { disabled: disabled, role: field.multiple ? undefined : "radiogroup", "aria-required": !field.multiple && field.required ? true : undefined, "aria-invalid": error ? true : undefined, "aria-describedby": describedBy, className: "grid gap-1.5", children: [_jsxs("legend", { className: "text-xs font-medium text-foreground", children: [field.label, field.required && _jsx(RequiredIndicator, {})] }), field.description && (_jsx("p", { id: descriptionId, className: "text-[11px] leading-relaxed text-muted-foreground", children: field.description })), _jsxs("div", { className: "grid gap-1.5", children: [field.options.map((option, optionIndex) => {
|
|
40
|
+
const optionId = `${domId}-option-${optionIndex}`;
|
|
41
|
+
const checked = field.multiple
|
|
42
|
+
? Array.isArray(currentAnswer) && currentAnswer.includes(option.value)
|
|
43
|
+
: otherSelections[field.id] !== true && currentAnswer === option.value;
|
|
44
|
+
return (_jsx(ChoiceRow, { id: optionId, name: field.multiple ? undefined : domId, type: field.multiple ? "checkbox" : "radio", checked: checked, label: option.label, description: option.description, onChange: (selected) => {
|
|
45
|
+
if (field.multiple) {
|
|
46
|
+
const values = Array.isArray(currentAnswer) ? currentAnswer : [];
|
|
47
|
+
onAnswerChange(field.id, selected
|
|
48
|
+
? [...values.filter((value) => value !== option.value), option.value]
|
|
49
|
+
: values.filter((value) => value !== option.value));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
onAnswerChange(field.id, option.value);
|
|
53
|
+
onOtherSelectionChange(field.id, false);
|
|
54
|
+
}
|
|
55
|
+
} }, option.value));
|
|
56
|
+
}), field.allowOther && (_jsxs("div", { className: "grid gap-1.5 rounded-lg border border-border bg-background/60 px-2.5 py-2 has-[:checked]:border-primary/50 has-[:checked]:bg-primary/5", children: [_jsx(ChoiceRow, { id: `${domId}-other`, name: field.multiple ? undefined : domId, type: field.multiple ? "checkbox" : "radio", checked: otherSelections[field.id] === true, label: "Other", embedded: true, onChange: (selected) => {
|
|
57
|
+
onOtherSelectionChange(field.id, selected);
|
|
58
|
+
if (selected && !field.multiple)
|
|
59
|
+
onAnswerChange(field.id, "");
|
|
60
|
+
} }), _jsx(Input, { value: otherValues[field.id] ?? "", disabled: disabled || otherSelections[field.id] !== true, "aria-label": `Other answer for ${field.label}`, "aria-invalid": error ? true : undefined, "aria-describedby": describedBy, placeholder: "Enter another answer", onChange: (event) => onOtherValueChange(field.id, event.target.value) })] })), !field.required
|
|
61
|
+
&& !field.multiple
|
|
62
|
+
&& (otherSelections[field.id] === true
|
|
63
|
+
|| (typeof currentAnswer === "string" && currentAnswer.length > 0)) && (_jsx(Button, { type: "button", size: "xs", variant: "ghost", className: "justify-self-start text-muted-foreground", onClick: () => {
|
|
64
|
+
onAnswerChange(field.id, "");
|
|
65
|
+
onOtherSelectionChange(field.id, false);
|
|
66
|
+
}, children: "Clear selection" }))] }), _jsx(FieldError, { id: errorId, error: error })] })) }), fields.length > 1 && (_jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-border/70 pt-2", children: [_jsxs(Button, { type: "button", size: "xs", variant: "ghost", disabled: disabled || index === 0, onClick: () => onNavigate(fields[index - 1].id), children: [_jsx(ChevronLeft, {}), "Previous"] }), _jsxs(Button, { type: "button", size: "xs", variant: "outline", disabled: disabled || index === fields.length - 1, onClick: () => onNavigate(fields[index + 1].id), children: ["Next", _jsx(ChevronRight, {})] })] }))] }));
|
|
67
|
+
}
|
|
68
|
+
function ChoiceRow({ id, name, type, checked, label, description, embedded = false, onChange, }) {
|
|
69
|
+
return (_jsxs("label", { htmlFor: id, className: cn("flex cursor-pointer items-start gap-2 text-xs text-foreground", !embedded
|
|
70
|
+
&& "rounded-lg border border-border bg-background/60 px-2.5 py-2 transition-colors hover:bg-muted/60 has-[:checked]:border-primary/50 has-[:checked]:bg-primary/5"), children: [_jsxs("span", { className: "relative mt-0.5 size-4 shrink-0", children: [_jsx("input", { id: id, type: type, name: name, checked: checked, className: "peer size-4 appearance-none rounded-sm border border-input bg-background outline-none transition-colors checked:border-primary checked:bg-primary focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-60", onChange: (event) => onChange(event.target.checked) }), _jsx(Check, { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 size-4 stroke-[3] text-primary-foreground opacity-0 peer-checked:opacity-100" })] }), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block", children: label }), description && (_jsx("span", { className: "mt-0.5 block text-[11px] leading-relaxed text-muted-foreground", children: description }))] })] }));
|
|
71
|
+
}
|
|
72
|
+
function FieldError({ id, error }) {
|
|
73
|
+
if (!error)
|
|
74
|
+
return null;
|
|
75
|
+
return (_jsx("p", { id: id, role: "alert", className: "text-[11px] text-destructive", children: error }));
|
|
76
|
+
}
|
|
77
|
+
function RequiredIndicator() {
|
|
78
|
+
return (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": "true", className: "ml-0.5 text-destructive", children: "*" }), _jsx("span", { className: "sr-only", children: " (required)" })] }));
|
|
79
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type NativeSelectProps = Omit<React.ComponentProps<"select">, "size"> & {
|
|
3
|
+
size?: "sm" | "default";
|
|
4
|
+
};
|
|
5
|
+
export declare function NativeSelect({ className, size, ...props }: NativeSelectProps): React.JSX.Element;
|
|
6
|
+
export declare function NativeSelectOption({ className, ...props }: React.ComponentProps<"option">): React.JSX.Element;
|
|
7
|
+
export declare function NativeSelectOptGroup({ className, ...props }: React.ComponentProps<"optgroup">): React.JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ChevronDown } from "lucide-react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
export function NativeSelect({ className, size = "default", ...props }) {
|
|
5
|
+
return (_jsxs("div", { "data-slot": "native-select-wrapper", "data-size": size, className: cn("group/native-select relative w-fit has-[select:disabled]:opacity-50", className), children: [_jsx("select", { "data-slot": "native-select", "data-size": size, className: "h-8 w-full min-w-0 appearance-none rounded-lg border border-input bg-transparent py-1 pr-8 pl-2.5 text-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-[size=sm]:py-0.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", ...props }), _jsx(ChevronDown, { "aria-hidden": "true", "data-slot": "native-select-icon", className: "pointer-events-none absolute top-1/2 right-2.5 size-4 -translate-y-1/2 text-muted-foreground select-none" })] }));
|
|
6
|
+
}
|
|
7
|
+
export function NativeSelectOption({ className, ...props }) {
|
|
8
|
+
return (_jsx("option", { "data-slot": "native-select-option", className: cn("bg-[Canvas] text-[CanvasText]", className), ...props }));
|
|
9
|
+
}
|
|
10
|
+
export function NativeSelectOptGroup({ className, ...props }) {
|
|
11
|
+
return (_jsx("optgroup", { "data-slot": "native-select-optgroup", className: cn("bg-[Canvas] text-[CanvasText]", className), ...props }));
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export declare const ScrollArea: React.ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
4
|
+
viewportClassName?: string;
|
|
5
|
+
viewportRef?: React.Ref<React.ElementRef<typeof ScrollAreaPrimitive.Viewport>>;
|
|
6
|
+
viewportProps?: Omit<React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Viewport>, "children" | "className">;
|
|
7
|
+
scrollbars?: "vertical" | "horizontal" | "both";
|
|
8
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
9
|
+
export declare const ScrollBar: React.ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaScrollbarProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
export const ScrollArea = React.forwardRef(({ className, children, viewportClassName, viewportRef, viewportProps, scrollbars = "vertical", type = "auto", ...props }, ref) => (_jsxs(ScrollAreaPrimitive.Root, { ref: ref, "data-slot": "scroll-area", type: type, className: cn("relative overflow-hidden", className), ...props, children: [_jsx(ScrollAreaPrimitive.Viewport, { ref: viewportRef, "data-slot": "scroll-area-viewport", className: cn("size-full rounded-[inherit] outline-none transition-[color,box-shadow] focus-visible:ring-2 focus-visible:ring-[var(--ring)]/45", scrollbars === "vertical" && "[&>div]:!block [&>div]:min-w-0 [&>div]:w-full", viewportClassName), ...viewportProps, children: children }), scrollbars !== "horizontal" && _jsx(ScrollBar, { orientation: "vertical" }), scrollbars !== "vertical" && _jsx(ScrollBar, { orientation: "horizontal" }), _jsx(ScrollAreaPrimitive.Corner, { "data-slot": "scroll-area-corner" })] })));
|
|
6
|
+
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
7
|
+
export const ScrollBar = React.forwardRef(({ className, orientation = "vertical", style, ...props }, ref) => (_jsx(ScrollAreaPrimitive.ScrollAreaScrollbar, { ref: ref, "data-slot": "scroll-area-scrollbar", orientation: orientation, className: cn("group flex touch-none select-none p-px transition-colors", orientation === "vertical" && "h-full w-2", orientation === "horizontal" && "h-2 flex-col", className), style: {
|
|
8
|
+
...(orientation === "vertical" ? { right: 2 } : { bottom: 2 }),
|
|
9
|
+
...style,
|
|
10
|
+
}, ...props, children: _jsx(ScrollAreaPrimitive.ScrollAreaThumb, { "data-slot": "scroll-area-thumb", className: cn("relative flex-1 rounded-full bg-[var(--scrollbar-thumb)] transition-colors group-hover:bg-[var(--scrollbar-thumb-hover)] active:bg-[var(--scrollbar-thumb-active)]", orientation === "vertical" ? "min-h-8 w-full" : "h-full min-w-8") }) })));
|
|
11
|
+
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export declare function Select(props: React.ComponentProps<typeof SelectPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
export declare const SelectGroup: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectGroupProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
5
|
+
export declare const SelectValue: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectValueProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
6
|
+
export declare const SelectTrigger: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & {
|
|
7
|
+
size?: "sm" | "default";
|
|
8
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
9
|
+
export declare const SelectScrollUpButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollUpButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
export declare const SelectScrollDownButton: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectScrollDownButtonProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
11
|
+
export declare const SelectContent: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
export declare const SelectLabel: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectLabelProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
13
|
+
export declare const SelectItem: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
14
|
+
export declare const SelectSeparator: React.ForwardRefExoticComponent<Omit<SelectPrimitive.SelectSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
3
|
+
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { cn } from "../lib/utils.js";
|
|
6
|
+
export function Select(props) {
|
|
7
|
+
return _jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
|
|
8
|
+
}
|
|
9
|
+
export const SelectGroup = React.forwardRef(({ className, ...props }, ref) => (_jsx(SelectPrimitive.Group, { ref: ref, "data-slot": "select-group", className: cn("scroll-my-1 p-1", className), ...props })));
|
|
10
|
+
SelectGroup.displayName = SelectPrimitive.Group.displayName;
|
|
11
|
+
export const SelectValue = React.forwardRef((props, ref) => _jsx(SelectPrimitive.Value, { ref: ref, "data-slot": "select-value", ...props }));
|
|
12
|
+
SelectValue.displayName = SelectPrimitive.Value.displayName;
|
|
13
|
+
export const SelectTrigger = React.forwardRef(({ className, size = "default", children, ...props }, ref) => (_jsxs(SelectPrimitive.Trigger, { ref: ref, "data-slot": "select-trigger", "data-size": size, className: cn("flex w-full min-w-0 items-center justify-between gap-1.5 whitespace-nowrap rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm 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)] dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&>span]:min-w-0 [&>span]:truncate [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDown, { "aria-hidden": "true", className: "pointer-events-none size-4 shrink-0 text-muted-foreground" }) })] })));
|
|
14
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
15
|
+
export const SelectScrollUpButton = React.forwardRef(({ className, ...props }, ref) => (_jsx(SelectPrimitive.ScrollUpButton, { ref: ref, "data-slot": "select-scroll-up-button", className: cn("z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: _jsx(ChevronUp, { "aria-hidden": "true" }) })));
|
|
16
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
17
|
+
export const SelectScrollDownButton = React.forwardRef(({ className, ...props }, ref) => (_jsx(SelectPrimitive.ScrollDownButton, { ref: ref, "data-slot": "select-scroll-down-button", className: cn("z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: _jsx(ChevronDown, { "aria-hidden": "true" }) })));
|
|
18
|
+
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
19
|
+
export const SelectContent = React.forwardRef(({ className, children, position = "popper", align = "center", sideOffset = 4, collisionPadding = 8, ...props }, ref) => (_jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { ref: ref, "data-slot": "select-content", "data-align-trigger": position === "item-aligned", position: position, align: align, sideOffset: sideOffset, collisionPadding: collisionPadding, className: cn("cn-menu-translucent relative z-50 max-h-[var(--radix-select-content-available-height)] min-w-36 origin-[var(--radix-select-content-transform-origin)] overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-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", position === "popper" &&
|
|
20
|
+
"w-[var(--radix-select-trigger-width)] data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className), ...props, children: [_jsx(SelectScrollUpButton, {}), _jsx(SelectPrimitive.Viewport, { "data-position": position, className: cn("p-1", position === "popper" &&
|
|
21
|
+
"min-w-[var(--radix-select-trigger-width)]"), children: children }), _jsx(SelectScrollDownButton, {})] }) })));
|
|
22
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
23
|
+
export const SelectLabel = React.forwardRef(({ className, ...props }, ref) => (_jsx(SelectPrimitive.Label, { ref: ref, "data-slot": "select-label", className: cn("px-1.5 py-1 text-xs text-muted-foreground", className), ...props })));
|
|
24
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
25
|
+
export const SelectItem = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(SelectPrimitive.Item, { ref: ref, "data-slot": "select-item", className: cn("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 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [_jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center", children: _jsx(SelectPrimitive.ItemIndicator, { children: _jsx(Check, { "aria-hidden": "true", className: "pointer-events-none" }) }) }), _jsx(SelectPrimitive.ItemText, { children: children })] })));
|
|
26
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
27
|
+
export const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => (_jsx(SelectPrimitive.Separator, { ref: ref, "data-slot": "select-separator", className: cn("pointer-events-none -mx-1 my-1 h-px bg-border", className), ...props })));
|
|
28
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export declare function Tabs(props: React.ComponentProps<typeof TabsPrimitive.Root>): React.JSX.Element;
|
|
4
|
+
export declare const TabsList: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsListProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
5
|
+
export declare const TabsTrigger: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsTriggerProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
export declare const TabsContent: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
export function Tabs(props) {
|
|
6
|
+
return _jsx(TabsPrimitive.Root, { "data-slot": "tabs", ...props });
|
|
7
|
+
}
|
|
8
|
+
export const TabsList = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.List, { ref: ref, "data-slot": "tabs-list", className: cn("inline-flex h-9 items-center gap-1 rounded-lg bg-muted p-1 text-muted-foreground", className), ...props })));
|
|
9
|
+
TabsList.displayName = "TabsList";
|
|
10
|
+
export const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Trigger, { ref: ref, "data-slot": "tabs-trigger", className: cn("inline-flex h-7 items-center justify-center whitespace-nowrap rounded-md border border-transparent px-3 text-sm font-medium transition-all outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-border data-[state=active]:bg-background data-[state=active]:text-foreground", className), ...props })));
|
|
11
|
+
TabsTrigger.displayName = "TabsTrigger";
|
|
12
|
+
export const TabsContent = React.forwardRef(({ className, ...props }, ref) => (_jsx(TabsPrimitive.Content, { ref: ref, "data-slot": "tabs-content", className: cn("mt-4 outline-none", className), ...props })));
|
|
13
|
+
TabsContent.displayName = "TabsContent";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
export function Textarea({ className, ...props }) {
|
|
4
|
+
return (_jsx("textarea", { "data-slot": "textarea", className: cn("flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className), ...props }));
|
|
5
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./components/alert-dialog.js";
|
|
2
|
+
export * from "./components/button.js";
|
|
3
|
+
export * from "./components/dialog.js";
|
|
4
|
+
export * from "./components/dropdown-menu.js";
|
|
5
|
+
export * from "./components/input.js";
|
|
6
|
+
export * from "./components/interaction-question.js";
|
|
7
|
+
export * from "./components/native-select.js";
|
|
8
|
+
export * from "./components/scroll-area.js";
|
|
9
|
+
export * from "./components/select.js";
|
|
10
|
+
export * from "./components/tabs.js";
|
|
11
|
+
export * from "./components/textarea.js";
|
|
12
|
+
export * from "./lib/utils.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./components/alert-dialog.js";
|
|
2
|
+
export * from "./components/button.js";
|
|
3
|
+
export * from "./components/dialog.js";
|
|
4
|
+
export * from "./components/dropdown-menu.js";
|
|
5
|
+
export * from "./components/input.js";
|
|
6
|
+
export * from "./components/interaction-question.js";
|
|
7
|
+
export * from "./components/native-select.js";
|
|
8
|
+
export * from "./components/scroll-area.js";
|
|
9
|
+
export * from "./components/select.js";
|
|
10
|
+
export * from "./components/tabs.js";
|
|
11
|
+
export * from "./components/textarea.js";
|
|
12
|
+
export * from "./lib/utils.js";
|