startx 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/.prettierignore +0 -13
  2. package/.prettierrc.js +52 -52
  3. package/.vscode/launch.json +32 -0
  4. package/.vscode/settings.json +9 -3
  5. package/apps/core-server/.env.example +18 -24
  6. package/apps/core-server/Dockerfile +35 -61
  7. package/apps/core-server/eslint.config.ts +7 -0
  8. package/apps/core-server/package.json +41 -52
  9. package/apps/core-server/src/config/custom-type.ts +2 -40
  10. package/apps/core-server/src/events/index.ts +37 -37
  11. package/apps/core-server/src/index.ts +4 -13
  12. package/apps/core-server/src/middlewares/auth-middleware.ts +24 -7
  13. package/apps/core-server/src/middlewares/cors-middleware.ts +7 -6
  14. package/apps/core-server/src/middlewares/error-middleware.ts +7 -4
  15. package/apps/core-server/src/middlewares/logger-middleware.ts +81 -21
  16. package/apps/core-server/src/middlewares/notfound-middleware.ts +6 -14
  17. package/apps/core-server/src/middlewares/serve-static.ts +30 -24
  18. package/apps/core-server/src/routes/files/router.ts +9 -7
  19. package/apps/core-server/src/routes/server.ts +30 -36
  20. package/apps/core-server/tsdown.config.ts +4 -3
  21. package/biome.json +58 -60
  22. package/configs/eslint-config/package.json +16 -19
  23. package/configs/eslint-config/src/configs/base.ts +185 -225
  24. package/configs/eslint-config/src/configs/extend.ts +3 -0
  25. package/configs/eslint-config/src/configs/frontend.ts +81 -56
  26. package/configs/eslint-config/src/configs/node.ts +6 -6
  27. package/configs/eslint-config/src/plugin.ts +1 -0
  28. package/configs/eslint-config/src/rules/index.ts +8 -12
  29. package/configs/eslint-config/src/rules/no-json-parse-json-stringify.test.ts +30 -17
  30. package/configs/eslint-config/src/rules/no-json-parse-json-stringify.ts +52 -49
  31. package/configs/eslint-config/src/rules/no-uncaught-json-parse.ts +43 -45
  32. package/configs/tsdown-config/package.json +10 -3
  33. package/configs/typescript-config/package.json +10 -1
  34. package/configs/typescript-config/tsconfig.common.json +3 -3
  35. package/configs/vitest-config/dist/base.mjs +1 -0
  36. package/configs/vitest-config/dist/frontend.mjs +1 -0
  37. package/configs/vitest-config/dist/node.mjs +1 -0
  38. package/configs/vitest-config/package.json +12 -0
  39. package/configs/vitest-config/src/base.ts +17 -29
  40. package/configs/vitest-config/src/index.ts +1 -0
  41. package/package.json +21 -13
  42. package/packages/@repo/constants/eslint.config.ts +4 -0
  43. package/packages/@repo/constants/package.json +16 -0
  44. package/packages/@repo/constants/src/index.ts +8 -8
  45. package/packages/@repo/db/eslint.config.ts +4 -0
  46. package/packages/@repo/db/package.json +16 -8
  47. package/packages/@repo/db/src/index.ts +26 -20
  48. package/packages/@repo/db/src/schema/common.ts +45 -49
  49. package/packages/@repo/env/eslint.config.ts +4 -0
  50. package/packages/@repo/env/package.json +39 -0
  51. package/packages/@repo/env/src/default-env.ts +12 -0
  52. package/packages/@repo/env/src/define-env.ts +70 -0
  53. package/packages/@repo/env/src/index.ts +2 -0
  54. package/packages/@repo/env/src/utils.ts +52 -0
  55. package/packages/@repo/env/tsconfig.json +7 -0
  56. package/packages/@repo/lib/eslint.config.ts +4 -0
  57. package/packages/@repo/lib/package.json +34 -34
  58. package/packages/@repo/lib/src/bucket-module/file-storage.ts +50 -49
  59. package/packages/@repo/lib/src/bucket-module/index.ts +3 -0
  60. package/packages/@repo/lib/src/bucket-module/s3-storage.ts +120 -114
  61. package/packages/@repo/lib/src/bucket-module/utils.ts +10 -11
  62. package/packages/@repo/lib/src/{cookie-module.ts → cookie-module/cookie-module.ts} +48 -42
  63. package/packages/@repo/lib/src/cookie-module/index.ts +1 -0
  64. package/packages/@repo/lib/src/extra/index.ts +1 -0
  65. package/packages/@repo/lib/src/extra/pagination-module.ts +35 -0
  66. package/packages/@repo/lib/src/{token-module.ts → extra/token-module.ts} +12 -5
  67. package/packages/@repo/lib/src/file-system-module/index.ts +170 -0
  68. package/packages/@repo/lib/src/{hashing-module.ts → hashing-module/index.ts} +9 -9
  69. package/packages/@repo/lib/src/index.ts +0 -26
  70. package/packages/@repo/lib/src/mail-module/index.ts +2 -0
  71. package/packages/@repo/lib/src/mail-module/mock.ts +8 -8
  72. package/packages/@repo/lib/src/mail-module/nodemailer.ts +17 -7
  73. package/packages/@repo/lib/src/notification-module/index.ts +1 -172
  74. package/packages/@repo/lib/src/notification-module/push-notification.ts +97 -90
  75. package/packages/@repo/lib/src/{oauth2-client.ts → oauth2-module/index.ts} +107 -109
  76. package/packages/@repo/lib/src/otp-module/index.ts +91 -0
  77. package/packages/@repo/lib/src/session-module/index.ts +113 -0
  78. package/packages/@repo/lib/src/utils.ts +43 -42
  79. package/packages/@repo/lib/src/validation-module/index.ts +242 -0
  80. package/packages/@repo/logger/eslint.config.ts +4 -0
  81. package/packages/@repo/logger/package.json +40 -0
  82. package/packages/@repo/logger/src/index.ts +2 -0
  83. package/packages/@repo/logger/src/logger.ts +72 -0
  84. package/packages/@repo/{lib/src/logger-module → logger/src}/memory-profiler.ts +64 -65
  85. package/packages/@repo/logger/tsconfig.json +7 -0
  86. package/packages/@repo/mail/eslint.config.ts +4 -0
  87. package/packages/@repo/mail/package.json +10 -3
  88. package/packages/@repo/mail/src/emails/admin/OtpEmail.tsx +169 -168
  89. package/packages/@repo/mail/src/index.ts +1 -2
  90. package/packages/@repo/mail/tsconfig.json +3 -3
  91. package/packages/@repo/redis/dist/index.d.mts +3 -0
  92. package/packages/@repo/redis/dist/index.mjs +5 -0
  93. package/packages/@repo/redis/dist/lib/redis-client.d.mts +7 -0
  94. package/packages/@repo/redis/dist/lib/redis-client.mjs +25 -0
  95. package/packages/@repo/redis/dist/lib/redis-client.mjs.map +1 -0
  96. package/packages/@repo/redis/dist/lib/redis-module.d.mts +5 -0
  97. package/packages/@repo/redis/dist/lib/redis-module.mjs +6 -0
  98. package/packages/@repo/redis/dist/lib/redis-module.mjs.map +1 -0
  99. package/packages/@repo/redis/eslint.config.ts +4 -0
  100. package/packages/@repo/redis/package.json +13 -10
  101. package/packages/@repo/redis/src/index.ts +2 -2
  102. package/packages/@repo/redis/src/lib/redis-client.ts +36 -23
  103. package/packages/@repo/redis/src/lib/redis-module.ts +69 -3
  104. package/packages/cli/dist/index.mjs +203 -0
  105. package/packages/cli/eslint.config.ts +4 -0
  106. package/packages/cli/package.json +44 -0
  107. package/packages/cli/tsconfig.json +12 -0
  108. package/packages/cli/tsdown.config.ts +17 -0
  109. package/packages/ui/components.json +0 -1
  110. package/packages/ui/eslint.config.ts +4 -0
  111. package/packages/ui/package.json +16 -3
  112. package/packages/ui/postcss.config.mjs +9 -9
  113. package/packages/ui/src/components/lib/utils.ts +53 -53
  114. package/packages/ui/src/components/ui/alert-dialog.tsx +118 -116
  115. package/packages/ui/src/components/ui/avatar.tsx +52 -53
  116. package/packages/ui/src/components/ui/badge.tsx +45 -46
  117. package/packages/ui/src/components/ui/breadcrumb.tsx +108 -109
  118. package/packages/ui/src/components/ui/card.tsx +91 -92
  119. package/packages/ui/src/components/ui/carousel.tsx +243 -243
  120. package/packages/ui/src/components/ui/checkbox.tsx +32 -32
  121. package/packages/ui/src/components/ui/command.tsx +144 -155
  122. package/packages/ui/src/components/ui/dialog.tsx +124 -127
  123. package/packages/ui/src/components/ui/form.tsx +166 -165
  124. package/packages/ui/src/components/ui/input-otp.tsx +74 -76
  125. package/packages/ui/src/components/ui/input.tsx +19 -21
  126. package/packages/ui/src/components/ui/multiple-select.tsx +4 -4
  127. package/packages/ui/src/{components/lucide.tsx → lucide.ts} +3 -3
  128. package/packages/ui/tailwind.config.ts +94 -94
  129. package/packages/ui/tsconfig.json +7 -1
  130. package/pnpm-workspace.yaml +41 -1
  131. package/turbo.json +20 -27
  132. package/apps/core-server/eslint.config.mjs +0 -47
  133. package/configs/eslint-config/src/rules/no-dynamic-import-template.ts +0 -32
  134. package/configs/eslint-config/src/rules/no-plain-errors.ts +0 -50
  135. package/configs/eslint-config/tsdown.config.ts +0 -11
  136. package/packages/@repo/constants/eslint.config.mjs +0 -21
  137. package/packages/@repo/db/eslint.config.mjs +0 -21
  138. package/packages/@repo/lib/eslint.config.mjs +0 -49
  139. package/packages/@repo/lib/src/command-module.ts +0 -77
  140. package/packages/@repo/lib/src/constants.ts +0 -3
  141. package/packages/@repo/lib/src/custom-type.ts +0 -54
  142. package/packages/@repo/lib/src/env.ts +0 -13
  143. package/packages/@repo/lib/src/file-system/index.ts +0 -90
  144. package/packages/@repo/lib/src/logger-module/log-config.ts +0 -16
  145. package/packages/@repo/lib/src/logger-module/logger.ts +0 -78
  146. package/packages/@repo/lib/src/mail-module/api.ts +0 -0
  147. package/packages/@repo/lib/src/otp-module.ts +0 -98
  148. package/packages/@repo/lib/src/pagination-module.ts +0 -49
  149. package/packages/@repo/lib/src/user-session.ts +0 -117
  150. package/packages/@repo/lib/src/validation-module.ts +0 -187
  151. package/packages/@repo/mail/tsconfig.build.json +0 -14
  152. package/packages/@repo/mail/tsdown.config.ts +0 -9
  153. package/packages/@repo/redis/eslint.config.mjs +0 -8
  154. package/packages/ui/eslint.config.mjs +0 -18
