startx 1.0.2 → 1.0.3

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 (147) 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 +0 -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/lib/package.json +3 -1
  46. package/packages/@repo/lib/src/session-module/i-session.ts +108 -0
  47. package/packages/@repo/lib/src/session-module/index.ts +8 -111
  48. package/packages/@repo/lib/src/session-module/redis-session.ts +44 -0
  49. package/packages/@repo/lib/tsconfig.json +0 -1
  50. package/packages/@repo/logger/package.json +0 -1
  51. package/packages/@repo/logger/tsconfig.json +1 -1
  52. package/packages/@repo/mail/tsconfig.json +1 -1
  53. package/packages/@repo/redis/tsconfig.json +1 -1
  54. package/packages/aix/package.json +2 -0
  55. package/packages/aix/src/providers/ai-interface.ts +4 -4
  56. package/packages/aix/src/providers/bedrock/bedrock.ts +261 -0
  57. package/packages/aix/src/providers/default-models.ts +65 -0
  58. package/packages/aix/src/providers/openai/openai.ts +2 -2
  59. package/packages/aix/src/providers/providers.ts +11 -0
  60. package/packages/aix/src/providers/types.ts +1 -1
  61. package/packages/{constants → common}/package.json +4 -2
  62. package/packages/{constants/src/index.ts → common/src/constants.ts} +0 -5
  63. package/packages/common/src/types/users.ts +10 -0
  64. package/packages/{constants → common}/tsconfig.json +0 -3
  65. package/packages/ui/components.json +15 -8
  66. package/packages/ui/package.json +23 -36
  67. package/packages/ui/src/api/axios/i-client.ts +40 -0
  68. package/packages/ui/src/api/index.ts +6 -0
  69. package/packages/ui/src/api/query-provider.tsx +34 -0
  70. package/packages/ui/src/api/use-api/api-builder.ts +139 -0
  71. package/packages/ui/src/api/use-api/api-helpers.ts +165 -0
  72. package/packages/ui/src/api/use-api/api-types.ts +138 -0
  73. package/packages/ui/src/api/use-api/query-factory.ts +66 -0
  74. package/packages/ui/src/api/use-api/react-query/types.ts +64 -0
  75. package/packages/ui/src/api/use-api/react-query/use-api-client.ts +56 -0
  76. package/packages/ui/src/api/use-api/react-query/use-api.ts +297 -0
  77. package/packages/ui/src/components/custom/form-wrapper.tsx +113 -160
  78. package/packages/ui/src/components/custom/grid-component.tsx +4 -4
  79. package/packages/ui/src/components/custom/hover-tool.tsx +1 -1
  80. package/packages/ui/src/components/custom/image-picker.tsx +18 -20
  81. package/packages/ui/src/components/custom/no-content.tsx +6 -16
  82. package/packages/ui/src/components/custom/page-section.tsx +14 -17
  83. package/packages/ui/src/components/custom/simple-popover.tsx +5 -9
  84. package/packages/ui/src/components/custom/theme-provider.tsx +117 -42
  85. package/packages/ui/src/components/custom/typography.tsx +20 -22
  86. package/packages/ui/src/components/extensions/timeline.tsx +100 -0
  87. package/packages/ui/src/components/ui/alert-dialog.tsx +46 -108
  88. package/packages/ui/src/components/ui/avatar.tsx +79 -42
  89. package/packages/ui/src/components/ui/badge.tsx +29 -34
  90. package/packages/ui/src/components/ui/breadcrumb.tsx +65 -81
  91. package/packages/ui/src/components/ui/button.tsx +80 -80
  92. package/packages/ui/src/components/ui/card.tsx +48 -69
  93. package/packages/ui/src/components/ui/carousel.tsx +184 -211
  94. package/packages/ui/src/components/ui/checkbox.tsx +21 -24
  95. package/packages/ui/src/components/ui/command.tsx +121 -102
  96. package/packages/ui/src/components/ui/dialog.tsx +45 -32
  97. package/packages/ui/src/components/ui/dropdown-menu.tsx +45 -33
  98. package/packages/ui/src/components/ui/field.tsx +218 -0
  99. package/packages/ui/src/components/ui/form.tsx +63 -76
  100. package/packages/ui/src/components/ui/input-group.tsx +137 -0
  101. package/packages/ui/src/components/ui/input-otp.tsx +60 -50
  102. package/packages/ui/src/components/ui/input.tsx +16 -15
  103. package/packages/ui/src/components/ui/label.tsx +14 -17
  104. package/packages/ui/src/components/ui/multiple-select.tsx +22 -33
  105. package/packages/ui/src/components/ui/popover.tsx +20 -8
  106. package/packages/ui/src/components/ui/select.tsx +33 -34
  107. package/packages/ui/src/components/ui/separator.tsx +8 -8
  108. package/packages/ui/src/components/ui/sheet.tsx +32 -59
  109. package/packages/ui/src/components/ui/sidebar.tsx +654 -0
  110. package/packages/ui/src/components/ui/skeleton.tsx +2 -8
  111. package/packages/ui/src/components/ui/sonner.tsx +39 -0
  112. package/packages/ui/src/components/ui/spinner.tsx +6 -13
  113. package/packages/ui/src/components/ui/switch.tsx +15 -10
  114. package/packages/ui/src/components/ui/table.tsx +48 -89
  115. package/packages/ui/src/components/ui/tabs.tsx +37 -15
  116. package/packages/ui/src/components/ui/textarea.tsx +13 -13
  117. package/packages/ui/src/components/ui/tooltip.tsx +37 -23
  118. package/packages/ui/src/{components/hooks → hooks}/event/use-click.tsx +6 -10
  119. package/packages/ui/src/hooks/time/use-timer.tsx +51 -0
  120. package/packages/ui/src/hooks/use-media-query.tsx +19 -0
  121. package/packages/ui/src/hooks/use-mobile.tsx +17 -0
  122. package/packages/ui/src/{components/hooks → hooks}/use-update-effect.tsx +2 -2
  123. package/packages/ui/src/lib/utils.ts +113 -0
  124. package/packages/ui/src/styles/globals.css +311 -0
  125. package/packages/ui/src/styles/tailwind.css +89 -0
  126. package/packages/ui/tsconfig.json +7 -9
  127. package/pnpm-workspace.yaml +74 -64
  128. package/packages/ui/postcss.config.mjs +0 -9
  129. package/packages/ui/src/components/extensions/carousel.tsx +0 -392
  130. package/packages/ui/src/components/hooks/time/useTimer.tsx +0 -51
  131. package/packages/ui/src/components/hooks/use-media-query.tsx +0 -19
  132. package/packages/ui/src/components/lib/utils.ts +0 -242
  133. package/packages/ui/src/components/ui/timeline.tsx +0 -118
  134. package/packages/ui/src/components/util/n-formattor.ts +0 -22
  135. package/packages/ui/src/components/util/storage.ts +0 -37
  136. package/packages/ui/src/globals.css +0 -87
  137. package/packages/ui/tailwind.config.ts +0 -94
  138. /package/packages/{constants → common}/eslint.config.ts +0 -0
  139. /package/packages/{constants → common}/src/api.ts +0 -0
  140. /package/packages/{constants → common}/src/time.ts +0 -0
  141. /package/packages/{constants → common}/vitest.config.ts +0 -0
  142. /package/packages/ui/src/{components/hooks/time/useDebounce.tsx → hooks/time/use-debounce.tsx} +0 -0
  143. /package/packages/ui/src/{components/hooks/time/useInterval.tsx → hooks/time/use-interval.tsx} +0 -0
  144. /package/packages/ui/src/{components/hooks/time/useTimeout.tsx → hooks/time/use-timeout.tsx} +0 -0
  145. /package/packages/ui/src/{components/hooks → hooks}/use-persistent-storage.tsx +0 -0
  146. /package/packages/ui/src/{components/hooks → hooks}/use-window-dimension.tsx +0 -0
  147. /package/packages/ui/src/{components/sonner.tsx → sonner.ts} +0 -0
