@cntyclub/ui-react 0.1.0
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/dist/chunk-HDGMSYQS.js +26461 -0
- package/dist/chunk-HDGMSYQS.js.map +1 -0
- package/dist/chunk-PR4QN5HX.js +39 -0
- package/dist/chunk-PR4QN5HX.js.map +1 -0
- package/dist/form.d.ts +175 -0
- package/dist/form.js +5207 -0
- package/dist/form.js.map +1 -0
- package/dist/index.d.ts +1462 -0
- package/dist/index.js +81862 -0
- package/dist/index.js.map +1 -0
- package/dist/input-CZvh825j.d.ts +24 -0
- package/dist/qr-code-styling-3Y6LZH6V.js +1123 -0
- package/dist/qr-code-styling-3Y6LZH6V.js.map +1 -0
- package/package.json +79 -0
- package/src/components/form/checkbox-group-field.tsx +101 -0
- package/src/components/form/date-field.tsx +79 -0
- package/src/components/form/date-range-field.tsx +106 -0
- package/src/components/form/form-context.ts +10 -0
- package/src/components/form/form.tsx +54 -0
- package/src/components/form/number-field.tsx +69 -0
- package/src/components/form/select-field.tsx +76 -0
- package/src/components/form/submit-button.tsx +28 -0
- package/src/components/form/text-field.tsx +107 -0
- package/src/components/layout/dashboard-header.tsx +54 -0
- package/src/components/layout/dashboard-panel.tsx +34 -0
- package/src/components/theme-provider.tsx +403 -0
- package/src/components/ui/accordion.tsx +69 -0
- package/src/components/ui/alert-dialog.tsx +169 -0
- package/src/components/ui/alert.tsx +80 -0
- package/src/components/ui/animated-theme-toggler.tsx +265 -0
- package/src/components/ui/app-store-buttons.tsx +182 -0
- package/src/components/ui/aspect-ratio.tsx +23 -0
- package/src/components/ui/autocomplete.tsx +296 -0
- package/src/components/ui/avatar-group.tsx +95 -0
- package/src/components/ui/avatar.tsx +285 -0
- package/src/components/ui/badge-group.tsx +160 -0
- package/src/components/ui/badge.tsx +172 -0
- package/src/components/ui/breadcrumb.tsx +112 -0
- package/src/components/ui/button.tsx +77 -0
- package/src/components/ui/calendar.tsx +137 -0
- package/src/components/ui/card.tsx +244 -0
- package/src/components/ui/carousel.tsx +258 -0
- package/src/components/ui/chart.tsx +379 -0
- package/src/components/ui/checkbox-group.tsx +16 -0
- package/src/components/ui/checkbox.tsx +82 -0
- package/src/components/ui/collapsible.tsx +45 -0
- package/src/components/ui/combobox.tsx +411 -0
- package/src/components/ui/command.tsx +264 -0
- package/src/components/ui/context-menu.tsx +271 -0
- package/src/components/ui/credit-card.tsx +214 -0
- package/src/components/ui/dialog.tsx +196 -0
- package/src/components/ui/drawer.tsx +135 -0
- package/src/components/ui/empty.tsx +127 -0
- package/src/components/ui/featured-icon.tsx +149 -0
- package/src/components/ui/field.tsx +88 -0
- package/src/components/ui/fieldset.tsx +29 -0
- package/src/components/ui/form.tsx +17 -0
- package/src/components/ui/frame.tsx +82 -0
- package/src/components/ui/generic-empty.tsx +142 -0
- package/src/components/ui/group.tsx +97 -0
- package/src/components/ui/horizontal-scroll-fader.tsx +228 -0
- package/src/components/ui/input-group.tsx +102 -0
- package/src/components/ui/input-otp.tsx +96 -0
- package/src/components/ui/input.tsx +66 -0
- package/src/components/ui/item.tsx +198 -0
- package/src/components/ui/kbd.tsx +30 -0
- package/src/components/ui/label.tsx +28 -0
- package/src/components/ui/menu.tsx +312 -0
- package/src/components/ui/menubar.tsx +93 -0
- package/src/components/ui/meter.tsx +67 -0
- package/src/components/ui/multi-select.tsx +308 -0
- package/src/components/ui/navigation-menu.tsx +143 -0
- package/src/components/ui/number-field.tsx +160 -0
- package/src/components/ui/pagination-controls.tsx +74 -0
- package/src/components/ui/pagination.tsx +149 -0
- package/src/components/ui/popover.tsx +119 -0
- package/src/components/ui/preview-card.tsx +55 -0
- package/src/components/ui/progress.tsx +289 -0
- package/src/components/ui/qr-code.tsx +150 -0
- package/src/components/ui/radio-group.tsx +103 -0
- package/src/components/ui/resizable.tsx +56 -0
- package/src/components/ui/scroll-area.tsx +90 -0
- package/src/components/ui/scroller.tsx +38 -0
- package/src/components/ui/section-header.tsx +118 -0
- package/src/components/ui/select.tsx +181 -0
- package/src/components/ui/separator.tsx +23 -0
- package/src/components/ui/sheet.tsx +224 -0
- package/src/components/ui/sidebar.tsx +744 -0
- package/src/components/ui/skeleton.tsx +16 -0
- package/src/components/ui/slider.tsx +108 -0
- package/src/components/ui/smooth-scroll.tsx +143 -0
- package/src/components/ui/social-button.tsx +247 -0
- package/src/components/ui/spinner-on-demand.tsx +32 -0
- package/src/components/ui/spinner.tsx +18 -0
- package/src/components/ui/stat.tsx +187 -0
- package/src/components/ui/stepper.tsx +167 -0
- package/src/components/ui/switch.tsx +56 -0
- package/src/components/ui/table.tsx +126 -0
- package/src/components/ui/tabs.tsx +90 -0
- package/src/components/ui/tag.tsx +229 -0
- package/src/components/ui/target-countdown.tsx +46 -0
- package/src/components/ui/text-editor.tsx +313 -0
- package/src/components/ui/textarea.tsx +51 -0
- package/src/components/ui/timeline.tsx +116 -0
- package/src/components/ui/toast.tsx +268 -0
- package/src/components/ui/toggle-group.tsx +101 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/components/ui/toolbar.tsx +89 -0
- package/src/components/ui/tooltip.tsx +102 -0
- package/src/components/ui/vertical-scroll-fader.tsx +250 -0
- package/src/components/ui/video-player.tsx +275 -0
- package/src/components/upload/avatar-upload-base.tsx +131 -0
- package/src/components/upload/image-upload-base.tsx +112 -0
- package/src/form.ts +17 -0
- package/src/index.ts +125 -0
- package/src/lib/hooks/use-callback-ref.ts +15 -0
- package/src/lib/hooks/use-first-render.ts +11 -0
- package/src/lib/hooks/use-hover.ts +53 -0
- package/src/lib/hooks/use-is-tab-active.ts +17 -0
- package/src/lib/hooks/use-media-query.ts +164 -0
- package/src/lib/utils/css.ts +6 -0
- package/src/styles.css +300 -0
- package/src/types/helpers.ts +24 -0
- package/src/types/react.d.ts +7 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
|
+
import { ArrowRightIcon } from "lucide-react";
|
|
7
|
+
import type * as React from "react";
|
|
8
|
+
|
|
9
|
+
import { cn } from "../../lib/utils/css";
|
|
10
|
+
|
|
11
|
+
const badgeGroupVariants = cva(
|
|
12
|
+
"relative inline-flex max-w-full shrink-0 items-center gap-2 whitespace-nowrap border border-transparent font-medium text-sm outline-none transition-shadow focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background sm:text-xs [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-3.5 sm:[&_svg:not([class*='size-'])]:size-3 [&_svg]:pointer-events-none [&_svg]:shrink-0 [button,a&]:cursor-pointer [button,a&]:pointer-coarse:after:absolute [button,a&]:pointer-coarse:after:size-full [button,a&]:pointer-coarse:after:min-h-11 [button,a&]:pointer-coarse:after:min-w-11",
|
|
13
|
+
{
|
|
14
|
+
compoundVariants: [
|
|
15
|
+
{
|
|
16
|
+
className: "bg-secondary text-secondary-foreground",
|
|
17
|
+
color: "gray",
|
|
18
|
+
variant: "pill",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
className: "bg-brand/12 text-sidebar-primary dark:bg-brand/20",
|
|
22
|
+
color: "brand",
|
|
23
|
+
variant: "pill",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
className:
|
|
27
|
+
"bg-destructive/8 text-destructive-foreground dark:bg-destructive/16",
|
|
28
|
+
color: "error",
|
|
29
|
+
variant: "pill",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
className: "bg-warning/8 text-warning-foreground dark:bg-warning/16",
|
|
33
|
+
color: "warning",
|
|
34
|
+
variant: "pill",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
className: "bg-success/8 text-success-foreground dark:bg-success/16",
|
|
38
|
+
color: "success",
|
|
39
|
+
variant: "pill",
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
defaultVariants: {
|
|
43
|
+
align: "leading",
|
|
44
|
+
color: "gray",
|
|
45
|
+
variant: "pill",
|
|
46
|
+
},
|
|
47
|
+
variants: {
|
|
48
|
+
align: {
|
|
49
|
+
leading: "p-1 pe-2.5",
|
|
50
|
+
trailing: "p-1 ps-3",
|
|
51
|
+
},
|
|
52
|
+
color: {
|
|
53
|
+
brand: "",
|
|
54
|
+
error: "",
|
|
55
|
+
gray: "",
|
|
56
|
+
success: "",
|
|
57
|
+
warning: "",
|
|
58
|
+
},
|
|
59
|
+
variant: {
|
|
60
|
+
modern:
|
|
61
|
+
"rounded-[10px] border-input bg-background text-foreground shadow-xs dark:bg-input/32",
|
|
62
|
+
pill: "rounded-full",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
type BadgeGroupColor = NonNullable<
|
|
69
|
+
VariantProps<typeof badgeGroupVariants>["color"]
|
|
70
|
+
>;
|
|
71
|
+
|
|
72
|
+
/** Ring tint of the inner pill badge, per color. */
|
|
73
|
+
const pillBadgeRing: Record<BadgeGroupColor, string> = {
|
|
74
|
+
brand: "ring-brand/48",
|
|
75
|
+
error: "ring-destructive/32",
|
|
76
|
+
gray: "ring-border",
|
|
77
|
+
success: "ring-success/32",
|
|
78
|
+
warning: "ring-warning/40",
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** Status dot of the inner modern badge, per color. */
|
|
82
|
+
const modernBadgeDot: Record<BadgeGroupColor, string> = {
|
|
83
|
+
brand: "bg-brand",
|
|
84
|
+
error: "bg-destructive",
|
|
85
|
+
gray: "bg-muted-foreground",
|
|
86
|
+
success: "bg-success",
|
|
87
|
+
warning: "bg-warning",
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
interface BadgeGroupProps
|
|
91
|
+
extends Omit<useRender.ComponentProps<"span">, "color"> {
|
|
92
|
+
/** `pill` is a tonal, fully-rounded chip; `modern` is a bordered card-style chip with a status dot. */
|
|
93
|
+
variant?: VariantProps<typeof badgeGroupVariants>["variant"];
|
|
94
|
+
color?: BadgeGroupColor;
|
|
95
|
+
/** Which side of the message the inner badge sits on. */
|
|
96
|
+
align?: VariantProps<typeof badgeGroupVariants>["align"];
|
|
97
|
+
/** Short label rendered inside the inner badge. */
|
|
98
|
+
badge: React.ReactNode;
|
|
99
|
+
/** Arrow shown after the message (leading) or inside the badge (trailing). Pass `null` to hide. */
|
|
100
|
+
icon?: React.ReactNode;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function BadgeGroup({
|
|
104
|
+
className,
|
|
105
|
+
variant = "pill",
|
|
106
|
+
color = "gray",
|
|
107
|
+
align = "leading",
|
|
108
|
+
badge,
|
|
109
|
+
icon,
|
|
110
|
+
children,
|
|
111
|
+
render,
|
|
112
|
+
...props
|
|
113
|
+
}: BadgeGroupProps) {
|
|
114
|
+
const arrow =
|
|
115
|
+
icon === null ? null : (icon ?? <ArrowRightIcon className="rtl:-scale-x-100" />);
|
|
116
|
+
|
|
117
|
+
const innerBadge = (
|
|
118
|
+
<span
|
|
119
|
+
className={cn(
|
|
120
|
+
"inline-flex shrink-0 items-center gap-1.5 bg-background px-2.5 py-0.5",
|
|
121
|
+
variant === "modern"
|
|
122
|
+
? "rounded-md border border-input shadow-xs dark:bg-input/32"
|
|
123
|
+
: cn("rounded-full ring-1 ring-inset", pillBadgeRing[color]),
|
|
124
|
+
align === "trailing" && "pe-2",
|
|
125
|
+
)}
|
|
126
|
+
data-slot="badge-group-badge"
|
|
127
|
+
>
|
|
128
|
+
{variant === "modern" ? (
|
|
129
|
+
<span
|
|
130
|
+
className={cn("size-1.5 rounded-full", modernBadgeDot[color])}
|
|
131
|
+
data-slot="badge-group-dot"
|
|
132
|
+
/>
|
|
133
|
+
) : null}
|
|
134
|
+
{badge}
|
|
135
|
+
{align === "trailing" ? arrow : null}
|
|
136
|
+
</span>
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const defaultProps = {
|
|
140
|
+
className: cn(badgeGroupVariants({ align, className, color, variant })),
|
|
141
|
+
"data-slot": "badge-group",
|
|
142
|
+
children: (
|
|
143
|
+
<>
|
|
144
|
+
{align === "leading" ? innerBadge : null}
|
|
145
|
+
<span className="truncate" data-slot="badge-group-text">
|
|
146
|
+
{children}
|
|
147
|
+
</span>
|
|
148
|
+
{align === "leading" ? arrow : innerBadge}
|
|
149
|
+
</>
|
|
150
|
+
),
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
return useRender({
|
|
154
|
+
defaultTagName: "span",
|
|
155
|
+
props: mergeProps<"span">(defaultProps, props),
|
|
156
|
+
render,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export { BadgeGroup, badgeGroupVariants };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
|
+
import { XIcon } from "lucide-react";
|
|
7
|
+
import type * as React from "react";
|
|
8
|
+
|
|
9
|
+
import { cn } from "../../lib/utils/css";
|
|
10
|
+
|
|
11
|
+
const badgeVariants = cva(
|
|
12
|
+
"relative inline-flex shrink-0 items-center justify-center gap-1 whitespace-nowrap border border-transparent font-medium outline-none transition-shadow focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-3.5 sm:[&_svg:not([class*='size-'])]:size-3 [&_svg]:pointer-events-none [&_svg]:shrink-0 [button,a&]:cursor-pointer [button,a&]:pointer-coarse:after:absolute [button,a&]:pointer-coarse:after:size-full [button,a&]:pointer-coarse:after:min-h-11 [button,a&]:pointer-coarse:after:min-w-11",
|
|
13
|
+
{
|
|
14
|
+
compoundVariants: [
|
|
15
|
+
{ className: "rounded-sm", shape: "default", size: ["default", "lg"] },
|
|
16
|
+
{
|
|
17
|
+
className: "rounded-[calc(var(--radius-sm)-2px)]",
|
|
18
|
+
shape: "default",
|
|
19
|
+
size: "sm",
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
shape: "default",
|
|
24
|
+
size: "default",
|
|
25
|
+
variant: "default",
|
|
26
|
+
},
|
|
27
|
+
variants: {
|
|
28
|
+
shape: {
|
|
29
|
+
default: "",
|
|
30
|
+
pill: "rounded-full",
|
|
31
|
+
},
|
|
32
|
+
size: {
|
|
33
|
+
default:
|
|
34
|
+
"h-5.5 min-w-5.5 px-[calc(--spacing(1)-1px)] text-sm sm:h-4.5 sm:min-w-4.5 sm:text-xs",
|
|
35
|
+
lg: "h-6.5 min-w-6.5 px-[calc(--spacing(1.5)-1px)] text-base sm:h-5.5 sm:min-w-5.5 sm:text-sm",
|
|
36
|
+
sm: "h-5 min-w-5 px-[calc(--spacing(1)-1px)] text-xs sm:h-4 sm:min-w-4 sm:text-[.625rem]",
|
|
37
|
+
},
|
|
38
|
+
variant: {
|
|
39
|
+
default:
|
|
40
|
+
"bg-primary text-primary-foreground [button,a&]:hover:bg-primary/90",
|
|
41
|
+
destructive:
|
|
42
|
+
"bg-destructive text-white [button,a&]:hover:bg-destructive/90",
|
|
43
|
+
error:
|
|
44
|
+
"bg-destructive/8 text-destructive-foreground dark:bg-destructive/16",
|
|
45
|
+
info: "bg-info/8 text-info-foreground dark:bg-info/16",
|
|
46
|
+
modern:
|
|
47
|
+
"border-input bg-background text-foreground shadow-xs dark:bg-input/32 [button,a&]:hover:bg-accent/50 dark:[button,a&]:hover:bg-input/48",
|
|
48
|
+
outline:
|
|
49
|
+
"border-input bg-background text-foreground dark:bg-input/32 [button,a&]:hover:bg-accent/50 dark:[button,a&]:hover:bg-input/48",
|
|
50
|
+
secondary:
|
|
51
|
+
"bg-secondary text-secondary-foreground [button,a&]:hover:bg-secondary/90",
|
|
52
|
+
success: "bg-success/8 text-success-foreground dark:bg-success/16",
|
|
53
|
+
warning: "bg-warning/8 text-warning-foreground dark:bg-warning/16",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
interface BadgeProps extends useRender.ComponentProps<"span"> {
|
|
60
|
+
variant?: VariantProps<typeof badgeVariants>["variant"];
|
|
61
|
+
size?: VariantProps<typeof badgeVariants>["size"];
|
|
62
|
+
shape?: VariantProps<typeof badgeVariants>["shape"];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function Badge({
|
|
66
|
+
className,
|
|
67
|
+
variant,
|
|
68
|
+
size,
|
|
69
|
+
shape,
|
|
70
|
+
render,
|
|
71
|
+
...props
|
|
72
|
+
}: BadgeProps) {
|
|
73
|
+
const defaultProps = {
|
|
74
|
+
className: cn(badgeVariants({ className, shape, size, variant })),
|
|
75
|
+
"data-slot": "badge",
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return useRender({
|
|
79
|
+
defaultTagName: "span",
|
|
80
|
+
props: mergeProps<"span">(defaultProps, props),
|
|
81
|
+
render,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** A small status dot. Inherits the badge's text color; recolor via className. */
|
|
86
|
+
function BadgeDot({ className, ...props }: React.ComponentProps<"span">) {
|
|
87
|
+
return (
|
|
88
|
+
<span
|
|
89
|
+
aria-hidden="true"
|
|
90
|
+
className={cn(
|
|
91
|
+
"size-1.5 shrink-0 rounded-full bg-current sm:size-[5px]",
|
|
92
|
+
className,
|
|
93
|
+
)}
|
|
94
|
+
data-slot="badge-dot"
|
|
95
|
+
{...props}
|
|
96
|
+
/>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** A tiny round avatar image sized to sit inside a badge. */
|
|
101
|
+
function BadgeAvatar({ alt, className, ...props }: React.ComponentProps<"img">) {
|
|
102
|
+
return (
|
|
103
|
+
// biome-ignore lint/a11y/useAltText: alt forwarded via props
|
|
104
|
+
<img
|
|
105
|
+
alt={alt}
|
|
106
|
+
className={cn(
|
|
107
|
+
"size-4 shrink-0 rounded-full object-cover sm:size-3.5",
|
|
108
|
+
className,
|
|
109
|
+
)}
|
|
110
|
+
data-slot="badge-avatar"
|
|
111
|
+
{...props}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** A round country flag. `country` is an ISO 3166-1 alpha-2 code (e.g. "AU"). */
|
|
117
|
+
function BadgeFlag({
|
|
118
|
+
alt,
|
|
119
|
+
className,
|
|
120
|
+
country,
|
|
121
|
+
src,
|
|
122
|
+
...props
|
|
123
|
+
}: React.ComponentProps<"img"> & { country?: string }) {
|
|
124
|
+
return (
|
|
125
|
+
// biome-ignore lint/a11y/useAltText: alt forwarded via props
|
|
126
|
+
<img
|
|
127
|
+
alt={alt ?? country}
|
|
128
|
+
className={cn(
|
|
129
|
+
"size-4 shrink-0 rounded-full object-cover sm:size-3.5",
|
|
130
|
+
className,
|
|
131
|
+
)}
|
|
132
|
+
data-slot="badge-flag"
|
|
133
|
+
src={
|
|
134
|
+
src ??
|
|
135
|
+
(country
|
|
136
|
+
? `https://hatscripts.github.io/circle-flags/flags/${country.toLowerCase()}.svg`
|
|
137
|
+
: undefined)
|
|
138
|
+
}
|
|
139
|
+
{...props}
|
|
140
|
+
/>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** A small remove button for dismissible badges. Renders an X by default. */
|
|
145
|
+
function BadgeCloseButton({
|
|
146
|
+
children,
|
|
147
|
+
className,
|
|
148
|
+
...props
|
|
149
|
+
}: React.ComponentProps<"button">) {
|
|
150
|
+
return (
|
|
151
|
+
<button
|
|
152
|
+
className={cn(
|
|
153
|
+
"-me-px inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full text-current opacity-64 outline-none transition-opacity hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring",
|
|
154
|
+
className,
|
|
155
|
+
)}
|
|
156
|
+
data-slot="badge-close-button"
|
|
157
|
+
type="button"
|
|
158
|
+
{...props}
|
|
159
|
+
>
|
|
160
|
+
{children ?? <XIcon className="pointer-events-none" />}
|
|
161
|
+
</button>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export {
|
|
166
|
+
Badge,
|
|
167
|
+
BadgeDot,
|
|
168
|
+
BadgeAvatar,
|
|
169
|
+
BadgeFlag,
|
|
170
|
+
BadgeCloseButton,
|
|
171
|
+
badgeVariants,
|
|
172
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
import { ChevronRight, MoreHorizontal } from "lucide-react";
|
|
6
|
+
import type * as React from "react";
|
|
7
|
+
|
|
8
|
+
import { cn } from "../../lib/utils/css";
|
|
9
|
+
|
|
10
|
+
function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
|
|
11
|
+
return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
|
|
15
|
+
return (
|
|
16
|
+
<ol
|
|
17
|
+
className={cn(
|
|
18
|
+
"wrap-break-word flex flex-wrap items-center gap-1.5 text-muted-foreground text-sm sm:gap-2.5",
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
data-slot="breadcrumb-list"
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
|
|
28
|
+
return (
|
|
29
|
+
<li
|
|
30
|
+
className={cn("inline-flex items-center gap-1.5", className)}
|
|
31
|
+
data-slot="breadcrumb-item"
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function BreadcrumbLink({
|
|
38
|
+
className,
|
|
39
|
+
render,
|
|
40
|
+
...props
|
|
41
|
+
}: useRender.ComponentProps<"a">) {
|
|
42
|
+
const defaultProps = {
|
|
43
|
+
className: cn("transition-colors hover:text-foreground", className),
|
|
44
|
+
"data-slot": "breadcrumb-link",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return useRender({
|
|
48
|
+
defaultTagName: "a",
|
|
49
|
+
props: mergeProps<"a">(defaultProps, props),
|
|
50
|
+
render,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
|
|
55
|
+
return (
|
|
56
|
+
// biome-ignore lint(a11y/useFocusableInteractive): known
|
|
57
|
+
<span
|
|
58
|
+
aria-current="page"
|
|
59
|
+
aria-disabled="true"
|
|
60
|
+
className={cn("font-normal text-foreground", className)}
|
|
61
|
+
data-slot="breadcrumb-page"
|
|
62
|
+
role="link"
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function BreadcrumbSeparator({
|
|
69
|
+
children,
|
|
70
|
+
className,
|
|
71
|
+
...props
|
|
72
|
+
}: React.ComponentProps<"li">) {
|
|
73
|
+
return (
|
|
74
|
+
<li
|
|
75
|
+
aria-hidden="true"
|
|
76
|
+
className={cn("opacity-80 [&>svg]:size-4", className)}
|
|
77
|
+
data-slot="breadcrumb-separator"
|
|
78
|
+
role="presentation"
|
|
79
|
+
{...props}
|
|
80
|
+
>
|
|
81
|
+
{children ?? <ChevronRight />}
|
|
82
|
+
</li>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function BreadcrumbEllipsis({
|
|
87
|
+
className,
|
|
88
|
+
...props
|
|
89
|
+
}: React.ComponentProps<"span">) {
|
|
90
|
+
return (
|
|
91
|
+
<span
|
|
92
|
+
aria-hidden="true"
|
|
93
|
+
className={className}
|
|
94
|
+
data-slot="breadcrumb-ellipsis"
|
|
95
|
+
role="presentation"
|
|
96
|
+
{...props}
|
|
97
|
+
>
|
|
98
|
+
<MoreHorizontal className="size-4" />
|
|
99
|
+
<span className="sr-only">More</span>
|
|
100
|
+
</span>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export {
|
|
105
|
+
Breadcrumb,
|
|
106
|
+
BreadcrumbList,
|
|
107
|
+
BreadcrumbItem,
|
|
108
|
+
BreadcrumbLink,
|
|
109
|
+
BreadcrumbPage,
|
|
110
|
+
BreadcrumbSeparator,
|
|
111
|
+
BreadcrumbEllipsis,
|
|
112
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
|
+
import type * as React from "react";
|
|
7
|
+
|
|
8
|
+
import { cn } from "../../lib/utils/css";
|
|
9
|
+
|
|
10
|
+
const buttonVariants = cva(
|
|
11
|
+
"[&_svg]:-mx-0.5 [&_img]:-mx-0.5 [&_picture]:-mx-0.5 relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-lg border font-medium text-base outline-none transition-[box-shadow,filter] duration-100 [:active:not(:disabled)]:brightness-95 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 sm:text-sm [&_svg:not([class*='opacity-'])]:opacity-80 [&_img:not([class*='opacity-'])]:opacity-80 [&_picture:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 [&_img:not([class*='size-'])]:size-4.5 [&_picture:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 sm:[&_img:not([class*='size-'])]:size-4 sm:[&_picture:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_img]:pointer-events-none [&_picture]:pointer-events-none [&_svg]:shrink-0 [&_img]:shrink-0 [&_picture]:shrink-0",
|
|
12
|
+
{
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
size: "default",
|
|
15
|
+
variant: "default",
|
|
16
|
+
},
|
|
17
|
+
variants: {
|
|
18
|
+
size: {
|
|
19
|
+
default: "h-9 px-[calc(--spacing(3)-1px)] sm:h-8",
|
|
20
|
+
icon: "size-9 sm:size-8",
|
|
21
|
+
"icon-lg": "size-10 sm:size-9",
|
|
22
|
+
"icon-sm": "size-8 sm:size-7",
|
|
23
|
+
"icon-xl":
|
|
24
|
+
"size-11 sm:size-10 [&_svg:not([class*='size-'])]:size-5 [&_img:not([class*='size-'])]:size-5 [&_picture:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5 sm:[&_img:not([class*='size-'])]:size-4.5 sm:[&_picture:not([class*='size-'])]:size-4.5",
|
|
25
|
+
"icon-xs":
|
|
26
|
+
"size-7 rounded-md before:rounded-[calc(var(--radius-md)-1px)] sm:size-6 not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-4 not-in-data-[slot=input-group]:[&_img:not([class*='size-'])]:size-4 not-in-data-[slot=input-group]:[&_picture:not([class*='size-'])]:size-4 sm:not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-3.5 sm:not-in-data-[slot=input-group]:[&_img:not([class*='size-'])]:size-3.5 sm:not-in-data-[slot=input-group]:[&_picture:not([class*='size-'])]:size-3.5",
|
|
27
|
+
lg: "h-10 px-[calc(--spacing(3.5)-1px)] sm:h-9",
|
|
28
|
+
sm: "h-8 gap-1.5 px-[calc(--spacing(2.5)-1px)] sm:h-7",
|
|
29
|
+
xl: "h-11 px-[calc(--spacing(4)-1px)] text-lg sm:h-10 sm:text-base [&_svg:not([class*='size-'])]:size-5 [&_img:not([class*='size-'])]:size-5 [&_picture:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5 sm:[&_img:not([class*='size-'])]:size-4.5 sm:[&_picture:not([class*='size-'])]:size-4.5",
|
|
30
|
+
xs: "h-7 gap-1 rounded-md px-[calc(--spacing(2)-1px)] text-sm before:rounded-[calc(var(--radius-md)-1px)] sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 [&_img:not([class*='size-'])]:size-4 [&_picture:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5 sm:[&_img:not([class*='size-'])]:size-3.5 sm:[&_picture:not([class*='size-'])]:size-3.5",
|
|
31
|
+
},
|
|
32
|
+
variant: {
|
|
33
|
+
default:
|
|
34
|
+
"not-disabled:inset-shadow-[0_1px_--theme(--color-white/16%)] border-primary bg-primary text-primary-foreground shadow-primary/24 shadow-xs [:active,[data-pressed]]:inset-shadow-[0_1px_--theme(--color-black/8%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-primary/90",
|
|
35
|
+
destructive:
|
|
36
|
+
"not-disabled:inset-shadow-[0_1px_--theme(--color-white/16%)] border-destructive bg-destructive text-white shadow-destructive/24 shadow-xs [:active,[data-pressed]]:inset-shadow-[0_1px_--theme(--color-black/8%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-destructive/90",
|
|
37
|
+
"destructive-outline":
|
|
38
|
+
"border-input bg-popover not-dark:bg-clip-padding text-destructive-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:border-destructive/32 [:hover,[data-pressed]]:bg-destructive/4",
|
|
39
|
+
"destructive-ghost":
|
|
40
|
+
"border-transparent text-destructive-foreground data-pressed:bg-destructive/8 [:hover,[data-pressed]]:bg-destructive/8",
|
|
41
|
+
ghost:
|
|
42
|
+
"border-transparent text-foreground data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent",
|
|
43
|
+
link: "border-transparent pointer-coarse:underline pointer-coarse:underline-offset-4 pointer-fine:after:absolute pointer-fine:after:inset-x-3 pointer-fine:after:bottom-1.5 pointer-fine:after:h-px pointer-fine:after:origin-right pointer-fine:after:scale-x-0 pointer-fine:after:bg-current pointer-fine:after:transition-transform pointer-fine:after:duration-300 pointer-fine:after:ease-out pointer-fine:hover:after:origin-left pointer-fine:hover:after:scale-x-100 pointer-fine:data-pressed:after:origin-left pointer-fine:data-pressed:after:scale-x-100",
|
|
44
|
+
"link-muted":
|
|
45
|
+
"border-transparent text-muted-foreground transition-[box-shadow,filter,color] [:hover,[data-pressed]]:text-foreground pointer-coarse:underline pointer-coarse:underline-offset-4 pointer-fine:after:absolute pointer-fine:after:inset-x-3 pointer-fine:after:bottom-1.5 pointer-fine:after:h-px pointer-fine:after:origin-right pointer-fine:after:scale-x-0 pointer-fine:after:bg-current pointer-fine:after:transition-transform pointer-fine:after:duration-300 pointer-fine:after:ease-out pointer-fine:hover:after:origin-left pointer-fine:hover:after:scale-x-100 pointer-fine:data-pressed:after:origin-left pointer-fine:data-pressed:after:scale-x-100",
|
|
46
|
+
outline:
|
|
47
|
+
"border-input bg-popover not-dark:bg-clip-padding text-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-accent/50 dark:[:hover,[data-pressed]]:bg-input/64",
|
|
48
|
+
secondary:
|
|
49
|
+
"border-transparent bg-secondary text-secondary-foreground [:active,[data-pressed]]:bg-secondary/80 [:hover,[data-pressed]]:bg-secondary/90",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
export interface ButtonProps extends useRender.ComponentProps<"button"> {
|
|
56
|
+
variant?: VariantProps<typeof buttonVariants>["variant"];
|
|
57
|
+
size?: VariantProps<typeof buttonVariants>["size"];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function Button({ className, variant, size, render, ...props }: ButtonProps) {
|
|
61
|
+
const typeValue: React.ButtonHTMLAttributes<HTMLButtonElement>["type"] =
|
|
62
|
+
render ? undefined : "button";
|
|
63
|
+
|
|
64
|
+
const defaultProps = {
|
|
65
|
+
className: cn(buttonVariants({ className, size, variant })),
|
|
66
|
+
"data-slot": "button",
|
|
67
|
+
type: typeValue,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return useRender({
|
|
71
|
+
defaultTagName: "button",
|
|
72
|
+
props: mergeProps<"button">(defaultProps, props),
|
|
73
|
+
render,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ChevronLeftIcon,
|
|
5
|
+
ChevronRightIcon,
|
|
6
|
+
ChevronsUpDownIcon,
|
|
7
|
+
} from "lucide-react";
|
|
8
|
+
import type * as React from "react";
|
|
9
|
+
import { DayPicker } from "react-day-picker";
|
|
10
|
+
|
|
11
|
+
import { cn } from "../../lib/utils/css";
|
|
12
|
+
|
|
13
|
+
const buttonClassNames =
|
|
14
|
+
"relative flex size-(--cell-size) text-base sm:text-sm items-center justify-center rounded-lg text-foreground not-in-data-selected:hover:bg-accent disabled:pointer-events-none disabled:opacity-64 [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0";
|
|
15
|
+
|
|
16
|
+
function Calendar({
|
|
17
|
+
className,
|
|
18
|
+
classNames,
|
|
19
|
+
showOutsideDays = true,
|
|
20
|
+
components: userComponents,
|
|
21
|
+
...props
|
|
22
|
+
}: React.ComponentProps<typeof DayPicker>) {
|
|
23
|
+
const defaultClassNames = {
|
|
24
|
+
button_next: buttonClassNames,
|
|
25
|
+
button_previous: buttonClassNames,
|
|
26
|
+
caption_label:
|
|
27
|
+
"text-base sm:text-sm font-medium flex items-center gap-2 h-full",
|
|
28
|
+
day: "size-(--cell-size) text-sm py-px",
|
|
29
|
+
day_button: cn(
|
|
30
|
+
buttonClassNames,
|
|
31
|
+
"in-[[data-selected]:not(.range-middle)]:transition-[color,background-color,border-radius,box-shadow] in-data-disabled:pointer-events-none focus-visible:z-1 in-data-selected:bg-primary in-data-selected:text-primary-foreground in-data-disabled:text-muted-foreground/70 in-data-disabled:line-through in-data-outside:text-muted-foreground/70 in-data-selected:in-data-outside:text-primary-foreground outline-none focus-visible:ring-ring/50 focus-visible:ring-[3px] in-[.range-start:not(.range-end)]:rounded-e-none in-[.range-end:not(.range-start)]:rounded-s-none in-[.range-middle]:rounded-none in-[.range-middle]:in-data-selected:bg-accent in-[.range-middle]:in-data-selected:text-foreground",
|
|
32
|
+
),
|
|
33
|
+
dropdown: "absolute bg-popover inset-0 opacity-0",
|
|
34
|
+
dropdown_root:
|
|
35
|
+
"relative has-focus:border-ring has-focus:ring-ring/50 has-focus:ring-[3px] border border-input shadow-xs/5 rounded-lg px-[calc(--spacing(3)-1px)] h-9 sm:h-8 [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-me-1",
|
|
36
|
+
dropdowns:
|
|
37
|
+
"w-full flex items-center text-base sm:text-sm justify-center h-(--cell-size) gap-1.5 *:[span]:font-medium",
|
|
38
|
+
hidden: "invisible",
|
|
39
|
+
month: "w-full",
|
|
40
|
+
month_caption:
|
|
41
|
+
"relative mx-(--cell-size) px-1 mb-1 flex h-(--cell-size) items-center justify-center z-2",
|
|
42
|
+
months: "relative flex flex-col sm:flex-row gap-2",
|
|
43
|
+
nav: "absolute top-0 flex w-full justify-between z-1",
|
|
44
|
+
outside:
|
|
45
|
+
"text-muted-foreground data-selected:bg-accent/50 data-selected:text-muted-foreground",
|
|
46
|
+
range_end: "range-end",
|
|
47
|
+
range_middle: "range-middle",
|
|
48
|
+
range_start: "range-start",
|
|
49
|
+
today:
|
|
50
|
+
"*:after:pointer-events-none *:after:absolute *:after:bottom-1 *:after:start-1/2 *:after:z-1 *:after:size-[3px] *:after:-translate-x-1/2 *:after:rounded-full *:after:bg-primary [&[data-selected]:not(.range-middle)>*]:after:bg-background [&[data-disabled]>*]:after:bg-foreground/30 *:after:transition-colors",
|
|
51
|
+
week_number:
|
|
52
|
+
"size-(--cell-size) p-0 text-xs font-medium text-muted-foreground/70",
|
|
53
|
+
weekday:
|
|
54
|
+
"size-(--cell-size) p-0 text-xs font-medium text-muted-foreground/70",
|
|
55
|
+
};
|
|
56
|
+
const mergedClassNames: typeof defaultClassNames = Object.keys(
|
|
57
|
+
defaultClassNames,
|
|
58
|
+
).reduce(
|
|
59
|
+
(acc, key) => {
|
|
60
|
+
const userClass = classNames?.[key as keyof typeof classNames];
|
|
61
|
+
const baseClass =
|
|
62
|
+
defaultClassNames[key as keyof typeof defaultClassNames];
|
|
63
|
+
|
|
64
|
+
acc[key as keyof typeof defaultClassNames] = userClass
|
|
65
|
+
? cn(baseClass, userClass)
|
|
66
|
+
: baseClass;
|
|
67
|
+
|
|
68
|
+
return acc;
|
|
69
|
+
},
|
|
70
|
+
{ ...defaultClassNames } as typeof defaultClassNames,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const defaultComponents = {
|
|
74
|
+
Chevron: ({
|
|
75
|
+
className,
|
|
76
|
+
orientation,
|
|
77
|
+
...props
|
|
78
|
+
}: {
|
|
79
|
+
className?: string;
|
|
80
|
+
orientation?: "left" | "right" | "up" | "down";
|
|
81
|
+
}) => {
|
|
82
|
+
if (orientation === "left") {
|
|
83
|
+
return (
|
|
84
|
+
<ChevronLeftIcon
|
|
85
|
+
className={cn(className, "rtl:rotate-180")}
|
|
86
|
+
{...props}
|
|
87
|
+
aria-hidden="true"
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (orientation === "right") {
|
|
93
|
+
return (
|
|
94
|
+
<ChevronRightIcon
|
|
95
|
+
className={cn(className, "rtl:rotate-180")}
|
|
96
|
+
{...props}
|
|
97
|
+
aria-hidden="true"
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<ChevronsUpDownIcon
|
|
104
|
+
className={className}
|
|
105
|
+
{...props}
|
|
106
|
+
aria-hidden="true"
|
|
107
|
+
/>
|
|
108
|
+
);
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const mergedComponents = {
|
|
113
|
+
...defaultComponents,
|
|
114
|
+
...userComponents,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<DayPicker
|
|
119
|
+
className={cn(
|
|
120
|
+
"w-fit [--cell-size:--spacing(10)] sm:[--cell-size:--spacing(9)]",
|
|
121
|
+
className,
|
|
122
|
+
)}
|
|
123
|
+
classNames={mergedClassNames}
|
|
124
|
+
components={mergedComponents}
|
|
125
|
+
data-slot="calendar"
|
|
126
|
+
formatters={{
|
|
127
|
+
formatMonthDropdown: (date) =>
|
|
128
|
+
date.toLocaleString("default", { month: "short" }),
|
|
129
|
+
}}
|
|
130
|
+
mode="single"
|
|
131
|
+
showOutsideDays={showOutsideDays}
|
|
132
|
+
{...props}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export { Calendar };
|