@lark-apaas/coding-templates 0.1.4 → 0.1.6
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/package.json +1 -1
- package/template-vite-react/README.md +175 -0
- package/template-vite-react/client/index.html +2 -1
- package/template-vite-react/client/src/app.tsx +3 -1
- package/template-vite-react/client/src/components/layout.tsx +0 -2
- package/template-vite-react/client/src/components/ui/README.md +134 -0
- package/template-vite-react/client/src/components/ui/accordion.tsx +22 -28
- package/template-vite-react/client/src/components/ui/alert-dialog.tsx +34 -64
- package/template-vite-react/client/src/components/ui/alert.tsx +10 -15
- package/template-vite-react/client/src/components/ui/aspect-ratio.tsx +5 -16
- package/template-vite-react/client/src/components/ui/avatar.tsx +11 -67
- package/template-vite-react/client/src/components/ui/badge.tsx +21 -31
- package/template-vite-react/client/src/components/ui/breadcrumb.tsx +23 -39
- package/template-vite-react/client/src/components/ui/button.tsx +36 -25
- package/template-vite-react/client/src/components/ui/calendar.tsx +37 -43
- package/template-vite-react/client/src/components/ui/card.tsx +73 -94
- package/template-vite-react/client/src/components/ui/carousel.tsx +7 -8
- package/template-vite-react/client/src/components/ui/chart.tsx +35 -49
- package/template-vite-react/client/src/components/ui/checkbox.tsx +10 -7
- package/template-vite-react/client/src/components/ui/collapsible.tsx +20 -6
- package/template-vite-react/client/src/components/ui/command.tsx +52 -40
- package/template-vite-react/client/src/components/ui/context-menu.tsx +170 -117
- package/template-vite-react/client/src/components/ui/dialog.tsx +37 -52
- package/template-vite-react/client/src/components/ui/drawer.tsx +12 -9
- package/template-vite-react/client/src/components/ui/dropdown-menu.tsx +194 -133
- package/template-vite-react/client/src/components/ui/hover-card.tsx +24 -29
- package/template-vite-react/client/src/components/ui/input-group.tsx +39 -29
- package/template-vite-react/client/src/components/ui/input-otp.tsx +7 -17
- package/template-vite-react/client/src/components/ui/input.tsx +4 -3
- package/template-vite-react/client/src/components/ui/label.tsx +9 -3
- package/template-vite-react/client/src/components/ui/menubar.tsx +160 -92
- package/template-vite-react/client/src/components/ui/navigation-menu.tsx +45 -45
- package/template-vite-react/client/src/components/ui/pagination.tsx +32 -35
- package/template-vite-react/client/src/components/ui/popover.tsx +20 -62
- package/template-vite-react/client/src/components/ui/progress.tsx +14 -64
- package/template-vite-react/client/src/components/ui/radio-group.tsx +20 -13
- package/template-vite-react/client/src/components/ui/resizable.tsx +18 -10
- package/template-vite-react/client/src/components/ui/scroll-area.tsx +13 -10
- package/template-vite-react/client/src/components/ui/select.tsx +122 -78
- package/template-vite-react/client/src/components/ui/separator.tsx +7 -4
- package/template-vite-react/client/src/components/ui/sheet.tsx +42 -41
- package/template-vite-react/client/src/components/ui/sidebar.tsx +162 -156
- package/template-vite-react/client/src/components/ui/skeleton.tsx +1 -1
- package/template-vite-react/client/src/components/ui/slider.tsx +52 -22
- package/template-vite-react/client/src/components/ui/sonner.tsx +44 -26
- package/template-vite-react/client/src/components/ui/switch.tsx +9 -8
- package/template-vite-react/client/src/components/ui/table.tsx +5 -5
- package/template-vite-react/client/src/components/ui/tabs.tsx +24 -38
- package/template-vite-react/client/src/components/ui/textarea.tsx +1 -1
- package/template-vite-react/client/src/components/ui/toggle-group.tsx +14 -20
- package/template-vite-react/client/src/components/ui/toggle.tsx +13 -10
- package/template-vite-react/client/src/components/ui/tooltip.tsx +30 -33
- package/template-vite-react/client/src/index.css +130 -0
- package/template-vite-react/client/src/main.tsx +1 -4
- package/template-vite-react/client/src/pages/home/index.tsx +5 -5
- package/template-vite-react/components.json +2 -6
- package/template-vite-react/eslint.config.js +11 -0
- package/template-vite-react/package.json +27 -2
- package/template-vite-react/vite.config.ts +5 -0
- package/template-vite-react/client/src/components/header.tsx +0 -22
- package/template-vite-react/client/src/components/theme-provider.tsx +0 -45
- package/template-vite-react/client/src/components/ui/icons/file-ae-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/components/ui/icons/file-ai-colorful-icon.tsx +0 -36
- package/template-vite-react/client/src/components/ui/icons/file-android-colorful-icon.tsx +0 -33
- package/template-vite-react/client/src/components/ui/icons/file-audio-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/components/ui/icons/file-code-colorful-icon.tsx +0 -28
- package/template-vite-react/client/src/components/ui/icons/file-csv-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/components/ui/icons/file-eml-colorful-icon.tsx +0 -29
- package/template-vite-react/client/src/components/ui/icons/file-ios-colorful-icon.tsx +0 -25
- package/template-vite-react/client/src/components/ui/icons/file-keynote-colorful-icon.tsx +0 -29
- package/template-vite-react/client/src/components/ui/icons/file-pages-colorful-icon.tsx +0 -29
- package/template-vite-react/client/src/components/ui/icons/file-ps-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/components/ui/icons/file-sketch-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/components/ui/icons/file-slide-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/components/ui/icons/file-vcf-colorful-icon.tsx +0 -29
- package/template-vite-react/client/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +0 -23
- package/template-vite-react/client/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +0 -27
- package/template-vite-react/client/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +0 -20
- package/template-vite-react/client/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +0 -12
- package/template-vite-react/client/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +0 -14
- package/template-vite-react/client/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +0 -23
- package/template-vite-react/client/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +0 -38
- package/template-vite-react/client/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +0 -21
- package/template-vite-react/client/src/types/index.ts +0 -1
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from "react"
|
|
2
4
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "react-day-picker"
|
|
5
|
+
ChevronDownIcon,
|
|
6
|
+
ChevronLeftIcon,
|
|
7
|
+
ChevronRightIcon,
|
|
8
|
+
} from "lucide-react"
|
|
9
|
+
import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
|
|
8
10
|
|
|
9
11
|
import { cn } from "@/lib/utils"
|
|
10
12
|
import { Button, buttonVariants } from "@/components/ui/button"
|
|
11
|
-
import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from "lucide-react"
|
|
12
13
|
|
|
13
14
|
function Calendar({
|
|
14
15
|
className,
|
|
@@ -16,7 +17,6 @@ function Calendar({
|
|
|
16
17
|
showOutsideDays = true,
|
|
17
18
|
captionLayout = "label",
|
|
18
19
|
buttonVariant = "ghost",
|
|
19
|
-
locale,
|
|
20
20
|
formatters,
|
|
21
21
|
components,
|
|
22
22
|
...props
|
|
@@ -29,95 +29,88 @@ function Calendar({
|
|
|
29
29
|
<DayPicker
|
|
30
30
|
showOutsideDays={showOutsideDays}
|
|
31
31
|
className={cn(
|
|
32
|
-
"group/calendar
|
|
32
|
+
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
33
33
|
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
34
34
|
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
35
35
|
className
|
|
36
36
|
)}
|
|
37
37
|
captionLayout={captionLayout}
|
|
38
|
-
locale={locale}
|
|
39
38
|
formatters={{
|
|
40
39
|
formatMonthDropdown: (date) =>
|
|
41
|
-
date.toLocaleString(
|
|
40
|
+
date.toLocaleString("default", { month: "short" }),
|
|
42
41
|
...formatters,
|
|
43
42
|
}}
|
|
44
43
|
classNames={{
|
|
45
44
|
root: cn("w-fit", defaultClassNames.root),
|
|
46
45
|
months: cn(
|
|
47
|
-
"
|
|
46
|
+
"flex gap-4 flex-col md:flex-row relative",
|
|
48
47
|
defaultClassNames.months
|
|
49
48
|
),
|
|
50
|
-
month: cn("flex w-full
|
|
49
|
+
month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
|
|
51
50
|
nav: cn(
|
|
52
|
-
"
|
|
51
|
+
"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
|
|
53
52
|
defaultClassNames.nav
|
|
54
53
|
),
|
|
55
54
|
button_previous: cn(
|
|
56
55
|
buttonVariants({ variant: buttonVariant }),
|
|
57
|
-
"size-(--cell-size) p-0 select-none
|
|
56
|
+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
|
58
57
|
defaultClassNames.button_previous
|
|
59
58
|
),
|
|
60
59
|
button_next: cn(
|
|
61
60
|
buttonVariants({ variant: buttonVariant }),
|
|
62
|
-
"size-(--cell-size) p-0 select-none
|
|
61
|
+
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
|
63
62
|
defaultClassNames.button_next
|
|
64
63
|
),
|
|
65
64
|
month_caption: cn(
|
|
66
|
-
"flex h-(--cell-size) w-full
|
|
65
|
+
"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
|
|
67
66
|
defaultClassNames.month_caption
|
|
68
67
|
),
|
|
69
68
|
dropdowns: cn(
|
|
70
|
-
"
|
|
69
|
+
"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
|
|
71
70
|
defaultClassNames.dropdowns
|
|
72
71
|
),
|
|
73
72
|
dropdown_root: cn(
|
|
74
|
-
"relative rounded-
|
|
73
|
+
"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
|
|
75
74
|
defaultClassNames.dropdown_root
|
|
76
75
|
),
|
|
77
76
|
dropdown: cn(
|
|
78
|
-
"absolute inset-0
|
|
77
|
+
"absolute bg-popover inset-0 opacity-0",
|
|
79
78
|
defaultClassNames.dropdown
|
|
80
79
|
),
|
|
81
80
|
caption_label: cn(
|
|
82
|
-
"font-medium
|
|
81
|
+
"select-none font-medium",
|
|
83
82
|
captionLayout === "label"
|
|
84
83
|
? "text-sm"
|
|
85
|
-
: "flex items-center gap-1
|
|
84
|
+
: "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
|
|
86
85
|
defaultClassNames.caption_label
|
|
87
86
|
),
|
|
88
87
|
table: "w-full border-collapse",
|
|
89
88
|
weekdays: cn("flex", defaultClassNames.weekdays),
|
|
90
89
|
weekday: cn(
|
|
91
|
-
"
|
|
90
|
+
"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
|
|
92
91
|
defaultClassNames.weekday
|
|
93
92
|
),
|
|
94
|
-
week: cn("
|
|
93
|
+
week: cn("flex w-full mt-2", defaultClassNames.week),
|
|
95
94
|
week_number_header: cn(
|
|
96
|
-
"w-(--cell-size)
|
|
95
|
+
"select-none w-(--cell-size)",
|
|
97
96
|
defaultClassNames.week_number_header
|
|
98
97
|
),
|
|
99
98
|
week_number: cn(
|
|
100
|
-
"text-[0.8rem] text-muted-foreground
|
|
99
|
+
"text-[0.8rem] select-none text-muted-foreground",
|
|
101
100
|
defaultClassNames.week_number
|
|
102
101
|
),
|
|
103
102
|
day: cn(
|
|
104
|
-
"
|
|
105
|
-
props.showWeekNumber
|
|
106
|
-
? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)"
|
|
107
|
-
: "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
|
|
103
|
+
"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",
|
|
108
104
|
defaultClassNames.day
|
|
109
105
|
),
|
|
110
106
|
range_start: cn(
|
|
111
|
-
"
|
|
107
|
+
"rounded-l-md bg-accent",
|
|
112
108
|
defaultClassNames.range_start
|
|
113
109
|
),
|
|
114
110
|
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
|
115
|
-
range_end: cn(
|
|
116
|
-
"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",
|
|
117
|
-
defaultClassNames.range_end
|
|
118
|
-
),
|
|
111
|
+
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
|
|
119
112
|
today: cn(
|
|
120
|
-
"
|
|
113
|
+
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
|
|
121
114
|
defaultClassNames.today
|
|
122
115
|
),
|
|
123
116
|
outside: cn(
|
|
@@ -151,7 +144,10 @@ function Calendar({
|
|
|
151
144
|
|
|
152
145
|
if (orientation === "right") {
|
|
153
146
|
return (
|
|
154
|
-
<ChevronRightIcon
|
|
147
|
+
<ChevronRightIcon
|
|
148
|
+
className={cn("size-4", className)}
|
|
149
|
+
{...props}
|
|
150
|
+
/>
|
|
155
151
|
)
|
|
156
152
|
}
|
|
157
153
|
|
|
@@ -159,9 +155,7 @@ function Calendar({
|
|
|
159
155
|
<ChevronDownIcon className={cn("size-4", className)} {...props} />
|
|
160
156
|
)
|
|
161
157
|
},
|
|
162
|
-
DayButton:
|
|
163
|
-
<CalendarDayButton locale={locale} {...props} />
|
|
164
|
-
),
|
|
158
|
+
DayButton: CalendarDayButton,
|
|
165
159
|
WeekNumber: ({ children, ...props }) => {
|
|
166
160
|
return (
|
|
167
161
|
<td {...props}>
|
|
@@ -182,9 +176,8 @@ function CalendarDayButton({
|
|
|
182
176
|
className,
|
|
183
177
|
day,
|
|
184
178
|
modifiers,
|
|
185
|
-
locale,
|
|
186
179
|
...props
|
|
187
|
-
}: React.ComponentProps<typeof DayButton>
|
|
180
|
+
}: React.ComponentProps<typeof DayButton>) {
|
|
188
181
|
const defaultClassNames = getDefaultClassNames()
|
|
189
182
|
|
|
190
183
|
const ref = React.useRef<HTMLButtonElement>(null)
|
|
@@ -194,9 +187,10 @@ function CalendarDayButton({
|
|
|
194
187
|
|
|
195
188
|
return (
|
|
196
189
|
<Button
|
|
190
|
+
ref={ref}
|
|
197
191
|
variant="ghost"
|
|
198
192
|
size="icon"
|
|
199
|
-
data-day={day.date.toLocaleDateString(
|
|
193
|
+
data-day={day.date.toLocaleDateString()}
|
|
200
194
|
data-selected-single={
|
|
201
195
|
modifiers.selected &&
|
|
202
196
|
!modifiers.range_start &&
|
|
@@ -207,7 +201,7 @@ function CalendarDayButton({
|
|
|
207
201
|
data-range-end={modifiers.range_end}
|
|
208
202
|
data-range-middle={modifiers.range_middle}
|
|
209
203
|
className={cn(
|
|
210
|
-
"
|
|
204
|
+
"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",
|
|
211
205
|
defaultClassNames.day,
|
|
212
206
|
className
|
|
213
207
|
)}
|
|
@@ -1,103 +1,82 @@
|
|
|
1
|
-
import * as React from "react"
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import { cn } from "@/lib/utils"
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
/>
|
|
20
|
-
)
|
|
21
|
-
}
|
|
5
|
+
const Card = React.forwardRef<
|
|
6
|
+
HTMLDivElement,
|
|
7
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
8
|
+
>(({ className, ...props }, ref) => (
|
|
9
|
+
<div
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={cn(
|
|
12
|
+
"rounded-xl border bg-card border-card-border text-card-foreground shadow-sm",
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
));
|
|
18
|
+
Card.displayName = "Card"
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
20
|
+
const CardHeader = React.forwardRef<
|
|
21
|
+
HTMLDivElement,
|
|
22
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
23
|
+
>(({ className, ...props }, ref) => (
|
|
24
|
+
<div
|
|
25
|
+
ref={ref}
|
|
26
|
+
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
));
|
|
30
|
+
CardHeader.displayName = "CardHeader"
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
32
|
+
const CardTitle = React.forwardRef<
|
|
33
|
+
HTMLDivElement,
|
|
34
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
35
|
+
>(({ className, ...props }, ref) => (
|
|
36
|
+
<div
|
|
37
|
+
ref={ref}
|
|
38
|
+
className={cn(
|
|
39
|
+
"text-2xl font-semibold leading-none tracking-tight",
|
|
40
|
+
className
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
))
|
|
45
|
+
CardTitle.displayName = "CardTitle"
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
const CardDescription = React.forwardRef<
|
|
48
|
+
HTMLDivElement,
|
|
49
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
50
|
+
>(({ className, ...props }, ref) => (
|
|
51
|
+
<div
|
|
52
|
+
ref={ref}
|
|
53
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
));
|
|
57
|
+
CardDescription.displayName = "CardDescription"
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
)}
|
|
67
|
-
{...props}
|
|
68
|
-
/>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
59
|
+
const CardContent = React.forwardRef<
|
|
60
|
+
HTMLDivElement,
|
|
61
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
62
|
+
>(({ className, ...props }, ref) => (
|
|
63
|
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
64
|
+
))
|
|
65
|
+
CardContent.displayName = "CardContent"
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<div
|
|
85
|
-
data-slot="card-footer"
|
|
86
|
-
className={cn(
|
|
87
|
-
"flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3",
|
|
88
|
-
className
|
|
89
|
-
)}
|
|
90
|
-
{...props}
|
|
91
|
-
/>
|
|
92
|
-
)
|
|
93
|
-
}
|
|
67
|
+
const CardFooter = React.forwardRef<
|
|
68
|
+
HTMLDivElement,
|
|
69
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
70
|
+
>(({ className, ...props }, ref) => (
|
|
71
|
+
<div
|
|
72
|
+
ref={ref}
|
|
73
|
+
className={cn("flex items-center p-6 pt-0", className)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
))
|
|
77
|
+
CardFooter.displayName = "CardFooter"
|
|
94
78
|
|
|
95
79
|
export {
|
|
96
|
-
Card,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
CardTitle,
|
|
100
|
-
CardAction,
|
|
101
|
-
CardDescription,
|
|
102
|
-
CardContent,
|
|
103
|
-
}
|
|
80
|
+
Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle
|
|
81
|
+
};
|
|
82
|
+
|
|
@@ -4,10 +4,10 @@ import * as React from "react"
|
|
|
4
4
|
import useEmblaCarousel, {
|
|
5
5
|
type UseEmblaCarouselType,
|
|
6
6
|
} from "embla-carousel-react"
|
|
7
|
+
import { ArrowLeft, ArrowRight } from "lucide-react"
|
|
7
8
|
|
|
8
9
|
import { cn } from "@/lib/utils"
|
|
9
10
|
import { Button } from "@/components/ui/button"
|
|
10
|
-
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"
|
|
11
11
|
|
|
12
12
|
type CarouselApi = UseEmblaCarouselType[1]
|
|
13
13
|
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
|
@@ -174,7 +174,7 @@ function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
174
174
|
function CarouselPrevious({
|
|
175
175
|
className,
|
|
176
176
|
variant = "outline",
|
|
177
|
-
size = "icon
|
|
177
|
+
size = "icon",
|
|
178
178
|
...props
|
|
179
179
|
}: React.ComponentProps<typeof Button>) {
|
|
180
180
|
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
|
|
@@ -185,7 +185,7 @@ function CarouselPrevious({
|
|
|
185
185
|
variant={variant}
|
|
186
186
|
size={size}
|
|
187
187
|
className={cn(
|
|
188
|
-
"absolute
|
|
188
|
+
"absolute size-8 rounded-full",
|
|
189
189
|
orientation === "horizontal"
|
|
190
190
|
? "top-1/2 -left-12 -translate-y-1/2"
|
|
191
191
|
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
@@ -195,7 +195,7 @@ function CarouselPrevious({
|
|
|
195
195
|
onClick={scrollPrev}
|
|
196
196
|
{...props}
|
|
197
197
|
>
|
|
198
|
-
<
|
|
198
|
+
<ArrowLeft />
|
|
199
199
|
<span className="sr-only">Previous slide</span>
|
|
200
200
|
</Button>
|
|
201
201
|
)
|
|
@@ -204,7 +204,7 @@ function CarouselPrevious({
|
|
|
204
204
|
function CarouselNext({
|
|
205
205
|
className,
|
|
206
206
|
variant = "outline",
|
|
207
|
-
size = "icon
|
|
207
|
+
size = "icon",
|
|
208
208
|
...props
|
|
209
209
|
}: React.ComponentProps<typeof Button>) {
|
|
210
210
|
const { orientation, scrollNext, canScrollNext } = useCarousel()
|
|
@@ -215,7 +215,7 @@ function CarouselNext({
|
|
|
215
215
|
variant={variant}
|
|
216
216
|
size={size}
|
|
217
217
|
className={cn(
|
|
218
|
-
"absolute
|
|
218
|
+
"absolute size-8 rounded-full",
|
|
219
219
|
orientation === "horizontal"
|
|
220
220
|
? "top-1/2 -right-12 -translate-y-1/2"
|
|
221
221
|
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
@@ -225,7 +225,7 @@ function CarouselNext({
|
|
|
225
225
|
onClick={scrollNext}
|
|
226
226
|
{...props}
|
|
227
227
|
>
|
|
228
|
-
<
|
|
228
|
+
<ArrowRight />
|
|
229
229
|
<span className="sr-only">Next slide</span>
|
|
230
230
|
</Button>
|
|
231
231
|
)
|
|
@@ -238,5 +238,4 @@ export {
|
|
|
238
238
|
CarouselItem,
|
|
239
239
|
CarouselPrevious,
|
|
240
240
|
CarouselNext,
|
|
241
|
-
useCarousel,
|
|
242
241
|
}
|
|
@@ -1,25 +1,22 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
1
3
|
import * as React from "react"
|
|
2
4
|
import * as RechartsPrimitive from "recharts"
|
|
3
|
-
import type { TooltipValueType } from "recharts"
|
|
4
5
|
|
|
5
6
|
import { cn } from "@/lib/utils"
|
|
6
7
|
|
|
7
8
|
// Format: { THEME_NAME: CSS_SELECTOR }
|
|
8
9
|
const THEMES = { light: "", dark: ".dark" } as const
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export type ChartConfig = Record<
|
|
14
|
-
string,
|
|
15
|
-
{
|
|
11
|
+
export type ChartConfig = {
|
|
12
|
+
[k in string]: {
|
|
16
13
|
label?: React.ReactNode
|
|
17
14
|
icon?: React.ComponentType
|
|
18
15
|
} & (
|
|
19
16
|
| { color?: string; theme?: never }
|
|
20
17
|
| { color?: never; theme: Record<keyof typeof THEMES, string> }
|
|
21
18
|
)
|
|
22
|
-
|
|
19
|
+
}
|
|
23
20
|
|
|
24
21
|
type ChartContextProps = {
|
|
25
22
|
config: ChartConfig
|
|
@@ -42,20 +39,15 @@ function ChartContainer({
|
|
|
42
39
|
className,
|
|
43
40
|
children,
|
|
44
41
|
config,
|
|
45
|
-
initialDimension = INITIAL_DIMENSION,
|
|
46
42
|
...props
|
|
47
43
|
}: React.ComponentProps<"div"> & {
|
|
48
44
|
config: ChartConfig
|
|
49
45
|
children: React.ComponentProps<
|
|
50
46
|
typeof RechartsPrimitive.ResponsiveContainer
|
|
51
47
|
>["children"]
|
|
52
|
-
initialDimension?: {
|
|
53
|
-
width: number
|
|
54
|
-
height: number
|
|
55
|
-
}
|
|
56
48
|
}) {
|
|
57
49
|
const uniqueId = React.useId()
|
|
58
|
-
const chartId = `chart-${id
|
|
50
|
+
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
|
|
59
51
|
|
|
60
52
|
return (
|
|
61
53
|
<ChartContext.Provider value={{ config }}>
|
|
@@ -63,15 +55,13 @@ function ChartContainer({
|
|
|
63
55
|
data-slot="chart"
|
|
64
56
|
data-chart={chartId}
|
|
65
57
|
className={cn(
|
|
66
|
-
"
|
|
58
|
+
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
|
|
67
59
|
className
|
|
68
60
|
)}
|
|
69
61
|
{...props}
|
|
70
62
|
>
|
|
71
63
|
<ChartStyle id={chartId} config={config} />
|
|
72
|
-
<RechartsPrimitive.ResponsiveContainer
|
|
73
|
-
initialDimension={initialDimension}
|
|
74
|
-
>
|
|
64
|
+
<RechartsPrimitive.ResponsiveContainer>
|
|
75
65
|
{children}
|
|
76
66
|
</RechartsPrimitive.ResponsiveContainer>
|
|
77
67
|
</div>
|
|
@@ -81,7 +71,7 @@ function ChartContainer({
|
|
|
81
71
|
|
|
82
72
|
const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
|
|
83
73
|
const colorConfig = Object.entries(config).filter(
|
|
84
|
-
([, config]) => config.theme
|
|
74
|
+
([, config]) => config.theme || config.color
|
|
85
75
|
)
|
|
86
76
|
|
|
87
77
|
if (!colorConfig.length) {
|
|
@@ -98,7 +88,7 @@ ${prefix} [data-chart=${id}] {
|
|
|
98
88
|
${colorConfig
|
|
99
89
|
.map(([key, itemConfig]) => {
|
|
100
90
|
const color =
|
|
101
|
-
itemConfig.theme?.[theme as keyof typeof itemConfig.theme]
|
|
91
|
+
itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
|
|
102
92
|
itemConfig.color
|
|
103
93
|
return color ? ` --color-${key}: ${color};` : null
|
|
104
94
|
})
|
|
@@ -135,13 +125,7 @@ function ChartTooltipContent({
|
|
|
135
125
|
indicator?: "line" | "dot" | "dashed"
|
|
136
126
|
nameKey?: string
|
|
137
127
|
labelKey?: string
|
|
138
|
-
}
|
|
139
|
-
RechartsPrimitive.DefaultTooltipContentProps<
|
|
140
|
-
TooltipValueType,
|
|
141
|
-
TooltipNameType
|
|
142
|
-
>,
|
|
143
|
-
"accessibilityLayer"
|
|
144
|
-
>) {
|
|
128
|
+
}) {
|
|
145
129
|
const { config } = useChart()
|
|
146
130
|
|
|
147
131
|
const tooltipLabel = React.useMemo(() => {
|
|
@@ -150,11 +134,11 @@ function ChartTooltipContent({
|
|
|
150
134
|
}
|
|
151
135
|
|
|
152
136
|
const [item] = payload
|
|
153
|
-
const key = `${labelKey
|
|
137
|
+
const key = `${labelKey || item?.dataKey || item?.name || "value"}`
|
|
154
138
|
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
|
155
139
|
const value =
|
|
156
140
|
!labelKey && typeof label === "string"
|
|
157
|
-
?
|
|
141
|
+
? config[label as keyof typeof config]?.label || label
|
|
158
142
|
: itemConfig?.label
|
|
159
143
|
|
|
160
144
|
if (labelFormatter) {
|
|
@@ -189,7 +173,7 @@ function ChartTooltipContent({
|
|
|
189
173
|
return (
|
|
190
174
|
<div
|
|
191
175
|
className={cn(
|
|
192
|
-
"grid min-w-
|
|
176
|
+
"border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl",
|
|
193
177
|
className
|
|
194
178
|
)}
|
|
195
179
|
>
|
|
@@ -198,15 +182,15 @@ function ChartTooltipContent({
|
|
|
198
182
|
{payload
|
|
199
183
|
.filter((item) => item.type !== "none")
|
|
200
184
|
.map((item, index) => {
|
|
201
|
-
const key = `${nameKey
|
|
185
|
+
const key = `${nameKey || item.name || item.dataKey || "value"}`
|
|
202
186
|
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
|
203
|
-
const indicatorColor = color
|
|
187
|
+
const indicatorColor = color || item.payload.fill || item.color
|
|
204
188
|
|
|
205
189
|
return (
|
|
206
190
|
<div
|
|
207
|
-
key={
|
|
191
|
+
key={item.dataKey}
|
|
208
192
|
className={cn(
|
|
209
|
-
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5
|
|
193
|
+
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
|
|
210
194
|
indicator === "dot" && "items-center"
|
|
211
195
|
)}
|
|
212
196
|
>
|
|
@@ -247,14 +231,12 @@ function ChartTooltipContent({
|
|
|
247
231
|
<div className="grid gap-1.5">
|
|
248
232
|
{nestLabel ? tooltipLabel : null}
|
|
249
233
|
<span className="text-muted-foreground">
|
|
250
|
-
{itemConfig?.label
|
|
234
|
+
{itemConfig?.label || item.name}
|
|
251
235
|
</span>
|
|
252
236
|
</div>
|
|
253
|
-
{item.value
|
|
254
|
-
<span className="font-mono font-medium
|
|
255
|
-
{
|
|
256
|
-
? item.value.toLocaleString()
|
|
257
|
-
: String(item.value)}
|
|
237
|
+
{item.value && (
|
|
238
|
+
<span className="text-foreground font-mono font-medium tabular-nums">
|
|
239
|
+
{item.value.toLocaleString()}
|
|
258
240
|
</span>
|
|
259
241
|
)}
|
|
260
242
|
</div>
|
|
@@ -276,10 +258,11 @@ function ChartLegendContent({
|
|
|
276
258
|
payload,
|
|
277
259
|
verticalAlign = "bottom",
|
|
278
260
|
nameKey,
|
|
279
|
-
}: React.ComponentProps<"div"> &
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
261
|
+
}: React.ComponentProps<"div"> &
|
|
262
|
+
Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
|
|
263
|
+
hideIcon?: boolean
|
|
264
|
+
nameKey?: string
|
|
265
|
+
}) {
|
|
283
266
|
const { config } = useChart()
|
|
284
267
|
|
|
285
268
|
if (!payload?.length) {
|
|
@@ -296,15 +279,15 @@ function ChartLegendContent({
|
|
|
296
279
|
>
|
|
297
280
|
{payload
|
|
298
281
|
.filter((item) => item.type !== "none")
|
|
299
|
-
.map((item
|
|
300
|
-
const key = `${nameKey
|
|
282
|
+
.map((item) => {
|
|
283
|
+
const key = `${nameKey || item.dataKey || "value"}`
|
|
301
284
|
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
|
302
285
|
|
|
303
286
|
return (
|
|
304
287
|
<div
|
|
305
|
-
key={
|
|
288
|
+
key={item.value}
|
|
306
289
|
className={cn(
|
|
307
|
-
"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3
|
|
290
|
+
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
|
|
308
291
|
)}
|
|
309
292
|
>
|
|
310
293
|
{itemConfig?.icon && !hideIcon ? (
|
|
@@ -325,6 +308,7 @@ function ChartLegendContent({
|
|
|
325
308
|
)
|
|
326
309
|
}
|
|
327
310
|
|
|
311
|
+
// Helper to extract item config from a payload.
|
|
328
312
|
function getPayloadConfigFromPayload(
|
|
329
313
|
config: ChartConfig,
|
|
330
314
|
payload: unknown,
|
|
@@ -358,7 +342,9 @@ function getPayloadConfigFromPayload(
|
|
|
358
342
|
] as string
|
|
359
343
|
}
|
|
360
344
|
|
|
361
|
-
return configLabelKey in config
|
|
345
|
+
return configLabelKey in config
|
|
346
|
+
? config[configLabelKey]
|
|
347
|
+
: config[key as keyof typeof config]
|
|
362
348
|
}
|
|
363
349
|
|
|
364
350
|
export {
|