@tangle-network/ui 11.17.0 → 11.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/index.d.ts +10 -1
  3. package/dist/index.js +10 -1
  4. package/dist/primitives/alert-dialog.d.ts +34 -0
  5. package/dist/primitives/alert-dialog.js +68 -0
  6. package/dist/primitives/checkbox.d.ts +12 -0
  7. package/dist/primitives/checkbox.js +34 -0
  8. package/dist/primitives/collapsible.d.ts +12 -0
  9. package/dist/primitives/collapsible.js +13 -0
  10. package/dist/primitives/context-menu.d.ts +36 -0
  11. package/dist/primitives/context-menu.js +86 -0
  12. package/dist/primitives/popover.d.ts +15 -0
  13. package/dist/primitives/popover.js +25 -0
  14. package/dist/primitives/separator.d.ts +11 -0
  15. package/dist/primitives/separator.js +21 -0
  16. package/dist/primitives/sheet.d.ts +28 -0
  17. package/dist/primitives/sheet.js +70 -0
  18. package/dist/primitives/slider.d.ts +14 -0
  19. package/dist/primitives/slider.js +37 -0
  20. package/dist/primitives/theme-toggle.js +8 -0
  21. package/dist/primitives/tooltip.d.ts +16 -0
  22. package/dist/primitives/tooltip.js +32 -0
  23. package/dist/primitives.d.ts +10 -1
  24. package/dist/primitives.js +10 -1
  25. package/package.json +9 -2
  26. package/src/primitives/alert-dialog.tsx +139 -0
  27. package/src/primitives/checkbox-separator-sheet-tooltip.stories.tsx +92 -0
  28. package/src/primitives/checkbox-separator-sheet-tooltip.test.tsx +107 -0
  29. package/src/primitives/checkbox.tsx +42 -0
  30. package/src/primitives/collapsible.tsx +16 -0
  31. package/src/primitives/context-menu.tsx +168 -0
  32. package/src/primitives/index.ts +57 -0
  33. package/src/primitives/popover-collapsible-alert-dialog-context-menu-slider.stories.tsx +124 -0
  34. package/src/primitives/popover-collapsible-alert-dialog-context-menu-slider.test.tsx +165 -0
  35. package/src/primitives/popover.tsx +45 -0
  36. package/src/primitives/separator.tsx +30 -0
  37. package/src/primitives/sheet.tsx +134 -0
  38. package/src/primitives/slider.tsx +71 -0
  39. package/src/primitives/theme-toggle.test.tsx +2 -1
  40. package/src/primitives/theme-toggle.tsx +2 -0
  41. package/src/primitives/tooltip.tsx +54 -0
  42. package/src/stories/theme-showcase.stories.tsx +2 -0
