@djangocfg/ui-core 1.0.1

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 (88) hide show
  1. package/README.md +135 -0
  2. package/package.json +111 -0
  3. package/src/components/accordion.tsx +56 -0
  4. package/src/components/alert-dialog.tsx +142 -0
  5. package/src/components/alert.tsx +59 -0
  6. package/src/components/aspect-ratio.tsx +7 -0
  7. package/src/components/avatar.tsx +50 -0
  8. package/src/components/badge.tsx +36 -0
  9. package/src/components/button-group.tsx +85 -0
  10. package/src/components/button.tsx +111 -0
  11. package/src/components/calendar.tsx +213 -0
  12. package/src/components/card.tsx +76 -0
  13. package/src/components/carousel.tsx +261 -0
  14. package/src/components/chart.tsx +369 -0
  15. package/src/components/checkbox.tsx +29 -0
  16. package/src/components/collapsible.tsx +11 -0
  17. package/src/components/combobox.tsx +182 -0
  18. package/src/components/command.tsx +170 -0
  19. package/src/components/context-menu.tsx +200 -0
  20. package/src/components/copy.tsx +144 -0
  21. package/src/components/dialog.tsx +122 -0
  22. package/src/components/drawer.tsx +137 -0
  23. package/src/components/empty.tsx +104 -0
  24. package/src/components/field.tsx +244 -0
  25. package/src/components/form.tsx +178 -0
  26. package/src/components/hover-card.tsx +29 -0
  27. package/src/components/image-with-fallback.tsx +170 -0
  28. package/src/components/index.ts +86 -0
  29. package/src/components/input-group.tsx +170 -0
  30. package/src/components/input-otp.tsx +81 -0
  31. package/src/components/input.tsx +22 -0
  32. package/src/components/item.tsx +195 -0
  33. package/src/components/kbd.tsx +28 -0
  34. package/src/components/label.tsx +26 -0
  35. package/src/components/multi-select.tsx +222 -0
  36. package/src/components/og-image.tsx +47 -0
  37. package/src/components/popover.tsx +33 -0
  38. package/src/components/portal.tsx +106 -0
  39. package/src/components/preloader.tsx +250 -0
  40. package/src/components/progress.tsx +28 -0
  41. package/src/components/radio-group.tsx +43 -0
  42. package/src/components/resizable.tsx +111 -0
  43. package/src/components/scroll-area.tsx +102 -0
  44. package/src/components/section.tsx +58 -0
  45. package/src/components/select.tsx +158 -0
  46. package/src/components/separator.tsx +31 -0
  47. package/src/components/sheet.tsx +140 -0
  48. package/src/components/skeleton.tsx +15 -0
  49. package/src/components/slider.tsx +28 -0
  50. package/src/components/spinner.tsx +16 -0
  51. package/src/components/sticky.tsx +117 -0
  52. package/src/components/switch.tsx +29 -0
  53. package/src/components/table.tsx +120 -0
  54. package/src/components/tabs.tsx +238 -0
  55. package/src/components/textarea.tsx +22 -0
  56. package/src/components/toast.tsx +129 -0
  57. package/src/components/toaster.tsx +41 -0
  58. package/src/components/toggle-group.tsx +61 -0
  59. package/src/components/toggle.tsx +45 -0
  60. package/src/components/token-icon.tsx +156 -0
  61. package/src/components/tooltip-provider-safe.tsx +43 -0
  62. package/src/components/tooltip.tsx +32 -0
  63. package/src/hooks/index.ts +15 -0
  64. package/src/hooks/useCopy.ts +41 -0
  65. package/src/hooks/useCountdown.ts +73 -0
  66. package/src/hooks/useDebounce.ts +25 -0
  67. package/src/hooks/useDebouncedCallback.ts +58 -0
  68. package/src/hooks/useDebugTools.ts +52 -0
  69. package/src/hooks/useEventsBus.ts +53 -0
  70. package/src/hooks/useImageLoader.ts +95 -0
  71. package/src/hooks/useMediaQuery.ts +40 -0
  72. package/src/hooks/useMobile.tsx +22 -0
  73. package/src/hooks/useToast.ts +194 -0
  74. package/src/index.ts +14 -0
  75. package/src/lib/index.ts +2 -0
  76. package/src/lib/og-image.ts +151 -0
  77. package/src/lib/utils.ts +6 -0
  78. package/src/styles/base.css +20 -0
  79. package/src/styles/globals.css +12 -0
  80. package/src/styles/index.css +25 -0
  81. package/src/styles/sources.css +11 -0
  82. package/src/styles/theme/animations.css +65 -0
  83. package/src/styles/theme/dark.css +49 -0
  84. package/src/styles/theme/light.css +50 -0
  85. package/src/styles/theme/tokens.css +134 -0
  86. package/src/styles/theme.css +22 -0
  87. package/src/styles/utilities.css +187 -0
  88. package/src/types/index.ts +0 -0
