startx 1.0.2 → 1.0.4

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 (148) hide show
  1. package/.dockerignore +4 -0
  2. package/apps/cli/src/commands/index.ts +1 -1
  3. package/apps/cli/src/commands/{common → test}/test.ts +4 -2
  4. package/apps/cli/tsconfig.json +0 -1
  5. package/apps/core-server/Dockerfile +5 -4
  6. package/apps/core-server/package.json +1 -1
  7. package/apps/core-server/tsconfig.json +1 -1
  8. package/apps/queue-worker/package.json +1 -1
  9. package/apps/queue-worker/tsconfig.json +1 -1
  10. package/apps/startx-cli/dist/index.mjs +68 -53
  11. package/apps/startx-cli/src/commands/package.ts +453 -0
  12. package/apps/startx-cli/src/configs/scripts.ts +18 -2
  13. package/apps/startx-cli/src/index.ts +2 -4
  14. package/apps/startx-cli/src/types.ts +2 -4
  15. package/apps/startx-cli/src/utils/inquirer.ts +8 -1
  16. package/apps/web-client/.dockerignore +4 -0
  17. package/apps/web-client/app/app.css +1 -0
  18. package/apps/web-client/app/components.json +23 -0
  19. package/apps/web-client/app/config/auth/auth-state.ts +59 -0
  20. package/apps/web-client/app/config/axios-client.ts +87 -0
  21. package/apps/web-client/app/config/env.ts +5 -0
  22. package/apps/web-client/app/entry.client.tsx +7 -0
  23. package/apps/web-client/app/eslint.config.ts +4 -0
  24. package/apps/web-client/app/root.tsx +77 -0
  25. package/apps/web-client/app/routes/home.tsx +12 -0
  26. package/apps/web-client/app/routes.ts +3 -0
  27. package/apps/web-client/eslint.config.ts +4 -0
  28. package/apps/web-client/package.json +55 -0
  29. package/apps/web-client/react-router.config.ts +7 -0
  30. package/apps/web-client/tsconfig.json +22 -0
  31. package/apps/web-client/vite-env.d.ts +8 -0
  32. package/apps/web-client/vite.config.ts +30 -0
  33. package/biome.json +5 -0
  34. package/configs/eslint-config/eslint.config.ts +1 -0
  35. package/configs/eslint-config/src/configs/base.ts +2 -1
  36. package/configs/eslint-config/src/configs/frontend.ts +1 -1
  37. package/configs/eslint-config/tsconfig.json +1 -1
  38. package/configs/typescript-config/tsconfig.frontend.json +1 -1
  39. package/configs/vitest-config/tsconfig.json +1 -1
  40. package/package.json +1 -1
  41. package/packages/@db/drizzle/tsconfig.json +1 -1
  42. package/packages/@db/sqlite/tsconfig.json +1 -1
  43. package/packages/@repo/env/package.json +1 -2
  44. package/packages/@repo/env/src/utils.ts +17 -11
  45. package/packages/@repo/env/tsconfig.json +1 -1
  46. package/packages/@repo/lib/package.json +3 -1
  47. package/packages/@repo/lib/src/session-module/i-session.ts +108 -0
  48. package/packages/@repo/lib/src/session-module/index.ts +8 -111
  49. package/packages/@repo/lib/src/session-module/redis-session.ts +44 -0
  50. package/packages/@repo/lib/tsconfig.json +0 -1
  51. package/packages/@repo/logger/package.json +0 -1
  52. package/packages/@repo/logger/tsconfig.json +1 -1
  53. package/packages/@repo/mail/tsconfig.json +1 -1
  54. package/packages/@repo/redis/tsconfig.json +1 -1
  55. package/packages/aix/package.json +2 -0
  56. package/packages/aix/src/providers/ai-interface.ts +4 -4
  57. package/packages/aix/src/providers/bedrock/bedrock.ts +261 -0
  58. package/packages/aix/src/providers/default-models.ts +65 -0
  59. package/packages/aix/src/providers/openai/openai.ts +2 -2
  60. package/packages/aix/src/providers/providers.ts +11 -0
  61. package/packages/aix/src/providers/types.ts +1 -1
  62. package/packages/{constants → common}/package.json +4 -2
  63. package/packages/{constants/src/index.ts → common/src/constants.ts} +0 -5
  64. package/packages/common/src/types/users.ts +10 -0
  65. package/packages/{constants → common}/tsconfig.json +0 -3
  66. package/packages/ui/components.json +15 -8
  67. package/packages/ui/package.json +24 -36
  68. package/packages/ui/src/api/axios/i-client.ts +40 -0
  69. package/packages/ui/src/api/index.ts +6 -0
  70. package/packages/ui/src/api/query-provider.tsx +34 -0
  71. package/packages/ui/src/api/use-api/api-builder.ts +139 -0
  72. package/packages/ui/src/api/use-api/api-helpers.ts +165 -0
  73. package/packages/ui/src/api/use-api/api-types.ts +138 -0
  74. package/packages/ui/src/api/use-api/query-factory.ts +66 -0
  75. package/packages/ui/src/api/use-api/react-query/types.ts +64 -0
  76. package/packages/ui/src/api/use-api/react-query/use-api-client.ts +56 -0
  77. package/packages/ui/src/api/use-api/react-query/use-api.ts +297 -0
  78. package/packages/ui/src/components/custom/form-wrapper.tsx +113 -160
  79. package/packages/ui/src/components/custom/grid-component.tsx +4 -4
  80. package/packages/ui/src/components/custom/hover-tool.tsx +1 -1
  81. package/packages/ui/src/components/custom/image-picker.tsx +18 -20
  82. package/packages/ui/src/components/custom/no-content.tsx +6 -16
  83. package/packages/ui/src/components/custom/page-section.tsx +14 -17
  84. package/packages/ui/src/components/custom/simple-popover.tsx +5 -9
  85. package/packages/ui/src/components/custom/theme-provider.tsx +117 -42
  86. package/packages/ui/src/components/custom/typography.tsx +20 -22
  87. package/packages/ui/src/components/extensions/timeline.tsx +100 -0
  88. package/packages/ui/src/components/ui/alert-dialog.tsx +46 -108
  89. package/packages/ui/src/components/ui/avatar.tsx +79 -42
  90. package/packages/ui/src/components/ui/badge.tsx +29 -34
  91. package/packages/ui/src/components/ui/breadcrumb.tsx +65 -81
  92. package/packages/ui/src/components/ui/button.tsx +80 -80
  93. package/packages/ui/src/components/ui/card.tsx +48 -69
  94. package/packages/ui/src/components/ui/carousel.tsx +184 -211
  95. package/packages/ui/src/components/ui/checkbox.tsx +21 -24
  96. package/packages/ui/src/components/ui/command.tsx +121 -102
  97. package/packages/ui/src/components/ui/dialog.tsx +45 -32
  98. package/packages/ui/src/components/ui/dropdown-menu.tsx +45 -33
  99. package/packages/ui/src/components/ui/field.tsx +218 -0
  100. package/packages/ui/src/components/ui/form.tsx +63 -76
  101. package/packages/ui/src/components/ui/input-group.tsx +137 -0
  102. package/packages/ui/src/components/ui/input-otp.tsx +60 -50
  103. package/packages/ui/src/components/ui/input.tsx +16 -15
  104. package/packages/ui/src/components/ui/label.tsx +14 -17
  105. package/packages/ui/src/components/ui/multiple-select.tsx +22 -33
  106. package/packages/ui/src/components/ui/popover.tsx +20 -8
  107. package/packages/ui/src/components/ui/select.tsx +33 -34
  108. package/packages/ui/src/components/ui/separator.tsx +8 -8
  109. package/packages/ui/src/components/ui/sheet.tsx +32 -59
  110. package/packages/ui/src/components/ui/sidebar.tsx +654 -0
  111. package/packages/ui/src/components/ui/skeleton.tsx +2 -8
  112. package/packages/ui/src/components/ui/sonner.tsx +39 -0
  113. package/packages/ui/src/components/ui/spinner.tsx +6 -13
  114. package/packages/ui/src/components/ui/switch.tsx +15 -10
  115. package/packages/ui/src/components/ui/table.tsx +48 -89
  116. package/packages/ui/src/components/ui/tabs.tsx +37 -15
  117. package/packages/ui/src/components/ui/textarea.tsx +13 -13
  118. package/packages/ui/src/components/ui/tooltip.tsx +37 -23
  119. package/packages/ui/src/{components/hooks → hooks}/event/use-click.tsx +6 -10
  120. package/packages/ui/src/hooks/time/use-timer.tsx +51 -0
  121. package/packages/ui/src/hooks/use-media-query.tsx +19 -0
  122. package/packages/ui/src/hooks/use-mobile.tsx +17 -0
  123. package/packages/ui/src/{components/hooks → hooks}/use-update-effect.tsx +2 -2
  124. package/packages/ui/src/lib/utils.ts +113 -0
  125. package/packages/ui/src/styles/globals.css +314 -0
  126. package/packages/ui/src/styles/tailwind.css +89 -0
  127. package/packages/ui/tsconfig.json +7 -9
  128. package/pnpm-workspace.yaml +74 -64
  129. package/packages/ui/postcss.config.mjs +0 -9
  130. package/packages/ui/src/components/extensions/carousel.tsx +0 -392
  131. package/packages/ui/src/components/hooks/time/useTimer.tsx +0 -51
  132. package/packages/ui/src/components/hooks/use-media-query.tsx +0 -19
  133. package/packages/ui/src/components/lib/utils.ts +0 -242
  134. package/packages/ui/src/components/ui/timeline.tsx +0 -118
  135. package/packages/ui/src/components/util/n-formattor.ts +0 -22
  136. package/packages/ui/src/components/util/storage.ts +0 -37
  137. package/packages/ui/src/globals.css +0 -87
  138. package/packages/ui/tailwind.config.ts +0 -94
  139. /package/packages/{constants → common}/eslint.config.ts +0 -0
  140. /package/packages/{constants → common}/src/api.ts +0 -0
  141. /package/packages/{constants → common}/src/time.ts +0 -0
  142. /package/packages/{constants → common}/vitest.config.ts +0 -0
  143. /package/packages/ui/src/{components/hooks/time/useDebounce.tsx → hooks/time/use-debounce.tsx} +0 -0
  144. /package/packages/ui/src/{components/hooks/time/useInterval.tsx → hooks/time/use-interval.tsx} +0 -0
  145. /package/packages/ui/src/{components/hooks/time/useTimeout.tsx → hooks/time/use-timeout.tsx} +0 -0
  146. /package/packages/ui/src/{components/hooks → hooks}/use-persistent-storage.tsx +0 -0
  147. /package/packages/ui/src/{components/hooks → hooks}/use-window-dimension.tsx +0 -0
  148. /package/packages/ui/src/{components/sonner.tsx → sonner.ts} +0 -0