@@ -0,0 +1,134 @@
1
+ "use client";
2
+
3
+ import * as SheetPrimitive from "@radix-ui/react-dialog";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+ import { X } from "lucide-react";
6
+ import * as React from "react";
7
+ import { focusRing } from "../lib/focus";
8
+ import { cn } from "../lib/utils";
9
+
10
+ /** A dialog that slides in from an edge: a mobile nav drawer or a side panel. */
11
+ const Sheet = SheetPrimitive.Root;
12
+
13
+ const SheetTrigger = SheetPrimitive.Trigger;
14
+
15
+ const SheetClose = SheetPrimitive.Close;
16
+
17
+ const SheetPortal = SheetPrimitive.Portal;
18
+
19
+ const SheetOverlay = React.forwardRef<
20
+ React.ElementRef<typeof SheetPrimitive.Overlay>,
21
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
22
+ >(({ className, ...props }, ref) => (
23
+ <SheetPrimitive.Overlay
24
+ ref={ref}
25
+ className={cn(
26
+ "fixed inset-0 z-50 bg-black/40",
27
+ "data-[state=closed]:animate-out data-[state=open]:animate-in",
28
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
29
+ className,
30
+ )}
31
+ {...props}
32
+ />
33
+ ));
34
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
35
+
36
+ const sheetVariants = cva(
37
+ [
38
+ "fixed z-50 flex flex-col gap-4 border-border bg-card shadow-lg",
39
+ "data-[state=closed]:animate-out data-[state=open]:animate-in",
40
+ "data-[state=closed]:duration-200 data-[state=open]:duration-300 ease-out motion-reduce:animate-none",
41
+ ],
42
+ {
43
+ variants: {
44
+ side: {
45
+ right:
46
+ "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
47
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
48
+ top: "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
49
+ bottom:
50
+ "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
51
+ },
52
+ },
53
+ defaultVariants: { side: "right" },
54
+ },
55
+ );
56
+
57
+ const SheetContent = React.forwardRef<
58
+ React.ElementRef<typeof SheetPrimitive.Content>,
59
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content> &
60
+ VariantProps<typeof sheetVariants> & {
61
+ /** Hide only the built-in close button; Escape and outside clicks still dismiss. */
62
+ hideCloseButton?: boolean;
63
+ }
64
+ >(({ className, children, side = "right", hideCloseButton = false, ...props }, ref) => (
65
+ <SheetPortal>
66
+ <SheetOverlay />
67
+ <SheetPrimitive.Content
68
+ ref={ref}
69
+ className={cn(sheetVariants({ side }), className)}
70
+ {...props}
71
+ >
72
+ {children}
73
+ {!hideCloseButton && (
74
+ <SheetPrimitive.Close
75
+ className={cn(
76
+ "absolute top-4 right-4 rounded-sm text-muted-foreground opacity-70 transition-[opacity,box-shadow] hover:opacity-100 focus-visible:opacity-100 disabled:pointer-events-none",
77
+ focusRing,
78
+ )}
79
+ >
80
+ <X className="size-4" />
81
+ <span className="sr-only">Close</span>
82
+ </SheetPrimitive.Close>
83
+ )}
84
+ </SheetPrimitive.Content>
85
+ </SheetPortal>
86
+ ));
87
+ SheetContent.displayName = SheetPrimitive.Content.displayName;
88
+
89
+ const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
90
+ <div className={cn("flex flex-col gap-1.5 p-4 pr-10", className)} {...props} />
91
+ );
92
+ SheetHeader.displayName = "SheetHeader";
93
+
94
+ const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
95
+ <div className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />
96
+ );
97
+ SheetFooter.displayName = "SheetFooter";
98
+
99
+ const SheetTitle = React.forwardRef<
100
+ React.ElementRef<typeof SheetPrimitive.Title>,
101
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
102
+ >(({ className, ...props }, ref) => (
103
+ <SheetPrimitive.Title
104
+ ref={ref}
105
+ className={cn("font-semibold text-base text-foreground leading-tight", className)}
106
+ {...props}
107
+ />
108
+ ));
109
+ SheetTitle.displayName = SheetPrimitive.Title.displayName;
110
+
111
+ const SheetDescription = React.forwardRef<
112
+ React.ElementRef<typeof SheetPrimitive.Description>,
113
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
114
+ >(({ className, ...props }, ref) => (
115
+ <SheetPrimitive.Description
116
+ ref={ref}
117
+ className={cn("text-muted-foreground text-sm", className)}
118
+ {...props}
119
+ />
120
+ ));
121
+ SheetDescription.displayName = SheetPrimitive.Description.displayName;
122
+
123
+ export {
124
+ Sheet,
125
+ SheetClose,
126
+ SheetContent,
127
+ SheetDescription,
128
+ SheetFooter,
129
+ SheetHeader,
130
+ SheetOverlay,
131
+ SheetPortal,
132
+ SheetTitle,
133
+ SheetTrigger,
134
+ };
@@ -0,0 +1,71 @@
1
+ "use client";
2
+
3
+ import * as SliderPrimitive from "@radix-ui/react-slider";
4
+ import * as React from "react";
5
+ import { focusRing } from "../lib/focus";
6
+ import { cn } from "../lib/utils";
7
+
8
+ /**
9
+ * Range input with one thumb per value. A single value renders one thumb; an
10
+ * array of two renders a range. The thumbs are what assistive technology
11
+ * focuses, so the names go on them: `aria-label` / `aria-labelledby` name a
12
+ * single thumb, and `thumbLabels` names each thumb of a range.
13
+ */
14
+ const Slider = React.forwardRef<
15
+ React.ElementRef<typeof SliderPrimitive.Root>,
16
+ React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> & {
17
+ thumbLabels?: string[];
18
+ }
19
+ >(
20
+ (
21
+ {
22
+ className,
23
+ defaultValue,
24
+ value,
25
+ min = 0,
26
+ max = 100,
27
+ thumbLabels,
28
+ "aria-label": ariaLabel,
29
+ "aria-labelledby": ariaLabelledBy,
30
+ ...props
31
+ },
32
+ ref,
33
+ ) => {
34
+ const values = Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min];
35
+ const single = values.length === 1;
36
+
37
+ return (
38
+ <SliderPrimitive.Root
39
+ ref={ref}
40
+ defaultValue={defaultValue}
41
+ value={value}
42
+ min={min}
43
+ max={max}
44
+ className={cn(
45
+ "relative flex w-full touch-none select-none items-center data-[disabled]:opacity-50",
46
+ "data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
47
+ className,
48
+ )}
49
+ {...props}
50
+ >
51
+ <SliderPrimitive.Track className="relative grow overflow-hidden rounded-full bg-muted data-[orientation=horizontal]:h-1.5 data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-1.5">
52
+ <SliderPrimitive.Range className="absolute bg-primary data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full" />
53
+ </SliderPrimitive.Track>
54
+ {values.map((_, index) => (
55
+ <SliderPrimitive.Thumb
56
+ key={index}
57
+ aria-label={thumbLabels?.[index] ?? (single ? ariaLabel : undefined)}
58
+ aria-labelledby={single && !thumbLabels?.[index] ? ariaLabelledBy : undefined}
59
+ className={cn(
60
+ "block size-4 shrink-0 rounded-full border border-primary bg-background shadow-sm transition-[box-shadow] disabled:pointer-events-none",
61
+ focusRing,
62
+ )}
63
+ />
64
+ ))}
65
+ </SliderPrimitive.Root>
66
+ );
67
+ },
68
+ );
69
+ Slider.displayName = SliderPrimitive.Root.displayName;
70
+
71
+ export { Slider };
@@ -101,7 +101,8 @@ describe("root mode preference", () => {
101
101
  });
