create-freakpunch 0.0.0-stage → 0.2.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 (216) hide show
  1. package/README.md +24 -3
  2. package/bin/create-freakpunch.mjs +227 -0
  3. package/files/README.md +19 -0
  4. package/files/app.config.ts +50 -0
  5. package/files/locales.ts +10 -0
  6. package/files/registry.ts +17 -0
  7. package/package.json +23 -6
  8. package/template/.dockerignore +17 -0
  9. package/template/.oxlintrc.json +9 -0
  10. package/template/AGENTS.md +6 -0
  11. package/template/BACKEND.md +108 -0
  12. package/template/CLAUDE.md +297 -0
  13. package/template/Dockerfile +19 -0
  14. package/template/_gitignore +26 -0
  15. package/template/components.json +27 -0
  16. package/template/design/COMPONENTS.md +145 -0
  17. package/template/design/DESIGN.md +212 -0
  18. package/template/design/PATTERNS.md +110 -0
  19. package/template/index.html +25 -0
  20. package/template/nginx.conf +32 -0
  21. package/template/package-lock.json +6484 -0
  22. package/template/package.json +51 -0
  23. package/template/public/favicon.svg +1 -0
  24. package/template/public/robots.txt +2 -0
  25. package/template/src/app.config.ts +50 -0
  26. package/template/src/app.roles.ts +24 -0
  27. package/template/src/components/ui/alert-dialog.tsx +181 -0
  28. package/template/src/components/ui/avatar.tsx +116 -0
  29. package/template/src/components/ui/badge.tsx +57 -0
  30. package/template/src/components/ui/breadcrumb.tsx +130 -0
  31. package/template/src/components/ui/button.tsx +58 -0
  32. package/template/src/components/ui/calendar.tsx +277 -0
  33. package/template/src/components/ui/card.tsx +99 -0
  34. package/template/src/components/ui/chart.tsx +370 -0
  35. package/template/src/components/ui/checkbox.tsx +28 -0
  36. package/template/src/components/ui/combobox.tsx +329 -0
  37. package/template/src/components/ui/command.tsx +191 -0
  38. package/template/src/components/ui/dialog.tsx +162 -0
  39. package/template/src/components/ui/dropdown-menu.tsx +271 -0
  40. package/template/src/components/ui/empty.tsx +103 -0
  41. package/template/src/components/ui/field.tsx +236 -0
  42. package/template/src/components/ui/input-group.tsx +263 -0
  43. package/template/src/components/ui/input.tsx +45 -0
  44. package/template/src/components/ui/kbd.tsx +31 -0
  45. package/template/src/components/ui/label.tsx +17 -0
  46. package/template/src/components/ui/pagination.tsx +134 -0
  47. package/template/src/components/ui/popover.tsx +87 -0
  48. package/template/src/components/ui/radio-group.tsx +35 -0
  49. package/template/src/components/ui/select.tsx +204 -0
  50. package/template/src/components/ui/separator.tsx +25 -0
  51. package/template/src/components/ui/sheet.tsx +139 -0
  52. package/template/src/components/ui/sidebar.tsx +741 -0
  53. package/template/src/components/ui/skeleton.tsx +13 -0
  54. package/template/src/components/ui/sonner.tsx +78 -0
  55. package/template/src/components/ui/spinner.tsx +42 -0
  56. package/template/src/components/ui/switch.tsx +29 -0
  57. package/template/src/components/ui/table.tsx +121 -0
  58. package/template/src/components/ui/tabs.tsx +191 -0
  59. package/template/src/components/ui/textarea.tsx +17 -0
  60. package/template/src/components/ui/toggle-group.tsx +94 -0
  61. package/template/src/components/ui/toggle.tsx +48 -0
  62. package/template/src/components/ui/tooltip.tsx +91 -0
  63. package/template/src/core/api/demo.ts +8 -0
  64. package/template/src/core/api/http.ts +76 -0
  65. package/template/src/core/api/mock.ts +88 -0
  66. package/template/src/core/api/rest.ts +67 -0
  67. package/template/src/core/api/types.ts +21 -0
  68. package/template/src/core/audit/audit.service.ts +94 -0
  69. package/template/src/core/audit/hooks.ts +19 -0
  70. package/template/src/core/auth/auth-store.ts +52 -0
  71. package/template/src/core/auth/auth.service.ts +86 -0
  72. package/template/src/core/auth/can.tsx +39 -0
  73. package/template/src/core/auth/dev-role-switcher.tsx +64 -0
  74. package/template/src/core/auth/local-credentials.ts +46 -0
  75. package/template/src/core/auth/permissions.ts +115 -0
  76. package/template/src/core/auth/require-auth.tsx +16 -0
  77. package/template/src/core/auth/require-permission.tsx +24 -0
  78. package/template/src/core/auth/roles.ts +9 -0
  79. package/template/src/core/auth/types.ts +20 -0
  80. package/template/src/core/auth/use-auth.ts +19 -0
  81. package/template/src/core/company/company.service.ts +94 -0
  82. package/template/src/core/company/hooks.ts +40 -0
  83. package/template/src/core/company/password-policy.ts +40 -0
  84. package/template/src/core/company/types.ts +46 -0
  85. package/template/src/core/company/use-app-name.ts +7 -0
  86. package/template/src/core/components/button-link.tsx +14 -0
  87. package/template/src/core/components/confirm-dialog.tsx +116 -0
  88. package/template/src/core/components/data-table/data-table.tsx +297 -0
  89. package/template/src/core/components/data-table/features.ts +24 -0
  90. package/template/src/core/components/data-table/table-header-cell.tsx +13 -0
  91. package/template/src/core/components/data-table/toolbar.tsx +100 -0
  92. package/template/src/core/components/data-table/use-list-url-state.ts +108 -0
  93. package/template/src/core/components/date-picker.tsx +71 -0
  94. package/template/src/core/components/file-attachments.tsx +84 -0
  95. package/template/src/core/components/form-error.tsx +9 -0
  96. package/template/src/core/components/form-page.tsx +93 -0
  97. package/template/src/core/components/image-upload.tsx +86 -0
  98. package/template/src/core/components/page.tsx +75 -0
  99. package/template/src/core/components/phone-input.tsx +58 -0
  100. package/template/src/core/components/search-select.tsx +57 -0
  101. package/template/src/core/components/segmented.tsx +41 -0
  102. package/template/src/core/components/states.tsx +97 -0
  103. package/template/src/core/components/status-badge.tsx +26 -0
  104. package/template/src/core/components/user-avatar.tsx +23 -0
  105. package/template/src/core/config/runtime.ts +16 -0
  106. package/template/src/core/config/types.ts +37 -0
  107. package/template/src/core/i18n/i18n.ts +69 -0
  108. package/template/src/core/i18n/i18next.d.ts +12 -0
  109. package/template/src/core/i18n/keys.ts +37 -0
  110. package/template/src/core/i18n/language-switcher.tsx +45 -0
  111. package/template/src/core/i18n/types.ts +17 -0
  112. package/template/src/core/i18n/use-format.ts +31 -0
  113. package/template/src/core/layout/app-shell.tsx +50 -0
  114. package/template/src/core/layout/app-sidebar.tsx +285 -0
  115. package/template/src/core/layout/command-menu.tsx +117 -0
  116. package/template/src/core/layout/top-bar.tsx +100 -0
  117. package/template/src/core/lib/csv.ts +27 -0
  118. package/template/src/core/lib/format.ts +87 -0
  119. package/template/src/core/lib/phone.ts +50 -0
  120. package/template/src/core/lib/storage.ts +27 -0
  121. package/template/src/core/modules/lazy-page.ts +9 -0
  122. package/template/src/core/modules/navigation.ts +39 -0
  123. package/template/src/core/modules/types.ts +55 -0
  124. package/template/src/core/notifications/hooks.ts +84 -0
  125. package/template/src/core/notifications/notification-center.tsx +251 -0
  126. package/template/src/core/notifications/notifications.service.ts +132 -0
  127. package/template/src/core/notifications/types.ts +70 -0
  128. package/template/src/core/preferences/preferences-store.ts +70 -0
  129. package/template/src/core/setup/setup-gate.tsx +20 -0
  130. package/template/src/core/setup/setup.service.ts +101 -0
  131. package/template/src/core/theme/brand-context.tsx +53 -0
  132. package/template/src/core/theme/brand.ts +29 -0
  133. package/template/src/core/theme/theme-context.tsx +62 -0
  134. package/template/src/core/theme/theme-options.ts +8 -0
  135. package/template/src/core/theme/theme-toggle.tsx +45 -0
  136. package/template/src/core/users/hooks.ts +51 -0
  137. package/template/src/core/users/types.ts +37 -0
  138. package/template/src/core/users/users.service.ts +167 -0
  139. package/template/src/hooks/use-mobile.ts +19 -0
  140. package/template/src/index.css +321 -0
  141. package/template/src/lib/utils.ts +1 -0
  142. package/template/src/locales/en/account.ts +180 -0
  143. package/template/src/locales/en/auth.ts +18 -0
  144. package/template/src/locales/en/common.ts +151 -0
  145. package/template/src/locales/en/company.ts +380 -0
  146. package/template/src/locales/en/dashboard.ts +46 -0
  147. package/template/src/locales/en/errors.ts +18 -0
  148. package/template/src/locales/en/notifications.ts +43 -0
  149. package/template/src/locales/en/settings.ts +25 -0
  150. package/template/src/locales/en/setup.ts +45 -0
  151. package/template/src/locales/index.ts +58 -0
  152. package/template/src/locales/tr/account.ts +184 -0
  153. package/template/src/locales/tr/auth.ts +22 -0
  154. package/template/src/locales/tr/common.ts +154 -0
  155. package/template/src/locales/tr/company.ts +384 -0
  156. package/template/src/locales/tr/dashboard.ts +50 -0
  157. package/template/src/locales/tr/errors.ts +22 -0
  158. package/template/src/locales/tr/notifications.ts +47 -0
  159. package/template/src/locales/tr/settings.ts +29 -0
  160. package/template/src/locales/tr/setup.ts +49 -0
  161. package/template/src/main.tsx +16 -0
  162. package/template/src/modules/locales.ts +10 -0
  163. package/template/src/modules/registry.ts +17 -0
  164. package/template/src/pages/dashboard/dashboard-page.tsx +55 -0
  165. package/template/src/pages/dashboard/quick-actions.tsx +37 -0
  166. package/template/src/pages/login-page.tsx +152 -0
  167. package/template/src/pages/no-access-page.tsx +11 -0
  168. package/template/src/pages/not-found-page.tsx +61 -0
  169. package/template/src/pages/settings/account/account.service.ts +128 -0
  170. package/template/src/pages/settings/account/components/mock-qr.tsx +50 -0
  171. package/template/src/pages/settings/account/components/password-strength.tsx +38 -0
  172. package/template/src/pages/settings/account/components/two-factor-dialog.tsx +140 -0
  173. package/template/src/pages/settings/account/hooks.ts +73 -0
  174. package/template/src/pages/settings/account/notifications-page.tsx +103 -0
  175. package/template/src/pages/settings/account/preferences-page.tsx +157 -0
  176. package/template/src/pages/settings/account/profile-page.tsx +242 -0
  177. package/template/src/pages/settings/account/security-page.tsx +364 -0
  178. package/template/src/pages/settings/account/types.ts +37 -0
  179. package/template/src/pages/settings/company/audit-log-page.tsx +126 -0
  180. package/template/src/pages/settings/company/branding-page.tsx +278 -0
  181. package/template/src/pages/settings/company/components/invite-dialog.tsx +106 -0
  182. package/template/src/pages/settings/company/components/read-only-notice.tsx +13 -0
  183. package/template/src/pages/settings/company/danger-zone-page.tsx +127 -0
  184. package/template/src/pages/settings/company/general-page.tsx +234 -0
  185. package/template/src/pages/settings/company/integrations/api-keys-panel.tsx +170 -0
  186. package/template/src/pages/settings/company/integrations/hooks.ts +37 -0
  187. package/template/src/pages/settings/company/integrations/integrations-page.tsx +57 -0
  188. package/template/src/pages/settings/company/integrations/integrations.service.ts +153 -0
  189. package/template/src/pages/settings/company/integrations/settings-forms.tsx +299 -0
  190. package/template/src/pages/settings/company/integrations/webhooks-panel.tsx +179 -0
  191. package/template/src/pages/settings/company/modules-page.tsx +65 -0
  192. package/template/src/pages/settings/company/roles-page.tsx +116 -0
  193. package/template/src/pages/settings/company/security-policies-page.tsx +164 -0
  194. package/template/src/pages/settings/company/users-page.tsx +262 -0
  195. package/template/src/pages/settings/settings-layout.tsx +57 -0
  196. package/template/src/pages/settings/settings-nav.ts +69 -0
  197. package/template/src/pages/settings/settings-routes.tsx +49 -0
  198. package/template/src/pages/setup-page.tsx +387 -0
  199. package/template/src/providers.tsx +68 -0
  200. package/template/src/router.tsx +59 -0
  201. package/template/tools/check-design.mjs +73 -0
  202. package/template/tools/new-module.mjs +90 -0
  203. package/template/tools/templates/module/api/__id__.mock.ts.tpl +17 -0
  204. package/template/tools/templates/module/api/__id__.service.ts.tpl +51 -0
  205. package/template/tools/templates/module/hooks.ts.tpl +57 -0
  206. package/template/tools/templates/module/index.ts.tpl +44 -0
  207. package/template/tools/templates/module/locales/en.ts.tpl +51 -0
  208. package/template/tools/templates/module/locales/tr.ts.tpl +55 -0
  209. package/template/tools/templates/module/pages/__id__-detail-page.tsx.tpl +103 -0
  210. package/template/tools/templates/module/pages/__id__-form-page.tsx.tpl +121 -0
  211. package/template/tools/templates/module/pages/__id__-list-page.tsx.tpl +234 -0
  212. package/template/tools/templates/module/types.ts.tpl +32 -0
  213. package/template/tsconfig.app.json +32 -0
  214. package/template/tsconfig.json +12 -0
  215. package/template/tsconfig.node.json +23 -0
  216. package/template/vite.config.ts +47 -0
