create-nextjs-cms 0.9.28 → 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.
- package/LICENSE +21 -21
- package/README.md +71 -71
- package/dist/helpers/utils.js +16 -16
- package/dist/lib/section-creators.js +166 -166
- package/package.json +2 -2
- package/templates/default/.eslintrc.json +5 -5
- package/templates/default/.prettierignore +7 -7
- package/templates/default/.prettierrc.json +27 -27
- package/templates/default/CHANGELOG.md +140 -140
- package/templates/default/_gitignore +57 -57
- package/templates/default/app/(auth)/auth/login/LoginPage.tsx +192 -192
- package/templates/default/app/(auth)/auth/login/page.tsx +11 -11
- package/templates/default/app/(auth)/auth-language-provider.tsx +34 -34
- package/templates/default/app/(auth)/layout.tsx +81 -81
- package/templates/default/app/(rootLayout)/admins/page.tsx +10 -10
- package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +22 -22
- package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +15 -15
- package/templates/default/app/(rootLayout)/dashboard/page.tsx +70 -70
- package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +20 -20
- package/templates/default/app/(rootLayout)/layout.tsx +81 -81
- package/templates/default/app/(rootLayout)/loading.tsx +10 -10
- package/templates/default/app/(rootLayout)/log/page.tsx +7 -7
- package/templates/default/app/(rootLayout)/new/[section]/page.tsx +15 -15
- package/templates/default/app/(rootLayout)/section/[section]/page.tsx +19 -19
- package/templates/default/app/(rootLayout)/settings/page.tsx +13 -13
- package/templates/default/app/api/auth/csrf/route.ts +25 -25
- package/templates/default/app/api/auth/refresh/route.ts +10 -10
- package/templates/default/app/api/auth/route.ts +49 -49
- package/templates/default/app/api/auth/session/route.ts +20 -20
- package/templates/default/app/api/document/route.ts +165 -165
- package/templates/default/app/api/editor/photo/route.ts +49 -49
- package/templates/default/app/api/photo/route.ts +27 -27
- package/templates/default/app/api/submit/section/item/[slug]/route.ts +95 -95
- package/templates/default/app/api/submit/section/item/route.ts +56 -56
- package/templates/default/app/api/submit/section/simple/route.ts +86 -86
- package/templates/default/app/api/video/route.ts +174 -174
- package/templates/default/app/globals.css +236 -236
- package/templates/default/cms.config.ts +56 -56
- package/templates/default/components/admin/admin-card.tsx +165 -165
- package/templates/default/components/admin/admin-edit-page.tsx +124 -124
- package/templates/default/components/admin/admin-privilege-card.tsx +184 -184
- package/templates/default/components/admin/new-admin-form.tsx +172 -172
- package/templates/default/components/container-box.tsx +24 -24
- package/templates/default/components/dnd-kit/draggable.tsx +21 -21
- package/templates/default/components/dnd-kit/droppable.tsx +20 -20
- package/templates/default/components/dnd-kit/sortable-item.tsx +18 -18
- package/templates/default/components/feedback/error-component.tsx +16 -16
- package/templates/default/components/feedback/info-card.tsx +93 -93
- package/templates/default/components/feedback/loading-spinners.tsx +67 -67
- package/templates/default/components/feedback/modal.tsx +166 -166
- package/templates/default/components/feedback/progress-bar.tsx +48 -48
- package/templates/default/components/feedback/tooltip-component.tsx +27 -27
- package/templates/default/components/form/form-input-element.tsx +70 -70
- package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
- package/templates/default/components/form/helpers/util.ts +17 -17
- package/templates/default/components/form/inputs/checkbox-form-input.tsx +46 -46
- package/templates/default/components/form/inputs/color-form-input.tsx +44 -44
- package/templates/default/components/form/inputs/date-form-input.tsx +93 -93
- package/templates/default/components/form/inputs/map-form-input.tsx +141 -141
- package/templates/default/components/form/inputs/multiple-select-form-input.tsx +85 -85
- package/templates/default/components/form/inputs/number-form-input.tsx +43 -43
- package/templates/default/components/form/inputs/password-form-input.tsx +47 -47
- package/templates/default/components/form/inputs/photo-form-input.tsx +279 -279
- package/templates/default/components/form/inputs/rich-text-form-input.tsx +148 -148
- package/templates/default/components/form/inputs/select-form-input.tsx +159 -159
- package/templates/default/components/form/inputs/slug-form-input.tsx +131 -131
- package/templates/default/components/form/inputs/tags-form-input.tsx +255 -255
- package/templates/default/components/form/inputs/text-form-input.tsx +61 -61
- package/templates/default/components/form/inputs/textarea-form-input.tsx +61 -61
- package/templates/default/components/layout/default-nav-items.tsx +3 -3
- package/templates/default/components/layout/layout.tsx +84 -84
- package/templates/default/components/layout/navbar.tsx +258 -258
- package/templates/default/components/layout/sidebar-dropdown-item.tsx +83 -83
- package/templates/default/components/layout/sidebar-item.tsx +24 -24
- package/templates/default/components/layout/sidebar.tsx +229 -229
- package/templates/default/components/layout/theme-provider.tsx +8 -8
- package/templates/default/components/layout/theme-toggle.tsx +39 -39
- package/templates/default/components/locale/locale-switcher.tsx +98 -98
- package/templates/default/components/media/dropzone.tsx +154 -154
- package/templates/default/components/media/protected-document.tsx +44 -44
- package/templates/default/components/media/protected-image.tsx +143 -143
- package/templates/default/components/media/protected-video.tsx +76 -76
- package/templates/default/components/multi-select.tsx +1150 -1150
- package/templates/default/components/pages/admins-page.tsx +43 -43
- package/templates/default/components/pages/browse-page.tsx +106 -106
- package/templates/default/components/pages/categorized-section-page.tsx +31 -31
- package/templates/default/components/pages/dashboard-page-alt.tsx +45 -45
- package/templates/default/components/pages/item-edit-page.tsx +267 -267
- package/templates/default/components/pages/log-page.tsx +107 -107
- package/templates/default/components/pages/new-page.tsx +183 -183
- package/templates/default/components/pages/section-page.tsx +203 -203
- package/templates/default/components/pages/settings-page.tsx +232 -232
- package/templates/default/components/pagination/pagination-buttons.tsx +147 -147
- package/templates/default/components/pagination/pagination.tsx +36 -36
- package/templates/default/components/sections/category-delete-confirm-page.tsx +130 -130
- package/templates/default/components/sections/category-section-select-input.tsx +139 -139
- package/templates/default/components/sections/conditional-fields.tsx +49 -49
- package/templates/default/components/sections/section-icon.tsx +8 -8
- package/templates/default/components/sections/section-item-card.tsx +143 -143
- package/templates/default/components/sections/section-item-status-badge.tsx +17 -17
- package/templates/default/components/sections/select-input-buttons.tsx +125 -125
- package/templates/default/components/select-box.tsx +98 -98
- package/templates/default/components/ui/accordion.tsx +53 -53
- package/templates/default/components/ui/alert-dialog.tsx +113 -113
- package/templates/default/components/ui/alert.tsx +47 -47
- package/templates/default/components/ui/badge.tsx +38 -38
- package/templates/default/components/ui/card.tsx +43 -43
- package/templates/default/components/ui/command.tsx +137 -137
- package/templates/default/components/ui/custom-alert-dialog.tsx +113 -113
- package/templates/default/components/ui/custom-dialog.tsx +123 -123
- package/templates/default/components/ui/dialog.tsx +123 -123
- package/templates/default/components/ui/direction.tsx +22 -22
- package/templates/default/components/ui/dropdown-menu.tsx +182 -182
- package/templates/default/components/ui/input-group.tsx +54 -54
- package/templates/default/components/ui/input.tsx +22 -22
- package/templates/default/components/ui/label.tsx +19 -19
- package/templates/default/components/ui/popover.tsx +42 -42
- package/templates/default/components/ui/progress.tsx +31 -31
- package/templates/default/components/ui/scroll-area.tsx +42 -42
- package/templates/default/components/ui/select.tsx +165 -165
- package/templates/default/components/ui/separator.tsx +28 -28
- package/templates/default/components/ui/sheet.tsx +103 -103
- package/templates/default/components/ui/spinner.tsx +16 -16
- package/templates/default/components/ui/switch.tsx +29 -29
- package/templates/default/components/ui/table.tsx +83 -83
- package/templates/default/components/ui/tabs.tsx +55 -55
- package/templates/default/components/ui/toast.tsx +113 -113
- package/templates/default/components/ui/toaster.tsx +35 -35
- package/templates/default/components/ui/tooltip.tsx +30 -30
- package/templates/default/components/ui/use-toast.ts +187 -187
- package/templates/default/drizzle.config.ts +4 -4
- package/templates/default/dynamic-schemas/schema.ts +75 -225
- package/templates/default/env/env.ts +46 -46
- package/templates/default/envConfig.ts +4 -4
- package/templates/default/lib/postinstall.js +14 -14
- package/templates/default/lib/utils.ts +6 -6
- package/templates/default/next-env.d.ts +6 -6
- package/templates/default/next.config.ts +24 -24
- package/templates/default/package.json +1 -1
- package/templates/default/postcss.config.mjs +6 -6
- package/templates/default/proxy.ts +32 -32
- 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 }
|