@catalystsoftware/ui 1.0.4 → 1.0.5
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/data/tailwind.config.js +261 -3821
- package/dist/components/catalyst-ui/buttons/burger.tsx +207 -0
- package/dist/components/catalyst-ui/core/data-display/timeline.tsx +210 -0
- package/dist/components/catalyst-ui/core/feedback/alert.tsx +491 -0
- package/dist/components/catalyst-ui/core/feedback/spinner-1.tsx +65 -0
- package/dist/components/catalyst-ui/core/feedback/toast.tsx +1857 -0
- package/dist/components/catalyst-ui/core/navigation/menu.tsx +164 -0
- package/dist/components/catalyst-ui/forms/toggle-class.tsx +176 -0
- package/dist/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +419 -0
- package/dist/components/catalyst-ui/hooks/use-counter.tsx +13 -0
- package/dist/components/catalyst-ui/hooks/use-event-listener.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-export-markdown.tsx +47 -0
- package/dist/components/catalyst-ui/hooks/use-focus.tsx +17 -0
- package/dist/components/catalyst-ui/hooks/use-interval.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-is-client.tsx +16 -0
- package/dist/components/catalyst-ui/hooks/use-media-query.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-mobile.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-resize-observer.tsx +81 -0
- package/dist/components/catalyst-ui/hooks/use-timeout.tsx +21 -0
- package/dist/components/catalyst-ui/hooks/use-timer.tsx +209 -0
- package/dist/components/catalyst-ui/hooks/use-toggle.tsx +12 -0
- package/dist/components/catalyst-ui/media/image.tsx +13 -0
- package/dist/components/catalyst-ui/overlays/dual-sidebar.tsx +4142 -0
- package/dist/components/catalyst-ui/overlays/sidebar-original.tsx +726 -0
- package/dist/components/catalyst-ui/primitives/accordion.tsx +250 -0
- package/dist/components/catalyst-ui/primitives/alert-dialog.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/aspect-ratio.tsx +9 -0
- package/dist/components/catalyst-ui/primitives/avatar.tsx +296 -0
- package/dist/components/catalyst-ui/primitives/badge.tsx +57 -0
- package/dist/components/catalyst-ui/primitives/breadcrumb.tsx +101 -0
- package/dist/components/catalyst-ui/primitives/button.tsx +265 -0
- package/dist/components/catalyst-ui/primitives/calendar-v4.tsx +208 -0
- package/dist/components/catalyst-ui/primitives/calendar.tsx +295 -0
- package/dist/components/catalyst-ui/primitives/card.tsx +618 -0
- package/dist/components/catalyst-ui/primitives/carousel.tsx +238 -0
- package/dist/components/catalyst-ui/primitives/chart.tsx +347 -0
- package/dist/components/catalyst-ui/primitives/checkbox.tsx +225 -0
- package/dist/components/catalyst-ui/primitives/collapsible.tsx +212 -0
- package/dist/components/catalyst-ui/primitives/command.tsx +393 -0
- package/dist/components/catalyst-ui/primitives/context-menu.tsx +236 -0
- package/dist/components/catalyst-ui/primitives/dialog.tsx +471 -0
- package/dist/components/catalyst-ui/primitives/drawer.tsx +761 -0
- package/dist/components/catalyst-ui/primitives/dropdown-menu.tsx +290 -0
- package/dist/components/catalyst-ui/primitives/empty.tsx +104 -0
- package/dist/components/catalyst-ui/primitives/field.tsx +244 -0
- package/dist/components/catalyst-ui/primitives/hover-card.tsx +124 -0
- package/dist/components/catalyst-ui/primitives/input-otp.tsx +76 -0
- package/dist/components/catalyst-ui/primitives/input.tsx +64 -0
- package/dist/components/catalyst-ui/primitives/item.tsx +196 -0
- package/dist/components/catalyst-ui/primitives/kbd.tsx +75 -0
- package/dist/components/catalyst-ui/primitives/label.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/navigation-menu.tsx +150 -0
- package/dist/components/catalyst-ui/primitives/pagination.tsx +198 -0
- package/dist/components/catalyst-ui/primitives/popover.tsx +232 -0
- package/dist/components/catalyst-ui/primitives/progress.tsx +34 -0
- package/dist/components/catalyst-ui/primitives/radio-group.tsx +43 -0
- package/dist/components/catalyst-ui/primitives/resizable.tsx +56 -0
- package/dist/components/catalyst-ui/primitives/select.tsx +155 -0
- package/dist/components/catalyst-ui/primitives/separator.tsx +74 -0
- package/dist/components/catalyst-ui/primitives/sheet.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/skeleton.tsx +15 -0
- package/dist/components/catalyst-ui/primitives/slider.tsx +27 -0
- package/dist/components/catalyst-ui/primitives/switch.tsx +187 -0
- package/dist/components/catalyst-ui/primitives/tabs.tsx +335 -0
- package/dist/components/catalyst-ui/primitives/textarea.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/toggle-group.tsx +55 -0
- package/dist/components/catalyst-ui/primitives/toggle.tsx +42 -0
- package/dist/components/catalyst-ui/primitives/tooltip.tsx +116 -0
- package/dist/components/catalyst-ui/utils/basic-auth.tsx +40 -0
- package/dist/components/catalyst-ui/utils/context-storage.tsx +19 -0
- package/dist/components/catalyst-ui/utils/cors-middleware.tsx +71 -0
- package/dist/components/catalyst-ui/utils/deferred-content.tsx +595 -0
- package/dist/components/catalyst-ui/utils/honeypot-middleware.tsx +38 -0
- package/dist/components/catalyst-ui/utils/incId.tsx +75 -0
- package/dist/components/catalyst-ui/utils/jwk-auth.tsx +36 -0
- package/dist/components/catalyst-ui/utils/request-id.tsx +14 -0
- package/dist/components/catalyst-ui/utils/secure-headers.tsx +37 -0
- package/dist/components/catalyst-ui/utils/server-timing.tsx +23 -0
- package/dist/components/catalyst-ui/utils/utils.ts +43 -0
- package/dist/components/catalyst-ui/utils/with-cookie.tsx +43 -0
- package/dist/components/catalyst-ui/x/accordian-x.tsx +428 -0
- package/dist/components/catalyst-ui/x/alert-x.tsx +413 -0
- package/dist/components/catalyst-ui/x/animated-text-x.tsx +2242 -0
- package/dist/components/catalyst-ui/x/avatar-x.tsx +515 -0
- package/dist/components/catalyst-ui/x/badge-x.tsx +670 -0
- package/dist/components/catalyst-ui/x/button-X.tsx +2857 -0
- package/dist/components/catalyst-ui/x/button-group-x.tsx +847 -0
- package/dist/components/catalyst-ui/x/calendar-x.tsx +1910 -0
- package/dist/components/catalyst-ui/x/card-x.tsx +2597 -0
- package/dist/components/catalyst-ui/x/checkbox-x.tsx +656 -0
- package/dist/components/catalyst-ui/x/collapsible-x.tsx +1360 -0
- package/dist/components/catalyst-ui/x/combobox-x.tsx +911 -0
- package/dist/components/catalyst-ui/x/data-table-x.tsx +1753 -0
- package/dist/components/catalyst-ui/x/date-picker-x.tsx +648 -0
- package/dist/components/catalyst-ui/x/dialog-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/dropdown-menu-x.tsx +612 -0
- package/dist/components/catalyst-ui/x/hover-card-x.tsx +375 -0
- package/dist/components/catalyst-ui/x/icon-x.tsx +840 -0
- package/dist/components/catalyst-ui/x/input-mask-x.tsx +981 -0
- package/dist/components/catalyst-ui/x/input-otp-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/loader-x.tsx +1757 -0
- package/dist/components/catalyst-ui/x/pagination-x.tsx +622 -0
- package/dist/components/catalyst-ui/x/popover-x.tsx +744 -0
- package/dist/components/catalyst-ui/x/radio-group-x.tsx +499 -0
- package/dist/components/catalyst-ui/x/select-x.tsx +1127 -0
- package/dist/components/catalyst-ui/x/sheet-x.tsx +668 -0
- package/dist/components/catalyst-ui/x/switch-x.tsx +681 -0
- package/dist/components/catalyst-ui/x/table-x.tsx +574 -0
- package/dist/components/catalyst-ui/x/tabs-x.tsx +839 -0
- package/dist/components/catalyst-ui/x/textarea-x.tsx +1263 -0
- package/dist/components/catalyst-ui/x/tooltip-x.tsx +396 -0
- package/dist/components/catalyst-ui/x/tracker-x.tsx +560 -0
- package/dist/data/bg-data.tsx +901 -0
- package/dist/data/buttons-data.tsx +2327 -0
- package/dist/data/charts-data.tsx +102 -0
- package/dist/data/chat-data.tsx +83 -0
- package/dist/data/code-data.tsx +1040 -0
- package/dist/data/comboboxes-data.tsx +1843 -0
- package/dist/data/command-data.tsx +1381 -0
- package/dist/data/core-data.tsx +15953 -0
- package/dist/data/crm-data.tsx +47 -0
- package/dist/data/data.tsx +159 -0
- package/dist/data/date-and-time-data.tsx +554 -0
- package/dist/data/dependencies.tsx +7 -0
- package/dist/data/ecommerce-data.tsx +1387 -0
- package/dist/data/forms-data.tsx +7890 -0
- package/dist/data/hooks-data.tsx +5487 -0
- package/dist/data/index.ts +34 -0
- package/dist/data/inputs-data.tsx +557 -0
- package/dist/data/interactive-data.tsx +5394 -0
- package/dist/data/lofi-data.tsx +18295 -0
- package/dist/data/marketing-data.tsx +2546 -0
- package/dist/data/media-data.tsx +1510 -0
- package/dist/data/motion-data.tsx +5801 -0
- package/dist/data/overlay-data.tsx +4136 -0
- package/dist/data/pdf-data.tsx +124 -0
- package/dist/data/pos-data.tsx +213 -0
- package/dist/data/postcss.config.js +6 -0
- package/dist/data/primitive-data.tsx +5170 -0
- package/dist/data/prompt-data.tsx +1226 -0
- package/dist/data/requiredLibs.ts +4 -0
- package/dist/data/sandbox-data.tsx +1 -0
- package/dist/data/sidebars-data.tsx +5421 -0
- package/dist/data/stacks-data.tsx +32 -0
- package/dist/data/table-data.tsx +706 -0
- package/dist/data/tailwind.config.js +270 -0
- package/dist/data/tailwind.config.ngin.js +3830 -0
- package/dist/data/tailwind.css +431 -0
- package/dist/data/tools-data.tsx +6910 -0
- package/dist/data/typography-data.tsx +2050 -0
- package/dist/data/utils-data.tsx +6500 -0
- package/dist/data/x-data.tsx +1171 -0
- package/dist/data.tsx +159 -0
- package/package.json +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -362
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
+
import { cn } from '~/components/catalyst-ui'
|
|
4
|
+
|
|
5
|
+
// @dev app/components/catalyst-ui/data/primitive-data.tsx:751
|
|
6
|
+
|
|
7
|
+
const badgeVariants = cva(
|
|
8
|
+
'inline-flex items-center rounded-full border border-border px-2.5 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 overflow-hidden [&>svg]:size-3',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
|
|
13
|
+
secondary: 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
14
|
+
destructive: 'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
|
|
15
|
+
outline: 'text-foreground',
|
|
16
|
+
// animated: 'relative bg-background text-foreground font-normal gap-1 justify-center px-2 py-0.5 [a&]:hover:bg-accent [a&]:hover:text-accent-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
|
17
|
+
dot: 'inline-flex gap-1 px-2 py-0.5 border-transparent bg-transparent',
|
|
18
|
+
rounded: 'rounded-sm',
|
|
19
|
+
number: 'h-5 min-w-5 px-1 tabular-nums',
|
|
20
|
+
large: 'px-3 py-1',
|
|
21
|
+
small: 'px-1.5 py-px',
|
|
22
|
+
'with-icon': '',
|
|
23
|
+
link: 'focus-visible:ring-ring/50 focus-visible:ring-2 focus-visible:outline-0',
|
|
24
|
+
closable: '',
|
|
25
|
+
selectable: 'has-focus-visible:border-ring/50 has-focus-visible:ring-ring/50 relative cursor-pointer rounded-sm outline-none has-focus-visible:ring-2',
|
|
26
|
+
gradient: 'rounded-sm border-transparent bg-gradient-to-r from-indigo-500 to-pink-500 [background-size:105%] bg-center text-white',
|
|
27
|
+
'gradient-outline': 'bg-background hover:bg-background text-foreground border-none',
|
|
28
|
+
'in-progress': 'border-none bg-amber-600/10 text-amber-600 focus-visible:ring-amber-600/20 focus-visible:outline-none dark:bg-amber-400/10 dark:text-amber-400 dark:focus-visible:ring-amber-400/40 [a&]:hover:bg-amber-600/5 dark:[a&]:hover:bg-amber-400/5',
|
|
29
|
+
blocked: 'bg-destructive/10 [a&]:hover:bg-destructive/5 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive border-none focus-visible:outline-none',
|
|
30
|
+
completed: 'border-none bg-green-600/10 text-green-600 focus-visible:ring-green-600/20 focus-visible:outline-none dark:bg-green-400/10 dark:text-green-400 dark:focus-visible:ring-green-400/40 [a&]:hover:bg-green-600/5 dark:[a&]:hover:bg-green-400/5',
|
|
31
|
+
pending: 'rounded-sm border-amber-600 text-amber-600 dark:border-amber-400 dark:text-amber-400 [a&]:hover:bg-amber-600/10 [a&]:hover:text-amber-600/90 dark:[a&]:hover:bg-amber-400/10 dark:[a&]:hover:text-amber-400/90',
|
|
32
|
+
failed: 'text-destructive [a&]:hover:bg-destructive/10 [a&]:hover:text-destructive/90 border-destructive rounded-sm',
|
|
33
|
+
successful: 'rounded-sm border-green-600 text-green-600 dark:border-green-400 dark:text-green-400 [a&]:hover:bg-green-600/10 [a&]:hover:text-green-600/90 dark:[a&]:hover:bg-green-400/10 dark:[a&]:hover:text-green-400/90',
|
|
34
|
+
avatar: 'p-1 pr-2',
|
|
35
|
+
cart: 'absolute -top-2.5 -right-2.5 h-5 min-w-5 px-1 tabular-nums',
|
|
36
|
+
'status-online': 'border-background absolute -right-0.5 -bottom-0.5 size-3 rounded-full border-2 bg-green-600 dark:bg-green-400',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
defaultVariants: {
|
|
40
|
+
variant: 'default',
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
export interface BadgeProps
|
|
45
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
46
|
+
VariantProps<typeof badgeVariants> {}
|
|
47
|
+
|
|
48
|
+
function Badge({ className, variant, children, ...props }: BadgeProps) {
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className={cn(badgeVariants({ variant }), "overflow-hidden", className)} {...props}>
|
|
52
|
+
{children}
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { Badge, badgeVariants }
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { ChevronRight, MoreHorizontal } from 'lucide-react'
|
|
3
|
+
import { cn } from '~/components/catalyst-ui'
|
|
4
|
+
|
|
5
|
+
// @dev app/components/catalyst-ui/data/primitive-data.tsx:1054
|
|
6
|
+
|
|
7
|
+
const Breadcrumb = React.forwardRef<
|
|
8
|
+
HTMLElement,
|
|
9
|
+
React.ComponentPropsWithoutRef<'nav'> & {
|
|
10
|
+
separator?: React.ComponentType<{ className?: string }>
|
|
11
|
+
}
|
|
12
|
+
>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
|
|
13
|
+
Breadcrumb.displayName = 'Breadcrumb'
|
|
14
|
+
|
|
15
|
+
const BreadcrumbList = React.forwardRef<
|
|
16
|
+
HTMLOListElement,
|
|
17
|
+
React.ComponentPropsWithoutRef<'ol'>
|
|
18
|
+
>(({ className, ...props }, ref) => (
|
|
19
|
+
<ol
|
|
20
|
+
ref={ref}
|
|
21
|
+
className={cn(
|
|
22
|
+
'flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5',
|
|
23
|
+
className
|
|
24
|
+
)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
))
|
|
28
|
+
BreadcrumbList.displayName = 'BreadcrumbList'
|
|
29
|
+
|
|
30
|
+
const BreadcrumbItem = React.forwardRef<
|
|
31
|
+
HTMLLIElement,
|
|
32
|
+
React.ComponentPropsWithoutRef<'li'>
|
|
33
|
+
>(({ className, ...props }, ref) => (
|
|
34
|
+
<li
|
|
35
|
+
ref={ref}
|
|
36
|
+
className={cn('inline-flex items-center gap-1.5', className)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
))
|
|
40
|
+
BreadcrumbItem.displayName = 'BreadcrumbItem'
|
|
41
|
+
|
|
42
|
+
const BreadcrumbLink = React.forwardRef<
|
|
43
|
+
HTMLAnchorElement,
|
|
44
|
+
React.ComponentPropsWithoutRef<'a'>
|
|
45
|
+
>(({ className, ...props }, ref) => (
|
|
46
|
+
<a
|
|
47
|
+
ref={ref}
|
|
48
|
+
className={cn('transition-colors hover:text-foreground', className)}
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
))
|
|
52
|
+
BreadcrumbLink.displayName = 'BreadcrumbLink'
|
|
53
|
+
|
|
54
|
+
const BreadcrumbPage = React.forwardRef<
|
|
55
|
+
HTMLSpanElement,
|
|
56
|
+
React.ComponentPropsWithoutRef<'span'>
|
|
57
|
+
>(({ className, ...props }, ref) => (
|
|
58
|
+
<span
|
|
59
|
+
ref={ref}
|
|
60
|
+
role="link"
|
|
61
|
+
aria-disabled="true"
|
|
62
|
+
aria-current="page"
|
|
63
|
+
className={cn('font-normal text-foreground', className)}
|
|
64
|
+
{...props}
|
|
65
|
+
/>
|
|
66
|
+
))
|
|
67
|
+
BreadcrumbPage.displayName = 'BreadcrumbPage'
|
|
68
|
+
|
|
69
|
+
const BreadcrumbSeparator = ({
|
|
70
|
+
children,
|
|
71
|
+
className,
|
|
72
|
+
...props
|
|
73
|
+
}: React.ComponentProps<'li'>) => (
|
|
74
|
+
<li
|
|
75
|
+
role="presentation"
|
|
76
|
+
aria-hidden="true"
|
|
77
|
+
className={cn('[&>svg]:size-3.5', className)}
|
|
78
|
+
{...props}
|
|
79
|
+
>
|
|
80
|
+
{children ?? <ChevronRight />}
|
|
81
|
+
</li>
|
|
82
|
+
)
|
|
83
|
+
BreadcrumbSeparator.displayName = 'BreadcrumbSeparator'
|
|
84
|
+
|
|
85
|
+
const BreadcrumbEllipsis = ({
|
|
86
|
+
className,
|
|
87
|
+
...props
|
|
88
|
+
}: React.ComponentProps<'span'>) => (
|
|
89
|
+
<span
|
|
90
|
+
role="presentation"
|
|
91
|
+
aria-hidden="true"
|
|
92
|
+
className={cn('flex h-9 w-9 items-center justify-center', className)}
|
|
93
|
+
{...props}
|
|
94
|
+
>
|
|
95
|
+
<MoreHorizontal className="h-4 w-4" />
|
|
96
|
+
<span className="sr-only">More</span>
|
|
97
|
+
</span>
|
|
98
|
+
)
|
|
99
|
+
BreadcrumbEllipsis.displayName = 'BreadcrumbElipssis'
|
|
100
|
+
|
|
101
|
+
export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis,}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
+
import { cn } from '~/components/catalyst-ui'
|
|
4
|
+
import { Slot } from "@radix-ui/react-slot"
|
|
5
|
+
import { Link, useNavigation, useResolvedPath } from '@remix-run/react';
|
|
6
|
+
import { SpinnerV4 } from '~/components/catalyst-ui'
|
|
7
|
+
|
|
8
|
+
// @dev app/components/catalyst-ui/data/primitive-data.tsx:2485
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
### BUTTON
|
|
12
|
+
##### ---------- PROPS ----------
|
|
13
|
+
- **className**
|
|
14
|
+
- **variant**
|
|
15
|
+
- **size**
|
|
16
|
+
- **align**
|
|
17
|
+
- **effect**
|
|
18
|
+
- **icon**: Icon
|
|
19
|
+
- **iconPlacement**: "left"
|
|
20
|
+
- **prefetch**: "intent"
|
|
21
|
+
- **to**: "/"
|
|
22
|
+
- **nav**: null
|
|
23
|
+
- **newTab**: true
|
|
24
|
+
- **asChild**: false
|
|
25
|
+
- **type**: null
|
|
26
|
+
- **children**:
|
|
27
|
+
- **...props**:
|
|
28
|
+
*
|
|
29
|
+
##### ---------- BASIC USAGE ----------
|
|
30
|
+
```jsx
|
|
31
|
+
<Button>
|
|
32
|
+
Click Me
|
|
33
|
+
</Button>
|
|
34
|
+
```
|
|
35
|
+
##### ---------- USAGE ----------
|
|
36
|
+
```jsx
|
|
37
|
+
<Button
|
|
38
|
+
variant="styled" // default | destructive | outline | secondary | ghost | link | elevated | filled | tonal | outlined | text | styled | reverted | dashed | gradient | soft | glass | success | warning | info | shine | pulse
|
|
39
|
+
size="default" // default | sm | lg | icon
|
|
40
|
+
align="middle" // left | middle | right
|
|
41
|
+
effect="hoverUnderline" // expandIcon | ringHover | shine | shineHover | gooeyRight | gooeyLeft | underline | hoverUnderline | gradientSlideShow
|
|
42
|
+
prefetch="intent" // none | intent | render | viewport
|
|
43
|
+
nav='null' // anchor | navlink
|
|
44
|
+
to='/'
|
|
45
|
+
iconPlacement="left" // left | right
|
|
46
|
+
icon={Bot}
|
|
47
|
+
newTab={true}
|
|
48
|
+
onClick={() => {
|
|
49
|
+
|
|
50
|
+
}}
|
|
51
|
+
className=""
|
|
52
|
+
>
|
|
53
|
+
Click Me
|
|
54
|
+
</Button>
|
|
55
|
+
```
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
function Button({
|
|
59
|
+
className,
|
|
60
|
+
variant,
|
|
61
|
+
size,
|
|
62
|
+
align,
|
|
63
|
+
effect,
|
|
64
|
+
icon: Icon,
|
|
65
|
+
iconPlacement = "left",
|
|
66
|
+
prefetch = "intent",
|
|
67
|
+
to = "/",
|
|
68
|
+
nav = null,
|
|
69
|
+
newTab = true,
|
|
70
|
+
asChild = false,
|
|
71
|
+
type = null,
|
|
72
|
+
children,
|
|
73
|
+
...props
|
|
74
|
+
}: React.ComponentProps<"button"> &
|
|
75
|
+
VariantProps<typeof buttonVariants> & {
|
|
76
|
+
asChild?: boolean
|
|
77
|
+
}) {
|
|
78
|
+
const Comp = asChild ? Slot : "button"
|
|
79
|
+
const n = useNavigation()
|
|
80
|
+
const resolvedTo = useResolvedPath(to);
|
|
81
|
+
const isSubmitting = n.state === 'submitting';
|
|
82
|
+
const isNavigating = n.state === 'loading' && n.location?.pathname === resolvedTo.pathname;
|
|
83
|
+
const isDisabled = isSubmitting && isNavigating;
|
|
84
|
+
let loadingText = 'Navigating...'
|
|
85
|
+
if (nav === 'navlink') {
|
|
86
|
+
return (
|
|
87
|
+
<Link
|
|
88
|
+
to={to}
|
|
89
|
+
prefetch={prefetch}
|
|
90
|
+
preventScrollReset
|
|
91
|
+
disabled={isDisabled}
|
|
92
|
+
{...props}>
|
|
93
|
+
<Comp
|
|
94
|
+
data-slot="button"
|
|
95
|
+
type={type || 'button'}
|
|
96
|
+
className={cn(buttonVariants({ variant, effect, size, align, className }))}
|
|
97
|
+
disabled={isDisabled}
|
|
98
|
+
>
|
|
99
|
+
{isNavigating ? (
|
|
100
|
+
<div className='flex items-center gap-3'>
|
|
101
|
+
<SpinnerV4 title={loadingText} subtitle='' size='icon' />
|
|
102
|
+
</div>
|
|
103
|
+
) : (
|
|
104
|
+
children
|
|
105
|
+
)}
|
|
106
|
+
</Comp>
|
|
107
|
+
</Link>
|
|
108
|
+
)
|
|
109
|
+
} else if (nav === 'anchor') {
|
|
110
|
+
const anchorProps = newTab ? {
|
|
111
|
+
target: "_blank",
|
|
112
|
+
rel: "noopener noreferrer"
|
|
113
|
+
} : {};
|
|
114
|
+
return (
|
|
115
|
+
<a
|
|
116
|
+
href={to}
|
|
117
|
+
preventScrollReset
|
|
118
|
+
disabled={isDisabled}
|
|
119
|
+
{...anchorProps}
|
|
120
|
+
>
|
|
121
|
+
<Comp
|
|
122
|
+
data-slot="button"
|
|
123
|
+
type={type || 'button'}
|
|
124
|
+
className={cn(buttonVariants({ variant, effect, size, align, className }))}
|
|
125
|
+
disabled={isDisabled}
|
|
126
|
+
{...props}
|
|
127
|
+
>
|
|
128
|
+
{isNavigating ? (
|
|
129
|
+
<div className='flex items-center gap-3'>
|
|
130
|
+
<SpinnerV4 title={loadingText} subtitle='' size='icon' />
|
|
131
|
+
</div>
|
|
132
|
+
) : (
|
|
133
|
+
children
|
|
134
|
+
)}
|
|
135
|
+
</Comp>
|
|
136
|
+
</a>
|
|
137
|
+
)
|
|
138
|
+
} else if (effect) {
|
|
139
|
+
let loadingText = 'Submitting...'
|
|
140
|
+
return (
|
|
141
|
+
<Comp
|
|
142
|
+
data-slot="button"
|
|
143
|
+
type={type || 'submit'}
|
|
144
|
+
className={cn(buttonVariants({ variant, effect, size, align, className }))}
|
|
145
|
+
{...props}
|
|
146
|
+
>
|
|
147
|
+
{Icon &&
|
|
148
|
+
iconPlacement === 'left' &&
|
|
149
|
+
(effect === 'expandIcon' ? (
|
|
150
|
+
<div className="w-0 translate-x-[0%] pr-0 opacity-0 transition-all duration-200 group-hover:w-5 group-hover:translate-x-100 group-hover:pr-2 group-hover:opacity-100">
|
|
151
|
+
<Icon />
|
|
152
|
+
</div>
|
|
153
|
+
) : (
|
|
154
|
+
<Icon />
|
|
155
|
+
))}
|
|
156
|
+
|
|
157
|
+
{isNavigating ? (
|
|
158
|
+
<div className='flex items-center gap-3'>
|
|
159
|
+
<SpinnerV4 title={loadingText} subtitle='' size='icon' />
|
|
160
|
+
</div>
|
|
161
|
+
) : (
|
|
162
|
+
children
|
|
163
|
+
)}
|
|
164
|
+
{Icon &&
|
|
165
|
+
iconPlacement === 'right' &&
|
|
166
|
+
(effect === 'expandIcon' ? (
|
|
167
|
+
<div className="w-0 translate-x-[100%] pl-0 opacity-0 transition-all duration-200 group-hover:w-5 group-hover:translate-x-0 group-hover:pl-2 group-hover:opacity-100">
|
|
168
|
+
<Icon />
|
|
169
|
+
</div>
|
|
170
|
+
) : (
|
|
171
|
+
<Icon />
|
|
172
|
+
))}
|
|
173
|
+
</Comp>
|
|
174
|
+
)
|
|
175
|
+
} else {
|
|
176
|
+
let loadingText = 'Submitting...'
|
|
177
|
+
return (
|
|
178
|
+
<Comp
|
|
179
|
+
data-slot="button"
|
|
180
|
+
type={type || 'submit'}
|
|
181
|
+
className={cn(buttonVariants({ variant, effect, size, align, className }))}
|
|
182
|
+
{...props}
|
|
183
|
+
>
|
|
184
|
+
{isNavigating ? (
|
|
185
|
+
<div className='flex items-center gap-3'>
|
|
186
|
+
<SpinnerV4 title={loadingText} subtitle='' size='icon' />
|
|
187
|
+
</div>
|
|
188
|
+
) : (
|
|
189
|
+
children
|
|
190
|
+
)}
|
|
191
|
+
</Comp>
|
|
192
|
+
)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const buttonVariants = cva(
|
|
198
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
199
|
+
{
|
|
200
|
+
variants: {
|
|
201
|
+
variant: {
|
|
202
|
+
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 rounded-full",
|
|
203
|
+
destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 rounded-full",
|
|
204
|
+
outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 rounded-md",
|
|
205
|
+
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80 rounded-full",
|
|
206
|
+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 rounded-full",
|
|
207
|
+
link: "text-primary underline-offset-4 hover:underline hover:text-foreground",
|
|
208
|
+
elevated: "bg-surface-container-low text-primary shadow-md hover:shadow-lg active:shadow-sm rounded-full",
|
|
209
|
+
filled: "bg-primary text-on-primary shadow-sm hover:shadow-md active:shadow-sm rounded-full",
|
|
210
|
+
tonal: "bg-secondary-container text-on-secondary-container hover:shadow-sm active:shadow-none rounded-full",
|
|
211
|
+
outlined: "border border-outline text-primary hover:bg-primary/8 active:bg-primary/12 rounded-full",
|
|
212
|
+
text: "text-primary hover:bg-primary/8 active:bg-primary/12 rounded-full",
|
|
213
|
+
styled: "transition duration-300 border-2 border-border w-[95%] text-center mx-auto text-primary-foreground px-6 py-3 rounded-md bg-primary hover:bg-muted",
|
|
214
|
+
reverted: "transition duration-300 border-2 border-border w-[95%] text-center mx-auto text-foreground px-6 py-3 rounded-md bg-background hover:bg-primary",
|
|
215
|
+
dashed: "transition duration-300 border-2 border-border w-[95%] text-center mx-auto text-foreground px-6 py-3 rounded-md h-8 border-dashed",
|
|
216
|
+
gradient: "bg-gradient-to-r from-primary to-primary/80 text-primary-foreground shadow-md hover:shadow-lg active:shadow-sm rounded-full",
|
|
217
|
+
soft: "bg-primary/10 text-primary hover:bg-primary/20 active:bg-primary/30 rounded-full",
|
|
218
|
+
glass: "bg-background/20 backdrop-blur-md border border-border/50 text-foreground hover:bg-background/30 rounded-full",
|
|
219
|
+
success: "bg-green-600 text-white shadow-sm hover:bg-green-700 active:shadow-none rounded-full",
|
|
220
|
+
warning: "bg-amber-600 text-white shadow-sm hover:bg-amber-700 active:shadow-none rounded-full",
|
|
221
|
+
info: "bg-blue-600 text-white shadow-sm hover:bg-blue-700 active:shadow-none rounded-full",
|
|
222
|
+
shine: "bg-primary text-primary-foreground rounded-full relative overflow-hidden before:absolute before:inset-0 before:bg-gradient-to-r before:from-transparent before:via-white/20 before:to-transparent before:-translate-x-full hover:before:translate-x-full before:transition-transform before:duration-700",
|
|
223
|
+
pulse: "bg-primary text-primary-foreground rounded-full animate-pulse hover:animate-none shadow-md hover:shadow-lg",
|
|
224
|
+
|
|
225
|
+
violet: "bg-violet-100 dark:bg-violet-900 hover:bg-violet-200 dark:hover:bg-violet-800 text-violet-600 dark:text-violet-300 border border-violet-300 dark:border-violet-700",
|
|
226
|
+
blue: "bg-blue-100 dark:bg-blue-900 hover:bg-blue-200 dark:hover:bg-blue-800 text-blue-600 dark:text-blue-300 border border-blue-300 dark:border-blue-700",
|
|
227
|
+
green: "bg-green-100 dark:bg-green-900 hover:bg-green-200 dark:hover:bg-green-800 text-green-600 dark:text-green-300 border border-green-300 dark:border-green-700",
|
|
228
|
+
default: "bg-primary/10 hover:bg-primary/20 text-primary border border-primary/30",
|
|
229
|
+
},
|
|
230
|
+
effect: {
|
|
231
|
+
expandIcon: 'group gap-0 relative',
|
|
232
|
+
ringHover: 'transition-all duration-300 hover:ring-2 hover:ring-primary/90 hover:ring-offset-2',
|
|
233
|
+
shine: 'before:animate-shine relative overflow-hidden before:absolute before:inset-0 before:rounded-[inherit] before:bg-[linear-gradient(45deg,transparent_25%,rgba(255,255,255,0.5)_50%,transparent_75%,transparent_100%)] before:bg-[length:250%_250%,100%_100%] before:bg-no-repeat background-position_0s_ease',
|
|
234
|
+
shineHover: 'relative overflow-hidden before:absolute before:inset-0 before:rounded-[inherit] before:bg-[linear-gradient(45deg,transparent_25%,rgba(255,255,255,0.5)_50%,transparent_75%,transparent_100%)] before:bg-[length:250%_250%,100%_100%] before:bg-[position:200%_0,0_0] before:bg-no-repeat before:transition-[background-position_0s_ease] hover:before:bg-[position:-100%_0,0_0] before:duration-1000',
|
|
235
|
+
gooeyRight: 'relative z-0 overflow-hidden transition-all duration-500 before:absolute before:inset-0 before:-z-10 before:translate-x-[150%] before:translate-y-[150%] before:scale-[2.5] before:rounded-[100%] before:bg-gradient-to-r from-white/40 before:transition-transform before:duration-1000 hover:before:translate-x-[0%] hover:before:translate-y-[0%]',
|
|
236
|
+
gooeyLeft: 'relative z-0 overflow-hidden transition-all duration-500 after:absolute after:inset-0 after:-z-10 after:translate-x-[-150%] after:translate-y-[150%] after:scale-[2.5] after:rounded-[100%] after:bg-gradient-to-l from-white/40 after:transition-transform after:duration-1000 hover:after:translate-x-[0%] hover:after:translate-y-[0%]',
|
|
237
|
+
underline: 'relative !no-underline after:absolute after:bg-primary after:bottom-2 after:h-[1px] after:w-2/3 after:origin-bottom-left after:scale-x-100 hover:after:origin-bottom-right hover:after:scale-x-0 after:transition-transform after:ease-in-out after:duration-300',
|
|
238
|
+
hoverUnderline: 'relative !no-underline after:absolute after:bg-primary after:bottom-2 after:h-[1px] after:w-2/3 after:origin-bottom-right after:scale-x-0 hover:after:origin-bottom-left hover:after:scale-x-100 after:transition-transform after:ease-in-out after:duration-300',
|
|
239
|
+
gradientSlideShow: 'bg-[size:400%] bg-[linear-gradient(-45deg,var(--gradient-lime),var(--gradient-ocean),var(--gradient-wine),var(--gradient-rust))] animate-gradient-flow',
|
|
240
|
+
},
|
|
241
|
+
size: {
|
|
242
|
+
default: "h-10 px-6 py-2.5 has-[>svg]:px-4",
|
|
243
|
+
sm: "h-8 rounded-full gap-1.5 px-4 has-[>svg]:px-3",
|
|
244
|
+
lg: "h-12 rounded-full px-8 has-[>svg]:px-6",
|
|
245
|
+
icon: "h-9 w-9",
|
|
246
|
+
"icon-sm": "h-8 w-8",
|
|
247
|
+
"icon-lg": "h-10 w-10",
|
|
248
|
+
},
|
|
249
|
+
align: {
|
|
250
|
+
left: "justify-start text-left",
|
|
251
|
+
middle: "justify-center text-center",
|
|
252
|
+
right: "justify-end text-right",
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
defaultVariants: {
|
|
256
|
+
variant: "default",
|
|
257
|
+
size: "default",
|
|
258
|
+
align: "middle",
|
|
259
|
+
},
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
Button.displayName = "Button"
|
|
264
|
+
|
|
265
|
+
export { Button, buttonVariants }
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, } from "lucide-react";
|
|
3
|
+
import { DayButton, DayPicker, getDefaultClassNames, } from "react-day-picker";
|
|
4
|
+
import { cn, } from "~/components/catalyst-ui";
|
|
5
|
+
import { Button, buttonVariants, } from "~/components/catalyst-ui";
|
|
6
|
+
|
|
7
|
+
// @dev app/components/catalyst-ui/data/primitive-data.tsx:1359
|
|
8
|
+
|
|
9
|
+
function CalendarV4({
|
|
10
|
+
className,
|
|
11
|
+
classNames,
|
|
12
|
+
showOutsideDays = true,
|
|
13
|
+
captionLayout = "label",
|
|
14
|
+
buttonVariant = "ghost",
|
|
15
|
+
formatters,
|
|
16
|
+
components,
|
|
17
|
+
...props
|
|
18
|
+
}: React.ComponentProps<typeof DayPicker> & {
|
|
19
|
+
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
|
|
20
|
+
}) {
|
|
21
|
+
const defaultClassNames = getDefaultClassNames()
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<DayPicker
|
|
25
|
+
showOutsideDays={showOutsideDays}
|
|
26
|
+
className={cn(
|
|
27
|
+
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
28
|
+
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
29
|
+
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
captionLayout={captionLayout}
|
|
33
|
+
formatters={{
|
|
34
|
+
formatMonthDropdown: (date) =>
|
|
35
|
+
date.toLocaleString("default", { month: "short" }),
|
|
36
|
+
...formatters,
|
|
37
|
+
}}
|
|
38
|
+
classNames={{
|
|
39
|
+
root: cn("w-fit", defaultClassNames.root),
|
|
40
|
+
months: cn(
|
|
41
|
+
"flex gap-4 flex-col md:flex-row relative",
|
|
42
|
+
defaultClassNames.months
|
|
43
|
+
),
|
|
44
|
+
month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
|
|
45
|
+
nav: cn(
|
|
46
|
+
"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
|
|
47
|
+
defaultClassNames.nav
|
|
48
|
+
),
|
|
49
|
+
button_previous: cn(
|
|
50
|
+
buttonVariants({ variant: buttonVariant }),
|
|
51
|
+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
|
52
|
+
defaultClassNames.button_previous
|
|
53
|
+
),
|
|
54
|
+
button_next: cn(
|
|
55
|
+
buttonVariants({ variant: buttonVariant }),
|
|
56
|
+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
|
57
|
+
defaultClassNames.button_next
|
|
58
|
+
),
|
|
59
|
+
month_caption: cn(
|
|
60
|
+
"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
|
|
61
|
+
defaultClassNames.month_caption
|
|
62
|
+
),
|
|
63
|
+
dropdowns: cn(
|
|
64
|
+
"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
|
|
65
|
+
defaultClassNames.dropdowns
|
|
66
|
+
),
|
|
67
|
+
dropdown_root: cn(
|
|
68
|
+
"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
|
|
69
|
+
defaultClassNames.dropdown_root
|
|
70
|
+
),
|
|
71
|
+
dropdown: cn(
|
|
72
|
+
"absolute bg-popover inset-0 opacity-0",
|
|
73
|
+
defaultClassNames.dropdown
|
|
74
|
+
),
|
|
75
|
+
caption_label: cn(
|
|
76
|
+
"select-none font-medium",
|
|
77
|
+
captionLayout === "label"
|
|
78
|
+
? "text-sm"
|
|
79
|
+
: "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
|
|
80
|
+
defaultClassNames.caption_label
|
|
81
|
+
),
|
|
82
|
+
table: "w-full border-collapse",
|
|
83
|
+
weekdays: cn("flex", defaultClassNames.weekdays),
|
|
84
|
+
weekday: cn(
|
|
85
|
+
"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
|
|
86
|
+
defaultClassNames.weekday
|
|
87
|
+
),
|
|
88
|
+
week: cn("flex w-full mt-2", defaultClassNames.week),
|
|
89
|
+
week_number_header: cn(
|
|
90
|
+
"select-none w-(--cell-size)",
|
|
91
|
+
defaultClassNames.week_number_header
|
|
92
|
+
),
|
|
93
|
+
week_number: cn(
|
|
94
|
+
"text-[0.8rem] select-none text-muted-foreground",
|
|
95
|
+
defaultClassNames.week_number
|
|
96
|
+
),
|
|
97
|
+
day: cn(
|
|
98
|
+
"relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
|
|
99
|
+
defaultClassNames.day
|
|
100
|
+
),
|
|
101
|
+
range_start: cn(
|
|
102
|
+
"rounded-l-md bg-accent",
|
|
103
|
+
defaultClassNames.range_start
|
|
104
|
+
),
|
|
105
|
+
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
|
106
|
+
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
|
|
107
|
+
today: cn(
|
|
108
|
+
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
|
|
109
|
+
defaultClassNames.today
|
|
110
|
+
),
|
|
111
|
+
outside: cn(
|
|
112
|
+
"text-muted-foreground aria-selected:text-muted-foreground",
|
|
113
|
+
defaultClassNames.outside
|
|
114
|
+
),
|
|
115
|
+
disabled: cn(
|
|
116
|
+
"text-muted-foreground opacity-50",
|
|
117
|
+
defaultClassNames.disabled
|
|
118
|
+
),
|
|
119
|
+
hidden: cn("invisible", defaultClassNames.hidden),
|
|
120
|
+
...classNames,
|
|
121
|
+
}}
|
|
122
|
+
components={{
|
|
123
|
+
Root: ({ className, rootRef, ...props }) => {
|
|
124
|
+
return (
|
|
125
|
+
<div
|
|
126
|
+
data-slot="calendar"
|
|
127
|
+
ref={rootRef}
|
|
128
|
+
className={cn(className)}
|
|
129
|
+
{...props}
|
|
130
|
+
/>
|
|
131
|
+
)
|
|
132
|
+
},
|
|
133
|
+
Chevron: ({ className, orientation, ...props }) => {
|
|
134
|
+
if (orientation === "left") {
|
|
135
|
+
return (
|
|
136
|
+
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (orientation === "right") {
|
|
141
|
+
return (
|
|
142
|
+
<ChevronRightIcon
|
|
143
|
+
className={cn("size-4", className)}
|
|
144
|
+
{...props}
|
|
145
|
+
/>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<ChevronDownIcon className={cn("size-4", className)} {...props} />
|
|
151
|
+
)
|
|
152
|
+
},
|
|
153
|
+
DayButton: CalendarDayButton,
|
|
154
|
+
WeekNumber: ({ children, ...props }) => {
|
|
155
|
+
return (
|
|
156
|
+
<td {...props}>
|
|
157
|
+
<div className="flex size-(--cell-size) items-center justify-center text-center">
|
|
158
|
+
{children}
|
|
159
|
+
</div>
|
|
160
|
+
</td>
|
|
161
|
+
)
|
|
162
|
+
},
|
|
163
|
+
...components,
|
|
164
|
+
}}
|
|
165
|
+
{...props}
|
|
166
|
+
/>
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function CalendarV4DayButton({
|
|
171
|
+
className,
|
|
172
|
+
day,
|
|
173
|
+
modifiers,
|
|
174
|
+
...props
|
|
175
|
+
}: React.ComponentProps<typeof DayButton>) {
|
|
176
|
+
const defaultClassNames = getDefaultClassNames()
|
|
177
|
+
|
|
178
|
+
const ref = React.useRef<HTMLButtonElement>(null)
|
|
179
|
+
React.useEffect(() => {
|
|
180
|
+
if (modifiers.focused) ref.current?.focus()
|
|
181
|
+
}, [modifiers.focused])
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<Button
|
|
185
|
+
ref={ref}
|
|
186
|
+
variant="ghost"
|
|
187
|
+
size="icon"
|
|
188
|
+
data-day={day.date.toLocaleDateString()}
|
|
189
|
+
data-selected-single={
|
|
190
|
+
modifiers.selected &&
|
|
191
|
+
!modifiers.range_start &&
|
|
192
|
+
!modifiers.range_end &&
|
|
193
|
+
!modifiers.range_middle
|
|
194
|
+
}
|
|
195
|
+
data-range-start={modifiers.range_start}
|
|
196
|
+
data-range-end={modifiers.range_end}
|
|
197
|
+
data-range-middle={modifiers.range_middle}
|
|
198
|
+
className={cn(
|
|
199
|
+
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70",
|
|
200
|
+
defaultClassNames.day,
|
|
201
|
+
className
|
|
202
|
+
)}
|
|
203
|
+
{...props}
|
|
204
|
+
/>
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export { CalendarV4, CalendarV4DayButton }
|