@@ -1,165 +1,166 @@
1
- import type * as LabelPrimitive from "@radix-ui/react-label";
2
- import { Slot } from "@radix-ui/react-slot";
3
- import { CircleAlert } from "lucide-react";
4
- import * as React from "react";
5
- import type { ControllerProps, FieldPath, FieldValues } from "react-hook-form";
6
- import { Controller, FormProvider, useFormContext } from "react-hook-form";
7
- import type { ClassNameValue } from "tailwind-merge";
8
- import { cn } from "../lib/utils";
9
- import { Label } from "./label";
10
-
11
- const Form = FormProvider;
12
-
13
- type FormFieldContextValue<
14
- TFieldValues extends FieldValues = FieldValues,
15
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
16
- > = {
17
- name: TName;
18
- };
19
-
20
- const FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);
21
-
22
- const FormField = <
23
- TFieldValues extends FieldValues = FieldValues,
24
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
25
- >({
26
- ...props
27
- }: ControllerProps<TFieldValues, TName>) => {
28
- return (
29
- <FormFieldContext.Provider value={{ name: props.name }}>
30
- <Controller {...props} />
31
- </FormFieldContext.Provider>
32
- );
33
- };
34
-
35
- const useFormField = () => {
36
- const fieldContext = React.useContext(FormFieldContext);
37
- const itemContext = React.useContext(FormItemContext);
38
- const { getFieldState, formState } = useFormContext();
39
-
40
- const fieldState = getFieldState(fieldContext.name, formState);
41
-
42
- if (!fieldContext) {
43
- throw new Error("useFormField should be used within <FormField>");
44
- }
45
-
46
- const { id } = itemContext;
47
-
48
- return {
49
- id,
50
- name: fieldContext.name,
51
- formItemId: `${id}-form-item`,
52
- formDescriptionId: `${id}-form-item-description`,
53
- formMessageId: `${id}-form-item-message`,
54
- ...fieldState,
55
- };
56
- };
57
-
58
- type FormItemContextValue = {
59
- id: string;
60
- };
61
-
62
- const FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);
63
-
64
- const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
65
- ({ className, ...props }, ref) => {
66
- const id = React.useId();
67
-
68
- return (
69
- <FormItemContext.Provider value={{ id }}>
70
- <div ref={ref} className={cn("space-y-2", className)} {...props} />
71
- </FormItemContext.Provider>
72
- );
73
- }
74
- );
75
- FormItem.displayName = "FormItem";
76
-
77
- const FormLabel = React.forwardRef<
78
- React.ElementRef<typeof LabelPrimitive.Root>,
79
- React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {
80
- className?: ClassNameValue;
81
- }
82
- >(({ className, ...props }, ref) => {
83
- const { error, formItemId } = useFormField();
84
-
85
- return (
86
- <Label
87
- ref={ref}
88
- className={cn(error && "text-destructive", className)}
89
- htmlFor={formItemId}
90
- {...props}
91
- />
92
- );
93
- });
94
- FormLabel.displayName = "FormLabel";
95
-
96
- const FormControl = React.forwardRef<
97
- React.ElementRef<typeof Slot>,
98
- React.ComponentPropsWithoutRef<typeof Slot>
99
- >(({ ...props }, ref) => {
100
- const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
101
-
102
- return (
103
- <Slot
104
- ref={ref}
105
- id={formItemId}
106
- aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}
107
- aria-invalid={!!error}
108
- {...props}
109
- />
110
- );
111
- });
112
- FormControl.displayName = "FormControl";
113
-
114
- const FormDescription = React.forwardRef<
115
- HTMLParagraphElement,
116
- React.HTMLAttributes<HTMLParagraphElement>
117
- >(({ className, ...props }, ref) => {
118
- const { formDescriptionId } = useFormField();
119
-
120
- return (
121
- <p
122
- ref={ref}
123
- id={formDescriptionId}
124
- className={cn("text-sm text-muted-foreground", className)}
125
- {...props}
126
- />
127
- );
128
- });
129
- FormDescription.displayName = "FormDescription";
130
-
131
- const FormMessage = React.forwardRef<
132
- HTMLParagraphElement,
133
- React.HTMLAttributes<HTMLParagraphElement>
134
- >(({ className, children, ...props }, ref) => {
135
- const { error, formMessageId } = useFormField();
136
- const body = error ? String(error?.message) : children;
137
-
138
- if (!body) {
139
- return null;
140
- }
141
-
142
- return (
143
- <span
144
- ref={ref}
145
- id={formMessageId}
146
- className={cn("text-sm flex gap-2 items-center font-medium text-destructive", className)}
147
- {...props}
148
- >
149
- <CircleAlert size={18} strokeWidth={2} />
150
- <p>{body}</p>
151
- </span>
152
- );
153
- });
154
- FormMessage.displayName = "FormMessage";
155
-
156
- export {
157
- useFormField,
158
- Form,
159
- FormItem,
160
- FormLabel,
161
- FormControl,
162
- FormDescription,
163
- FormMessage,
164
- FormField,
165
- };
1
+ import type * as LabelPrimitive from "@radix-ui/react-label";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { CircleAlert } from "lucide-react";
4
+ import * as React from "react";
5
+ import type { ControllerProps, FieldPath, FieldValues } from "react-hook-form";
6
+ import { Controller, FormProvider, useFormContext } from "react-hook-form";
7
+ import type { ClassNameValue } from "tailwind-merge";
8
+
9
+ import { Label } from "./label";
10
+ import { cn } from "../lib/utils";
11
+
12
+ const Form = FormProvider;
13
+
14
+ type FormFieldContextValue<
15
+ TFieldValues extends FieldValues = FieldValues,
16
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
17
+ > = {
18
+ name: TName;
19
+ };
20
+
21
+ const FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);
22
+
23
+ const FormField = <
24
+ TFieldValues extends FieldValues = FieldValues,
25
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
26
+ >({
27
+ ...props
28
+ }: ControllerProps<TFieldValues, TName>) => {
29
+ return (
30
+ <FormFieldContext.Provider value={{ name: props.name }}>
31
+ <Controller {...props} />
32
+ </FormFieldContext.Provider>
33
+ );
34
+ };
35
+
36
+ const useFormField = () => {
37
+ const fieldContext = React.useContext(FormFieldContext);
38
+ const itemContext = React.useContext(FormItemContext);
39
+ const { getFieldState, formState } = useFormContext();
40
+
41
+ const fieldState = getFieldState(fieldContext.name, formState);
42
+
43
+ if (!fieldContext) {
44
+ throw new Error("useFormField should be used within <FormField>");
45
+ }
46
+
47
+ const { id } = itemContext;
48
+
49
+ return {
50
+ id,
51
+ name: fieldContext.name,
52
+ formItemId: `${id}-form-item`,
53
+ formDescriptionId: `${id}-form-item-description`,
54
+ formMessageId: `${id}-form-item-message`,
55
+ ...fieldState,
56
+ };
57
+ };
58
+
59
+ type FormItemContextValue = {
60
+ id: string;
61
+ };
62
+
63
+ const FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);
64
+
65
+ const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
66
+ ({ className, ...props }, ref) => {
67
+ const id = React.useId();
68
+
69
+ return (
70
+ <FormItemContext.Provider value={{ id }}>
71
+ <div ref={ref} className={cn("space-y-2", className)} {...props} />
72
+ </FormItemContext.Provider>
73
+ );
74
+ }
75
+ );
76
+ FormItem.displayName = "FormItem";
77
+
78
+ const FormLabel = React.forwardRef<
79
+ React.ElementRef<typeof LabelPrimitive.Root>,
80
+ React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {
81
+ className?: ClassNameValue;
82
+ }
83
+ >(({ className, ...props }, ref) => {
84
+ const { error, formItemId } = useFormField();
85
+
86
+ return (
87
+ <Label
88
+ ref={ref}
89
+ className={cn(error && "text-destructive", className)}
90
+ htmlFor={formItemId}
91
+ {...props}
92
+ />
93
+ );
94
+ });
95
+ FormLabel.displayName = "FormLabel";
96
+
97
+ const FormControl = React.forwardRef<
98
+ React.ElementRef<typeof Slot>,
99
+ React.ComponentPropsWithoutRef<typeof Slot>
100
+ >(({ ...props }, ref) => {
101
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
102
+
103
+ return (
104
+ <Slot
105
+ ref={ref}
106
+ id={formItemId}
107
+ aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}
108
+ aria-invalid={!!error}
109
+ {...props}
110
+ />
111
+ );
112
+ });
113
+ FormControl.displayName = "FormControl";
114
+
115
+ const FormDescription = React.forwardRef<
116
+ HTMLParagraphElement,
117
+ React.HTMLAttributes<HTMLParagraphElement>
118
+ >(({ className, ...props }, ref) => {
119
+ const { formDescriptionId } = useFormField();
120
+
121
+ return (
122
+ <p
123
+ ref={ref}
124
+ id={formDescriptionId}
125
+ className={cn("text-sm text-muted-foreground", className)}
126
+ {...props}
127
+ />
128
+ );
129
+ });
130
+ FormDescription.displayName = "FormDescription";
131
+
132
+ const FormMessage = React.forwardRef<
133
+ HTMLParagraphElement,
134
+ React.HTMLAttributes<HTMLParagraphElement>
135
+ >(({ className, children, ...props }, ref) => {
136
+ const { error, formMessageId } = useFormField();
137
+ const body = error ? String(error?.message) : children;
138
+
139
+ if (!body) {
140
+ return null;
141
+ }
142
+
143
+ return (
144
+ <span
145
+ ref={ref}
146
+ id={formMessageId}
147
+ className={cn("text-sm flex gap-2 items-center font-medium text-destructive", className)}
148
+ {...props}
149
+ >
150
+ <CircleAlert size={18} strokeWidth={2} />
151
+ <p>{body}</p>
152
+ </span>
153
+ );
154
+ });
155
+ FormMessage.displayName = "FormMessage";
156
+
157
+ export {
158
+ useFormField,
159
+ Form,
160
+ FormItem,
161
+ FormLabel,
162
+ FormControl,
163
+ FormDescription,
164
+ FormMessage,
165
+ FormField,
166
+ };
@@ -1,76 +1,74 @@
1
- "use client";
2
- import { OTPInput, OTPInputContext } from "input-otp";
3
- import { MinusIcon } from "lucide-react";
4
- import * as React from "react";
5
-
6
- import { cn } from "../lib/utils";
7
-
8
- function InputOTP({
9
- className,
10
- containerClassName,
11
- ...props
12
- }: React.ComponentProps<typeof OTPInput> & {
13
- containerClassName?: string;
14
- }) {
15
- return (
16
- <OTPInput
17
- data-slot="input-otp"
18
- containerClassName={cn(
19
- "flex items-center gap-2 has-disabled:opacity-50",
20
- containerClassName
21
- )}
22
- className={cn("disabled:cursor-not-allowed", className)}
23
- {...props}
24
- />
25
- );
26
- }
27
-
28
- function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
29
- return (
30
- <div
31
- data-slot="input-otp-group"
32
- className={cn("flex items-center", className)}
33
- {...props}
34
- />
35
- );
36
- }
37
-
38
- function InputOTPSlot({
39
- index,
40
- className,
41
- ...props
42
- }: React.ComponentProps<"div"> & {
43
- index: number;
44
- }) {
45
- const inputOTPContext = React.useContext(OTPInputContext);
46
- const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
47
-
48
- return (
49
- <div
50
- data-slot="input-otp-slot"
51
- data-active={isActive}
52
- className={cn(
53
- "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
54
- className
55
- )}
56
- {...props}
57
- >
58
- {char}
59
- {hasFakeCaret && (
60
- <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
61
- <div className="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
62
- </div>
63
- )}
64
- </div>
65
- );
66
- }
67
-
68
- function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
69
- return (
70
- <div data-slot="input-otp-separator" role="separator" {...props}>
71
- <MinusIcon />
72
- </div>
73
- );
74
- }
75
-
76
- export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
1
+ "use client";
2
+ import { OTPInput, OTPInputContext } from "input-otp";
3
+ import { MinusIcon } from "lucide-react";
4
+ import * as React from "react";
5
+
6
+ import { cn } from "../lib/utils";
7
+
8
+ function InputOTP({
9
+ className,
10
+ containerClassName,
11
+ ...props
12
+ }: React.ComponentProps<typeof OTPInput> & {
13
+ containerClassName?: string;
14
+ }) {
15
+ return (
16
+ <OTPInput
17
+ data-slot="input-otp"
18
+ containerClassName={cn(
19
+ "flex items-center gap-2 has-disabled:opacity-50",
20
+ containerClassName
21
+ )}
22
+ className={cn("disabled:cursor-not-allowed", className)}
23
+ {...props}
24
+ />
25
+ );
26
+ }
27
+
28
+ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
29
+ return (
30
+ <div
31
+ data-slot="input-otp-group"
32
+ className={cn("flex items-center", className)}
33
+ {...props}
34
+ />
35
+ );
36
+ }
37
+
38
+ function InputOTPSlot({
39
+ index,
40
+ className,
41
+ ...props
42
+ }: React.ComponentProps<"div"> & {
43
+ index: number;
44
+ }) {
45
+ const inputOTPContext = React.useContext(OTPInputContext);
46
+ const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
47
+
48
+ return (
49
+ <div
50
+ data-slot="input-otp-slot"
51
+ data-active={isActive}
52
+ className={cn(
53
+ "data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
54
+ className
55
+ )}
56
+ {...props}
57
+ >
58
+ {char}
59
+ {hasFakeCaret ? <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
60
+ <div className="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
61
+ </div> : null}
62
+ </div>
63
+ );
64
+ }
65
+
66
+ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
67
+ return (
68
+ <div data-slot="input-otp-separator" role="separator" {...props}>
69
+ <MinusIcon />
70
+ </div>
71
+ );
72
+ }
73
+
74
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
@@ -1,21 +1,19 @@
1
- import * as React from "react";
2
-
3
- import { cn } from "../lib/utils";
4
- export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
5
- function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
- return (
7
- <input
8
- type={type}
9
- data-slot="input"
10
- className={cn(
11
- "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-background border-b-1 border-b-primary/40 shadow px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14
- className
15
- )}
16
- {...props}
17
- />
18
- );
19
- }
20
-
21
- export { Input };
1
+ import { cn } from "../lib/utils";
2
+ export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
3
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
4
+ return (
5
+ <input
6
+ type={type}
7
+ data-slot="input"
8
+ className={cn(
9
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-background border-b-1 border-b-primary/40 shadow px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
10
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
11
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ );
17
+ }
18
+
19
+ export { Input };
@@ -1,4 +1,3 @@
1
- /* eslint-disable local-rules/no-json-parse-json-stringify */
2
1
  "use client";
3
2
 
4
3
  import { Command as CommandPrimitive, useCommandState } from "cmdk";
@@ -364,7 +363,6 @@ const MultipleSelector = React.forwardRef<MultipleSelectorRef, MultipleSelectorP
364
363
  }}
