create-nextjs-cms 0.9.29 → 0.9.30

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 (142) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +71 -71
  3. package/dist/helpers/utils.js +16 -16
  4. package/dist/lib/section-creators.js +166 -166
  5. package/package.json +3 -3
  6. package/templates/default/.eslintrc.json +5 -5
  7. package/templates/default/.prettierignore +7 -7
  8. package/templates/default/.prettierrc.json +27 -27
  9. package/templates/default/CHANGELOG.md +140 -140
  10. package/templates/default/_gitignore +57 -57
  11. package/templates/default/app/(auth)/auth/login/LoginPage.tsx +192 -192
  12. package/templates/default/app/(auth)/auth/login/page.tsx +11 -11
  13. package/templates/default/app/(auth)/auth-language-provider.tsx +34 -34
  14. package/templates/default/app/(auth)/layout.tsx +81 -81
  15. package/templates/default/app/(rootLayout)/admins/page.tsx +10 -10
  16. package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +22 -22
  17. package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +15 -15
  18. package/templates/default/app/(rootLayout)/dashboard/page.tsx +70 -70
  19. package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +20 -20
  20. package/templates/default/app/(rootLayout)/layout.tsx +81 -81
  21. package/templates/default/app/(rootLayout)/loading.tsx +10 -10
  22. package/templates/default/app/(rootLayout)/log/page.tsx +7 -7
  23. package/templates/default/app/(rootLayout)/new/[section]/page.tsx +15 -15
  24. package/templates/default/app/(rootLayout)/section/[section]/page.tsx +19 -19
  25. package/templates/default/app/(rootLayout)/settings/page.tsx +13 -13
  26. package/templates/default/app/api/auth/csrf/route.ts +25 -25
  27. package/templates/default/app/api/auth/refresh/route.ts +10 -10
  28. package/templates/default/app/api/auth/route.ts +49 -49
  29. package/templates/default/app/api/auth/session/route.ts +20 -20
  30. package/templates/default/app/api/document/route.ts +165 -165
  31. package/templates/default/app/api/editor/photo/route.ts +49 -49
  32. package/templates/default/app/api/photo/route.ts +27 -27
  33. package/templates/default/app/api/submit/section/item/[slug]/route.ts +95 -95
  34. package/templates/default/app/api/submit/section/item/route.ts +56 -56
  35. package/templates/default/app/api/submit/section/simple/route.ts +86 -86
  36. package/templates/default/app/api/video/route.ts +174 -174
  37. package/templates/default/app/globals.css +236 -236
  38. package/templates/default/cms.config.ts +56 -56
  39. package/templates/default/components/admin/admin-card.tsx +165 -165
  40. package/templates/default/components/admin/admin-edit-page.tsx +124 -124
  41. package/templates/default/components/admin/admin-privilege-card.tsx +184 -184
  42. package/templates/default/components/admin/new-admin-form.tsx +172 -172
  43. package/templates/default/components/container-box.tsx +24 -24
  44. package/templates/default/components/dnd-kit/draggable.tsx +21 -21
  45. package/templates/default/components/dnd-kit/droppable.tsx +20 -20
  46. package/templates/default/components/dnd-kit/sortable-item.tsx +18 -18
  47. package/templates/default/components/feedback/error-component.tsx +16 -16
  48. package/templates/default/components/feedback/info-card.tsx +93 -93
  49. package/templates/default/components/feedback/loading-spinners.tsx +67 -67
  50. package/templates/default/components/feedback/modal.tsx +166 -166
  51. package/templates/default/components/feedback/progress-bar.tsx +48 -48
  52. package/templates/default/components/feedback/tooltip-component.tsx +27 -27
  53. package/templates/default/components/form/form-input-element.tsx +70 -70
  54. package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
  55. package/templates/default/components/form/helpers/util.ts +17 -17
  56. package/templates/default/components/form/inputs/checkbox-form-input.tsx +46 -46
  57. package/templates/default/components/form/inputs/color-form-input.tsx +44 -44
  58. package/templates/default/components/form/inputs/date-form-input.tsx +93 -93
  59. package/templates/default/components/form/inputs/map-form-input.tsx +141 -141
  60. package/templates/default/components/form/inputs/multiple-select-form-input.tsx +85 -85
  61. package/templates/default/components/form/inputs/number-form-input.tsx +43 -43
  62. package/templates/default/components/form/inputs/password-form-input.tsx +47 -47
  63. package/templates/default/components/form/inputs/photo-form-input.tsx +279 -279
  64. package/templates/default/components/form/inputs/rich-text-form-input.tsx +148 -148
  65. package/templates/default/components/form/inputs/select-form-input.tsx +159 -159
  66. package/templates/default/components/form/inputs/slug-form-input.tsx +131 -131
  67. package/templates/default/components/form/inputs/tags-form-input.tsx +255 -255
  68. package/templates/default/components/form/inputs/text-form-input.tsx +61 -61
  69. package/templates/default/components/form/inputs/textarea-form-input.tsx +61 -61
  70. package/templates/default/components/layout/default-nav-items.tsx +3 -3
  71. package/templates/default/components/layout/layout.tsx +84 -84
  72. package/templates/default/components/layout/navbar.tsx +258 -258
  73. package/templates/default/components/layout/sidebar-dropdown-item.tsx +83 -83
  74. package/templates/default/components/layout/sidebar-item.tsx +24 -24
  75. package/templates/default/components/layout/sidebar.tsx +229 -229
  76. package/templates/default/components/layout/theme-provider.tsx +8 -8
  77. package/templates/default/components/layout/theme-toggle.tsx +39 -39
  78. package/templates/default/components/locale/locale-switcher.tsx +98 -98
  79. package/templates/default/components/media/dropzone.tsx +154 -154
  80. package/templates/default/components/media/protected-document.tsx +44 -44
  81. package/templates/default/components/media/protected-image.tsx +143 -143
  82. package/templates/default/components/media/protected-video.tsx +76 -76
  83. package/templates/default/components/multi-select.tsx +1150 -1150
  84. package/templates/default/components/pages/admins-page.tsx +43 -43
  85. package/templates/default/components/pages/browse-page.tsx +106 -106
  86. package/templates/default/components/pages/categorized-section-page.tsx +31 -31
  87. package/templates/default/components/pages/dashboard-page-alt.tsx +45 -45
  88. package/templates/default/components/pages/item-edit-page.tsx +267 -267
  89. package/templates/default/components/pages/log-page.tsx +107 -107
  90. package/templates/default/components/pages/new-page.tsx +183 -183
  91. package/templates/default/components/pages/section-page.tsx +203 -203
  92. package/templates/default/components/pages/settings-page.tsx +232 -232
  93. package/templates/default/components/pagination/pagination-buttons.tsx +147 -147
  94. package/templates/default/components/pagination/pagination.tsx +36 -36
  95. package/templates/default/components/sections/category-delete-confirm-page.tsx +130 -130
  96. package/templates/default/components/sections/category-section-select-input.tsx +139 -139
  97. package/templates/default/components/sections/conditional-fields.tsx +49 -49
  98. package/templates/default/components/sections/section-icon.tsx +8 -8
  99. package/templates/default/components/sections/section-item-card.tsx +143 -143
  100. package/templates/default/components/sections/section-item-status-badge.tsx +17 -17
  101. package/templates/default/components/sections/select-input-buttons.tsx +125 -125
  102. package/templates/default/components/select-box.tsx +98 -98
  103. package/templates/default/components/ui/accordion.tsx +53 -53
  104. package/templates/default/components/ui/alert-dialog.tsx +113 -113
  105. package/templates/default/components/ui/alert.tsx +47 -47
  106. package/templates/default/components/ui/badge.tsx +38 -38
  107. package/templates/default/components/ui/card.tsx +43 -43
  108. package/templates/default/components/ui/command.tsx +137 -137
  109. package/templates/default/components/ui/custom-alert-dialog.tsx +113 -113
  110. package/templates/default/components/ui/custom-dialog.tsx +123 -123
  111. package/templates/default/components/ui/dialog.tsx +123 -123
  112. package/templates/default/components/ui/direction.tsx +22 -22
  113. package/templates/default/components/ui/dropdown-menu.tsx +182 -182
  114. package/templates/default/components/ui/input-group.tsx +54 -54
  115. package/templates/default/components/ui/input.tsx +22 -22
  116. package/templates/default/components/ui/label.tsx +19 -19
  117. package/templates/default/components/ui/popover.tsx +42 -42
  118. package/templates/default/components/ui/progress.tsx +31 -31
  119. package/templates/default/components/ui/scroll-area.tsx +42 -42
  120. package/templates/default/components/ui/select.tsx +165 -165
  121. package/templates/default/components/ui/separator.tsx +28 -28
  122. package/templates/default/components/ui/sheet.tsx +103 -103
  123. package/templates/default/components/ui/spinner.tsx +16 -16
  124. package/templates/default/components/ui/switch.tsx +29 -29
  125. package/templates/default/components/ui/table.tsx +83 -83
  126. package/templates/default/components/ui/tabs.tsx +55 -55
  127. package/templates/default/components/ui/toast.tsx +113 -113
  128. package/templates/default/components/ui/toaster.tsx +35 -35
  129. package/templates/default/components/ui/tooltip.tsx +30 -30
  130. package/templates/default/components/ui/use-toast.ts +187 -187
  131. package/templates/default/drizzle.config.ts +4 -4
  132. package/templates/default/dynamic-schemas/schema.ts +75 -225
  133. package/templates/default/env/env.ts +46 -46
  134. package/templates/default/envConfig.ts +4 -4
  135. package/templates/default/lib/postinstall.js +14 -14
  136. package/templates/default/lib/utils.ts +6 -6
  137. package/templates/default/next-env.d.ts +6 -6
  138. package/templates/default/next.config.ts +24 -24
  139. package/templates/default/package.json +1 -1
  140. package/templates/default/postcss.config.mjs +6 -6
  141. package/templates/default/proxy.ts +32 -32
  142. package/templates/default/tsconfig.json +48 -48