@@ -0,0 +1,158 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SelectPrimitive from "@radix-ui/react-select"
5
+ import { cn } from "../lib/utils"
6
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons"
7
+
8
+ const Select = SelectPrimitive.Root
9
+
10
+ const SelectGroup = SelectPrimitive.Group
11
+
12
+ const SelectValue = SelectPrimitive.Value
13
+
14
+ const SelectTrigger = React.forwardRef<
15
+ React.ElementRef<typeof SelectPrimitive.Trigger>,
16
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
17
+ >(({ className, children, ...props }, ref) => (
18
+ <SelectPrimitive.Trigger
19
+ ref={ref}
20
+ className={cn(
21
+ "flex h-10 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
22
+ className
23
+ )}
24
+ {...props}
25
+ >
26
+ {children}
27
+ <SelectPrimitive.Icon asChild>
28
+ <ChevronDownIcon className="h-4 w-4 opacity-50" />
29
+ </SelectPrimitive.Icon>
30
+ </SelectPrimitive.Trigger>
31
+ ))
32
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
33
+
34
+ const SelectScrollUpButton = React.forwardRef<
35
+ React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
36
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
37
+ >(({ className, ...props }, ref) => (
38
+ <SelectPrimitive.ScrollUpButton
39
+ ref={ref}
40
+ className={cn(
41
+ "flex cursor-default items-center justify-center py-1",
42
+ className
43
+ )}
44
+ {...props}
45
+ >
46
+ <ChevronUpIcon className="h-4 w-4" />
47
+ </SelectPrimitive.ScrollUpButton>
48
+ ))
49
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
50
+
51
+ const SelectScrollDownButton = React.forwardRef<
52
+ React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
53
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
54
+ >(({ className, ...props }, ref) => (
55
+ <SelectPrimitive.ScrollDownButton
56
+ ref={ref}
57
+ className={cn(
58
+ "flex cursor-default items-center justify-center py-1",
59
+ className
60
+ )}
61
+ {...props}
62
+ >
63
+ <ChevronDownIcon className="h-4 w-4" />
64
+ </SelectPrimitive.ScrollDownButton>
65
+ ))
66
+ SelectScrollDownButton.displayName =
67
+ SelectPrimitive.ScrollDownButton.displayName
68
+
69
+ const SelectContent = React.forwardRef<
70
+ React.ElementRef<typeof SelectPrimitive.Content>,
71
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
72
+ >(({ className, children, position = "popper", ...props }, ref) => (
73
+ <SelectPrimitive.Portal>
74
+ <SelectPrimitive.Content
75
+ ref={ref}
76
+ className={cn(
77
+ "relative z-200 max-h-[--radix-select-content-available-height] min-w-32 overflow-y-auto overflow-x-hidden rounded-sm border bg-popover backdrop-blur-xl text-popover-foreground shadow-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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",
78
+ position === "popper" &&
79
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
80
+ className
81
+ )}
82
+ position={position}
83
+ {...props}
84
+ >
85
+ <SelectScrollUpButton />
86
+ <SelectPrimitive.Viewport
87
+ className={cn(
88
+ "p-1",
89
+ position === "popper" &&
90
+ "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
91
+ )}
92
+ >
93
+ {children}
94
+ </SelectPrimitive.Viewport>
95
+ <SelectScrollDownButton />
96
+ </SelectPrimitive.Content>
97
+ </SelectPrimitive.Portal>
98
+ ))
99
+ SelectContent.displayName = SelectPrimitive.Content.displayName
100
+
101
+ const SelectLabel = React.forwardRef<
102
+ React.ElementRef<typeof SelectPrimitive.Label>,
103
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
104
+ >(({ className, ...props }, ref) => (
105
+ <SelectPrimitive.Label
106
+ ref={ref}
107
+ className={cn("px-2 py-1.5 text-sm font-semibold", className)}
108
+ {...props}
109
+ />
110
+ ))
111
+ SelectLabel.displayName = SelectPrimitive.Label.displayName
112
+
113
+ const SelectItem = React.forwardRef<
114
+ React.ElementRef<typeof SelectPrimitive.Item>,
115
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & { key?: React.Key }
116
+ >(({ className, children, ...props }, ref) => (
117
+ <SelectPrimitive.Item
118
+ ref={ref}
119
+ className={cn(
120
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
121
+ className
122
+ )}
123
+ {...props}
124
+ >
125
+ <span className="absolute right-2 flex h-3.5 w-3.5 items-center justify-center">
126
+ <SelectPrimitive.ItemIndicator>
127
+ <CheckIcon className="h-4 w-4" />
128
+ </SelectPrimitive.ItemIndicator>
129
+ </span>
130
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
131
+ </SelectPrimitive.Item>
132
+ ))
133
+ SelectItem.displayName = SelectPrimitive.Item.displayName
134
+
135
+ const SelectSeparator = React.forwardRef<
136
+ React.ElementRef<typeof SelectPrimitive.Separator>,
137
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator> & { key?: React.Key }
138
+ >(({ className, ...props }, ref) => (
139
+ <SelectPrimitive.Separator
140
+ ref={ref}
141
+ className={cn("-mx-1 my-1 h-px bg-muted", className)}
142
+ {...props}
143
+ />
144
+ ))
145
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName
146
+
147
+ export {
148
+ Select,
149
+ SelectGroup,
150
+ SelectValue,
151
+ SelectTrigger,
152
+ SelectContent,
153
+ SelectLabel,
154
+ SelectItem,
155
+ SelectSeparator,
156
+ SelectScrollUpButton,
157
+ SelectScrollDownButton,
158
+ }
@@ -0,0 +1,31 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SeparatorPrimitive from "@radix-ui/react-separator"
5
+
6
+ import { cn } from "../lib/utils"
7
+
8
+ const Separator = React.forwardRef<
9
+ React.ElementRef<typeof SeparatorPrimitive.Root>,
10
+ React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
11
+ >(
12
+ (
13
+ { className, orientation = "horizontal", decorative = true, ...props },
14
+ ref
15
+ ) => (
16
+ <SeparatorPrimitive.Root
17
+ ref={ref}
18
+ decorative={decorative}
19
+ orientation={orientation}
20
+ className={cn(
21
+ "shrink-0 bg-border",
22
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
23
+ className
24
+ )}
25
+ {...props}
26
+ />
27
+ )
28
+ )
29
+ Separator.displayName = SeparatorPrimitive.Root.displayName
30
+
31
+ export { Separator }
@@ -0,0 +1,140 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SheetPrimitive from "@radix-ui/react-dialog"
5
+ import { cva, type VariantProps } from "class-variance-authority"
6
+ import { cn } from "../lib/utils"
7
+ import { Cross2Icon } from "@radix-ui/react-icons"
8
+
9
+ const Sheet = SheetPrimitive.Root
10
+
11
+ const SheetTrigger = SheetPrimitive.Trigger
12
+
13
+ const SheetClose = SheetPrimitive.Close
14
+
15
+ const SheetPortal = SheetPrimitive.Portal
16
+
17
+ const SheetOverlay = React.forwardRef<
18
+ React.ElementRef<typeof SheetPrimitive.Overlay>,
19
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
20
+ >(({ className, style, ...props }, ref) => (
21
+ <SheetPrimitive.Overlay
22
+ className={cn(
23
+ "fixed inset-0 z-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
24
+ className
25
+ )}
26
+ style={{ backgroundColor: 'rgb(0 0 0 / 0.8)', ...style }}
27
+ {...props}
28
+ ref={ref}
29
+ />
30
+ ))
31
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
32
+
33
+ const sheetVariants = cva(
34
+ "fixed z-200 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
35
+ {
36
+ variants: {
37
+ side: {
38
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
39
+ bottom:
40
+ "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
41
+ 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",
42
+ right:
43
+ "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",
44
+ },
45
+ },
46
+ defaultVariants: {
47
+ side: "right",
48
+ },
49
+ }
50
+ )
51
+
52
+ interface SheetContentProps
53
+ extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
54
+ VariantProps<typeof sheetVariants> {}
55
+
56
+ const SheetContent = React.forwardRef<
57
+ React.ElementRef<typeof SheetPrimitive.Content>,
58
+ SheetContentProps
59
+ >(({ side = "right", className, children, ...props }, ref) => (
60
+ <SheetPortal>
61
+ <SheetOverlay />
62
+ <SheetPrimitive.Content
63
+ ref={ref}
64
+ className={cn(sheetVariants({ side }), className)}
65
+ {...props}
66
+ >
67
+ <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
68
+ <Cross2Icon className="h-4 w-4" />
69
+ <span className="sr-only">Close</span>
70
+ </SheetPrimitive.Close>
71
+ {children}
72
+ </SheetPrimitive.Content>
73
+ </SheetPortal>
74
+ ))
75
+ SheetContent.displayName = SheetPrimitive.Content.displayName
76
+
77
+ const SheetHeader = ({
78
+ className,
79
+ ...props
80
+ }: React.HTMLAttributes<HTMLDivElement>) => (
81
+ <div
82
+ className={cn(
83
+ "flex flex-col space-y-2 text-center sm:text-left",
84
+ className
85
+ )}
86
+ {...props}
87
+ />
88
+ )
89
+ SheetHeader.displayName = "SheetHeader"
90
+
91
+ const SheetFooter = ({
92
+ className,
93
+ ...props
94
+ }: React.HTMLAttributes<HTMLDivElement>) => (
95
+ <div
96
+ className={cn(
97
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
98
+ className
99
+ )}
100
+ {...props}
101
+ />
102
+ )
103
+ SheetFooter.displayName = "SheetFooter"
104
+
105
+ const SheetTitle = React.forwardRef<
106
+ React.ElementRef<typeof SheetPrimitive.Title>,
107
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
108
+ >(({ className, ...props }, ref) => (
109
+ <SheetPrimitive.Title
110
+ ref={ref}
111
+ className={cn("text-lg font-semibold text-foreground", className)}
112
+ {...props}
113
+ />
114
+ ))
115
+ SheetTitle.displayName = SheetPrimitive.Title.displayName
116
+
117
+ const SheetDescription = React.forwardRef<
118
+ React.ElementRef<typeof SheetPrimitive.Description>,
119
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
120
+ >(({ className, ...props }, ref) => (
121
+ <SheetPrimitive.Description
122
+ ref={ref}
123
+ className={cn("text-sm text-muted-foreground", className)}
124
+ {...props}
125
+ />
126
+ ))
127
+ SheetDescription.displayName = SheetPrimitive.Description.displayName
128
+
129
+ export {
130
+ Sheet,
131
+ SheetPortal,
132
+ SheetOverlay,
133
+ SheetTrigger,
134
+ SheetClose,
135
+ SheetContent,
136
+ SheetHeader,
137
+ SheetFooter,
138
+ SheetTitle,
139
+ SheetDescription,
140
+ }
@@ -0,0 +1,15 @@
1
+ import { cn } from "../lib/utils"
2
+
3
+ function Skeleton({
4
+ className,
5
+ ...props
6
+ }: React.HTMLAttributes<HTMLDivElement>) {
7
+ return (
8
+ <div
9
+ className={cn("animate-pulse rounded-md bg-primary/10", className)}
10
+ {...props}
11
+ />
12
+ )
13
+ }
14
+
15
+ export { Skeleton }
@@ -0,0 +1,28 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SliderPrimitive from "@radix-ui/react-slider"
5
+
6
+ import { cn } from "../lib/utils"
7
+
8
+ const Slider = React.forwardRef<
9
+ React.ElementRef<typeof SliderPrimitive.Root>,
10
+ React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
11
+ >(({ className, ...props }, ref) => (
12
+ <SliderPrimitive.Root
13
+ ref={ref}
14
+ className={cn(
15
+ "relative flex w-full touch-none select-none items-center",
16
+ className
17
+ )}
18
+ {...props}
19
+ >
20
+ <SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20">
21
+ <SliderPrimitive.Range className="absolute h-full bg-primary" />
22
+ </SliderPrimitive.Track>
23
+ <SliderPrimitive.Thumb className="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" />
24
+ </SliderPrimitive.Root>
25
+ ))
26
+ Slider.displayName = SliderPrimitive.Root.displayName
27
+
28
+ export { Slider }
@@ -0,0 +1,16 @@
1
+ import { Loader2Icon } from "lucide-react"
2
+
3
+ import { cn } from "../lib/utils"
4
+
5
+ function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
6
+ return (
7
+ <Loader2Icon
8
+ role="status"
9
+ aria-label="Loading"
10
+ className={cn("size-4 animate-spin", className)}
11
+ {...props}
12
+ />
13
+ )
14
+ }
15
+
16
+ export { Spinner }
@@ -0,0 +1,117 @@
1
+ "use client"
2
+
3
+ import * as React from 'react';
4
+ import StickyBox from 'react-sticky-box';
5
+
6
+ import { useIsMobile } from '../hooks/useMobile';
7
+
8
+ export interface StickyProps extends React.HTMLAttributes<HTMLDivElement> {
9
+ /** Stick to bottom instead of top */
10
+ bottom?: boolean;
11
+ /** Top offset in pixels */
12
+ offsetTop?: number;
13
+ /** Bottom offset in pixels */
14
+ offsetBottom?: number;
15
+ /** Disable sticking */
16
+ disabled?: boolean;
17
+ /** Disable sticky on mobile devices (default: true) */
18
+ disableOnMobile?: boolean;
19
+ /** Use native CSS sticky instead of react-sticky-box */
20
+ useNativeSticky?: boolean;
21
+ /** Enable debug logging (default: false) */
22
+ debug?: boolean;
23
+ /** Z-index value (default: 10) */
24
+ zIndex?: number;
25
+ }
26
+
27
+ const Sticky: React.FC<StickyProps> = ({
28
+ className,
29
+ bottom = false,
30
+ offsetTop = 0,
31
+ offsetBottom = 0,
32
+ disabled = false,
33
+ disableOnMobile = true,
34
+ useNativeSticky = false,
35
+ debug = false,
36
+ zIndex = 10,
37
+ children,
38
+ style,
39
+ ...props
40
+ }) => {
41
+ const isMobile = useIsMobile();
42
+
43
+ // Automatically disable sticky on mobile if disableOnMobile is true
44
+ const isDisabled = disabled || (disableOnMobile && isMobile);
45
+
46
+ // Debug logging (only when debug is enabled)
47
+ React.useEffect(() => {
48
+ if (debug) {
49
+ console.log('Sticky Debug:', {
50
+ isMobile,
51
+ disabled,
52
+ disableOnMobile,
53
+ isDisabled,
54
+ offsetTop,
55
+ offsetBottom,
56
+ useNativeSticky
57
+ });
58
+
59
+ if (!useNativeSticky) {
60
+ console.warn('⚠️ Make sure the parent container has position: relative for react-sticky-box to work properly');
61
+ }
62
+ }
63
+ }, [debug, isMobile, disabled, disableOnMobile, isDisabled, offsetTop, offsetBottom, useNativeSticky]);
64
+
65
+ // If disabled, render as regular div
66
+ if (isDisabled) {
67
+ return (
68
+ <div className={className} style={style} {...props}>
69
+ {children}
70
+ </div>
71
+ );
72
+ }
73
+
74
+ // Use native CSS sticky
75
+ if (useNativeSticky) {
76
+ const nativeStickyStyle: React.CSSProperties = {
77
+ position: 'sticky',
78
+ top: bottom ? 'auto' : `${offsetTop}px`,
79
+ bottom: bottom ? `${offsetBottom}px` : 'auto',
80
+ zIndex,
81
+ ...style,
82
+ };
83
+
84
+ return (
85
+ <div
86
+ className={className}
87
+ style={nativeStickyStyle}
88
+ {...props}
89
+ >
90
+ {children}
91
+ </div>
92
+ );
93
+ }
94
+
95
+ // Use react-sticky-box
96
+ const stickyBoxStyle: React.CSSProperties = {
97
+ zIndex,
98
+ ...style,
99
+ };
100
+
101
+ return (
102
+ <StickyBox
103
+ bottom={bottom}
104
+ offsetTop={offsetTop}
105
+ offsetBottom={offsetBottom}
106
+ className={className}
107
+ style={stickyBoxStyle}
108
+ {...props}
109
+ >
110
+ {children}
111
+ </StickyBox>
112
+ );
113
+ };
114
+
115
+ Sticky.displayName = "Sticky";
116
+
117
+ export { Sticky };
@@ -0,0 +1,29 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SwitchPrimitives from "@radix-ui/react-switch"
5
+
6
+ import { cn } from "../lib/utils"
7
+
8
+ const Switch = React.forwardRef<
9
+ React.ElementRef<typeof SwitchPrimitives.Root>,
10
+ React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
11
+ >(({ className, ...props }, ref) => (
12
+ <SwitchPrimitives.Root
13
+ className={cn(
14
+ "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
15
+ className
16
+ )}
17
+ {...props}
18
+ ref={ref}
19
+ >
20
+ <SwitchPrimitives.Thumb
21
+ className={cn(
22
+ "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
23
+ )}
24
+ />
25
+ </SwitchPrimitives.Root>
26
+ ))
27
+ Switch.displayName = SwitchPrimitives.Root.displayName
28
+
29
+ export { Switch }
@@ -0,0 +1,120 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "../lib/utils"
4
+
5
+ const Table = React.forwardRef<
6
+ HTMLTableElement,
7
+ React.HTMLAttributes<HTMLTableElement>
8
+ >(({ className, ...props }, ref) => (
9
+ <div className="relative w-full overflow-auto">
10
+ <table
11
+ ref={ref}
12
+ className={cn("w-full caption-bottom text-sm", className)}
13
+ {...props}
14
+ />
15
+ </div>
16
+ ))
17
+ Table.displayName = "Table"
18
+
19
+ const TableHeader = React.forwardRef<
20
+ HTMLTableSectionElement,
21
+ React.HTMLAttributes<HTMLTableSectionElement>
22
+ >(({ className, ...props }, ref) => (
23
+ <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
24
+ ))
25
+ TableHeader.displayName = "TableHeader"
26
+
27
+ const TableBody = React.forwardRef<
28
+ HTMLTableSectionElement,
29
+ React.HTMLAttributes<HTMLTableSectionElement>
30
+ >(({ className, ...props }, ref) => (
31
+ <tbody
32
+ ref={ref}
33
+ className={cn("[&_tr:last-child]:border-0", className)}
34
+ {...props}
35
+ />
36
+ ))
37
+ TableBody.displayName = "TableBody"
38
+
39
+ const TableFooter = React.forwardRef<
40
+ HTMLTableSectionElement,
41
+ React.HTMLAttributes<HTMLTableSectionElement>
42
+ >(({ className, ...props }, ref) => (
43
+ <tfoot
44
+ ref={ref}
45
+ className={cn(
46
+ "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
47
+ className
48
+ )}
49
+ {...props}
50
+ />
51
+ ))
52
+ TableFooter.displayName = "TableFooter"
53
+
54
+ const TableRow = React.forwardRef<
55
+ HTMLTableRowElement,
56
+ React.HTMLAttributes<HTMLTableRowElement> & { key?: React.Key }
57
+ >(({ className, ...props }, ref) => (
58
+ <tr
59
+ ref={ref}
60
+ className={cn(
61
+ "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
62
+ className
63
+ )}
64
+ {...props}
65
+ />
66
+ ))
67
+ TableRow.displayName = "TableRow"
68
+
69
+ const TableHead = React.forwardRef<
70
+ HTMLTableCellElement,
71
+ React.ThHTMLAttributes<HTMLTableCellElement> & { key?: React.Key }
72
+ >(({ className, ...props }, ref) => (
73
+ <th
74
+ ref={ref}
75
+ className={cn(
76
+ "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ ))
82
+ TableHead.displayName = "TableHead"
83
+
84
+ const TableCell = React.forwardRef<
85
+ HTMLTableCellElement,
86
+ React.TdHTMLAttributes<HTMLTableCellElement> & { key?: React.Key }
87
+ >(({ className, ...props }, ref) => (
88
+ <td
89
+ ref={ref}
90
+ className={cn(
91
+ "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
92
+ className
93
+ )}
94
+ {...props}
95
+ />
96
+ ))
97
+ TableCell.displayName = "TableCell"
98
+
99
+ const TableCaption = React.forwardRef<
100
+ HTMLTableCaptionElement,
101
+ React.HTMLAttributes<HTMLTableCaptionElement>
102
+ >(({ className, ...props }, ref) => (
103
+ <caption
104
+ ref={ref}
105
+ className={cn("mt-4 text-sm text-muted-foreground", className)}
106
+ {...props}
107
+ />
108
+ ))
109
+ TableCaption.displayName = "TableCaption"
110
+
111
+ export {
112
+ Table,
113
+ TableHeader,
114
+ TableBody,
115
+ TableFooter,
116
+ TableHead,
117
+ TableRow,
118
+ TableCell,
119
+ TableCaption,
120
+ }