create-nextjs-cms 0.9.30 → 0.9.31

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 (143) 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 +2 -2
  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)/(plugins)/[...slug]/plugin-server-registry.ts +10 -6
  16. package/templates/default/app/(rootLayout)/admins/page.tsx +10 -10
  17. package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +22 -22
  18. package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +15 -15
  19. package/templates/default/app/(rootLayout)/dashboard/page.tsx +70 -70
  20. package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +20 -20
  21. package/templates/default/app/(rootLayout)/layout.tsx +81 -81
  22. package/templates/default/app/(rootLayout)/loading.tsx +10 -10
  23. package/templates/default/app/(rootLayout)/log/page.tsx +7 -7
  24. package/templates/default/app/(rootLayout)/new/[section]/page.tsx +15 -15
  25. package/templates/default/app/(rootLayout)/section/[section]/page.tsx +19 -19
  26. package/templates/default/app/(rootLayout)/settings/page.tsx +13 -13
  27. package/templates/default/app/api/auth/csrf/route.ts +25 -25
  28. package/templates/default/app/api/auth/refresh/route.ts +10 -10
  29. package/templates/default/app/api/auth/route.ts +49 -49
  30. package/templates/default/app/api/auth/session/route.ts +20 -20
  31. package/templates/default/app/api/document/route.ts +165 -165
  32. package/templates/default/app/api/editor/photo/route.ts +49 -49
  33. package/templates/default/app/api/photo/route.ts +27 -27
  34. package/templates/default/app/api/submit/section/item/[slug]/route.ts +95 -95
  35. package/templates/default/app/api/submit/section/item/route.ts +56 -56
  36. package/templates/default/app/api/submit/section/simple/route.ts +86 -86
  37. package/templates/default/app/api/video/route.ts +174 -174
  38. package/templates/default/app/globals.css +236 -236
  39. package/templates/default/cms.config.ts +56 -56
  40. package/templates/default/components/admin/admin-card.tsx +165 -165
  41. package/templates/default/components/admin/admin-edit-page.tsx +124 -124
  42. package/templates/default/components/admin/admin-privilege-card.tsx +184 -184
  43. package/templates/default/components/admin/new-admin-form.tsx +172 -172
  44. package/templates/default/components/container-box.tsx +24 -24
  45. package/templates/default/components/dnd-kit/draggable.tsx +21 -21
  46. package/templates/default/components/dnd-kit/droppable.tsx +20 -20
  47. package/templates/default/components/dnd-kit/sortable-item.tsx +18 -18
  48. package/templates/default/components/feedback/error-component.tsx +16 -16
  49. package/templates/default/components/feedback/info-card.tsx +93 -93
  50. package/templates/default/components/feedback/loading-spinners.tsx +67 -67
  51. package/templates/default/components/feedback/modal.tsx +166 -166
  52. package/templates/default/components/feedback/progress-bar.tsx +48 -48
  53. package/templates/default/components/feedback/tooltip-component.tsx +27 -27
  54. package/templates/default/components/form/form-input-element.tsx +70 -70
  55. package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
  56. package/templates/default/components/form/helpers/util.ts +17 -17
  57. package/templates/default/components/form/inputs/checkbox-form-input.tsx +46 -46
  58. package/templates/default/components/form/inputs/color-form-input.tsx +44 -44
  59. package/templates/default/components/form/inputs/date-form-input.tsx +93 -93
  60. package/templates/default/components/form/inputs/map-form-input.tsx +141 -141
  61. package/templates/default/components/form/inputs/multiple-select-form-input.tsx +85 -85
  62. package/templates/default/components/form/inputs/number-form-input.tsx +43 -43
  63. package/templates/default/components/form/inputs/password-form-input.tsx +47 -47
  64. package/templates/default/components/form/inputs/photo-form-input.tsx +279 -279
  65. package/templates/default/components/form/inputs/rich-text-form-input.tsx +148 -148
  66. package/templates/default/components/form/inputs/select-form-input.tsx +159 -159
  67. package/templates/default/components/form/inputs/slug-form-input.tsx +131 -131
  68. package/templates/default/components/form/inputs/tags-form-input.tsx +255 -255
  69. package/templates/default/components/form/inputs/text-form-input.tsx +61 -61
  70. package/templates/default/components/form/inputs/textarea-form-input.tsx +61 -61
  71. package/templates/default/components/layout/default-nav-items.tsx +3 -3
  72. package/templates/default/components/layout/layout.tsx +84 -84
  73. package/templates/default/components/layout/navbar.tsx +258 -258
  74. package/templates/default/components/layout/sidebar-dropdown-item.tsx +83 -83
  75. package/templates/default/components/layout/sidebar-item.tsx +24 -24
  76. package/templates/default/components/layout/sidebar.tsx +229 -229
  77. package/templates/default/components/layout/theme-provider.tsx +8 -8
  78. package/templates/default/components/layout/theme-toggle.tsx +39 -39
  79. package/templates/default/components/locale/locale-switcher.tsx +98 -98
  80. package/templates/default/components/media/dropzone.tsx +154 -154
  81. package/templates/default/components/media/protected-document.tsx +44 -44
  82. package/templates/default/components/media/protected-image.tsx +143 -143
  83. package/templates/default/components/media/protected-video.tsx +76 -76
  84. package/templates/default/components/multi-select.tsx +1150 -1150
  85. package/templates/default/components/pages/admins-page.tsx +43 -43
  86. package/templates/default/components/pages/browse-page.tsx +106 -106
  87. package/templates/default/components/pages/categorized-section-page.tsx +31 -31
  88. package/templates/default/components/pages/dashboard-page-alt.tsx +45 -45
  89. package/templates/default/components/pages/item-edit-page.tsx +267 -267
  90. package/templates/default/components/pages/log-page.tsx +107 -107
  91. package/templates/default/components/pages/new-page.tsx +183 -183
  92. package/templates/default/components/pages/section-page.tsx +203 -203
  93. package/templates/default/components/pages/settings-page.tsx +232 -232
  94. package/templates/default/components/pagination/pagination-buttons.tsx +147 -147
  95. package/templates/default/components/pagination/pagination.tsx +36 -36
  96. package/templates/default/components/sections/category-delete-confirm-page.tsx +130 -130
  97. package/templates/default/components/sections/category-section-select-input.tsx +139 -139
  98. package/templates/default/components/sections/conditional-fields.tsx +49 -49
  99. package/templates/default/components/sections/section-icon.tsx +8 -8
  100. package/templates/default/components/sections/section-item-card.tsx +143 -143
  101. package/templates/default/components/sections/section-item-status-badge.tsx +17 -17
  102. package/templates/default/components/sections/select-input-buttons.tsx +125 -125
  103. package/templates/default/components/select-box.tsx +98 -98
  104. package/templates/default/components/ui/accordion.tsx +53 -53
  105. package/templates/default/components/ui/alert-dialog.tsx +113 -113
  106. package/templates/default/components/ui/alert.tsx +47 -47
  107. package/templates/default/components/ui/badge.tsx +38 -38
  108. package/templates/default/components/ui/card.tsx +43 -43
  109. package/templates/default/components/ui/command.tsx +137 -137
  110. package/templates/default/components/ui/custom-alert-dialog.tsx +113 -113
  111. package/templates/default/components/ui/custom-dialog.tsx +123 -123
  112. package/templates/default/components/ui/dialog.tsx +123 -123
  113. package/templates/default/components/ui/direction.tsx +22 -22
  114. package/templates/default/components/ui/dropdown-menu.tsx +182 -182
  115. package/templates/default/components/ui/input-group.tsx +54 -54
  116. package/templates/default/components/ui/input.tsx +22 -22
  117. package/templates/default/components/ui/label.tsx +19 -19
  118. package/templates/default/components/ui/popover.tsx +42 -42
  119. package/templates/default/components/ui/progress.tsx +31 -31
  120. package/templates/default/components/ui/scroll-area.tsx +42 -42
  121. package/templates/default/components/ui/select.tsx +165 -165
  122. package/templates/default/components/ui/separator.tsx +28 -28
  123. package/templates/default/components/ui/sheet.tsx +103 -103
  124. package/templates/default/components/ui/spinner.tsx +16 -16
  125. package/templates/default/components/ui/switch.tsx +29 -29
  126. package/templates/default/components/ui/table.tsx +83 -83
  127. package/templates/default/components/ui/tabs.tsx +55 -55
  128. package/templates/default/components/ui/toast.tsx +113 -113
  129. package/templates/default/components/ui/toaster.tsx +35 -35
  130. package/templates/default/components/ui/tooltip.tsx +30 -30
  131. package/templates/default/components/ui/use-toast.ts +187 -187
  132. package/templates/default/drizzle.config.ts +4 -4
  133. package/templates/default/dynamic-schemas/schema.ts +225 -75
  134. package/templates/default/env/env.ts +46 -46
  135. package/templates/default/envConfig.ts +4 -4
  136. package/templates/default/lib/postinstall.js +14 -14
  137. package/templates/default/lib/utils.ts +6 -6
  138. package/templates/default/next-env.d.ts +6 -6
  139. package/templates/default/next.config.ts +24 -24
  140. package/templates/default/package.json +1 -1
  141. package/templates/default/postcss.config.mjs +6 -6
  142. package/templates/default/proxy.ts +32 -32
  143. 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 }