@@ -1,23 +1,20 @@
1
- import { cva, type VariantProps } from 'class-variance-authority';
2
- import type { ReactNode } from 'react';
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+ import type { ReactNode } from "react";
3
3
 
4
- import { cn } from '../lib/utils';
5
- import { Separator } from '../ui/separator';
6
- const pageSectionVariant = cva(
7
- 'flex flex-col space-y-4 rounded-lg bg-background/70 p-6 md:px-6 px-2 w-full h-full ',
8
- {
9
- variants: {
10
- variant: {
11
- default: '',
12
- outline: 'border',
13
- transparent: 'bg-transparent md:px-0 px-0',
14
- },
15
- },
16
- defaultVariants: {
17
- variant: 'default',
4
+ import { cn } from "@repo/ui/lib/utils";
5
+ import { Separator } from "../ui/separator";
6
+ const pageSectionVariant = cva("flex flex-col space-y-4 rounded-lg bg-background/70 p-6 md:px-6 px-2 w-full h-full ", {
7
+ variants: {
8
+ variant: {
9
+ default: "",
10
+ outline: "border",
11
+ transparent: "bg-transparent md:px-0 px-0",
18
12
  },
19
13
  },
20
- );
14
+ defaultVariants: {
15
+ variant: "default",
16
+ },
17
+ });
21
18
  type PageSectionProps = {
22
19
  icon?: ReactNode;
23
20
  title: ReactNode;
@@ -1,12 +1,12 @@
1
- import type { ClassNameValue } from 'tailwind-merge';
1
+ import type { ClassNameValue } from "tailwind-merge";
2
2
 
3
- import { Popover, PopoverContent, PopoverTrigger } from '../../components/ui/popover';
4
- import { cn } from '../lib/utils';
3
+ import { cn } from "@repo/ui/lib/utils";
4
+ import { Popover, PopoverContent, PopoverTrigger } from "../../components/ui/popover";
5
5
 
6
6
  interface SimplePopoverProps {
7
7
  children: React.ReactNode;
8
8
  trigger: React.ReactNode;
9
- side?: 'top' | 'right' | 'bottom' | 'left';
9
+ side?: "top" | "right" | "bottom" | "left";
10
10
  sideOffset?: number;
11
11
  open?: boolean;
12
12
  onOpenChange?: (open: boolean) => void;
@@ -17,11 +17,7 @@ export const SimplePopover = (props: SimplePopoverProps) => {
17
17
  return (
18
18
  <Popover open={props.open} onOpenChange={props.onOpenChange}>
19
19
  <PopoverTrigger asChild>{props.trigger}</PopoverTrigger>
20
- <PopoverContent
21
- side={props.side}
22
- sideOffset={props.sideOffset}
23
- className={cn(props.className)}
24
- >
20
+ <PopoverContent side={props.side} sideOffset={props.sideOffset} className={cn(props.className)}>
25
21
  {props.children}
26
22
  </PopoverContent>
27
23
  </Popover>
@@ -1,61 +1,136 @@
1
- import { createContext, useContext, useEffect, useState } from 'react';
2
- import { Toaster } from 'sonner';
3
- type Theme = 'dark' | 'light' | 'system';
1
+ import * as React from "react";
2
+ import { Toaster } from "../ui/sonner";
3
+
4
+ export type Mode = "dark" | "light" | "system";
5
+ export type ThemeColor =
6
+ | "default"
7
+ | "orange"
8
+ | "purple"
9
+ | "emerald"
10
+ | "rose"
11
+ | "amber"
12
+ | "brick"
13
+ | "rust"
14
+ | "cyan"
15
+ | "indigo"
16
+ | "blue";
17
+
18
+ export const themes: Record<ThemeColor, string> = {
19
+ default: "default",
20
+ orange: "orange",
21
+ purple: "purple",
22
+ emerald: "emerald",
23
+ rose: "rose",
24
+ amber: "amber",
25
+ brick: "brick",
26
+ rust: "rust",
27
+ cyan: "cyan",
28
+ indigo: "indigo",
29
+ blue: "blue",
30
+ };
4
31
 
5
32
  type ThemeProviderProps = {
6
33
  children: React.ReactNode;
7
- defaultTheme?: Theme;
8
- storageKey?: string;
34
+ defaultMode?: Mode;
35
+ defaultColor?: ThemeColor;
36
+ storageKeyPrefix?: string;
9
37
  };
10
38
 
11
39
  type ThemeProviderState = {
12
- theme: Theme;
13
- setTheme: (theme: Theme) => void;
40
+ mode: Mode;
41
+ setMode: (mode: Mode) => void;
42
+ color: ThemeColor;
43
+ setColor: (color: ThemeColor) => void;
14
44
  };
15
45
 
16
- const initialState: ThemeProviderState = {
17
- theme: 'system',
18
- setTheme: () => null,
19
- };
20
-
21
- const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
46
+ const ThemeProviderContext = React.createContext<ThemeProviderState | undefined>(undefined);
22
47
 
23
- export const ThemeProvider = ({
48
+ export function ThemeProvider({
24
49
  children,
25
- defaultTheme = 'dark',
26
- storageKey = 'vite-ui-theme',
50
+ defaultMode = "system",
51
+ defaultColor = "default",
52
+ storageKeyPrefix = "app-theme",
27
53
  ...props
28
- }: ThemeProviderProps) => {
29
- const [theme, setTheme] = useState<Theme>(
30
- () =>
31
- (typeof window !== 'undefined' && (localStorage.getItem(storageKey) as Theme)) ||
32
- defaultTheme,
54
+ }: ThemeProviderProps) {
55
+ const modeKey = `${storageKeyPrefix}-mode`;
56
+ const colorKey = `${storageKeyPrefix}-color`;
57
+
58
+ // --- State ---
59
+ const [mode, setModeState] = React.useState<Mode>(() => (localStorage.getItem(modeKey) as Mode) || defaultMode);
60
+
61
+ const [color, setColorState] = React.useState<ThemeColor>(
62
+ () => (localStorage.getItem(colorKey) as ThemeColor) || defaultColor
63
+ );
64
+
65
+ // --- Actions ---
66
+ const setMode = React.useCallback(
67
+ (newMode: Mode) => {
68
+ if (!document.startViewTransition) {
69
+ localStorage.setItem(modeKey, newMode);
70
+ setModeState(newMode);
71
+ return;
72
+ }
73
+
74
+ document.startViewTransition(() => {
75
+ localStorage.setItem(modeKey, newMode);
76
+ setModeState(newMode);
77
+ });
78
+ },
79
+ [modeKey]
33
80
  );
34
81
 
35
- useEffect(() => {
36
- const root = window.document.documentElement;
82
+ const setColor = React.useCallback(
83
+ (newColor: ThemeColor) => {
84
+ if (!document.startViewTransition) {
85
+ localStorage.setItem(colorKey, newColor);
86
+ setColorState(newColor);
87
+ return;
88
+ }
37
89
 
38
- root.classList.remove('light', 'dark');
90
+ document.startViewTransition(() => {
91
+ localStorage.setItem(colorKey, newColor);
92
+ setColorState(newColor);
93
+ });
94
+ },
95
+ [colorKey]
96
+ );
39
97
 
40
- if (theme === 'system') {
41
- const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
42
- ? 'dark'
43
- : 'light';
98
+ // --- Apply Mode (Light/Dark) ---
99
+ React.useEffect(() => {
100
+ const root = document.documentElement;
101
+ root.classList.remove("light", "dark");
44
102
 
103
+ if (mode === "system") {
104
+ const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
45
105
  root.classList.add(systemTheme);
46
106
  return;
47
107
  }
48
108
 
49
- root.classList.add(theme);
50
- }, [theme]);
109
+ root.classList.add(mode);
110
+ }, [mode]);
51
111
 
52
- const value = {
53
- theme,
54
- setTheme: (theme: Theme) => {
55
- localStorage.setItem(storageKey, theme);
56
- setTheme(theme);
57
- },
58
- };
112
+ // --- Apply Color Scheme ---
113
+ React.useEffect(() => {
114
+ const root = document.documentElement;
115
+ if (color === "default") {
116
+ root.removeAttribute("data-theme");
117
+ } else {
118
+ root.setAttribute("data-theme", color);
119
+ }
120
+ }, [color]);
121
+
122
+ // --- System Mode Listener ---
123
+ React.useEffect(() => {
124
+ if (mode !== "system") return;
125
+
126
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
127
+ const handleChange = () => setModeState("system");
128
+
129
+ mediaQuery.addEventListener("change", handleChange);
130
+ return () => mediaQuery.removeEventListener("change", handleChange);
131
+ }, [mode]);
132
+
133
+ const value = React.useMemo(() => ({ mode, setMode, color, setColor }), [mode, color, setMode, setColor]);
59
134
 
60
135
  return (
61
136
  <ThemeProviderContext.Provider {...props} value={value}>
@@ -63,12 +138,12 @@ export const ThemeProvider = ({
63
138
  {children}
64
139
  </ThemeProviderContext.Provider>
65
140
  );
66
- };
141
+ }
67
142
 
68
143
  export const useTheme = () => {
69
- const context = useContext(ThemeProviderContext);
70
-
71
- if (context === undefined) throw new Error('useTheme must be used within a ThemeProvider');
72
-
144
+ const context = React.useContext(ThemeProviderContext);
145
+ if (context === undefined) {
146
+ throw new Error("useTheme must be used within a ThemeProvider");
147
+ }
73
148
  return context;
74
149
  };
@@ -1,6 +1,6 @@
1
- import type React from 'react';
1
+ import type React from "react";
2
2
 
3
- import { cn } from '../lib/utils';
3
+ import { cn } from "@repo/ui/lib/utils";
4
4
 
5
5
  interface TypographyProps {
6
6
  children: React.ReactNode; // Text content to display
@@ -8,71 +8,69 @@ interface TypographyProps {
8
8
  }
9
9
 
10
10
  const H1: React.FC<TypographyProps> = ({ children, className }) => (
11
- <h1 className={cn('text-4xl font-bold', className)}>{children}</h1>
11
+ <h1 className={cn("text-4xl font-bold", className)}>{children}</h1>
12
12
  );
13
13
 
14
14
  const H2: React.FC<TypographyProps> = ({ children, className }) => (
15
- <h2 className={cn('text-3xl font-semibold', className)}>{children}</h2>
15
+ <h2 className={cn("text-3xl font-semibold", className)}>{children}</h2>
16
16
  );
17
17
 
18
18
  const H3: React.FC<TypographyProps> = ({ children, className }) => (
19
- <h3 className={cn('text-2xl font-medium', className)}>{children}</h3>
19
+ <h3 className={cn("text-2xl font-medium", className)}>{children}</h3>
20
20
  );
21
21
 
22
22
  const H4: React.FC<TypographyProps> = ({ children, className }) => (
23
- <h4 className={cn('text-xl font-semibold', className)}>{children}</h4>
23
+ <h4 className={cn("text-xl font-semibold", className)}>{children}</h4>
24
24
  );
25
25
 
26
26
  const H5: React.FC<TypographyProps> = ({ children, className }) => (
27
- <h5 className={cn('text-lg font-medium', className)}>{children}</h5>
27
+ <h5 className={cn("text-lg font-medium", className)}>{children}</h5>
28
28
  );
29
29
 
30
30
  const H6: React.FC<TypographyProps> = ({ children, className }) => (
31
- <h6 className={cn('font-semibold', className)}>{children}</h6>
31
+ <h6 className={cn("font-semibold", className)}>{children}</h6>
32
32
  );
33
33
 
34
- const Default: React.FC<TypographyProps> = ({ children, className }) => (
35
- <p className={cn(className)}>{children}</p>
36
- );
34
+ const Default: React.FC<TypographyProps> = ({ children, className }) => <p className={cn(className)}>{children}</p>;
37
35
 
38
36
  const Secondary: React.FC<TypographyProps> = ({ children, className }) => (
39
- <span className={cn('text-muted-foreground', className)}>{children}</span>
37
+ <span className={cn("text-muted-foreground", className)}>{children}</span>
40
38
  );
41
39
 
42
40
  const Primary: React.FC<TypographyProps> = ({ children, className }) => (
43
- <span className={cn('text-primary', className)}>{children}</span>
41
+ <span className={cn("text-primary", className)}>{children}</span>
44
42
  );
45
43
 
46
44
  const Error: React.FC<TypographyProps> = ({ children, className }) => (
47
- <span className={cn('text-destructive text-sm', className)}>{children}</span>
45
+ <span className={cn("text-destructive text-sm", className)}>{children}</span>
48
46
  );
49
47
 
50
48
  const Warning: React.FC<TypographyProps> = ({ children, className }) => (
51
- <span className={cn('text-yellow-500 text-sm', className)}>{children}</span>
49
+ <span className={cn("text-yellow-500 text-sm", className)}>{children}</span>
52
50
  );
53
51
 
54
52
  const Success: React.FC<TypographyProps> = ({ children, className }) => (
55
- <span className={cn('text-green-500 text-sm', className)}>{children}</span>
53
+ <span className={cn("text-green-500 text-sm", className)}>{children}</span>
56
54
  );
57
55
 
58
56
  const Hint: React.FC<TypographyProps> = ({ children, className }) => (
59
- <span className={cn('text-muted-foreground text-xs', className)}>{children}</span>
57
+ <span className={cn("text-muted-foreground text-xs", className)}>{children}</span>
60
58
  );
61
59
 
62
60
  const Grayed: React.FC<TypographyProps> = ({ children, className }) => (
63
- <p className={cn('text-gray-500', className)}>{children}</p>
61
+ <p className={cn("text-gray-500", className)}>{children}</p>
64
62
  );
65
63
 
66
64
  const Muted: React.FC<TypographyProps> = ({ children, className }) => (
67
- <p className={cn('text-muted', className)}>{children}</p>
65
+ <p className={cn("text-muted", className)}>{children}</p>
68
66
  );
69
67
 
70
68
  const Key: React.FC<TypographyProps> = ({ children, className }) => (
71
- <span className={cn('font-thin text-xs', className)}>{children}</span>
69
+ <span className={cn("font-thin text-xs", className)}>{children}</span>
72
70
  );
73
71
 
74
72
  const Value: React.FC<TypographyProps> = ({ children, className }) => (
75
- <span className={cn('text-lg', className)}>{children}</span>
73
+ <span className={cn("text-lg", className)}>{children}</span>
76
74
  );
77
75
 
78
76
  const List: React.FC<TypographyProps & { label?: string }> = ({ children, className, label }) => (
@@ -82,7 +80,7 @@ const List: React.FC<TypographyProps & { label?: string }> = ({ children, classN
82
80
  </ul>
83
81
  );
84
82
  const Item: React.FC<TypographyProps> = ({ children, className }) => (
85
- <li className={cn('ml-6 text-sm list-disc', className)}>{children}</li>
83
+ <li className={cn("ml-6 text-sm list-disc", className)}>{children}</li>
86
84
  );
87
85
 
88
86
  // Combine all typography components into a single object
@@ -0,0 +1,100 @@
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@repo/ui/lib/utils";
4
+
5
+ const Timeline = React.forwardRef<HTMLOListElement, React.HTMLAttributes<HTMLOListElement>>(
6
+ ({ className, ...props }, ref) => <ol ref={ref} className={cn("flex flex-col", className)} {...props} />
7
+ );
8
+ Timeline.displayName = "Timeline";
9
+
10
+ const TimelineItem = React.forwardRef<HTMLLIElement, React.LiHTMLAttributes<HTMLLIElement> & { className: string }>(
11
+ ({ className, ...props }, ref) => (
12
+ <li ref={ref} className={cn("relative flex flex-col p-6 pl-3 pt-0 [&>*]:mb-2", className)} {...props} />
13
+ )
14
+ );
15
+ TimelineItem.displayName = "TimelineItem";
16
+
17
+ const TimelineTime = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
18
+ ({ className, ...props }, ref) => (
19
+ <p
20
+ ref={ref}
21
+ className={cn(
22
+ "absolute translate-x-36 md:-translate-x-24 text-sm font-semibold leading-none text-secondary-foreground",
23
+ className
24
+ )}
25
+ {...props}
26
+ />
27
+ )
28
+ );
29
+ TimelineTime.displayName = "TimelineTime";
30
+
31
+ const TimelineConnector = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
32
+ ({ className, ...props }, ref) => (
33
+ <div
34
+ ref={ref}
35
+ className={cn("absolute top-[5px] left-[30px] -translate-x-1/2 translate-y-2 h-full w-px bg-primary", className)}
36
+ {...props}
37
+ />
38
+ )
39
+ );
40
+ TimelineConnector.displayName = "TimelineConnector";
41
+
42
+ const TimelineHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
43
+ ({ className, ...props }, ref) => <div ref={ref} className={cn("flex items-center gap-4", className)} {...props} />
44
+ );
45
+ TimelineHeader.displayName = "TimelineHeader";
46
+
47
+ const TimelineTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(
48
+ ({ className, children, ...props }, ref) => (
49
+ <h3
50
+ ref={ref}
51
+ className={cn("font-semibold leading-none tracking-tight text-secondary-foreground", className)}
52
+ {...props}
53
+ >
54
+ {children}
55
+ </h3>
56
+ )
57
+ );
58
+ TimelineTitle.displayName = "CardTitle";
59
+
60
+ const TimelineIcon = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
61
+ ({ className, ...props }, ref) => (
62
+ <div
63
+ ref={ref}
64
+ className={cn(
65
+ "grid place-content-center flex-col text-center items-center size-7 justify-center relative left-1 bg-primary rounded-full",
66
+ className
67
+ )}
68
+ {...props}
69
+ >
70
+ {props.children}
71
+ </div>
72
+ )
73
+ );
74
+ TimelineIcon.displayName = "TimelineIcon";
75
+
76
+ const TimelineDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
77
+ ({ className, ...props }, ref) => (
78
+ <p ref={ref} className={cn("text-sm text-muted-foreground max-w-sm ml-5", className)} {...props} />
79
+ )
80
+ );
81
+ TimelineDescription.displayName = "TimelineDescription";
82
+
83
+ const TimelineContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
84
+ ({ className, ...props }, ref) => (
85
+ <div ref={ref} className={cn("flex flex-col items-start p-6 pt-0", className)} {...props} />
86
+ )
87
+ );
88
+ TimelineContent.displayName = "TimelineContent";
89
+
90
+ export {
91
+ Timeline,
92
+ TimelineItem,
93
+ TimelineConnector,
94
+ TimelineHeader,
95
+ TimelineTitle,
96
+ TimelineIcon,
97
+ TimelineDescription,
98
+ TimelineContent,
99
+ TimelineTime,
100
+ };
@@ -1,118 +1,56 @@
1
- "use client";
2
-
3
- import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
4
- import React from "react";
5
-
6
- import { buttonVariants } from "@/components/ui/button";
7
-
8
- import { cn } from "../lib/utils";
9
-
10
- const AlertDialog = AlertDialogPrimitive.Root;
11
-
12
- const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
13
-
14
- const AlertDialogPortal = AlertDialogPrimitive.Portal;
1
+ import { cva, type VariantProps } from "class-variance-authority";
2
+ import * as React from "react";
3
+
4
+ import { cn } from "@repo/ui/lib/utils";
5
+
6
+ const alertVariants = cva(
7
+ "group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: "bg-card text-card-foreground",
12
+ destructive:
13
+ "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: "default",
18
+ },
19
+ }
20
+ );
15
21
 
16
- const AlertDialogOverlay = React.forwardRef<
17
- React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
18
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
19
- >(({ className, ...props }, ref) => (
20
- <AlertDialogPrimitive.Overlay
21
- className={cn(
22
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
23
- className
24
- )}
25
- {...props}
26
- ref={ref}
27
- />
28
- ));
29
- AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
22
+ function Alert({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
23
+ return <div data-slot="alert" role="alert" className={cn(alertVariants({ variant }), className)} {...props} />;
24
+ }
30
25
 
31
- const AlertDialogContent = React.forwardRef<
32
- React.ElementRef<typeof AlertDialogPrimitive.Content>,
33
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
34
- >(({ className, ...props }, ref) => (
35
- <AlertDialogPortal>
36
- <AlertDialogOverlay />
37
- <AlertDialogPrimitive.Content
38
- ref={ref}
26
+ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
27
+ return (
28
+ <div
29
+ data-slot="alert-title"
39
30
  className={cn(
40
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
31
+ "font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground",
41
32
  className
42
33
  )}
43
34
  {...props}
44
35
  />
45
- </AlertDialogPortal>
46
- ));
47
- AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
48
-
49
- const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
50
- <div className={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...props} />
51
- );
52
- AlertDialogHeader.displayName = "AlertDialogHeader";
36
+ );
37
+ }
53
38
 
54
- const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
55
- <div
56
- className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
57
- {...props}
58
- />
59
- );
60
- AlertDialogFooter.displayName = "AlertDialogFooter";
61
-
62
- const AlertDialogTitle = React.forwardRef<
63
- React.ElementRef<typeof AlertDialogPrimitive.Title>,
64
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
65
- >(({ className, ...props }, ref) => (
66
- <AlertDialogPrimitive.Title
67
- ref={ref}
68
- className={cn("text-lg font-semibold", className)}
69
- {...props}
70
- />
71
- ));
72
- AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
73
-
74
- const AlertDialogDescription = React.forwardRef<
75
- React.ElementRef<typeof AlertDialogPrimitive.Description>,
76
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
77
- >(({ className, ...props }, ref) => (
78
- <AlertDialogPrimitive.Description
79
- ref={ref}
80
- className={cn("text-sm text-muted-foreground", className)}
81
- {...props}
82
- />
83
- ));
84
- AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
85
-
86
- const AlertDialogAction = React.forwardRef<
87
- React.ElementRef<typeof AlertDialogPrimitive.Action>,
88
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
89
- >(({ className, ...props }, ref) => (
90
- <AlertDialogPrimitive.Action ref={ref} className={cn(buttonVariants(), className)} {...props} />
91
- ));
92
- AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
39
+ function AlertDescription({ className, ...props }: React.ComponentProps<"div">) {
40
+ return (
41
+ <div
42
+ data-slot="alert-description"
43
+ className={cn(
44
+ "text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
45
+ className
46
+ )}
47
+ {...props}
48
+ />
49
+ );
50
+ }
93
51
 
94
- const AlertDialogCancel = React.forwardRef<
95
- React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
96
- React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
97
- >(({ className, ...props }, ref) => (
98
- <AlertDialogPrimitive.Cancel
99
- ref={ref}
100
- className={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
101
- {...props}
102
- />
103
- ));
104
- AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
52
+ function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
53
+ return <div data-slot="alert-action" className={cn("absolute top-2 right-2", className)} {...props} />;
54
+ }
105
55
 
106
- export {
107
- AlertDialog,
108
- AlertDialogPortal,
109
- AlertDialogOverlay,
110
- AlertDialogTrigger,
111
- AlertDialogContent,
112
- AlertDialogHeader,
113
- AlertDialogFooter,
114
- AlertDialogTitle,
115
- AlertDialogDescription,
116
- AlertDialogAction,
117
- AlertDialogCancel,
118
- };
56
+ export { Alert, AlertTitle, AlertDescription, AlertAction };