365
364
  className={cn("h-auto max-h-fit overflow-visible bg-transparent", commandProps?.className)}
366
365
  shouldFilter={
367
-
368
366
  commandProps?.shouldFilter !== undefined ? commandProps.shouldFilter : !onSearch
369
367
  } // When onSearch is provided, we don't want to filter the options. You can still override it.
370
368
  filter={commandFilter()}
@@ -454,7 +452,8 @@ const MultipleSelector = React.forwardRef<MultipleSelectorRef, MultipleSelectorP
454
452
  </div>
455
453
  </div>
456
454
  <div className="relative">
457
- {open ? <CommandList className="absolute top-1 z-10 w-full rounded-md border bg-popover text-popover-foreground shadow-md outline-none animate-in">
455
+ {open ? (
456
+ <CommandList className="absolute top-1 z-10 w-full rounded-md border bg-popover text-popover-foreground shadow-md outline-none animate-in">
458
457
  {isLoading ? (
459
458
  <>{loadingIndicator}</>
460
459
  ) : (
@@ -499,7 +498,8 @@ const MultipleSelector = React.forwardRef<MultipleSelectorRef, MultipleSelectorP
499
498
  ))}
500
499
  </>
501
500
  )}
502
- </CommandList> : null}
501
+ </CommandList>
502
+ ) : null}
503
503
  </div>
504
504
  </Command>
505
505
  );
@@ -1,3 +1,3 @@
1
- export * from "lucide-react";
2
- // export * from "react-icons/fa";
3
- export * from "react-icons/fa6";
1
+ export * from "lucide-react";
2
+ // export * from "react-icons/fa";
3
+ export * from "react-icons/fa6";