@salesforce/ui-bundle-template-base-react-app 1.117.2
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/.forceignore +15 -0
- package/.gitignore +1 -0
- package/CHANGELOG.md +1096 -0
- package/LICENSE.txt +82 -0
- package/README.md +17 -0
- package/package.json +18 -0
- package/src/force-app/main/default/uiBundles/base-react-app/.forceignore +15 -0
- package/src/force-app/main/default/uiBundles/base-react-app/.graphqlrc.yml +2 -0
- package/src/force-app/main/default/uiBundles/base-react-app/.prettierignore +9 -0
- package/src/force-app/main/default/uiBundles/base-react-app/.prettierrc +11 -0
- package/src/force-app/main/default/uiBundles/base-react-app/CHANGELOG.md +10 -0
- package/src/force-app/main/default/uiBundles/base-react-app/README.md +75 -0
- package/src/force-app/main/default/uiBundles/base-react-app/_uibundle.uibundle-meta.xml +7 -0
- package/src/force-app/main/default/uiBundles/base-react-app/codegen.yml +95 -0
- package/src/force-app/main/default/uiBundles/base-react-app/components.json +18 -0
- package/src/force-app/main/default/uiBundles/base-react-app/e2e/app.spec.ts +17 -0
- package/src/force-app/main/default/uiBundles/base-react-app/eslint.config.js +169 -0
- package/src/force-app/main/default/uiBundles/base-react-app/index.html +12 -0
- package/src/force-app/main/default/uiBundles/base-react-app/package.json +68 -0
- package/src/force-app/main/default/uiBundles/base-react-app/playwright.config.ts +24 -0
- package/src/force-app/main/default/uiBundles/base-react-app/scripts/get-graphql-schema.mjs +68 -0
- package/src/force-app/main/default/uiBundles/base-react-app/scripts/rewrite-e2e-assets.mjs +23 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/api/graphqlClient.ts +25 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/app.tsx +17 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/appLayout.tsx +83 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/book.svg +3 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/copy.svg +4 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/rocket.svg +3 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/star.svg +3 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/codey-1.png +0 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/codey-2.png +0 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/codey-3.png +0 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/vibe-codey.svg +194 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/alerts/status-alert.tsx +49 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/layouts/card-layout.tsx +29 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/alert.tsx +76 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/badge.tsx +48 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/breadcrumb.tsx +109 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/button.tsx +67 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/calendar.tsx +232 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/card.tsx +103 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/checkbox.tsx +32 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/collapsible.tsx +33 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/datePicker.tsx +127 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/dialog.tsx +162 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/field.tsx +237 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/index.ts +84 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/input.tsx +19 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/label.tsx +22 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/pagination.tsx +132 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/popover.tsx +89 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/select.tsx +193 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/separator.tsx +26 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/skeleton.tsx +14 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/sonner.tsx +20 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/spinner.tsx +16 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/table.tsx +114 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/tabs.tsx +88 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/lib/utils.ts +6 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/navigationMenu.tsx +80 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/pages/Home.tsx +12 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/pages/NotFound.tsx +18 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/router-utils.tsx +35 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/routes.tsx +22 -0
- package/src/force-app/main/default/uiBundles/base-react-app/src/styles/global.css +135 -0
- package/src/force-app/main/default/uiBundles/base-react-app/tsconfig.json +42 -0
- package/src/force-app/main/default/uiBundles/base-react-app/tsconfig.node.json +13 -0
- package/src/force-app/main/default/uiBundles/base-react-app/ui-bundle.json +7 -0
- package/src/force-app/main/default/uiBundles/base-react-app/vite-env.d.ts +1 -0
- package/src/force-app/main/default/uiBundles/base-react-app/vite.config.ts +106 -0
- package/src/force-app/main/default/uiBundles/base-react-app/vitest-env.d.ts +2 -0
- package/src/force-app/main/default/uiBundles/base-react-app/vitest.config.ts +11 -0
- package/src/force-app/main/default/uiBundles/base-react-app/vitest.setup.ts +1 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
import { Button } from './button';
|
|
5
|
+
import {
|
|
6
|
+
ChevronLeftIcon,
|
|
7
|
+
ChevronRightIcon,
|
|
8
|
+
MoreHorizontalIcon,
|
|
9
|
+
} from 'lucide-react';
|
|
10
|
+
|
|
11
|
+
function Pagination({ className, ...props }: React.ComponentProps<'nav'>) {
|
|
12
|
+
return (
|
|
13
|
+
<nav
|
|
14
|
+
role="navigation"
|
|
15
|
+
aria-label="pagination"
|
|
16
|
+
data-slot="pagination"
|
|
17
|
+
className={cn('mx-auto flex w-full justify-center', className)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function PaginationContent({
|
|
24
|
+
className,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<'ul'>) {
|
|
27
|
+
return (
|
|
28
|
+
<ul
|
|
29
|
+
data-slot="pagination-content"
|
|
30
|
+
className={cn('gap-0.5 flex items-center', className)}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function PaginationItem({ ...props }: React.ComponentProps<'li'>) {
|
|
37
|
+
return <li data-slot="pagination-item" {...props} />;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type PaginationLinkProps = {
|
|
41
|
+
isActive?: boolean;
|
|
42
|
+
} & Pick<React.ComponentProps<typeof Button>, 'size'> &
|
|
43
|
+
React.ComponentProps<'a'>;
|
|
44
|
+
|
|
45
|
+
function PaginationLink({
|
|
46
|
+
className,
|
|
47
|
+
isActive,
|
|
48
|
+
size = 'icon',
|
|
49
|
+
...props
|
|
50
|
+
}: PaginationLinkProps) {
|
|
51
|
+
return (
|
|
52
|
+
<Button
|
|
53
|
+
asChild
|
|
54
|
+
variant={isActive ? 'outline' : 'ghost'}
|
|
55
|
+
size={size}
|
|
56
|
+
className={cn(className)}
|
|
57
|
+
>
|
|
58
|
+
<a
|
|
59
|
+
aria-current={isActive ? 'page' : undefined}
|
|
60
|
+
data-slot="pagination-link"
|
|
61
|
+
data-active={isActive}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
</Button>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function PaginationPrevious({
|
|
69
|
+
className,
|
|
70
|
+
text = 'Previous',
|
|
71
|
+
...props
|
|
72
|
+
}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
|
|
73
|
+
return (
|
|
74
|
+
<PaginationLink
|
|
75
|
+
aria-label="Go to previous page"
|
|
76
|
+
size="default"
|
|
77
|
+
className={cn('pl-1.5!', className)}
|
|
78
|
+
{...props}
|
|
79
|
+
>
|
|
80
|
+
<ChevronLeftIcon data-icon="inline-start" className="cn-rtl-flip" />
|
|
81
|
+
<span className="hidden sm:block">{text}</span>
|
|
82
|
+
</PaginationLink>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function PaginationNext({
|
|
87
|
+
className,
|
|
88
|
+
text = 'Next',
|
|
89
|
+
...props
|
|
90
|
+
}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
|
|
91
|
+
return (
|
|
92
|
+
<PaginationLink
|
|
93
|
+
aria-label="Go to next page"
|
|
94
|
+
size="default"
|
|
95
|
+
className={cn('pr-1.5!', className)}
|
|
96
|
+
{...props}
|
|
97
|
+
>
|
|
98
|
+
<span className="hidden sm:block">{text}</span>
|
|
99
|
+
<ChevronRightIcon data-icon="inline-end" className="cn-rtl-flip" />
|
|
100
|
+
</PaginationLink>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function PaginationEllipsis({
|
|
105
|
+
className,
|
|
106
|
+
...props
|
|
107
|
+
}: React.ComponentProps<'span'>) {
|
|
108
|
+
return (
|
|
109
|
+
<span
|
|
110
|
+
aria-hidden
|
|
111
|
+
data-slot="pagination-ellipsis"
|
|
112
|
+
className={cn(
|
|
113
|
+
"size-8 [&_svg:not([class*='size-'])]:size-4 flex items-center justify-center",
|
|
114
|
+
className
|
|
115
|
+
)}
|
|
116
|
+
{...props}
|
|
117
|
+
>
|
|
118
|
+
<MoreHorizontalIcon />
|
|
119
|
+
<span className="sr-only">More pages</span>
|
|
120
|
+
</span>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export {
|
|
125
|
+
Pagination,
|
|
126
|
+
PaginationContent,
|
|
127
|
+
PaginationEllipsis,
|
|
128
|
+
PaginationItem,
|
|
129
|
+
PaginationLink,
|
|
130
|
+
PaginationNext,
|
|
131
|
+
PaginationPrevious,
|
|
132
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Popover as PopoverPrimitive } from 'radix-ui';
|
|
5
|
+
|
|
6
|
+
import { cn } from '@/lib/utils';
|
|
7
|
+
|
|
8
|
+
function Popover({
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
|
11
|
+
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function PopoverTrigger({
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
17
|
+
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function PopoverContent({
|
|
21
|
+
className,
|
|
22
|
+
align = 'center',
|
|
23
|
+
sideOffset = 4,
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
|
26
|
+
return (
|
|
27
|
+
<PopoverPrimitive.Portal>
|
|
28
|
+
<PopoverPrimitive.Content
|
|
29
|
+
data-slot="popover-content"
|
|
30
|
+
align={align}
|
|
31
|
+
sideOffset={sideOffset}
|
|
32
|
+
className={cn(
|
|
33
|
+
'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm shadow-md ring-1 duration-100 z-50 w-72 origin-(--radix-popover-content-transform-origin) outline-hidden',
|
|
34
|
+
className
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
</PopoverPrimitive.Portal>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function PopoverAnchor({
|
|
43
|
+
...props
|
|
44
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
|
45
|
+
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function PopoverHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
data-slot="popover-header"
|
|
52
|
+
className={cn('flex flex-col gap-0.5 text-sm', className)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function PopoverTitle({ className, ...props }: React.ComponentProps<'h2'>) {
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
data-slot="popover-title"
|
|
62
|
+
className={cn('font-medium', className)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function PopoverDescription({
|
|
69
|
+
className,
|
|
70
|
+
...props
|
|
71
|
+
}: React.ComponentProps<'p'>) {
|
|
72
|
+
return (
|
|
73
|
+
<p
|
|
74
|
+
data-slot="popover-description"
|
|
75
|
+
className={cn('text-muted-foreground', className)}
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export {
|
|
82
|
+
Popover,
|
|
83
|
+
PopoverAnchor,
|
|
84
|
+
PopoverContent,
|
|
85
|
+
PopoverDescription,
|
|
86
|
+
PopoverHeader,
|
|
87
|
+
PopoverTitle,
|
|
88
|
+
PopoverTrigger,
|
|
89
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Select as SelectPrimitive } from 'radix-ui';
|
|
3
|
+
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
function Select({
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
|
10
|
+
return <SelectPrimitive.Root data-slot="select" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function SelectGroup({
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
|
17
|
+
return (
|
|
18
|
+
<SelectPrimitive.Group
|
|
19
|
+
data-slot="select-group"
|
|
20
|
+
className={cn('scroll-my-1 p-1', className)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function SelectValue({
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
|
29
|
+
return <SelectPrimitive.Value data-slot="select-value" {...props} />;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function SelectTrigger({
|
|
33
|
+
className,
|
|
34
|
+
size = 'default',
|
|
35
|
+
children,
|
|
36
|
+
...props
|
|
37
|
+
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
|
38
|
+
size?: 'sm' | 'default';
|
|
39
|
+
}) {
|
|
40
|
+
return (
|
|
41
|
+
<SelectPrimitive.Trigger
|
|
42
|
+
data-slot="select-trigger"
|
|
43
|
+
data-size={size}
|
|
44
|
+
className={cn(
|
|
45
|
+
"border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
{children}
|
|
51
|
+
<SelectPrimitive.Icon asChild>
|
|
52
|
+
<ChevronDownIcon className="text-muted-foreground size-4 pointer-events-none" />
|
|
53
|
+
</SelectPrimitive.Icon>
|
|
54
|
+
</SelectPrimitive.Trigger>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function SelectContent({
|
|
59
|
+
className,
|
|
60
|
+
children,
|
|
61
|
+
position = 'item-aligned',
|
|
62
|
+
align = 'center',
|
|
63
|
+
...props
|
|
64
|
+
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
|
|
65
|
+
return (
|
|
66
|
+
<SelectPrimitive.Portal>
|
|
67
|
+
<SelectPrimitive.Content
|
|
68
|
+
data-slot="select-content"
|
|
69
|
+
data-align-trigger={position === 'item-aligned'}
|
|
70
|
+
className={cn(
|
|
71
|
+
'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-lg shadow-md ring-1 duration-100 relative z-50 max-h-(--radix-select-content-available-height) origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto data-[align-trigger=true]:animate-none',
|
|
72
|
+
position === 'popper' &&
|
|
73
|
+
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
|
74
|
+
className
|
|
75
|
+
)}
|
|
76
|
+
position={position}
|
|
77
|
+
align={align}
|
|
78
|
+
{...props}
|
|
79
|
+
>
|
|
80
|
+
<SelectScrollUpButton />
|
|
81
|
+
<SelectPrimitive.Viewport
|
|
82
|
+
data-position={position}
|
|
83
|
+
className={cn(
|
|
84
|
+
'data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)',
|
|
85
|
+
position === 'popper' && ''
|
|
86
|
+
)}
|
|
87
|
+
>
|
|
88
|
+
{children}
|
|
89
|
+
</SelectPrimitive.Viewport>
|
|
90
|
+
<SelectScrollDownButton />
|
|
91
|
+
</SelectPrimitive.Content>
|
|
92
|
+
</SelectPrimitive.Portal>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function SelectLabel({
|
|
97
|
+
className,
|
|
98
|
+
...props
|
|
99
|
+
}: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
|
100
|
+
return (
|
|
101
|
+
<SelectPrimitive.Label
|
|
102
|
+
data-slot="select-label"
|
|
103
|
+
className={cn('text-muted-foreground px-1.5 py-1 text-xs', className)}
|
|
104
|
+
{...props}
|
|
105
|
+
/>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function SelectItem({
|
|
110
|
+
className,
|
|
111
|
+
children,
|
|
112
|
+
...props
|
|
113
|
+
}: React.ComponentProps<typeof SelectPrimitive.Item>) {
|
|
114
|
+
return (
|
|
115
|
+
<SelectPrimitive.Item
|
|
116
|
+
data-slot="select-item"
|
|
117
|
+
className={cn(
|
|
118
|
+
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
119
|
+
className
|
|
120
|
+
)}
|
|
121
|
+
{...props}
|
|
122
|
+
>
|
|
123
|
+
<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
|
|
124
|
+
<SelectPrimitive.ItemIndicator>
|
|
125
|
+
<CheckIcon className="pointer-events-none" />
|
|
126
|
+
</SelectPrimitive.ItemIndicator>
|
|
127
|
+
</span>
|
|
128
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
129
|
+
</SelectPrimitive.Item>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function SelectSeparator({
|
|
134
|
+
className,
|
|
135
|
+
...props
|
|
136
|
+
}: React.ComponentProps<typeof SelectPrimitive.Separator>) {
|
|
137
|
+
return (
|
|
138
|
+
<SelectPrimitive.Separator
|
|
139
|
+
data-slot="select-separator"
|
|
140
|
+
className={cn('bg-border -mx-1 my-1 h-px pointer-events-none', className)}
|
|
141
|
+
{...props}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function SelectScrollUpButton({
|
|
147
|
+
className,
|
|
148
|
+
...props
|
|
149
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
|
|
150
|
+
return (
|
|
151
|
+
<SelectPrimitive.ScrollUpButton
|
|
152
|
+
data-slot="select-scroll-up-button"
|
|
153
|
+
className={cn(
|
|
154
|
+
"bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
155
|
+
className
|
|
156
|
+
)}
|
|
157
|
+
{...props}
|
|
158
|
+
>
|
|
159
|
+
<ChevronUpIcon />
|
|
160
|
+
</SelectPrimitive.ScrollUpButton>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function SelectScrollDownButton({
|
|
165
|
+
className,
|
|
166
|
+
...props
|
|
167
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
|
|
168
|
+
return (
|
|
169
|
+
<SelectPrimitive.ScrollDownButton
|
|
170
|
+
data-slot="select-scroll-down-button"
|
|
171
|
+
className={cn(
|
|
172
|
+
"bg-popover z-10 flex cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
173
|
+
className
|
|
174
|
+
)}
|
|
175
|
+
{...props}
|
|
176
|
+
>
|
|
177
|
+
<ChevronDownIcon />
|
|
178
|
+
</SelectPrimitive.ScrollDownButton>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export {
|
|
183
|
+
Select,
|
|
184
|
+
SelectContent,
|
|
185
|
+
SelectGroup,
|
|
186
|
+
SelectItem,
|
|
187
|
+
SelectLabel,
|
|
188
|
+
SelectScrollDownButton,
|
|
189
|
+
SelectScrollUpButton,
|
|
190
|
+
SelectSeparator,
|
|
191
|
+
SelectTrigger,
|
|
192
|
+
SelectValue,
|
|
193
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Separator as SeparatorPrimitive } from 'radix-ui';
|
|
3
|
+
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
|
|
6
|
+
function Separator({
|
|
7
|
+
className,
|
|
8
|
+
orientation = 'horizontal',
|
|
9
|
+
decorative = true,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<SeparatorPrimitive.Root
|
|
14
|
+
data-slot="separator"
|
|
15
|
+
decorative={decorative}
|
|
16
|
+
orientation={orientation}
|
|
17
|
+
className={cn(
|
|
18
|
+
'bg-border shrink-0 data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch',
|
|
19
|
+
className
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { Separator };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../lib/utils';
|
|
3
|
+
|
|
4
|
+
function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
|
|
5
|
+
return (
|
|
6
|
+
<div
|
|
7
|
+
data-slot="skeleton"
|
|
8
|
+
className={cn('bg-accent animate-pulse rounded-md', className)}
|
|
9
|
+
{...props}
|
|
10
|
+
/>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { Skeleton };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Toaster as Sonner } from 'sonner';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Renders the toast container. Use with `toast()` from this module for messages
|
|
5
|
+
* with title, description, actions, and variants (success, error, warning).
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* toast("Event has been created", {
|
|
9
|
+
* description: "Sunday, December 03, 2023 at 9:00 AM",
|
|
10
|
+
* action: { label: "Undo", onClick: () => {} },
|
|
11
|
+
* });
|
|
12
|
+
* toast.success("Saved!");
|
|
13
|
+
* toast.error("Something went wrong");
|
|
14
|
+
* toast.warning("Please review");
|
|
15
|
+
*/
|
|
16
|
+
export function Toaster() {
|
|
17
|
+
return <Sonner position="top-right" richColors />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { toast } from 'sonner';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../lib/utils';
|
|
3
|
+
import { Loader2Icon } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
function Spinner({ className, ...props }: React.ComponentProps<'svg'>) {
|
|
6
|
+
return (
|
|
7
|
+
<Loader2Icon
|
|
8
|
+
role="status"
|
|
9
|
+
aria-label="Loading"
|
|
10
|
+
className={cn('size-4 animate-spin', className)}
|
|
11
|
+
{...(props as any)}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { Spinner };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
|
|
5
|
+
function Table({ className, ...props }: React.ComponentProps<'table'>) {
|
|
6
|
+
return (
|
|
7
|
+
<div
|
|
8
|
+
data-slot="table-container"
|
|
9
|
+
className="relative w-full overflow-x-auto"
|
|
10
|
+
>
|
|
11
|
+
<table
|
|
12
|
+
data-slot="table"
|
|
13
|
+
className={cn('w-full caption-bottom text-sm', className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {
|
|
21
|
+
return (
|
|
22
|
+
<thead
|
|
23
|
+
data-slot="table-header"
|
|
24
|
+
className={cn('[&_tr]:border-b', className)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {
|
|
31
|
+
return (
|
|
32
|
+
<tbody
|
|
33
|
+
data-slot="table-body"
|
|
34
|
+
className={cn('[&_tr:last-child]:border-0', className)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {
|
|
41
|
+
return (
|
|
42
|
+
<tfoot
|
|
43
|
+
data-slot="table-footer"
|
|
44
|
+
className={cn(
|
|
45
|
+
'bg-muted/50 border-t font-medium [&>tr]:last:border-b-0',
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function TableRow({ className, ...props }: React.ComponentProps<'tr'>) {
|
|
54
|
+
return (
|
|
55
|
+
<tr
|
|
56
|
+
data-slot="table-row"
|
|
57
|
+
className={cn(
|
|
58
|
+
'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors',
|
|
59
|
+
className
|
|
60
|
+
)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function TableHead({ className, ...props }: React.ComponentProps<'th'>) {
|
|
67
|
+
return (
|
|
68
|
+
<th
|
|
69
|
+
data-slot="table-head"
|
|
70
|
+
className={cn(
|
|
71
|
+
'text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0',
|
|
72
|
+
className
|
|
73
|
+
)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function TableCell({ className, ...props }: React.ComponentProps<'td'>) {
|
|
80
|
+
return (
|
|
81
|
+
<td
|
|
82
|
+
data-slot="table-cell"
|
|
83
|
+
className={cn(
|
|
84
|
+
'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0',
|
|
85
|
+
className
|
|
86
|
+
)}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function TableCaption({
|
|
93
|
+
className,
|
|
94
|
+
...props
|
|
95
|
+
}: React.ComponentProps<'caption'>) {
|
|
96
|
+
return (
|
|
97
|
+
<caption
|
|
98
|
+
data-slot="table-caption"
|
|
99
|
+
className={cn('text-muted-foreground mt-4 text-sm', className)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
Table,
|
|
107
|
+
TableHeader,
|
|
108
|
+
TableBody,
|
|
109
|
+
TableFooter,
|
|
110
|
+
TableHead,
|
|
111
|
+
TableRow,
|
|
112
|
+
TableCell,
|
|
113
|
+
TableCaption,
|
|
114
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { Tabs as TabsPrimitive } from 'radix-ui';
|
|
4
|
+
|
|
5
|
+
import { cn } from '../../lib/utils';
|
|
6
|
+
|
|
7
|
+
function Tabs({
|
|
8
|
+
className,
|
|
9
|
+
orientation = 'horizontal',
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<TabsPrimitive.Root
|
|
14
|
+
data-slot="tabs"
|
|
15
|
+
data-orientation={orientation}
|
|
16
|
+
className={cn(
|
|
17
|
+
'gap-2 group/tabs flex data-horizontal:flex-col',
|
|
18
|
+
className
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const tabsListVariants = cva(
|
|
26
|
+
'rounded-lg p-[3px] group-data-horizontal/tabs:h-8 data-[variant=line]:rounded-none group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col',
|
|
27
|
+
{
|
|
28
|
+
variants: {
|
|
29
|
+
variant: {
|
|
30
|
+
default: 'bg-muted',
|
|
31
|
+
line: 'gap-1 bg-transparent',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
variant: 'default',
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
function TabsList({
|
|
41
|
+
className,
|
|
42
|
+
variant = 'default',
|
|
43
|
+
...props
|
|
44
|
+
}: React.ComponentProps<typeof TabsPrimitive.List> &
|
|
45
|
+
VariantProps<typeof tabsListVariants>) {
|
|
46
|
+
return (
|
|
47
|
+
<TabsPrimitive.List
|
|
48
|
+
data-slot="tabs-list"
|
|
49
|
+
data-variant={variant}
|
|
50
|
+
className={cn(tabsListVariants({ variant }), className)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function TabsTrigger({
|
|
57
|
+
className,
|
|
58
|
+
...props
|
|
59
|
+
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
|
60
|
+
return (
|
|
61
|
+
<TabsPrimitive.Trigger
|
|
62
|
+
data-slot="tabs-trigger"
|
|
63
|
+
className={cn(
|
|
64
|
+
"gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg:not([class*='size-'])]:size-4 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
65
|
+
'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent',
|
|
66
|
+
'data-active:bg-background dark:data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 data-active:text-foreground',
|
|
67
|
+
'after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100',
|
|
68
|
+
className
|
|
69
|
+
)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function TabsContent({
|
|
76
|
+
className,
|
|
77
|
+
...props
|
|
78
|
+
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
|
79
|
+
return (
|
|
80
|
+
<TabsPrimitive.Content
|
|
81
|
+
data-slot="tabs-content"
|
|
82
|
+
className={cn('text-sm flex-1 outline-none', className)}
|
|
83
|
+
{...props}
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
|