102
102
 
103
103
  it.each([
104
- ["aubergine", "aubergine-light"], ["arena", "arena-light"], ["tangle-dark", "tangle-light"],
104
+ ["aubergine", "aubergine-light"], ["arena", "arena-light"], ["super", "super-light"], ["tangle-dark", "tangle-light"],
105
+ ["agents", "agents-light"],
105
106
  ])("keeps the %s named family in both directions", (name, lightName) => {
106
107
  document.documentElement.dataset.theme = name;
107
108
  render(<ThemeToggle />);
@@ -10,7 +10,9 @@ const systemQuery = "(prefers-color-scheme: dark)";
10
10
  const namedModes = [
11
11
  { dark: "aubergine", light: "aubergine-light" },
12
12
  { dark: "arena", light: "arena-light" },
13
+ { dark: "super", light: "super-light" },
13
14
  { dark: "tangle-dark", light: "tangle-light" },
15
+ { dark: "agents", light: "agents-light" },
14
16
  ] as const;
15
17
 
16
18
  // Client-only preference cache also keeps the control usable when storage is
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
4
+ import * as React from "react";
5
+ import { cn } from "../lib/utils";
6
+
7
+ /**
8
+ * Wrap an app (or a toolbar) once. The open delay applies to the first tooltip;
9
+ * moving between triggers inside `skipDelayDuration` opens the next one at
10
+ * once, which keeps an icon rail fast to scan.
11
+ */
12
+ const TooltipProvider = ({
13
+ delayDuration = 400,
14
+ skipDelayDuration = 300,
15
+ ...props
16
+ }: React.ComponentProps<typeof TooltipPrimitive.Provider>) => (
17
+ <TooltipPrimitive.Provider
18
+ delayDuration={delayDuration}
19
+ skipDelayDuration={skipDelayDuration}
20
+ {...props}
21
+ />
22
+ );
23
+ TooltipProvider.displayName = "TooltipProvider";
24
+
25
+ const Tooltip = TooltipPrimitive.Root;
26
+
27
+ const TooltipTrigger = TooltipPrimitive.Trigger;
28
+
29
+ /**
30
+ * Inverse-surface label for a control whose name is otherwise only an icon.
31
+ * It is supplementary: the trigger still needs its own accessible name.
32
+ */
33
+ const TooltipContent = React.forwardRef<
34
+ React.ElementRef<typeof TooltipPrimitive.Content>,
35
+ React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
36
+ >(({ className, sideOffset = 6, ...props }, ref) => (
37
+ <TooltipPrimitive.Portal>
38
+ <TooltipPrimitive.Content
39
+ ref={ref}
40
+ sideOffset={sideOffset}
41
+ className={cn(
42
+ "z-50 max-w-xs origin-(--radix-tooltip-content-transform-origin) rounded-md bg-foreground px-2.5 py-1.5 text-background text-xs leading-snug shadow-md",
43
+ "data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95",
44
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
45
+ "duration-150 ease-out motion-reduce:animate-none",
46
+ className,
47
+ )}
48
+ {...props}
49
+ />
50
+ </TooltipPrimitive.Portal>
51
+ ));
52
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
53
+
54
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
@@ -17,6 +17,8 @@ const THEMES: { name: string; theme?: string }[] = [
17
17
  { name: "Aubergine · light", theme: "aubergine-light" },
18
18
  { name: "Experimental green", theme: "arena" },
19
19
  { name: "Experimental green · light", theme: "arena-light" },
20
+ { name: "Super (forest)", theme: "super" },
21
+ { name: "Super · light", theme: "super-light" },
20
22
  ];
21
23
 
22
24
  const NOW = Date.now();