@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.
Files changed (73) hide show
  1. package/.forceignore +15 -0
  2. package/.gitignore +1 -0
  3. package/CHANGELOG.md +1096 -0
  4. package/LICENSE.txt +82 -0
  5. package/README.md +17 -0
  6. package/package.json +18 -0
  7. package/src/force-app/main/default/uiBundles/base-react-app/.forceignore +15 -0
  8. package/src/force-app/main/default/uiBundles/base-react-app/.graphqlrc.yml +2 -0
  9. package/src/force-app/main/default/uiBundles/base-react-app/.prettierignore +9 -0
  10. package/src/force-app/main/default/uiBundles/base-react-app/.prettierrc +11 -0
  11. package/src/force-app/main/default/uiBundles/base-react-app/CHANGELOG.md +10 -0
  12. package/src/force-app/main/default/uiBundles/base-react-app/README.md +75 -0
  13. package/src/force-app/main/default/uiBundles/base-react-app/_uibundle.uibundle-meta.xml +7 -0
  14. package/src/force-app/main/default/uiBundles/base-react-app/codegen.yml +95 -0
  15. package/src/force-app/main/default/uiBundles/base-react-app/components.json +18 -0
  16. package/src/force-app/main/default/uiBundles/base-react-app/e2e/app.spec.ts +17 -0
  17. package/src/force-app/main/default/uiBundles/base-react-app/eslint.config.js +169 -0
  18. package/src/force-app/main/default/uiBundles/base-react-app/index.html +12 -0
  19. package/src/force-app/main/default/uiBundles/base-react-app/package.json +68 -0
  20. package/src/force-app/main/default/uiBundles/base-react-app/playwright.config.ts +24 -0
  21. package/src/force-app/main/default/uiBundles/base-react-app/scripts/get-graphql-schema.mjs +68 -0
  22. package/src/force-app/main/default/uiBundles/base-react-app/scripts/rewrite-e2e-assets.mjs +23 -0
  23. package/src/force-app/main/default/uiBundles/base-react-app/src/api/graphqlClient.ts +25 -0
  24. package/src/force-app/main/default/uiBundles/base-react-app/src/app.tsx +17 -0
  25. package/src/force-app/main/default/uiBundles/base-react-app/src/appLayout.tsx +83 -0
  26. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/book.svg +3 -0
  27. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/copy.svg +4 -0
  28. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/rocket.svg +3 -0
  29. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/icons/star.svg +3 -0
  30. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/codey-1.png +0 -0
  31. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/codey-2.png +0 -0
  32. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/codey-3.png +0 -0
  33. package/src/force-app/main/default/uiBundles/base-react-app/src/assets/images/vibe-codey.svg +194 -0
  34. package/src/force-app/main/default/uiBundles/base-react-app/src/components/alerts/status-alert.tsx +49 -0
  35. package/src/force-app/main/default/uiBundles/base-react-app/src/components/layouts/card-layout.tsx +29 -0
  36. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/alert.tsx +76 -0
  37. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/badge.tsx +48 -0
  38. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/breadcrumb.tsx +109 -0
  39. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/button.tsx +67 -0
  40. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/calendar.tsx +232 -0
  41. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/card.tsx +103 -0
  42. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/checkbox.tsx +32 -0
  43. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/collapsible.tsx +33 -0
  44. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/datePicker.tsx +127 -0
  45. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/dialog.tsx +162 -0
  46. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/field.tsx +237 -0
  47. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/index.ts +84 -0
  48. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/input.tsx +19 -0
  49. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/label.tsx +22 -0
  50. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/pagination.tsx +132 -0
  51. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/popover.tsx +89 -0
  52. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/select.tsx +193 -0
  53. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/separator.tsx +26 -0
  54. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/skeleton.tsx +14 -0
  55. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/sonner.tsx +20 -0
  56. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/spinner.tsx +16 -0
  57. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/table.tsx +114 -0
  58. package/src/force-app/main/default/uiBundles/base-react-app/src/components/ui/tabs.tsx +88 -0
  59. package/src/force-app/main/default/uiBundles/base-react-app/src/lib/utils.ts +6 -0
  60. package/src/force-app/main/default/uiBundles/base-react-app/src/navigationMenu.tsx +80 -0
  61. package/src/force-app/main/default/uiBundles/base-react-app/src/pages/Home.tsx +12 -0
  62. package/src/force-app/main/default/uiBundles/base-react-app/src/pages/NotFound.tsx +18 -0
  63. package/src/force-app/main/default/uiBundles/base-react-app/src/router-utils.tsx +35 -0
  64. package/src/force-app/main/default/uiBundles/base-react-app/src/routes.tsx +22 -0
  65. package/src/force-app/main/default/uiBundles/base-react-app/src/styles/global.css +135 -0
  66. package/src/force-app/main/default/uiBundles/base-react-app/tsconfig.json +42 -0
  67. package/src/force-app/main/default/uiBundles/base-react-app/tsconfig.node.json +13 -0
  68. package/src/force-app/main/default/uiBundles/base-react-app/ui-bundle.json +7 -0
  69. package/src/force-app/main/default/uiBundles/base-react-app/vite-env.d.ts +1 -0
  70. package/src/force-app/main/default/uiBundles/base-react-app/vite.config.ts +106 -0
  71. package/src/force-app/main/default/uiBundles/base-react-app/vitest-env.d.ts +2 -0
  72. package/src/force-app/main/default/uiBundles/base-react-app/vitest.config.ts +11 -0
  73. package/src/force-app/main/default/uiBundles/base-react-app/vitest.setup.ts +1 -0