@@ -1,125 +1,144 @@
1
+ /* eslint-disable @typescript-eslint/no-redundant-type-constituents */
1
2
  "use client";
2
3
 
3
- import type { DialogProps } from "@radix-ui/react-dialog";
4
4
  import { Command as CommandPrimitive } from "cmdk";
5
- import { Search } from "lucide-react";
5
+ import { CheckIcon, SearchIcon } from "lucide-react";
6
6
  import * as React from "react";
7
7
 
8
- import { Dialog, DialogContent } from "./dialog";
9
- import { cn } from "../lib/utils";
8
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@repo/ui/components/ui/dialog";
9
+ import { InputGroup, InputGroupAddon } from "@repo/ui/components/ui/input-group";
10
+ import { cn } from "@repo/ui/lib/utils";
10
11
 
11
- const Command = React.forwardRef<
12
- React.ElementRef<typeof CommandPrimitive>,
13
- React.ComponentPropsWithoutRef<typeof CommandPrimitive>
14
- >(({ className, ...props }, ref) => (
15
- <CommandPrimitive
16
- ref={ref}
17
- className={cn(
18
- "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
19
- className
20
- )}
21
- {...props}
22
- />
23
- ));
24
- Command.displayName = CommandPrimitive.displayName;
25
-
26
- interface CommandDialogProps extends DialogProps {}
27
- const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
12
+ function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
13
+ return (
14
+ <CommandPrimitive
15
+ data-slot="command"
16
+ className={cn(
17
+ "flex size-full flex-col overflow-hidden rounded-xl! bg-popover p-1 text-popover-foreground",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ );
23
+ }
24
+
25
+ function CommandDialog({
26
+ title = "Command Palette",
27
+ description = "Search for a command to run...",
28
+ children,
29
+ className,
30
+ showCloseButton = false,
31
+ ...props
32
+ }: React.ComponentProps<typeof Dialog> & {
33
+ title?: string;
34
+ description?: string;
35
+ className?: string;
36
+ showCloseButton?: boolean;
37
+ }) {
28
38
  return (
29
39
  <Dialog {...props}>
30
- <DialogContent className="overflow-hidden p-0 shadow-lg">
31
- <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
32
- {children}
33
- </Command>
40
+ <DialogHeader className="sr-only">
41
+ <DialogTitle>{title}</DialogTitle>
42
+ <DialogDescription>{description}</DialogDescription>
43
+ </DialogHeader>
44
+ <DialogContent
45
+ className={cn("top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0", className)}
46
+ showCloseButton={showCloseButton}
47
+ >
48
+ {children}
34
49
  </DialogContent>
35
50
  </Dialog>
36
51
  );
37
- };
52
+ }
53
+
54
+ function CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {
55
+ return (
56
+ <div data-slot="command-input-wrapper" className="p-1 pb-0">
57
+ <InputGroup className="h-8! rounded-lg! border-input/30 bg-input/30 shadow-none! *:data-[slot=input-group-addon]:pl-2!">
58
+ <CommandPrimitive.Input
59
+ data-slot="command-input"
60
+ className={cn("w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50", className)}
61
+ {...props}
62
+ />
63
+ <InputGroupAddon>
64
+ <SearchIcon className="size-4 shrink-0 opacity-50" />
65
+ </InputGroupAddon>
66
+ </InputGroup>
67
+ </div>
68
+ );
69
+ }
38
70
 