@@ -0,0 +1,204 @@
1
+ import * as React from "react"
2
+ import { Select as SelectPrimitive } from "@base-ui/react/select"
3
+ import { cn } from "@/lib/utils"
4
+ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
5
+
6
+ const Select = SelectPrimitive.Root
7
+
8
+ function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
9
+ return (
10
+ <SelectPrimitive.Group
11
+ data-slot="select-group"
12
+ className={cn("scroll-my-1.5 p-1", className)}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
19
+ return (
20
+ <SelectPrimitive.Value
21
+ data-slot="select-value"
22
+ className={cn("flex flex-1 text-left", className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function SelectTrigger({
29
+ className,
30
+ size = "default",
31
+ children,
32
+ ...props
33
+ }: SelectPrimitive.Trigger.Props & {
34
+ size?: "sm" | "default" | "lg" | "xl"
35
+ }) {
36
+ return (
37
+ <SelectPrimitive.Trigger
38
+ data-slot="select-trigger"
39
+ data-size={size}
40
+ className={cn(
41
+ "flex w-fit items-center justify-between gap-(--sel-gap) rounded-lg bg-field pl-(--sel-gap) text-xs whitespace-nowrap outline-1 -outline-offset-1 outline-field-border transition-[color,box-shadow,outline-color] duration-200 outline-solid [--sel-gap:--spacing(3)] focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:outline-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-2 aria-invalid:ring-destructive/20 aria-invalid:outline-destructive data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=default]:pr-2 data-[size=default]:[--sel-gap:--spacing(2.5)] data-[size=default]:has-[>:first-child:not([data-slot=select-value])]:pl-2 data-[size=lg]:h-9 data-[size=lg]:pr-2.5 data-[size=lg]:has-[>:first-child:not([data-slot=select-value])]:pl-2.5 data-[size=sm]:h-7 data-[size=sm]:rounded-md data-[size=sm]:pr-1.5 data-[size=sm]:[--sel-gap:--spacing(2.5)] data-[size=sm]:has-[>:first-child:not([data-slot=select-value])]:pl-1.5 data-[size=xl]:h-10 data-[size=xl]:pr-3 data-[size=xl]:has-[>:first-child:not([data-slot=select-value])]:pl-3 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:aria-invalid:ring-destructive/40 dark:aria-invalid:outline-destructive/50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
42
+ className
43
+ )}
44
+ {...props}
45
+ >
46
+ {children}
47
+ <SelectPrimitive.Icon
48
+ render={
49
+ <ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
50
+ }
51
+ />
52
+ </SelectPrimitive.Trigger>
53
+ )
54
+ }
55
+
56
+ function SelectContent({
57
+ className,
58
+ children,
59
+ side = "bottom",
60
+ sideOffset = 4,
61
+ align = "center",
62
+ alignOffset = 0,
63
+ alignItemWithTrigger = true,
64
+ ...props
65
+ }: SelectPrimitive.Popup.Props &
66
+ Pick<
67
+ SelectPrimitive.Positioner.Props,
68
+ "align" | "alignOffset" | "side" | "sideOffset" | "alignItemWithTrigger"
69
+ >) {
70
+ return (
71
+ <SelectPrimitive.Portal>
72
+ <SelectPrimitive.Positioner
73
+ side={side}
74
+ sideOffset={sideOffset}
75
+ align={align}
76
+ alignOffset={alignOffset}
77
+ alignItemWithTrigger={alignItemWithTrigger}
78
+ className="isolate z-50"
79
+ >
80
+ <SelectPrimitive.Popup
81
+ data-slot="select-content"
82
+ data-align-trigger={alignItemWithTrigger}
83
+ className={cn(
84
+ "relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-14 bg-popover text-popover-foreground shadow-(--shadow-popover) ring-1 ring-border duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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",
85
+ className
86
+ )}
87
+ {...props}
88
+ >
89
+ <SelectScrollUpButton />
90
+ <SelectPrimitive.List className="p-1 has-[>[data-slot=select-group]]:p-0 *:data-[slot=select-item]:scroll-my-1.5">
91
+ {children}
92
+ </SelectPrimitive.List>
93
+ <SelectScrollDownButton />
94
+ </SelectPrimitive.Popup>
95
+ </SelectPrimitive.Positioner>
96
+ </SelectPrimitive.Portal>
97
+ )
98
+ }
99
+
100
+ function SelectLabel({
101
+ className,
102
+ ...props
103
+ }: SelectPrimitive.GroupLabel.Props) {
104
+ return (
105
+ <SelectPrimitive.GroupLabel
106
+ data-slot="select-label"
107
+ className={cn("px-2 py-1 text-2xs text-muted-foreground", className)}
108
+ {...props}
109
+ />
110
+ )
111
+ }
112
+
113
+ function SelectItem({
114
+ className,
115
+ children,
116
+ ...props
117
+ }: SelectPrimitive.Item.Props) {
118
+ return (
119
+ <SelectPrimitive.Item
120
+ data-slot="select-item"
121
+ className={cn(
122
+ "relative flex w-full cursor-default items-center gap-2 rounded-lg py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
123
+ className
124
+ )}
125
+ {...props}
126
+ >
127
+ <SelectPrimitive.ItemText className="flex flex-1 shrink-0 items-center gap-2 whitespace-nowrap">
128
+ {children}
129
+ </SelectPrimitive.ItemText>
130
+ <SelectPrimitive.ItemIndicator
131
+ render={
132
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />
133
+ }
134
+ >
135
+ <CheckIcon className="pointer-events-none" />
136
+ </SelectPrimitive.ItemIndicator>
137
+ </SelectPrimitive.Item>
138
+ )
139
+ }
140
+
141
+ function SelectSeparator({
142
+ className,
143
+ ...props
144
+ }: SelectPrimitive.Separator.Props) {
145
+ return (
146
+ <SelectPrimitive.Separator
147
+ data-slot="select-separator"
148
+ className={cn(
149
+ "pointer-events-none -mx-1 mt-1 mb-[3px] h-px bg-border [&:has(+[data-slot=select-group])]:-mb-px [[data-slot=select-group]+&]:mt-0",
150
+ className
151
+ )}
152
+ {...props}
153
+ />
154
+ )
155
+ }
156
+
157
+ function SelectScrollUpButton({
158
+ className,
159
+ ...props
160
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {
161
+ return (
162
+ <SelectPrimitive.ScrollUpArrow
163
+ data-slot="select-scroll-up-button"
164
+ className={cn(
165
+ "top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
166
+ className
167
+ )}
168
+ {...props}
169
+ >
170
+ <ChevronUpIcon />
171
+ </SelectPrimitive.ScrollUpArrow>
172
+ )
173
+ }
174
+
175
+ function SelectScrollDownButton({
176
+ className,
177
+ ...props
178
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {
179
+ return (
180
+ <SelectPrimitive.ScrollDownArrow
181
+ data-slot="select-scroll-down-button"
182
+ className={cn(
183
+ "bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
184
+ className
185
+ )}
186
+ {...props}
187
+ >
188
+ <ChevronDownIcon />
189
+ </SelectPrimitive.ScrollDownArrow>
190
+ )
191
+ }
192
+
193
+ export {
194
+ Select,
195
+ SelectContent,
196
+ SelectGroup,
197
+ SelectItem,
198
+ SelectLabel,
199
+ SelectScrollDownButton,
200
+ SelectScrollUpButton,
201
+ SelectSeparator,
202
+ SelectTrigger,
203
+ SelectValue,
204
+ }
@@ -0,0 +1,25 @@
1
+ "use client"
2
+
3
+ import { Separator as SeparatorPrimitive } from "@base-ui/react/separator"
4
+ import { cn } from "@/lib/utils"
5
+
6
+ function Separator({
7
+ className,
8
+ orientation = "horizontal",
9
+ ...props
10
+ }: SeparatorPrimitive.Props) {
11
+ return (
12
+ <SeparatorPrimitive
13
+ data-slot="separator"
14
+ orientation={orientation}
15
+ className={cn(
16
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
17
+ orientation === "vertical" ? "-mx-[0.5px]" : "-my-[0.5px]",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ export { Separator }
@@ -0,0 +1,139 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog"
5
+ import { cn } from "@/lib/utils"
6
+ import { useTranslation } from "react-i18next"
7
+
8
+ import { Button } from "@/components/ui/button"
9
+ import { XIcon } from "lucide-react"
10
+
11
+ function Sheet({ ...props }: SheetPrimitive.Root.Props) {
12
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />
13
+ }
14
+
15
+ function SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {
16
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
17
+ }
18
+
19
+ function SheetClose({ ...props }: SheetPrimitive.Close.Props) {
20
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
21
+ }
22
+
23
+ function SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {
24
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
25
+ }
26
+
27
+ function SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {
28
+ return (
29
+ <SheetPrimitive.Backdrop
30
+ data-slot="sheet-overlay"
31
+ className={cn(
32
+ "fixed inset-0 z-50 bg-black/30 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-sm",
33
+ className
34
+ )}
35
+ {...props}
36
+ />
37
+ )
38
+ }
39
+
40
+ function SheetContent({
41
+ className,
42
+ children,
43
+ side = "right",
44
+ showCloseButton = true,
45
+ ...props
46
+ }: SheetPrimitive.Popup.Props & {
47
+ side?: "top" | "right" | "bottom" | "left"
48
+ showCloseButton?: boolean
49
+ }) {
50
+ const { t } = useTranslation()
51
+ return (
52
+ <SheetPortal>
53
+ <SheetOverlay />
54
+ <SheetPrimitive.Popup
55
+ data-slot="sheet-content"
56
+ data-side={side}
57
+ className={cn(
58
+ "fixed z-50 flex flex-col bg-popover text-sm text-popover-foreground shadow-(--shadow-dialog) ring-1 ring-border transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
59
+ className
60
+ )}
61
+ {...props}
62
+ >
63
+ {children}
64
+ {showCloseButton && (
65
+ <SheetPrimitive.Close
66
+ data-slot="sheet-close"
67
+ render={
68
+ <Button
69
+ variant="ghost"
70
+ className="absolute top-4 right-4"
71
+ size="icon-sm"
72
+ />
73
+ }
74
+ >
75
+ <XIcon />
76
+ <span className="sr-only">{t("actions.close")}</span>
77
+ </SheetPrimitive.Close>
78
+ )}
79
+ </SheetPrimitive.Popup>
80
+ </SheetPortal>
81
+ )
82
+ }
83
+
84
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="sheet-header"
88
+ className={cn("flex flex-col gap-1.5 p-6", className)}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
95
+ return (
96
+ <div
97
+ data-slot="sheet-footer"
98
+ className={cn("mt-auto flex flex-col gap-2 p-6", className)}
99
+ {...props}
100
+ />
101
+ )
102
+ }
103
+
104
+ function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
105
+ return (
106
+ <SheetPrimitive.Title
107
+ data-slot="sheet-title"
108
+ className={cn(
109
+ "font-heading text-base font-medium text-foreground",
110
+ className
111
+ )}
112
+ {...props}
113
+ />
114
+ )
115
+ }
116
+
117
+ function SheetDescription({
118
+ className,
119
+ ...props
120
+ }: SheetPrimitive.Description.Props) {
121
+ return (
122
+ <SheetPrimitive.Description
123
+ data-slot="sheet-description"
124
+ className={cn("text-sm text-muted-foreground", className)}
125
+ {...props}
126
+ />
127
+ )
128
+ }
129
+
130
+ export {
131
+ Sheet,
132
+ SheetTrigger,
133
+ SheetClose,
134
+ SheetContent,
135
+ SheetHeader,
136
+ SheetFooter,
137
+ SheetTitle,
138
+ SheetDescription,
139
+ }