@@ -0,0 +1,76 @@
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
+ "grid gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 w-full relative group/alert",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: 'bg-card text-card-foreground',
12
+ destructive:
13
+ 'text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current',
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: 'default',
18
+ },
19
+ }
20
+ );
21
+
22
+ function Alert({
23
+ className,
24
+ variant,
25
+ ...props
26
+ }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {
27
+ return (
28
+ <div
29
+ data-slot="alert"
30
+ role="alert"
31
+ className={cn(alertVariants({ variant }), className)}
32
+ {...props}
33
+ />
34
+ );
35
+ }
36
+
37
+ function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
38
+ return (
39
+ <div
40
+ data-slot="alert-title"
41
+ className={cn(
42
+ 'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3',
43
+ className
44
+ )}
45
+ {...props}
46
+ />
47
+ );
48
+ }
49
+
50
+ function AlertDescription({
51
+ className,
52
+ ...props
53
+ }: React.ComponentProps<'div'>) {
54
+ return (
55
+ <div
56
+ data-slot="alert-description"
57
+ className={cn(
58
+ 'text-muted-foreground text-sm text-balance md:text-pretty [&_p:not(:last-child)]:mb-4 [&_a]:hover:text-foreground [&_a]:underline [&_a]:underline-offset-3',
59
+ className
60
+ )}
61
+ {...props}
62
+ />
63
+ );
64
+ }
65
+
66
+ function AlertAction({ className, ...props }: React.ComponentProps<'div'>) {
67
+ return (
68
+ <div
69
+ data-slot="alert-action"
70
+ className={cn('absolute top-2 right-2', className)}
71
+ {...props}
72
+ />
73
+ );
74
+ }
75
+
76
+ export { Alert, AlertTitle, AlertDescription, AlertAction };
@@ -0,0 +1,48 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { Slot } from 'radix-ui';
4
+
5
+ import { cn } from '@/lib/utils';
6
+
7
+ const badgeVariants = cva(
8
+ 'inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3',
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: 'bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
13
+ secondary:
14
+ 'bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
15
+ destructive:
16
+ 'bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90',
17
+ outline:
18
+ 'border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
19
+ ghost: '[a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
20
+ link: 'text-primary underline-offset-4 [a&]:hover:underline',
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: 'default',
25
+ },
26
+ }
27
+ );
28
+
29
+ function Badge({
30
+ className,
31
+ variant = 'default',
32
+ asChild = false,
33
+ ...props
34
+ }: React.ComponentProps<'span'> &
35
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
36
+ const Comp = asChild ? Slot.Root : 'span';
37
+
38
+ return (
39
+ <Comp
40
+ data-slot="badge"
41
+ data-variant={variant}
42
+ className={cn(badgeVariants({ variant }), className)}
43
+ {...props}
44
+ />
45
+ );
46
+ }
47
+
48
+ export { Badge, badgeVariants };
@@ -0,0 +1,109 @@
1
+ import * as React from 'react';
2
+ import { ChevronRight, MoreHorizontal } from 'lucide-react';
3
+ import { Slot } from 'radix-ui';
4
+
5
+ import { cn } from '@/lib/utils';
6
+
7
+ function Breadcrumb({ ...props }: React.ComponentProps<'nav'>) {
8
+ return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />;
9
+ }
10
+
11
+ function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {
12
+ return (
13
+ <ol
14
+ data-slot="breadcrumb-list"
15
+ className={cn(
16
+ 'flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5',
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ );
22
+ }
23
+
24
+ function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {
25
+ return (
26
+ <li
27
+ data-slot="breadcrumb-item"
28
+ className={cn('inline-flex items-center gap-1.5', className)}
29
+ {...props}
30
+ />
31
+ );
32
+ }
33
+
34
+ function BreadcrumbLink({
35
+ asChild,
36
+ className,
37
+ ...props
38
+ }: React.ComponentProps<'a'> & {
39
+ asChild?: boolean;
40
+ }) {
41
+ const Comp = asChild ? Slot.Root : 'a';
42
+
43
+ return (
44
+ <Comp
45
+ data-slot="breadcrumb-link"
46
+ className={cn('transition-colors hover:text-foreground', className)}
47
+ {...props}
48
+ />
49
+ );
50
+ }
51
+
52
+ function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
53
+ return (
54
+ <span
55
+ data-slot="breadcrumb-page"
56
+ role="link"
57
+ aria-disabled="true"
58
+ aria-current="page"
59
+ className={cn('font-normal text-foreground', className)}
60
+ {...props}
61
+ />
62
+ );
63
+ }
64
+
65
+ function BreadcrumbSeparator({
66
+ children,
67
+ className,
68
+ ...props
69
+ }: React.ComponentProps<'li'>) {
70
+ return (
71
+ <li
72
+ data-slot="breadcrumb-separator"
73
+ role="presentation"
74
+ aria-hidden="true"
75
+ className={cn('[&>svg]:size-3.5', className)}
76
+ {...props}
77
+ >
78
+ {children ?? <ChevronRight />}
79
+ </li>
80
+ );
81
+ }
82
+
83
+ function BreadcrumbEllipsis({
84
+ className,
85
+ ...props
86
+ }: React.ComponentProps<'span'>) {
87
+ return (
88
+ <span
89
+ data-slot="breadcrumb-ellipsis"
90
+ role="presentation"
91
+ aria-hidden="true"
92
+ className={cn('flex size-9 items-center justify-center', className)}
93
+ {...props}
94
+ >
95
+ <MoreHorizontal className="size-4" />
96
+ <span className="sr-only">More</span>
97
+ </span>
98
+ );
99
+ }
100
+
101
+ export {
102
+ Breadcrumb,
103
+ BreadcrumbList,
104
+ BreadcrumbItem,
105
+ BreadcrumbLink,
106
+ BreadcrumbPage,
107
+ BreadcrumbSeparator,
108
+ BreadcrumbEllipsis,
109
+ };
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { Slot } from 'radix-ui';
4
+
5
+ import { cn } from '../../lib/utils';
6
+
7
+ const buttonVariants = cva(
8
+ "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 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',
13
+ outline:
14
+ 'border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground',
15
+ secondary:
16
+ 'bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',
17
+ ghost:
18
+ 'hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground',
19
+ destructive:
20
+ 'bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30',
21
+ link: 'text-primary underline-offset-4 hover:underline',
22
+ },
23
+ size: {
24
+ default:
25
+ 'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',
26
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
27
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
28
+ lg: 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3',
29
+ icon: 'size-8',
30
+ 'icon-xs':
31
+ "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
32
+ 'icon-sm':
33
+ 'size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg',
34
+ 'icon-lg': 'size-9',
35
+ },
36
+ },
37
+ defaultVariants: {
38
+ variant: 'default',
39
+ size: 'default',
40
+ },
41
+ }
42
+ );
43
+
44
+ function Button({
45
+ className,
46
+ variant = 'default',
47
+ size = 'default',
48
+ asChild = false,
49
+ ...props
50
+ }: React.ComponentProps<'button'> &
51
+ VariantProps<typeof buttonVariants> & {
52
+ asChild?: boolean;
53
+ }) {
54
+ const Comp = asChild ? Slot.Root : 'button';
55
+
56
+ return (
57
+ <Comp
58
+ data-slot="button"
59
+ data-variant={variant}
60
+ data-size={size}
61
+ className={cn(buttonVariants({ variant, size, className }))}
62
+ {...(props as any)}
63
+ />
64
+ );
65
+ }
66
+
67
+ export { Button, buttonVariants };
@@ -0,0 +1,232 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import {
5
+ DayPicker,
6
+ getDefaultClassNames,
7
+ type DayButton,
8
+ type Locale,
9
+ } from 'react-day-picker';
10
+
11
+ import { cn } from '@/lib/utils';
12
+ import { Button, buttonVariants } from '@/components/ui/button';
13
+ import {
14
+ ChevronLeftIcon,
15
+ ChevronRightIcon,
16
+ ChevronDownIcon,
17
+ } from 'lucide-react';
18
+
19
+ function Calendar({
20
+ className,
21
+ classNames,
22
+ showOutsideDays = true,
23
+ captionLayout = 'label',
24
+ buttonVariant = 'ghost',
25
+ locale,
26
+ formatters,
27
+ components,
28
+ ...props
29
+ }: React.ComponentProps<typeof DayPicker> & {
30
+ buttonVariant?: React.ComponentProps<typeof Button>['variant'];
31
+ }) {
32
+ const defaultClassNames = getDefaultClassNames();
33
+
34
+ return (
35
+ <DayPicker
36
+ showOutsideDays={showOutsideDays}
37
+ className={cn(
38
+ 'p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] group/calendar bg-background in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent',
39
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
40
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
41
+ className
42
+ )}
43
+ captionLayout={captionLayout}
44
+ locale={locale}
45
+ formatters={{
46
+ formatMonthDropdown: date =>
47
+ date.toLocaleString(locale?.code, { month: 'short' }),
48
+ ...formatters,
49
+ }}
50
+ classNames={{
51
+ root: cn('w-fit', defaultClassNames.root),
52
+ months: cn(
53
+ 'relative flex flex-col gap-4 md:flex-row',
54
+ defaultClassNames.months
55
+ ),
56
+ month: cn('flex w-full flex-col gap-4', defaultClassNames.month),
57
+ nav: cn(
58
+ 'absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1',
59
+ defaultClassNames.nav
60
+ ),
61
+ button_previous: cn(
62
+ buttonVariants({ variant: buttonVariant }),
63
+ 'size-(--cell-size) p-0 select-none aria-disabled:opacity-50',
64
+ defaultClassNames.button_previous
65
+ ),
66
+ button_next: cn(
67
+ buttonVariants({ variant: buttonVariant }),
68
+ 'size-(--cell-size) p-0 select-none aria-disabled:opacity-50',
69
+ defaultClassNames.button_next
70
+ ),
71
+ month_caption: cn(
72
+ 'flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)',
73
+ defaultClassNames.month_caption
74
+ ),
75
+ dropdowns: cn(
76
+ 'flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium',
77
+ defaultClassNames.dropdowns
78
+ ),
79
+ dropdown_root: cn(
80
+ 'cn-calendar-dropdown-root relative rounded-(--cell-radius)',
81
+ defaultClassNames.dropdown_root
82
+ ),
83
+ dropdown: cn(
84
+ 'absolute inset-0 bg-popover opacity-0',
85
+ defaultClassNames.dropdown
86
+ ),
87
+ caption_label: cn(
88
+ 'font-medium select-none',
89
+ captionLayout === 'label'
90
+ ? 'text-sm'
91
+ : 'cn-calendar-caption-label flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground',
92
+ defaultClassNames.caption_label
93
+ ),
94
+ table: 'w-full border-collapse',
95
+ weekdays: cn('flex', defaultClassNames.weekdays),
96
+ weekday: cn(
97
+ 'flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none',
98
+ defaultClassNames.weekday
99
+ ),
100
+ week: cn('mt-2 flex w-full', defaultClassNames.week),
101
+ week_number_header: cn(
102
+ 'w-(--cell-size) select-none',
103
+ defaultClassNames.week_number_header
104
+ ),
105
+ week_number: cn(
106
+ 'text-[0.8rem] text-muted-foreground select-none',
107
+ defaultClassNames.week_number
108
+ ),
109
+ day: cn(
110
+ 'group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)',
111
+ props.showWeekNumber
112
+ ? '[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)'
113
+ : '[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)',
114
+ defaultClassNames.day
115
+ ),
116
+ range_start: cn(
117
+ 'relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted',
118
+ defaultClassNames.range_start
119
+ ),
120
+ range_middle: cn('rounded-none', defaultClassNames.range_middle),
121
+ range_end: cn(
122
+ 'relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted',
123
+ defaultClassNames.range_end
124
+ ),
125
+ today: cn(
126
+ 'rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none',
127
+ defaultClassNames.today
128
+ ),
129
+ outside: cn(
130
+ 'text-muted-foreground aria-selected:text-muted-foreground',
131
+ defaultClassNames.outside
132
+ ),
133
+ disabled: cn(
134
+ 'text-muted-foreground opacity-50',
135
+ defaultClassNames.disabled
136
+ ),
137
+ hidden: cn('invisible', defaultClassNames.hidden),
138
+ ...classNames,
139
+ }}
140
+ components={{
141
+ Root: ({ className, rootRef, ...props }) => {
142
+ return (
143
+ <div
144
+ data-slot="calendar"
145
+ ref={rootRef}
146
+ className={cn(className)}
147
+ {...props}
148
+ />
149
+ );
150
+ },
151
+ Chevron: ({ className, orientation, ...props }) => {
152
+ if (orientation === 'left') {
153
+ return (
154
+ <ChevronLeftIcon
155
+ className={cn('cn-rtl-flip size-4', className)}
156
+ {...props}
157
+ />
158
+ );
159
+ }
160
+
161
+ if (orientation === 'right') {
162
+ return (
163
+ <ChevronRightIcon
164
+ className={cn('cn-rtl-flip size-4', className)}
165
+ {...props}
166
+ />
167
+ );
168
+ }
169
+
170
+ return (
171
+ <ChevronDownIcon className={cn('size-4', className)} {...props} />
172
+ );
173
+ },
174
+ DayButton: ({ ...props }) => (
175
+ <CalendarDayButton locale={locale} {...props} />
176
+ ),
177
+ WeekNumber: ({ children, ...props }) => {
178
+ return (
179
+ <td {...props}>
180
+ <div className="flex size-(--cell-size) items-center justify-center text-center">
181
+ {children}
182
+ </div>
183
+ </td>
184
+ );
185
+ },
186
+ ...components,
187
+ }}
188
+ {...props}
189
+ />
190
+ );
191
+ }
192
+
193
+ function CalendarDayButton({
194
+ className,
195
+ day,
196
+ modifiers,
197
+ locale,
198
+ ...props
199
+ }: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {
200
+ const defaultClassNames = getDefaultClassNames();
201
+
202
+ const ref = React.useRef<HTMLButtonElement>(null);
203
+ React.useEffect(() => {
204
+ if (modifiers.focused) ref.current?.focus();
205
+ }, [modifiers.focused]);
206
+
207
+ return (
208
+ <Button
209
+ ref={ref}
210
+ variant="ghost"
211
+ size="icon"
212
+ data-day={day.date.toLocaleDateString(locale?.code)}
213
+ data-selected-single={
214
+ modifiers.selected &&
215
+ !modifiers.range_start &&
216
+ !modifiers.range_end &&
217
+ !modifiers.range_middle
218
+ }
219
+ data-range-start={modifiers.range_start}
220
+ data-range-end={modifiers.range_end}
221
+ data-range-middle={modifiers.range_middle}
222
+ className={cn(
223
+ 'relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-r-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-l-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70',
224
+ defaultClassNames.day,
225
+ className
226
+ )}
227
+ {...props}
228
+ />
229
+ );
230
+ }
231
+
232
+ export { Calendar, CalendarDayButton };
@@ -0,0 +1,103 @@
1
+ import * as React from 'react';
2
+
3
+ import { cn } from '../../lib/utils';
4
+
5
+ function Card({
6
+ className,
7
+ size = 'default',
8
+ ...props
9
+ }: React.ComponentProps<'div'> & { size?: 'default' | 'sm' }) {
10
+ return (
11
+ <div
12
+ data-slot="card"
13
+ data-size={size}
14
+ className={cn(
15
+ 'ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col',
16
+ className
17
+ )}
18
+ {...props}
19
+ />
20
+ );
21
+ }
22
+
23
+ function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
24
+ return (
25
+ <div
26
+ data-slot="card-header"
27
+ className={cn(
28
+ 'gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]',
29
+ className
30
+ )}
31
+ {...props}
32
+ />
33
+ );
34
+ }
35
+
36
+ function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
37
+ return (
38
+ <div
39
+ data-slot="card-title"
40
+ className={cn(
41
+ 'text-base leading-snug font-medium group-data-[size=sm]/card:text-sm',
42
+ className
43
+ )}
44
+ {...props}
45
+ />
46
+ );
47
+ }
48
+
49
+ function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
50
+ return (
51
+ <div
52
+ data-slot="card-description"
53
+ className={cn('text-muted-foreground text-sm', className)}
54
+ {...props}
55
+ />
56
+ );
57
+ }
58
+
59
+ function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
60
+ return (
61
+ <div
62
+ data-slot="card-action"
63
+ className={cn(
64
+ 'col-start-2 row-span-2 row-start-1 self-start justify-self-end',
65
+ className
66
+ )}
67
+ {...props}
68
+ />
69
+ );
70
+ }
71
+
72
+ function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
73
+ return (
74
+ <div
75
+ data-slot="card-content"
76
+ className={cn('px-4 group-data-[size=sm]/card:px-3', className)}
77
+ {...props}
78
+ />
79
+ );
80
+ }
81
+
82
+ function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
83
+ return (
84
+ <div
85
+ data-slot="card-footer"
86
+ className={cn(
87
+ 'bg-muted/50 rounded-b-xl border-t p-4 group-data-[size=sm]/card:p-3 flex items-center',
88
+ className
89
+ )}
90
+ {...props}
91
+ />
92
+ );
93
+ }
94
+
95
+ export {
96
+ Card,
97
+ CardHeader,
98
+ CardFooter,
99
+ CardTitle,
100
+ CardAction,
101
+ CardDescription,
102
+ CardContent,
103
+ };
@@ -0,0 +1,32 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { Checkbox as CheckboxPrimitive } from 'radix-ui';
5
+
6
+ import { cn } from '@/lib/utils';
7
+ import { CheckIcon } from 'lucide-react';
8
+
9
+ function Checkbox({
10
+ className,
11
+ ...props
12
+ }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
13
+ return (
14
+ <CheckboxPrimitive.Root
15
+ data-slot="checkbox"
16
+ className={cn(
17
+ 'border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-[4px] border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-3 aria-invalid:ring-3 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50',
18
+ className
19
+ )}
20
+ {...props}
21
+ >
22
+ <CheckboxPrimitive.Indicator
23
+ data-slot="checkbox-indicator"
24
+ className="[&>svg]:size-3.5 grid place-content-center text-current transition-none"
25
+ >
26
+ <CheckIcon />
27
+ </CheckboxPrimitive.Indicator>
28
+ </CheckboxPrimitive.Root>
29
+ );
30
+ }
31
+
32
+ export { Checkbox };