39
- const CommandInput = React.forwardRef<
40
- React.ElementRef<typeof CommandPrimitive.Input>,
41
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
42
- >(({ className, ...props }, ref) => (
43
- <div className="flex items-center border-b px-3">
44
- <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
45
- <CommandPrimitive.Input
46
- ref={ref}
71
+ function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
72
+ return (
73
+ <CommandPrimitive.List
74
+ data-slot="command-list"
75
+ className={cn("no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none", className)}
76
+ {...props}
77
+ />
78
+ );
79
+ }
80
+
81
+ function CommandEmpty({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
82
+ return (
83
+ <CommandPrimitive.Empty
84
+ data-slot="command-empty"
85
+ className={cn("py-6 text-center text-sm", className)}
86
+ {...props}
87
+ />
88
+ );
89
+ }
90
+
91
+ function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {
92
+ return (
93
+ <CommandPrimitive.Group
94
+ data-slot="command-group"
47
95
  className={cn(
48
- "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
96
+ "overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground",
49
97
  className
50
98
  )}
51
99
  {...props}
52
100
  />
53
- </div>
54
- ));
55
-
56
- CommandInput.displayName = CommandPrimitive.Input.displayName;
57
-
58
- const CommandList = React.forwardRef<
59
- React.ElementRef<typeof CommandPrimitive.List>,
60
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
61
- >(({ className, ...props }, ref) => (
62
- <CommandPrimitive.List
63
- ref={ref}
64
- className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
65
- {...props}
66
- />
67
- ));
68
-
69
- CommandList.displayName = CommandPrimitive.List.displayName;
70
-
71
- const CommandEmpty = React.forwardRef<
72
- React.ElementRef<typeof CommandPrimitive.Empty>,
73
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
74
- >((props, ref) => <CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />);
75
-
76
- CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
77
-
78
- const CommandGroup = React.forwardRef<
79
- React.ElementRef<typeof CommandPrimitive.Group>,
80
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
81
- >(({ className, ...props }, ref) => (
82
- <CommandPrimitive.Group
83
- ref={ref}
84
- className={cn(
85
- "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
86
- className
87
- )}
88
- {...props}
89
- />
90
- ));
91
-
92
- CommandGroup.displayName = CommandPrimitive.Group.displayName;
93
-
94
- const CommandSeparator = React.forwardRef<
95
- React.ElementRef<typeof CommandPrimitive.Separator>,
96
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
97
- >(({ className, ...props }, ref) => (
98
- <CommandPrimitive.Separator ref={ref} className={cn("-mx-1 h-px bg-border", className)} {...props} />
99
- ));
100
- CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
101
+ );
102
+ }
101
103
 