@@ -1,98 +1,98 @@
1
- 'use client'
2
-
3
- import { useState, useEffect } from 'react'
4
- import { Check, ChevronsUpDown } from 'lucide-react'
5
- import { cn } from '@/lib/utils'
6
- import { Button } from '@/components/ui/button'
7
- import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'
8
- import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
9
- import { SelectOption } from 'nextjs-cms/core/fields'
10
- import { useI18n } from 'nextjs-cms/translations/client'
11
-
12
- export default function SelectBox({
13
- items,
14
- defaultValue,
15
- onChange = () => {},
16
- classname,
17
- }: {
18
- items: SelectOption[]
19
- defaultValue?: string | number | undefined
20
- onChange: any
21
- classname: string
22
- }) {
23
- const t = useI18n()
24
- const [selected, setSelected] = useState<SelectOption | undefined>(
25
- defaultValue !== undefined && defaultValue !== null
26
- ? items.find((item) => item.value?.toString() === defaultValue.toString())
27
- : items[0],
28
- )
29
- const [open, setOpen] = useState(false)
30
-
31
- // Update selected item when items or defaultValue changes (e.g., on language change)
32
- useEffect(() => {
33
- if (defaultValue !== undefined && defaultValue !== null) {
34
- const foundItem = items.find((item) => item.value?.toString() === defaultValue.toString())
35
- if (foundItem) {
36
- setSelected(foundItem)
37
- }
38
- } else {
39
- // If no value is selected, update to the first item (placeholder)
40
- // This ensures the placeholder label is updated when language changes
41
- setSelected(items[0])
42
- }
43
- }, [items, defaultValue])
44
-
45
- return (
46
- <div className={cn('relative', classname)}>
47
- <Popover open={open} onOpenChange={setOpen}>
48
- <PopoverTrigger asChild>
49
- <Button
50
- variant='outline'
51
- role='combobox'
52
- aria-expanded={open}
53
- className='bg-input text-foreground w-full justify-between rounded px-1 py-5 shadow-xs ring-2 ring-gray-300 outline-0 hover:ring-gray-400 focus:ring-2 focus:ring-blue-500 focus:outline-hidden sm:text-sm sm:leading-6'
54
- >
55
- <span className='block truncate'>{selected?.label ? selected.label : ''}</span>
56
- <ChevronsUpDown className='size-5 opacity-50' />
57
- </Button>
58
- </PopoverTrigger>
59
- <PopoverContent
60
- className='border-foreground/50 w-[var(--radix-popover-trigger-width)] border p-0 shadow-sm'
61
- align='start'
62
- >
63
- <Command>
64
- <CommandInput placeholder={t('searchDots') as string} className='h-9' />
65
- <CommandList>
66
- <CommandEmpty>{t('noItemFound')}</CommandEmpty>
67
- <CommandGroup>
68
- {items.map((item: SelectOption, index: number) => {
69
- // Use label for searchable value, but include value in a way that we can identify it
70
- // cmdk filters by both value prop and text content, so we use label for value to make search work
71
- const searchableValue = item.label
72
- const isSelected = selected && item.value && selected.value === item.value
73
- return (
74
- <CommandItem
75
- key={`${item.label}-${index}`}
76
- value={searchableValue}
77
- keywords={[item.label]}
78
- onSelect={() => {
79
- setSelected(item)
80
- onChange(item)
81
- setOpen(false)
82
- }}
83
- >
84
- <span className={isSelected ? 'font-extrabold' : 'text-foreground'}>
85
- {item.label}
86
- </span>
87
- {isSelected ? <Check strokeWidth={5} size={25} color='green' /> : null}
88
- </CommandItem>
89
- )
90
- })}
91
- </CommandGroup>
92
- </CommandList>
93
- </Command>
94
- </PopoverContent>
95
- </Popover>
96
- </div>
97
- )
98
- }
1
+ 'use client'
2
+
3
+ import { useState, useEffect } from 'react'
4
+ import { Check, ChevronsUpDown } from 'lucide-react'
5
+ import { cn } from '@/lib/utils'
6
+ import { Button } from '@/components/ui/button'
7
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'
8
+ import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
9
+ import { SelectOption } from 'nextjs-cms/core/fields'
10
+ import { useI18n } from 'nextjs-cms/translations/client'
11
+
12
+ export default function SelectBox({
13
+ items,
14
+ defaultValue,
15
+ onChange = () => {},
16
+ classname,
17
+ }: {
18
+ items: SelectOption[]
19
+ defaultValue?: string | number | undefined
20
+ onChange: any
21
+ classname: string
22
+ }) {
23
+ const t = useI18n()
24
+ const [selected, setSelected] = useState<SelectOption | undefined>(
25
+ defaultValue !== undefined && defaultValue !== null
26
+ ? items.find((item) => item.value?.toString() === defaultValue.toString())
27
+ : items[0],
28
+ )
29
+ const [open, setOpen] = useState(false)
30
+
31
+ // Update selected item when items or defaultValue changes (e.g., on language change)
32
+ useEffect(() => {
33
+ if (defaultValue !== undefined && defaultValue !== null) {
34
+ const foundItem = items.find((item) => item.value?.toString() === defaultValue.toString())
35
+ if (foundItem) {
36
+ setSelected(foundItem)
37
+ }
38
+ } else {
39
+ // If no value is selected, update to the first item (placeholder)
40
+ // This ensures the placeholder label is updated when language changes
41
+ setSelected(items[0])
42
+ }
43
+ }, [items, defaultValue])
44
+
45
+ return (
46
+ <div className={cn('relative', classname)}>
47
+ <Popover open={open} onOpenChange={setOpen}>
48
+ <PopoverTrigger asChild>
49
+ <Button
50
+ variant='outline'
51
+ role='combobox'
52
+ aria-expanded={open}
53
+ className='bg-input text-foreground w-full justify-between rounded px-1 py-5 shadow-xs ring-2 ring-gray-300 outline-0 hover:ring-gray-400 focus:ring-2 focus:ring-blue-500 focus:outline-hidden sm:text-sm sm:leading-6'
54
+ >
55
+ <span className='block truncate'>{selected?.label ? selected.label : ''}</span>
56
+ <ChevronsUpDown className='size-5 opacity-50' />
57
+ </Button>
58
+ </PopoverTrigger>
59
+ <PopoverContent
60
+ className='border-foreground/50 w-[var(--radix-popover-trigger-width)] border p-0 shadow-sm'
61
+ align='start'
62
+ >
63
+ <Command>
64
+ <CommandInput placeholder={t('searchDots') as string} className='h-9' />
65
+ <CommandList>
66
+ <CommandEmpty>{t('noItemFound')}</CommandEmpty>
67
+ <CommandGroup>
68
+ {items.map((item: SelectOption, index: number) => {
69
+ // Use label for searchable value, but include value in a way that we can identify it
70
+ // cmdk filters by both value prop and text content, so we use label for value to make search work
71
+ const searchableValue = item.label
72
+ const isSelected = selected && item.value && selected.value === item.value
73
+ return (
74
+ <CommandItem
75
+ key={`${item.label}-${index}`}
76
+ value={searchableValue}
77
+ keywords={[item.label]}
78
+ onSelect={() => {
79
+ setSelected(item)
80
+ onChange(item)
81
+ setOpen(false)
82
+ }}
83
+ >
84
+ <span className={isSelected ? 'font-extrabold' : 'text-foreground'}>
85
+ {item.label}
86
+ </span>
87
+ {isSelected ? <Check strokeWidth={5} size={25} color='green' /> : null}
88
+ </CommandItem>
89
+ )
90
+ })}
91
+ </CommandGroup>
92
+ </CommandList>
93
+ </Command>
94
+ </PopoverContent>
95
+ </Popover>
96
+ </div>
97
+ )
98
+ }
@@ -1,53 +1,53 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import * as AccordionPrimitive from '@radix-ui/react-accordion'
5
- import { ChevronDownIcon } from '@radix-ui/react-icons'
6
-
7
- import { cn } from '@/lib/utils'
8
-
9
- const Accordion = AccordionPrimitive.Root
10
-
11
- const AccordionItem = React.forwardRef<
12
- React.ElementRef<typeof AccordionPrimitive.Item>,
13
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
14
- >(({ className, ...props }, ref) => (
15
- <AccordionPrimitive.Item ref={ref} className={cn('border-b', className)} {...props} />
16
- ))
17
- AccordionItem.displayName = 'AccordionItem'
18
-
19
- const AccordionTrigger = React.forwardRef<
20
- React.ElementRef<typeof AccordionPrimitive.Trigger>,
21
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
22
- >(({ className, children, ...props }, ref) => (
23
- <AccordionPrimitive.Header className='flex'>
24
- <AccordionPrimitive.Trigger
25
- ref={ref}
26
- className={cn(
27
- 'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
28
- className,
29
- )}
30
- {...props}
31
- >
32
- {children}
33
- <ChevronDownIcon className='text-muted-foreground h-4 w-4 shrink-0 transition-transform duration-200' />
34
- </AccordionPrimitive.Trigger>
35
- </AccordionPrimitive.Header>
36
- ))
37
- AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
38
-
39
- const AccordionContent = React.forwardRef<
40
- React.ElementRef<typeof AccordionPrimitive.Content>,
41
- React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
42
- >(({ className, children, ...props }, ref) => (
43
- <AccordionPrimitive.Content
44
- ref={ref}
45
- className='data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm'
46
- {...props}
47
- >
48
- <div className={cn('pt-0 pb-4', className)}>{children}</div>
49
- </AccordionPrimitive.Content>
50
- ))
51
- AccordionContent.displayName = AccordionPrimitive.Content.displayName
52
-
53
- export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import * as AccordionPrimitive from '@radix-ui/react-accordion'
5
+ import { ChevronDownIcon } from '@radix-ui/react-icons'
6
+
7
+ import { cn } from '@/lib/utils'
8
+
9
+ const Accordion = AccordionPrimitive.Root
10
+
11
+ const AccordionItem = React.forwardRef<
12
+ React.ElementRef<typeof AccordionPrimitive.Item>,
13
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
14
+ >(({ className, ...props }, ref) => (
15
+ <AccordionPrimitive.Item ref={ref} className={cn('border-b', className)} {...props} />
16
+ ))
17
+ AccordionItem.displayName = 'AccordionItem'
18
+
19
+ const AccordionTrigger = React.forwardRef<
20
+ React.ElementRef<typeof AccordionPrimitive.Trigger>,
21
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
22
+ >(({ className, children, ...props }, ref) => (
23
+ <AccordionPrimitive.Header className='flex'>
24
+ <AccordionPrimitive.Trigger
25
+ ref={ref}
26
+ className={cn(
27
+ 'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
28
+ className,
29
+ )}
30
+ {...props}
31
+ >
32
+ {children}
33
+ <ChevronDownIcon className='text-muted-foreground h-4 w-4 shrink-0 transition-transform duration-200' />
34
+ </AccordionPrimitive.Trigger>
35
+ </AccordionPrimitive.Header>
36
+ ))
37
+ AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
38
+
39
+ const AccordionContent = React.forwardRef<
40
+ React.ElementRef<typeof AccordionPrimitive.Content>,
41
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
42
+ >(({ className, children, ...props }, ref) => (
43
+ <AccordionPrimitive.Content
44
+ ref={ref}
45
+ className='data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm'
46
+ {...props}
47
+ >
48
+ <div className={cn('pt-0 pb-4', className)}>{children}</div>
49
+ </AccordionPrimitive.Content>
50
+ ))
51
+ AccordionContent.displayName = AccordionPrimitive.Content.displayName
52
+
53
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
@@ -1,113 +1,113 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'
5
-
6
- import { cn } from '@/lib/utils'
7
- import { buttonVariants } from '@/components/ui/button'
8
-
9
- function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
10
- return <AlertDialogPrimitive.Root data-slot='alert-dialog' {...props} />
11
- }
12
-
13
- function AlertDialogTrigger({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
14
- return <AlertDialogPrimitive.Trigger data-slot='alert-dialog-trigger' {...props} />
15
- }
16
-
17
- function AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
18
- return <AlertDialogPrimitive.Portal data-slot='alert-dialog-portal' {...props} />
19
- }
20
-
21
- function AlertDialogOverlay({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
22
- return (
23
- <AlertDialogPrimitive.Overlay
24
- data-slot='alert-dialog-overlay'
25
- className={cn(
26
- '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',
27
- className,
28
- )}
29
- {...props}
30
- />
31
- )
32
- }
33
-
34
- function AlertDialogContent({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {
35
- return (
36
- <AlertDialogPortal>
37
- <AlertDialogOverlay />
38
- <AlertDialogPrimitive.Content
39
- data-slot='alert-dialog-content'
40
- className={cn(
41
- '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 start-[50%] top-[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 sm:max-w-lg rtl:-translate-x-[-50%]',
42
- className,
43
- )}
44
- {...props}
45
- />
46
- </AlertDialogPortal>
47
- )
48
- }
49
-
50
- function AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
51
- return (
52
- <div
53
- data-slot='alert-dialog-header'
54
- className={cn('flex flex-col gap-2 text-center sm:text-start', className)}
55
- {...props}
56
- />
57
- )
58
- }
59
-
60
- function AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
61
- return (
62
- <div
63
- data-slot='alert-dialog-footer'
64
- className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
65
- {...props}
66
- />
67
- )
68
- }
69
-
70
- function AlertDialogTitle({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
71
- return (
72
- <AlertDialogPrimitive.Title
73
- data-slot='alert-dialog-title'
74
- className={cn('text-lg font-semibold', className)}
75
- {...props}
76
- />
77
- )
78
- }
79
-
80
- function AlertDialogDescription({
81
- className,
82
- ...props
83
- }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
84
- return (
85
- <AlertDialogPrimitive.Description
86
- data-slot='alert-dialog-description'
87
- className={cn('text-muted-foreground text-sm', className)}
88
- {...props}
89
- />
90
- )
91
- }
92
-
93
- function AlertDialogAction({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
94
- return <AlertDialogPrimitive.Action className={cn(buttonVariants(), className)} {...props} />
95
- }
96
-
97
- function AlertDialogCancel({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
98
- return <AlertDialogPrimitive.Cancel className={cn(buttonVariants({ variant: 'outline' }), className)} {...props} />
99
- }
100
-
101
- export {
102
- AlertDialog,
103
- AlertDialogPortal,
104
- AlertDialogOverlay,
105
- AlertDialogTrigger,
106
- AlertDialogContent,
107
- AlertDialogHeader,
108
- AlertDialogFooter,
109
- AlertDialogTitle,
110
- AlertDialogDescription,
111
- AlertDialogAction,
112
- AlertDialogCancel,
113
- }
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'
5
+
6
+ import { cn } from '@/lib/utils'
7
+ import { buttonVariants } from '@/components/ui/button'
8
+
9
+ function AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
10
+ return <AlertDialogPrimitive.Root data-slot='alert-dialog' {...props} />
11
+ }
12
+
13
+ function AlertDialogTrigger({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
14
+ return <AlertDialogPrimitive.Trigger data-slot='alert-dialog-trigger' {...props} />
15
+ }
16
+
17
+ function AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
18
+ return <AlertDialogPrimitive.Portal data-slot='alert-dialog-portal' {...props} />
19
+ }
20
+
21
+ function AlertDialogOverlay({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
22
+ return (
23
+ <AlertDialogPrimitive.Overlay
24
+ data-slot='alert-dialog-overlay'
25
+ className={cn(
26
+ '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',
27
+ className,
28
+ )}
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function AlertDialogContent({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {
35
+ return (
36
+ <AlertDialogPortal>
37
+ <AlertDialogOverlay />
38
+ <AlertDialogPrimitive.Content
39
+ data-slot='alert-dialog-content'
40
+ className={cn(
41
+ '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 start-[50%] top-[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 sm:max-w-lg rtl:-translate-x-[-50%]',
42
+ className,
43
+ )}
44
+ {...props}
45
+ />
46
+ </AlertDialogPortal>
47
+ )
48
+ }
49
+
50
+ function AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
51
+ return (
52
+ <div
53
+ data-slot='alert-dialog-header'
54
+ className={cn('flex flex-col gap-2 text-center sm:text-start', className)}
55
+ {...props}
56
+ />
57
+ )
58
+ }
59
+
60
+ function AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
61
+ return (
62
+ <div
63
+ data-slot='alert-dialog-footer'
64
+ className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
65
+ {...props}
66
+ />
67
+ )
68
+ }
69
+
70
+ function AlertDialogTitle({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
71
+ return (
72
+ <AlertDialogPrimitive.Title
73
+ data-slot='alert-dialog-title'
74
+ className={cn('text-lg font-semibold', className)}
75
+ {...props}
76
+ />
77
+ )
78
+ }
79
+
80
+ function AlertDialogDescription({
81
+ className,
82
+ ...props
83
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
84
+ return (
85
+ <AlertDialogPrimitive.Description
86
+ data-slot='alert-dialog-description'
87
+ className={cn('text-muted-foreground text-sm', className)}
88
+ {...props}
89
+ />
90
+ )
91
+ }
92
+
93
+ function AlertDialogAction({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
94
+ return <AlertDialogPrimitive.Action className={cn(buttonVariants(), className)} {...props} />
95
+ }
96
+
97
+ function AlertDialogCancel({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
98
+ return <AlertDialogPrimitive.Cancel className={cn(buttonVariants({ variant: 'outline' }), className)} {...props} />
99
+ }
100
+
101
+ export {
102
+ AlertDialog,
103
+ AlertDialogPortal,
104
+ AlertDialogOverlay,
105
+ AlertDialogTrigger,
106
+ AlertDialogContent,
107
+ AlertDialogHeader,
108
+ AlertDialogFooter,
109
+ AlertDialogTitle,
110
+ AlertDialogDescription,
111
+ AlertDialogAction,
112
+ AlertDialogCancel,
113
+ }
@@ -1,47 +1,47 @@
1
- import * as React from 'react'
2
- import { cva, type VariantProps } from 'class-variance-authority'
3
-
4
- import { cn } from '@/lib/utils'
5
-
6
- const alertVariants = cva(
7
- 'relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:start-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:ps-7',
8
- {
9
- variants: {
10
- variant: {
11
- default: 'bg-background text-foreground',
12
- destructive:
13
- 'border-destructive/90 bg-destructive/10 text-destructive dark:border-destructive [&>svg]:text-destructive',
14
- light: 'bg-gray-100 text-gray-900 dark:bg-gray-950 dark:text-gray-100',
15
- info: 'border-info bg-info/10 text-info-foreground [&>svg]:text-info',
16
- warning: 'bg-warning text-warning dark:bg-warning dark:text-warning',
17
- },
18
- },
19
- defaultVariants: {
20
- variant: 'default',
21
- },
22
- },
23
- )
24
-
25
- const Alert = React.forwardRef<
26
- HTMLDivElement,
27
- React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
28
- >(({ className, variant, ...props }, ref) => (
29
- <div ref={ref} role='alert' className={cn(alertVariants({ variant }), className)} {...props} />
30
- ))
31
- Alert.displayName = 'Alert'
32
-
33
- const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
34
- ({ className, ...props }, ref) => (
35
- <h5 ref={ref} className={cn('mb-1 leading-none font-medium tracking-tight', className)} {...props} />
36
- ),
37
- )
38
- AlertTitle.displayName = 'AlertTitle'
39
-
40
- const AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
41
- ({ className, ...props }, ref) => (
42
- <div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)} {...props} />
43
- ),
44
- )
45
- AlertDescription.displayName = 'AlertDescription'
46
-
47
- export { Alert, AlertTitle, AlertDescription }
1
+ import * as React from 'react'
2
+ import { cva, type VariantProps } from 'class-variance-authority'
3
+
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const alertVariants = cva(
7
+ 'relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:start-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:ps-7',
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: 'bg-background text-foreground',
12
+ destructive:
13
+ 'border-destructive/90 bg-destructive/10 text-destructive dark:border-destructive [&>svg]:text-destructive',
14
+ light: 'bg-gray-100 text-gray-900 dark:bg-gray-950 dark:text-gray-100',
15
+ info: 'border-info bg-info/10 text-info-foreground [&>svg]:text-info',
16
+ warning: 'bg-warning text-warning dark:bg-warning dark:text-warning',
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ variant: 'default',
21
+ },
22
+ },
23
+ )
24
+
25
+ const Alert = React.forwardRef<
26
+ HTMLDivElement,
27
+ React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
28
+ >(({ className, variant, ...props }, ref) => (
29
+ <div ref={ref} role='alert' className={cn(alertVariants({ variant }), className)} {...props} />
30
+ ))
31
+ Alert.displayName = 'Alert'
32
+
33
+ const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
34
+ ({ className, ...props }, ref) => (
35
+ <h5 ref={ref} className={cn('mb-1 leading-none font-medium tracking-tight', className)} {...props} />
36
+ ),
37
+ )
38
+ AlertTitle.displayName = 'AlertTitle'
39
+
40
+ const AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
41
+ ({ className, ...props }, ref) => (
42
+ <div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)} {...props} />
43
+ ),
44
+ )
45
+ AlertDescription.displayName = 'AlertDescription'
46
+
47
+ export { Alert, AlertTitle, AlertDescription }