102
- const CommandItem = React.forwardRef<
103
- React.ElementRef<typeof CommandPrimitive.Item>,
104
- React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
105
- >(({ className, ...props }, ref) => (
106
- <CommandPrimitive.Item
107
- ref={ref}
108
- className={cn(
109
- // "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
110
- "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-[selected='true']:bg-accent aria-[selected='true']:text-accent-foreground data-[disabled='true']:pointer-events-none data-[disabled='true']:opacity-50",
111
- className
112
- )}
113
- {...props}
114
- />
115
- ));
104
+ function CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {
105
+ return (
106
+ <CommandPrimitive.Separator
107
+ data-slot="command-separator"
108
+ className={cn("-mx-1 h-px bg-border", className)}
109
+ {...props}
110
+ />
111
+ );
112
+ }
116
113
 
117
- CommandItem.displayName = CommandPrimitive.Item.displayName;
114
+ function CommandItem({ className, children, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {
115
+ return (
116
+ <CommandPrimitive.Item
117
+ data-slot="command-item"
118
+ className={cn(
119
+ "group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-selected:*:[svg]:text-foreground",
120
+ className
121
+ )}
122
+ {...props}
123
+ >
124
+ {children}
125
+ <CheckIcon className="ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" />
126
+ </CommandPrimitive.Item>
127
+ );
128
+ }
118
129
 
119
- const CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
120
- return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
121
- };
122
- CommandShortcut.displayName = "CommandShortcut";
130
+ function CommandShortcut({ className, ...props }: React.ComponentProps<"span">) {
131
+ return (
132
+ <span
133
+ data-slot="command-shortcut"
134
+ className={cn(
135
+ "ml-auto text-xs tracking-widest text-muted-foreground group-data-selected/command-item:text-foreground",
136
+ className
137
+ )}
138
+ {...props}
139
+ />
140
+ );
141
+ }
123
142
 
124
143
  export {
125
144
  Command,
@@ -1,7 +1,11 @@
1
- import * as DialogPrimitive from "@radix-ui/react-dialog";
1
+ "use client";
2
+
2
3
  import { XIcon } from "lucide-react";
4
+ import { Dialog as DialogPrimitive } from "radix-ui";
5
+ import * as React from "react";
3
6
 
4
- import { cn } from "../lib/utils";
7
+ import { Button } from "@repo/ui/components/ui/button";
8
+ import { cn } from "@repo/ui/lib/utils";
5
9
 
6
10
  function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
7
11
  return <DialogPrimitive.Root data-slot="dialog" {...props} />;
@@ -19,15 +23,12 @@ function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.C
19
23
  return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
20
24
  }
21
25
 
22
- function DialogOverlay({
23
- className,
24
- ...props
25
- }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
26
+ function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
26
27
  return (
27
28
  <DialogPrimitive.Overlay
28
29
  data-slot="dialog-overlay"
29
30
  className={cn(
30
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
31
+ "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
31
32
  className
32
33
  )}
33
34
  {...props}
@@ -44,46 +45,58 @@ function DialogContent({
44
45
  showCloseButton?: boolean;
45
46
  }) {
46
47
  return (
47
- <DialogPortal data-slot="dialog-portal">
48
+ <DialogPortal>
48
49
  <DialogOverlay />
49
50
  <DialogPrimitive.Content
50
51
  data-slot="dialog-content"
51
52
  className={cn(
52
- "bg-background 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
53
+ "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 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-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
53
54
  className
54
55
  )}
55
56
  {...props}
56
57
  >
57
58
  {children}
58
- {showCloseButton ? <DialogPrimitive.Close
59
- data-slot="dialog-close"
60
- className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
61
- >
62
- <XIcon />
63
- <span className="sr-only">Close</span>
64
- </DialogPrimitive.Close> : null}
59
+ {showCloseButton ? (
60
+ <DialogPrimitive.Close data-slot="dialog-close" asChild>
61
+ <Button variant="ghost" className="absolute top-2 right-2" size="icon-sm">
62
+ <XIcon />
63
+ <span className="sr-only">Close</span>
64
+ </Button>
65
+ </DialogPrimitive.Close>
66
+ ) : null}
65
67
  </DialogPrimitive.Content>
66
68
  </DialogPortal>
67
69
  );
68
70
  }
69
71
 
70
72
  function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
71
- return (
72
- <div
73
- data-slot="dialog-header"
74
- className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
75
- {...props}
76
- />
77
- );
73
+ return <div data-slot="dialog-header" className={cn("flex flex-col gap-2", className)} {...props} />;
78
74
  }
79
75
 
80
- function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
76
+ function DialogFooter({
77
+ className,
78
+ showCloseButton = false,
79
+ children,
80
+ ...props
81
+ }: React.ComponentProps<"div"> & {
82
+ showCloseButton?: boolean;
83
+ }) {
81
84
  return (
82
85
  <div
83
86
  data-slot="dialog-footer"
84
- className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
87
+ className={cn(
88
+ "-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",
89
+ className
90
+ )}
85
91
  {...props}
86
- />
92
+ >
93
+ {children}
94
+ {showCloseButton ? (
95
+ <DialogPrimitive.Close asChild>
96
+ <Button variant="outline">Close</Button>
97
+ </DialogPrimitive.Close>
98
+ ) : null}
99
+ </div>
87
100
  );
88
101
  }
89
102
 
@@ -91,20 +104,20 @@ function DialogTitle({ className, ...props }: React.ComponentProps<typeof Dialog
91
104
  return (
92
105
  <DialogPrimitive.Title
93
106
  data-slot="dialog-title"
94
- className={cn("text-lg leading-none font-semibold", className)}
107
+ className={cn("cn-font-heading text-base leading-none font-medium", className)}
95
108
  {...props}
96
109
  />
97
110
  );
98
111
  }
99
112
 
100
- function DialogDescription({
101
- className,
102
- ...props
103
- }: React.ComponentProps<typeof DialogPrimitive.Description>) {
113
+ function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
104
114
  return (
105
115
  <DialogPrimitive.Description
106
116
  data-slot="dialog-description"
107
- className={cn("text-muted-foreground text-sm", className)}
117
+ className={cn(
118
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
119
+ className
120
+ )}
108
121
  {...props}
109
122
  />
110
123
  );
@@ -1,27 +1,26 @@
1
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
2
- import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
3
- import type * as React from "react";
1
+ "use client";
4
2
 
5
- import { cn } from "../lib/utils";
3
+ import { CheckIcon, ChevronRightIcon } from "lucide-react";
4
+ import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
5
+ import * as React from "react";
6
+
7
+ import { cn } from "@repo/ui/lib/utils";
6
8
 
7
9
  function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
8
10
  return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
9
11
  }
10
12
 
11
- function DropdownMenuPortal({
12
- ...props
13
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
13
+ function DropdownMenuPortal({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
14
14
  return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
15
15
  }
16
16
 
17
- function DropdownMenuTrigger({
18
- ...props
19
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
17
+ function DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
20
18
  return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
21
19
  }
22
20
 
23
21
  function DropdownMenuContent({
24
22
  className,
23
+ align = "start",
25
24
  sideOffset = 4,
26
25
  ...props
27
26
  }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
@@ -30,8 +29,9 @@ function DropdownMenuContent({
30
29
  <DropdownMenuPrimitive.Content
31
30
  data-slot="dropdown-menu-content"
32
31
  sideOffset={sideOffset}
32
+ align={align}
33
33
  className={cn(
34
- "bg-popover text-popover-foreground 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 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
34
+ "z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
35
35
  className
36
36
  )}
37
37
  {...props}
@@ -59,7 +59,7 @@ function DropdownMenuItem({
59
59
  data-inset={inset}
60
60
  data-variant={variant}
61
61
  className={cn(
62
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
62
+ "group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
63
63
  className
64
64
  )}
65
65
  {...props}
@@ -71,21 +71,28 @@ function DropdownMenuCheckboxItem({
71
71
  className,
72
72
  children,
73
73
  checked,
74
+ inset,
74
75
  ...props
75
- }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
76
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
77
+ inset?: boolean;
78
+ }) {
76
79
  return (
77
80
  <DropdownMenuPrimitive.CheckboxItem
78
81
  data-slot="dropdown-menu-checkbox-item"
82
+ data-inset={inset}
79
83
  className={cn(
80
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
84
+ "relative flex 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 focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
81
85
  className
82
86
  )}
83
87
  checked={checked}
84
88
  {...props}
85
89
  >
86
- <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
90
+ <span
91
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
92
+ data-slot="dropdown-menu-checkbox-item-indicator"
93
+ >
87
94
  <DropdownMenuPrimitive.ItemIndicator>
88
- <CheckIcon className="size-4" />
95
+ <CheckIcon />
89
96
  </DropdownMenuPrimitive.ItemIndicator>
90
97
  </span>
91
98
  {children}
@@ -93,29 +100,34 @@ function DropdownMenuCheckboxItem({
93
100
  );
94
101
  }
95
102
 
96
- function DropdownMenuRadioGroup({
97
- ...props
98
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
103
+ function DropdownMenuRadioGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
99
104
  return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
100
105
  }
101
106
 
102
107
  function DropdownMenuRadioItem({
103
108
  className,
104
109
  children,
110
+ inset,
105
111
  ...props
106
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
112
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
113
+ inset?: boolean;
114
+ }) {
107
115
  return (
108
116
  <DropdownMenuPrimitive.RadioItem
109
117
  data-slot="dropdown-menu-radio-item"
118
+ data-inset={inset}
110
119
  className={cn(
111
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
120
+ "relative flex 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 focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
112
121
  className
113
122
  )}
114
123
  {...props}
115
124
  >
116
- <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
125
+ <span
126
+ className="pointer-events-none absolute right-2 flex items-center justify-center"
127
+ data-slot="dropdown-menu-radio-item-indicator"
128
+ >
117
129
  <DropdownMenuPrimitive.ItemIndicator>
118
- <CircleIcon className="size-2 fill-current" />
130
+ <CheckIcon />
119
131
  </DropdownMenuPrimitive.ItemIndicator>
120
132
  </span>
121
133
  {children}
@@ -134,20 +146,17 @@ function DropdownMenuLabel({
134
146
  <DropdownMenuPrimitive.Label
135
147
  data-slot="dropdown-menu-label"
136
148
  data-inset={inset}
137
- className={cn("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", className)}
149
+ className={cn("px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7", className)}
138
150
  {...props}
139
151
  />
140
152
  );
141
153
  }
142
154
 
143
- function DropdownMenuSeparator({
144
- className,
145
- ...props
146
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
155
+ function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
147
156
  return (
148
157
  <DropdownMenuPrimitive.Separator
149
158
  data-slot="dropdown-menu-separator"
150
- className={cn("bg-border -mx-1 my-1 h-px", className)}
159
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
151
160
  {...props}
152
161
  />
153
162
  );
@@ -157,7 +166,10 @@ function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"spa
157
166
  return (
158
167
  <span
159
168
  data-slot="dropdown-menu-shortcut"
160
- className={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)}
169
+ className={cn(
170
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",
171
+ className
172
+ )}
161
173
  {...props}
162
174
  />
163
175
  );
@@ -180,13 +192,13 @@ function DropdownMenuSubTrigger({
180
192
  data-slot="dropdown-menu-sub-trigger"
181
193
  data-inset={inset}
182
194
  className={cn(
183
- "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
195
+ "flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
184
196
  className
185
197
  )}
186
198
  {...props}
187
199
  >
188
200
  {children}
189
- <ChevronRightIcon className="ml-auto size-4" />
201
+ <ChevronRightIcon className="cn-rtl-flip ml-auto" />
190
202
  </DropdownMenuPrimitive.SubTrigger>
191
203
  );
192
204
  }
@@ -199,7 +211,7 @@ function DropdownMenuSubContent({
199
211
  <DropdownMenuPrimitive.SubContent
200
212
  data-slot="dropdown-menu-sub-content"
201
213
  className={cn(
202
- "bg-popover text-popover-foreground 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 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
214
+ "z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
203
215
  className
204
216
  )}
205
217
  {...props}