@mbao01/common 0.8.1 → 0.9.1
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/types/components/ActivityFeed/ActivityFeed.d.ts +6 -0
- package/dist/types/components/ActivityFeed/constants.d.ts +6 -0
- package/dist/types/components/ActivityFeed/index.d.ts +2 -0
- package/dist/types/components/ActivityFeed/types.d.ts +21 -0
- package/dist/types/components/Amount/Amount.d.ts +6 -0
- package/dist/types/components/Amount/index.d.ts +2 -0
- package/dist/types/components/Amount/types.d.ts +19 -0
- package/dist/types/components/AnimatedCounter/AnimatedCounter.d.ts +6 -0
- package/dist/types/components/AnimatedCounter/index.d.ts +2 -0
- package/dist/types/components/AnimatedCounter/types.d.ts +13 -0
- package/dist/types/components/AnimatedGroup/AnimatedGroup.d.ts +6 -0
- package/dist/types/components/AnimatedGroup/index.d.ts +2 -0
- package/dist/types/components/AnimatedGroup/types.d.ts +22 -0
- package/dist/types/components/AnimatedList/AnimatedList.d.ts +6 -0
- package/dist/types/components/AnimatedList/index.d.ts +2 -0
- package/dist/types/components/AnimatedList/types.d.ts +13 -0
- package/dist/types/components/BorderBeam/BorderBeam.d.ts +6 -0
- package/dist/types/components/BorderBeam/index.d.ts +2 -0
- package/dist/types/components/BorderBeam/types.d.ts +13 -0
- package/dist/types/components/Box/Box.d.ts +4 -0
- package/dist/types/components/Box/constants.d.ts +4 -0
- package/dist/types/components/CalendarHeatmap/CalendarHeatmap.d.ts +6 -0
- package/dist/types/components/CalendarHeatmap/index.d.ts +2 -0
- package/dist/types/components/CalendarHeatmap/types.d.ts +25 -0
- package/dist/types/components/Chart/stories/examples/AreaChart.d.ts +6 -0
- package/dist/types/components/Chart/stories/examples/BarChart.d.ts +11 -0
- package/dist/types/components/Chart/stories/examples/LineChart.d.ts +10 -0
- package/dist/types/components/Chart/stories/examples/PieChart.d.ts +5 -0
- package/dist/types/components/Chart/stories/examples/RadialChart.d.ts +5 -0
- package/dist/types/components/CircularProgress/CircularProgress.d.ts +6 -0
- package/dist/types/components/CircularProgress/constants.d.ts +5 -0
- package/dist/types/components/CircularProgress/index.d.ts +2 -0
- package/dist/types/components/CircularProgress/types.d.ts +17 -0
- package/dist/types/components/ComparisonBar/ComparisonBar.d.ts +6 -0
- package/dist/types/components/ComparisonBar/constants.d.ts +4 -0
- package/dist/types/components/ComparisonBar/index.d.ts +2 -0
- package/dist/types/components/ComparisonBar/types.d.ts +21 -0
- package/dist/types/components/Confetti/Confetti.d.ts +6 -0
- package/dist/types/components/Confetti/index.d.ts +2 -0
- package/dist/types/components/Confetti/types.d.ts +19 -0
- package/dist/types/components/CountdownTimer/CountdownTimer.d.ts +6 -0
- package/dist/types/components/CountdownTimer/index.d.ts +2 -0
- package/dist/types/components/CountdownTimer/types.d.ts +13 -0
- package/dist/types/components/DataList/DataList.d.ts +6 -0
- package/dist/types/components/DataList/constants.d.ts +12 -0
- package/dist/types/components/DataList/index.d.ts +2 -0
- package/dist/types/components/DataList/types.d.ts +15 -0
- package/dist/types/components/DatePicker/DateRangePresetPicker.d.ts +2 -0
- package/dist/types/components/DatePicker/index.d.ts +1 -0
- package/dist/types/components/DatePicker/types.d.ts +19 -0
- package/dist/types/components/Description/Description.d.ts +2 -1
- package/dist/types/components/Description/DescriptionGroup.d.ts +6 -0
- package/dist/types/components/Description/constants.d.ts +23 -0
- package/dist/types/components/Description/index.d.ts +2 -0
- package/dist/types/components/Description/types.d.ts +28 -3
- package/dist/types/components/Form/DatetimeInput/DatetimeInput.d.ts +1 -1
- package/dist/types/components/GlowCard/GlowCard.d.ts +6 -0
- package/dist/types/components/GlowCard/index.d.ts +2 -0
- package/dist/types/components/GlowCard/types.d.ts +8 -0
- package/dist/types/components/GradientText/GradientText.d.ts +6 -0
- package/dist/types/components/GradientText/index.d.ts +2 -0
- package/dist/types/components/GradientText/types.d.ts +14 -0
- package/dist/types/components/Greeting/Greeting.d.ts +6 -0
- package/dist/types/components/Greeting/index.d.ts +2 -0
- package/dist/types/components/Greeting/types.d.ts +9 -0
- package/dist/types/components/IconContainer/IconContainer.d.ts +2 -0
- package/dist/types/components/IconContainer/constants.d.ts +15 -0
- package/dist/types/components/IconContainer/index.d.ts +1 -0
- package/dist/types/components/IconContainer/types.d.ts +3 -0
- package/dist/types/components/KPICard/KPICard.d.ts +6 -0
- package/dist/types/components/KPICard/index.d.ts +2 -0
- package/dist/types/components/KPICard/types.d.ts +17 -0
- package/dist/types/components/Marquee/Marquee.d.ts +6 -0
- package/dist/types/components/Marquee/index.d.ts +2 -0
- package/dist/types/components/Marquee/types.d.ts +12 -0
- package/dist/types/components/Meteors/Meteors.d.ts +6 -0
- package/dist/types/components/Meteors/index.d.ts +2 -0
- package/dist/types/components/Meteors/types.d.ts +5 -0
- package/dist/types/components/MiniAreaChart/MiniAreaChart.d.ts +6 -0
- package/dist/types/components/MiniAreaChart/index.d.ts +2 -0
- package/dist/types/components/MiniAreaChart/types.d.ts +10 -0
- package/dist/types/components/MiniBarChart/MiniBarChart.d.ts +6 -0
- package/dist/types/components/MiniBarChart/index.d.ts +2 -0
- package/dist/types/components/MiniBarChart/types.d.ts +15 -0
- package/dist/types/components/MiniDonutChart/MiniDonutChart.d.ts +6 -0
- package/dist/types/components/MiniDonutChart/index.d.ts +2 -0
- package/dist/types/components/MiniDonutChart/types.d.ts +15 -0
- package/dist/types/components/MiniStackedBar/MiniStackedBar.d.ts +6 -0
- package/dist/types/components/MiniStackedBar/index.d.ts +2 -0
- package/dist/types/components/MiniStackedBar/types.d.ts +13 -0
- package/dist/types/components/NumberTicker/NumberTicker.d.ts +6 -0
- package/dist/types/components/NumberTicker/index.d.ts +2 -0
- package/dist/types/components/NumberTicker/types.d.ts +11 -0
- package/dist/types/components/Pulse/Pulse.d.ts +6 -0
- package/dist/types/components/Pulse/constants.d.ts +10 -0
- package/dist/types/components/Pulse/index.d.ts +2 -0
- package/dist/types/components/Pulse/types.d.ts +11 -0
- package/dist/types/components/ShinyButton/ShinyButton.d.ts +6 -0
- package/dist/types/components/ShinyButton/index.d.ts +2 -0
- package/dist/types/components/ShinyButton/types.d.ts +4 -0
- package/dist/types/components/Sparkline/Sparkline.d.ts +6 -0
- package/dist/types/components/Sparkline/index.d.ts +2 -0
- package/dist/types/components/Sparkline/types.d.ts +17 -0
- package/dist/types/components/SpotlightCard/SpotlightCard.d.ts +6 -0
- package/dist/types/components/SpotlightCard/index.d.ts +2 -0
- package/dist/types/components/SpotlightCard/types.d.ts +7 -0
- package/dist/types/components/StatCard/StatCard.d.ts +6 -0
- package/dist/types/components/StatCard/index.d.ts +2 -0
- package/dist/types/components/StatCard/types.d.ts +15 -0
- package/dist/types/components/TextShimmer/TextShimmer.d.ts +6 -0
- package/dist/types/components/TextShimmer/index.d.ts +2 -0
- package/dist/types/components/TextShimmer/types.d.ts +7 -0
- package/dist/types/components/TrendBadge/TrendBadge.d.ts +6 -0
- package/dist/types/components/TrendBadge/constants.d.ts +7 -0
- package/dist/types/components/TrendBadge/index.d.ts +2 -0
- package/dist/types/components/TrendBadge/types.d.ts +15 -0
- package/dist/types/components/WidgetShell/WidgetShell.d.ts +6 -0
- package/dist/types/components/WidgetShell/index.d.ts +2 -0
- package/dist/types/components/WidgetShell/types.d.ts +20 -0
- package/dist/types/index.d.ts +34 -0
- package/package.json +2 -1
- package/src/components/Accordion/constants.ts +1 -1
- package/src/components/ActivityFeed/ActivityFeed.tsx +51 -0
- package/src/components/ActivityFeed/constants.ts +19 -0
- package/src/components/ActivityFeed/index.ts +2 -0
- package/src/components/ActivityFeed/types.ts +23 -0
- package/src/components/Alert/constants.ts +1 -1
- package/src/components/AlertDialog/constants.ts +1 -1
- package/src/components/Amount/Amount.tsx +50 -0
- package/src/components/Amount/index.ts +2 -0
- package/src/components/Amount/types.ts +20 -0
- package/src/components/AnimatedCounter/AnimatedCounter.tsx +68 -0
- package/src/components/AnimatedCounter/index.ts +2 -0
- package/src/components/AnimatedCounter/types.ts +14 -0
- package/src/components/AnimatedGroup/AnimatedGroup.tsx +97 -0
- package/src/components/AnimatedGroup/index.ts +2 -0
- package/src/components/AnimatedGroup/types.ts +21 -0
- package/src/components/AnimatedList/AnimatedList.tsx +42 -0
- package/src/components/AnimatedList/index.ts +2 -0
- package/src/components/AnimatedList/types.ts +15 -0
- package/src/components/Badge/constants.ts +1 -1
- package/src/components/Banner/constants.ts +1 -1
- package/src/components/BorderBeam/BorderBeam.tsx +41 -0
- package/src/components/BorderBeam/index.ts +2 -0
- package/src/components/BorderBeam/types.ts +14 -0
- package/src/components/Box/Box.tsx +8 -2
- package/src/components/Box/constants.ts +35 -0
- package/src/components/Button/constants.ts +66 -63
- package/src/components/CalendarHeatmap/CalendarHeatmap.tsx +141 -0
- package/src/components/CalendarHeatmap/index.ts +2 -0
- package/src/components/CalendarHeatmap/types.ts +27 -0
- package/src/components/Card/constants.ts +24 -21
- package/src/components/Carousel/constants.ts +2 -2
- package/src/components/Chart/stories/examples/AreaChart.tsx +55 -0
- package/src/components/Chart/stories/examples/BarChart.tsx +95 -0
- package/src/components/Chart/stories/examples/LineChart.tsx +111 -0
- package/src/components/Chart/stories/examples/PieChart.tsx +55 -0
- package/src/components/Chart/stories/examples/RadialChart.tsx +65 -0
- package/src/components/CircularProgress/CircularProgress.tsx +46 -0
- package/src/components/CircularProgress/constants.ts +32 -0
- package/src/components/CircularProgress/index.ts +2 -0
- package/src/components/CircularProgress/types.ts +18 -0
- package/src/components/Command/constants.ts +1 -1
- package/src/components/ComparisonBar/ComparisonBar.tsx +65 -0
- package/src/components/ComparisonBar/constants.ts +23 -0
- package/src/components/ComparisonBar/index.ts +2 -0
- package/src/components/ComparisonBar/types.ts +23 -0
- package/src/components/Confetti/Confetti.tsx +82 -0
- package/src/components/Confetti/index.ts +2 -0
- package/src/components/Confetti/types.ts +20 -0
- package/src/components/CountdownTimer/CountdownTimer.tsx +91 -0
- package/src/components/CountdownTimer/index.ts +2 -0
- package/src/components/CountdownTimer/types.ts +14 -0
- package/src/components/DataList/DataList.tsx +32 -0
- package/src/components/DataList/constants.ts +47 -0
- package/src/components/DataList/index.ts +2 -0
- package/src/components/DataList/types.ts +17 -0
- package/src/components/DatePicker/DateRangePresetPicker.tsx +122 -0
- package/src/components/DatePicker/index.ts +1 -0
- package/src/components/DatePicker/types.ts +22 -0
- package/src/components/Description/Description.tsx +67 -5
- package/src/components/Description/DescriptionGroup.tsx +39 -0
- package/src/components/Description/constants.ts +128 -0
- package/src/components/Description/index.ts +10 -0
- package/src/components/Description/types.ts +31 -3
- package/src/components/Dialog/constants.ts +2 -2
- package/src/components/Dock/constants.ts +2 -2
- package/src/components/Drawer/constants.ts +2 -2
- package/src/components/Form/Checkbox/constants.ts +1 -1
- package/src/components/Form/DatetimeInput/constants.ts +1 -1
- package/src/components/Form/Input/constants.ts +1 -1
- package/src/components/Form/MultiSelect/constants.ts +1 -1
- package/src/components/Form/NativeSelect/constants.ts +1 -1
- package/src/components/Form/Radio/constants.ts +1 -1
- package/src/components/Form/Select/constants.ts +1 -1
- package/src/components/Form/Slider/constants.ts +1 -1
- package/src/components/Form/Switch/constants.ts +1 -1
- package/src/components/Form/Textarea/constants.ts +1 -1
- package/src/components/GlowCard/GlowCard.tsx +46 -0
- package/src/components/GlowCard/index.ts +2 -0
- package/src/components/GlowCard/types.ts +9 -0
- package/src/components/GradientText/GradientText.tsx +36 -0
- package/src/components/GradientText/index.ts +2 -0
- package/src/components/GradientText/types.ts +15 -0
- package/src/components/Greeting/Greeting.tsx +46 -0
- package/src/components/Greeting/index.ts +2 -0
- package/src/components/Greeting/types.ts +10 -0
- package/src/components/IconContainer/IconContainer.tsx +44 -0
- package/src/components/IconContainer/constants.ts +112 -0
- package/src/components/IconContainer/index.ts +1 -0
- package/src/components/IconContainer/types.ts +5 -0
- package/src/components/KPICard/KPICard.tsx +75 -0
- package/src/components/KPICard/index.ts +2 -0
- package/src/components/KPICard/types.ts +18 -0
- package/src/components/Marquee/Marquee.tsx +45 -0
- package/src/components/Marquee/index.ts +2 -0
- package/src/components/Marquee/types.ts +13 -0
- package/src/components/Menu/Menubar/constants.ts +2 -2
- package/src/components/Menu/NavigationMenu/constants.ts +2 -2
- package/src/components/Meteors/Meteors.tsx +38 -0
- package/src/components/Meteors/index.ts +2 -0
- package/src/components/Meteors/types.ts +6 -0
- package/src/components/MiniAreaChart/MiniAreaChart.tsx +68 -0
- package/src/components/MiniAreaChart/index.ts +2 -0
- package/src/components/MiniAreaChart/types.ts +11 -0
- package/src/components/MiniBarChart/MiniBarChart.tsx +49 -0
- package/src/components/MiniBarChart/index.ts +2 -0
- package/src/components/MiniBarChart/types.ts +16 -0
- package/src/components/MiniDonutChart/MiniDonutChart.tsx +87 -0
- package/src/components/MiniDonutChart/index.ts +2 -0
- package/src/components/MiniDonutChart/types.ts +17 -0
- package/src/components/MiniStackedBar/MiniStackedBar.tsx +61 -0
- package/src/components/MiniStackedBar/index.ts +2 -0
- package/src/components/MiniStackedBar/types.ts +15 -0
- package/src/components/NumberTicker/NumberTicker.tsx +58 -0
- package/src/components/NumberTicker/index.ts +2 -0
- package/src/components/NumberTicker/types.ts +12 -0
- package/src/components/Pagination/constants.ts +2 -2
- package/src/components/Progress/constants.ts +1 -1
- package/src/components/Pulse/Pulse.tsx +26 -0
- package/src/components/Pulse/constants.ts +55 -0
- package/src/components/Pulse/index.ts +2 -0
- package/src/components/Pulse/types.ts +12 -0
- package/src/components/Resizable/constants.ts +1 -1
- package/src/components/Sheet/constants.ts +1 -1
- package/src/components/ShinyButton/ShinyButton.tsx +57 -0
- package/src/components/ShinyButton/index.ts +2 -0
- package/src/components/ShinyButton/types.ts +8 -0
- package/src/components/Skeleton/constants.ts +1 -1
- package/src/components/Sonner/constants.ts +1 -1
- package/src/components/Sparkline/Sparkline.tsx +108 -0
- package/src/components/Sparkline/index.ts +2 -0
- package/src/components/Sparkline/types.ts +18 -0
- package/src/components/SpotlightCard/SpotlightCard.tsx +56 -0
- package/src/components/SpotlightCard/index.ts +2 -0
- package/src/components/SpotlightCard/types.ts +8 -0
- package/src/components/Stat/constants.ts +1 -1
- package/src/components/StatCard/StatCard.tsx +59 -0
- package/src/components/StatCard/index.ts +2 -0
- package/src/components/StatCard/types.ts +16 -0
- package/src/components/Tabs/constants.ts +1 -1
- package/src/components/TextShimmer/TextShimmer.tsx +34 -0
- package/src/components/TextShimmer/index.ts +2 -0
- package/src/components/TextShimmer/types.ts +8 -0
- package/src/components/Timeline/constants.ts +1 -1
- package/src/components/Toggle/constants.ts +1 -1
- package/src/components/Tooltip/constants.ts +1 -1
- package/src/components/TrendBadge/TrendBadge.tsx +40 -0
- package/src/components/TrendBadge/constants.ts +38 -0
- package/src/components/TrendBadge/index.ts +2 -0
- package/src/components/TrendBadge/types.ts +16 -0
- package/src/components/WidgetShell/WidgetShell.tsx +101 -0
- package/src/components/WidgetShell/index.ts +2 -0
- package/src/components/WidgetShell/types.ts +22 -0
- package/src/index.ts +36 -0
- package/src/stylesheets/tailwind.css +208 -0
- package/src/utilities/getSubpaths/getSubpaths.ts +1 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cva } from "../../../libs";
|
|
2
2
|
import { createVariants } from "../../../utilities";
|
|
3
3
|
|
|
4
|
-
export const getNativeSelectClasses = cva("select", {
|
|
4
|
+
export const getNativeSelectClasses = cva("select transition-all duration-200", {
|
|
5
5
|
variants: createVariants({
|
|
6
6
|
nativeOptions: {
|
|
7
7
|
true: "appearance-none",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cva } from "../../../libs";
|
|
2
2
|
import { createVariants } from "../../../utilities";
|
|
3
3
|
|
|
4
|
-
export const getRadioClasses = cva("radio", {
|
|
4
|
+
export const getRadioClasses = cva("radio transition-all duration-200", {
|
|
5
5
|
variants: createVariants({
|
|
6
6
|
variant: {
|
|
7
7
|
primary: "radio-primary",
|
|
@@ -2,7 +2,7 @@ import { cva } from "../../../libs";
|
|
|
2
2
|
import { createVariants } from "../../../utilities";
|
|
3
3
|
|
|
4
4
|
export const getSelectTriggerClasses = cva(
|
|
5
|
-
"select flex items-center justify-between rounded-md text-sm text-left disabled:cursor-not-allowed disabled:opacity-50 transition-all duration-
|
|
5
|
+
"select flex items-center justify-between rounded-md text-sm text-left disabled:cursor-not-allowed disabled:opacity-50 transition-all duration-200",
|
|
6
6
|
{
|
|
7
7
|
variants: createVariants({
|
|
8
8
|
variant: {
|
|
@@ -58,7 +58,7 @@ export const getSliderClasses = cva("absolute h-full", {
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
export const getSliderThumbClasses = cva(
|
|
61
|
-
"block h-5 w-5 rounded-full border-2 ring-offset-neutral transition-
|
|
61
|
+
"block h-5 w-5 rounded-full border-2 ring-offset-neutral transition-all duration-200 hover:scale-110 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
62
62
|
{
|
|
63
63
|
variants: createVariants({
|
|
64
64
|
variant: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cva } from "../../../libs";
|
|
2
2
|
import { createVariants } from "../../../utilities";
|
|
3
3
|
|
|
4
|
-
export const getSwitchClasses = cva("toggle", {
|
|
4
|
+
export const getSwitchClasses = cva("toggle transition-all duration-200", {
|
|
5
5
|
variants: createVariants({
|
|
6
6
|
variant: {
|
|
7
7
|
primary: "toggle-primary",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cva } from "../../../libs";
|
|
2
2
|
import { createVariants } from "../../../utilities";
|
|
3
3
|
|
|
4
|
-
export const getTextareaClasses = cva("textarea rounded-md transition-all duration-
|
|
4
|
+
export const getTextareaClasses = cva("textarea rounded-md transition-all duration-200", {
|
|
5
5
|
variants: createVariants({
|
|
6
6
|
variant: {
|
|
7
7
|
default: "bg-transparent",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import { cn } from "../../utilities";
|
|
3
|
+
import type { GlowCardProps } from "./types";
|
|
4
|
+
|
|
5
|
+
const GlowCard = ({
|
|
6
|
+
children,
|
|
7
|
+
className,
|
|
8
|
+
gradientFrom = "oklch(0.7 0.25 250)",
|
|
9
|
+
gradientVia = "oklch(0.7 0.2 330)",
|
|
10
|
+
gradientTo = "oklch(0.7 0.25 150)",
|
|
11
|
+
...props
|
|
12
|
+
}: GlowCardProps) => {
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
className={cn(
|
|
16
|
+
"group relative rounded-xl p-px transition-shadow duration-500",
|
|
17
|
+
className
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
>
|
|
21
|
+
<div
|
|
22
|
+
className="absolute -inset-px rounded-xl opacity-50 blur-sm transition-opacity duration-500 group-hover:opacity-100"
|
|
23
|
+
style={
|
|
24
|
+
{
|
|
25
|
+
background: `linear-gradient(135deg, ${gradientFrom}, ${gradientVia}, ${gradientTo})`,
|
|
26
|
+
} as CSSProperties
|
|
27
|
+
}
|
|
28
|
+
aria-hidden="true"
|
|
29
|
+
/>
|
|
30
|
+
<div
|
|
31
|
+
className="absolute -inset-px rounded-xl opacity-0 transition-opacity duration-500 group-hover:opacity-100"
|
|
32
|
+
style={
|
|
33
|
+
{
|
|
34
|
+
background: `linear-gradient(135deg, ${gradientFrom}, ${gradientVia}, ${gradientTo})`,
|
|
35
|
+
} as CSSProperties
|
|
36
|
+
}
|
|
37
|
+
aria-hidden="true"
|
|
38
|
+
/>
|
|
39
|
+
<div className="relative rounded-xl bg-base-100 p-6">{children}</div>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
GlowCard.displayName = "GlowCard";
|
|
45
|
+
|
|
46
|
+
export { GlowCard };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export type GlowCardProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/** Gradient colors for the glow border */
|
|
6
|
+
gradientFrom?: string;
|
|
7
|
+
gradientVia?: string;
|
|
8
|
+
gradientTo?: string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import { cn } from "../../utilities";
|
|
3
|
+
import type { GradientTextProps } from "./types";
|
|
4
|
+
|
|
5
|
+
const GradientText = ({
|
|
6
|
+
children,
|
|
7
|
+
className,
|
|
8
|
+
from = "oklch(0.7 0.25 250)",
|
|
9
|
+
via,
|
|
10
|
+
to = "oklch(0.7 0.2 330)",
|
|
11
|
+
angle = 135,
|
|
12
|
+
animated = false,
|
|
13
|
+
...props
|
|
14
|
+
}: GradientTextProps) => {
|
|
15
|
+
const gradient = via
|
|
16
|
+
? `linear-gradient(${angle}deg, ${from}, ${via}, ${to})`
|
|
17
|
+
: `linear-gradient(${angle}deg, ${from}, ${to})`;
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<span
|
|
21
|
+
className={cn(
|
|
22
|
+
"bg-clip-text text-transparent",
|
|
23
|
+
animated && "animate-gradient bg-[length:300%_100%]",
|
|
24
|
+
className
|
|
25
|
+
)}
|
|
26
|
+
style={{ backgroundImage: gradient } as CSSProperties}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
{children}
|
|
30
|
+
</span>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
GradientText.displayName = "GradientText";
|
|
35
|
+
|
|
36
|
+
export { GradientText };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export type GradientTextProps = HTMLAttributes<HTMLSpanElement> & {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/** Gradient start color */
|
|
6
|
+
from?: string;
|
|
7
|
+
/** Gradient middle color */
|
|
8
|
+
via?: string;
|
|
9
|
+
/** Gradient end color */
|
|
10
|
+
to?: string;
|
|
11
|
+
/** Gradient direction in degrees */
|
|
12
|
+
angle?: number;
|
|
13
|
+
/** Whether to animate the gradient */
|
|
14
|
+
animated?: boolean;
|
|
15
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { cn } from "../../utilities";
|
|
3
|
+
import type { GreetingProps } from "./types";
|
|
4
|
+
|
|
5
|
+
const getTimeGreeting = () => {
|
|
6
|
+
const hour = new Date().getHours();
|
|
7
|
+
if (hour < 12) return "Good morning";
|
|
8
|
+
if (hour < 17) return "Good afternoon";
|
|
9
|
+
return "Good evening";
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const Greeting = ({
|
|
13
|
+
name,
|
|
14
|
+
className,
|
|
15
|
+
subtitle,
|
|
16
|
+
greeting: customGreeting,
|
|
17
|
+
...props
|
|
18
|
+
}: GreetingProps) => {
|
|
19
|
+
const greeting = useMemo(() => customGreeting ?? getTimeGreeting(), [customGreeting]);
|
|
20
|
+
|
|
21
|
+
const dateStr = useMemo(
|
|
22
|
+
() =>
|
|
23
|
+
new Date().toLocaleDateString("en-US", {
|
|
24
|
+
weekday: "long",
|
|
25
|
+
year: "numeric",
|
|
26
|
+
month: "long",
|
|
27
|
+
day: "numeric",
|
|
28
|
+
}),
|
|
29
|
+
[]
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className={cn("flex flex-col gap-1", className)} {...props}>
|
|
34
|
+
<h1 className="text-2xl font-bold tracking-tight">
|
|
35
|
+
{greeting}, {name}
|
|
36
|
+
</h1>
|
|
37
|
+
<p className="text-sm text-base-content/60">
|
|
38
|
+
{subtitle ?? dateStr}
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
Greeting.displayName = "Greeting";
|
|
45
|
+
|
|
46
|
+
export { Greeting };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react";
|
|
2
|
+
|
|
3
|
+
export type GreetingProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
4
|
+
/** User's name */
|
|
5
|
+
name: string;
|
|
6
|
+
/** Optional subtitle/context line */
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
/** Custom greeting override (bypasses time-based greeting) */
|
|
9
|
+
greeting?: string;
|
|
10
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { cn } from "../../utilities";
|
|
2
|
+
import { getIconContainerClasses, getIconRaisedContainerClasses } from "./constants";
|
|
3
|
+
import { type IconContainerProps } from "./types";
|
|
4
|
+
|
|
5
|
+
export const IconContainer = ({
|
|
6
|
+
variant,
|
|
7
|
+
size,
|
|
8
|
+
shape,
|
|
9
|
+
shadow,
|
|
10
|
+
outline,
|
|
11
|
+
soft,
|
|
12
|
+
raised,
|
|
13
|
+
className,
|
|
14
|
+
children,
|
|
15
|
+
...props
|
|
16
|
+
}: IconContainerProps) => {
|
|
17
|
+
const content = raised ? (
|
|
18
|
+
<div className={getIconRaisedContainerClasses({ size, variant, shadow, raised })}>
|
|
19
|
+
{children}
|
|
20
|
+
</div>
|
|
21
|
+
) : (
|
|
22
|
+
children
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div
|
|
27
|
+
className={cn(
|
|
28
|
+
getIconContainerClasses({
|
|
29
|
+
size,
|
|
30
|
+
soft,
|
|
31
|
+
shape,
|
|
32
|
+
variant,
|
|
33
|
+
outline,
|
|
34
|
+
raised,
|
|
35
|
+
shadow: raised ? "none" : shadow,
|
|
36
|
+
}),
|
|
37
|
+
className
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{content}
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { cva } from "../../libs";
|
|
2
|
+
import { createVariants } from "../../utilities";
|
|
3
|
+
|
|
4
|
+
const variants = createVariants({
|
|
5
|
+
variant: {
|
|
6
|
+
accent: "bg-accent text-accent-content",
|
|
7
|
+
default: "bg-base-200 text-base-content",
|
|
8
|
+
error: "bg-error text-error-content",
|
|
9
|
+
ghost: "bg-ghost text-ghost-content",
|
|
10
|
+
info: "bg-info text-info-content",
|
|
11
|
+
neutral: "bg-neutral text-neutral-content",
|
|
12
|
+
primary: "bg-primary text-primary-content",
|
|
13
|
+
secondary: "bg-secondary text-secondary-content",
|
|
14
|
+
success: "bg-success text-success-content",
|
|
15
|
+
warning: "bg-warning text-warning-content",
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
xs: "size-6 text-xs",
|
|
19
|
+
sm: "size-8 text-sm",
|
|
20
|
+
md: "size-10 text-base",
|
|
21
|
+
lg: "size-12 text-lg",
|
|
22
|
+
xl: "size-16 text-2xl",
|
|
23
|
+
},
|
|
24
|
+
shape: {
|
|
25
|
+
circle: "rounded-full",
|
|
26
|
+
square: "rounded-none",
|
|
27
|
+
rounded: "rounded-lg",
|
|
28
|
+
},
|
|
29
|
+
shadow: {
|
|
30
|
+
none: "",
|
|
31
|
+
sm: "shadow-sm",
|
|
32
|
+
md: "shadow-md",
|
|
33
|
+
lg: "shadow-lg",
|
|
34
|
+
xl: "shadow-xl",
|
|
35
|
+
},
|
|
36
|
+
outline: {
|
|
37
|
+
true: "bg-transparent ring-2 ring-offset-2 ring-offset-base-100",
|
|
38
|
+
},
|
|
39
|
+
soft: {
|
|
40
|
+
true: "",
|
|
41
|
+
},
|
|
42
|
+
raised: {
|
|
43
|
+
true: "ring-3 ring-base-200 bg-base-200 [&>div]:bg-base-100 [&>div]:size-[inherit] [&>div]:rounded-[inherit]",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export const getIconRaisedContainerClasses = cva(
|
|
48
|
+
"inline-flex items-center justify-center shrink-0 [&>svg]:size-[1em]",
|
|
49
|
+
{
|
|
50
|
+
variants: createVariants({
|
|
51
|
+
variant: {
|
|
52
|
+
accent: "bg-accent text-accent",
|
|
53
|
+
default: "bg-base-200 text-base",
|
|
54
|
+
error: "bg-error text-error",
|
|
55
|
+
ghost: "bg-ghost text-ghost",
|
|
56
|
+
info: "bg-info text-info",
|
|
57
|
+
neutral: "bg-neutral text-neutral",
|
|
58
|
+
primary: "bg-primary text-primary",
|
|
59
|
+
secondary: "bg-secondary text-secondary",
|
|
60
|
+
success: "bg-success text-success",
|
|
61
|
+
warning: "bg-warning text-warning",
|
|
62
|
+
},
|
|
63
|
+
size: variants.size,
|
|
64
|
+
shadow: variants.shadow,
|
|
65
|
+
raised: {
|
|
66
|
+
true: "",
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
defaultVariants: {
|
|
70
|
+
variant: "default",
|
|
71
|
+
size: "md",
|
|
72
|
+
shadow: "md",
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
export const getIconContainerClasses = cva(
|
|
78
|
+
"inline-flex items-center justify-center shrink-0 [&>svg]:size-[1em]",
|
|
79
|
+
{
|
|
80
|
+
variants,
|
|
81
|
+
compoundVariants: [
|
|
82
|
+
// soft: pastel bg with colored icon
|
|
83
|
+
{ variant: "accent", soft: true, class: "bg-accent/10 text-accent" },
|
|
84
|
+
{ variant: "default", soft: true, class: "bg-base-200/50 text-base-content" },
|
|
85
|
+
{ variant: "error", soft: true, class: "bg-error/10 text-error" },
|
|
86
|
+
{ variant: "ghost", soft: true, class: "bg-base-100 text-base-content" },
|
|
87
|
+
{ variant: "info", soft: true, class: "bg-info/10 text-info" },
|
|
88
|
+
{ variant: "neutral", soft: true, class: "bg-neutral/10 text-neutral" },
|
|
89
|
+
{ variant: "primary", soft: true, class: "bg-primary/10 text-primary" },
|
|
90
|
+
{ variant: "secondary", soft: true, class: "bg-secondary/10 text-secondary" },
|
|
91
|
+
{ variant: "success", soft: true, class: "bg-success/10 text-success" },
|
|
92
|
+
{ variant: "warning", soft: true, class: "bg-warning/10 text-warning" },
|
|
93
|
+
// outline: variant dictates ring color and icon color
|
|
94
|
+
{ variant: "accent", outline: true, class: "ring-accent text-accent" },
|
|
95
|
+
{ variant: "default", outline: true, class: "ring-base-300 text-base-content" },
|
|
96
|
+
{ variant: "error", outline: true, class: "ring-error text-error" },
|
|
97
|
+
{ variant: "ghost", outline: true, class: "ring-base-300 text-base-content" },
|
|
98
|
+
{ variant: "info", outline: true, class: "ring-info text-info" },
|
|
99
|
+
{ variant: "neutral", outline: true, class: "ring-neutral text-neutral" },
|
|
100
|
+
{ variant: "primary", outline: true, class: "ring-primary text-primary" },
|
|
101
|
+
{ variant: "secondary", outline: true, class: "ring-secondary text-secondary" },
|
|
102
|
+
{ variant: "success", outline: true, class: "ring-success text-success" },
|
|
103
|
+
{ variant: "warning", outline: true, class: "ring-warning text-warning" },
|
|
104
|
+
],
|
|
105
|
+
defaultVariants: {
|
|
106
|
+
variant: "default",
|
|
107
|
+
size: "md",
|
|
108
|
+
shape: "circle",
|
|
109
|
+
shadow: "md",
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IconContainer } from "./IconContainer";
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { KPICardProps } from "./types";
|
|
2
|
+
import { cn } from "../../utilities";
|
|
3
|
+
import { Skeleton } from "../Skeleton";
|
|
4
|
+
import { TrendBadge } from "../TrendBadge";
|
|
5
|
+
|
|
6
|
+
const KPICard = ({
|
|
7
|
+
title,
|
|
8
|
+
value,
|
|
9
|
+
change,
|
|
10
|
+
description,
|
|
11
|
+
chart,
|
|
12
|
+
icon,
|
|
13
|
+
loading = false,
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
}: KPICardProps) => {
|
|
17
|
+
if (loading) {
|
|
18
|
+
return (
|
|
19
|
+
<div
|
|
20
|
+
className={cn(
|
|
21
|
+
"rounded-lg border bg-base-100 p-4 shadow-sm transition-shadow duration-300 hover:shadow-md",
|
|
22
|
+
className
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
>
|
|
26
|
+
<div className="flex items-center justify-between">
|
|
27
|
+
<Skeleton className="h-4 w-24 rounded" />
|
|
28
|
+
{icon && <Skeleton className="size-8 rounded-md" />}
|
|
29
|
+
</div>
|
|
30
|
+
<div className="mt-4 flex items-end justify-between gap-4">
|
|
31
|
+
<div className="flex flex-col gap-1.5">
|
|
32
|
+
<Skeleton className="h-7 w-28 rounded" />
|
|
33
|
+
<Skeleton className="h-3.5 w-20 rounded" />
|
|
34
|
+
</div>
|
|
35
|
+
<Skeleton className="h-8 w-20 rounded" />
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
className={cn(
|
|
44
|
+
"w-full @container/kpicard overflow-hidden rounded-lg border bg-base-100 p-4 shadow-sm transition-shadow duration-300 hover:shadow-md",
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
<div className="flex items-center justify-between">
|
|
50
|
+
<span className="min-w-0 truncate text-sm font-medium text-base-content/60">{title}</span>
|
|
51
|
+
{icon && (
|
|
52
|
+
<div className="flex size-8 shrink-0 items-center justify-center rounded-md bg-base-200/50 text-base-content/60">
|
|
53
|
+
{icon}
|
|
54
|
+
</div>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
<div className="mt-3 flex items-end justify-between gap-4">
|
|
58
|
+
<div className="min-w-0 flex flex-col gap-1">
|
|
59
|
+
<span className="truncate text-2xl font-bold tracking-tight">{value}</span>
|
|
60
|
+
<div className="flex items-center gap-2">
|
|
61
|
+
{change !== undefined && <TrendBadge value={change} size="xs" />}
|
|
62
|
+
{description && (
|
|
63
|
+
<span className="truncate text-xs text-base-content/50">{description}</span>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
{chart && <div className="shrink-0 @max-[160px]/kpicard:hidden">{chart}</div>}
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
KPICard.displayName = "KPICard";
|
|
74
|
+
|
|
75
|
+
export { KPICard };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export type KPICardProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
/** Card title/label */
|
|
5
|
+
title: string;
|
|
6
|
+
/** Primary value to display */
|
|
7
|
+
value: ReactNode;
|
|
8
|
+
/** Trend change percentage */
|
|
9
|
+
change?: number;
|
|
10
|
+
/** Description text below value */
|
|
11
|
+
description?: string;
|
|
12
|
+
/** Inline chart element (e.g. Sparkline, MiniBarChart, MiniAreaChart, MiniDonutChart, MiniStackedBar) */
|
|
13
|
+
chart?: ReactNode;
|
|
14
|
+
/** Icon to show in the card */
|
|
15
|
+
icon?: ReactNode;
|
|
16
|
+
/** Loading state */
|
|
17
|
+
loading?: boolean;
|
|
18
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { CSSProperties } from "react";
|
|
2
|
+
import { cn } from "../../utilities";
|
|
3
|
+
import type { MarqueeProps } from "./types";
|
|
4
|
+
|
|
5
|
+
const Marquee = ({
|
|
6
|
+
children,
|
|
7
|
+
className,
|
|
8
|
+
speed = 40,
|
|
9
|
+
direction = "left",
|
|
10
|
+
pauseOnHover = true,
|
|
11
|
+
gap = 16,
|
|
12
|
+
...props
|
|
13
|
+
}: MarqueeProps) => {
|
|
14
|
+
const animationDirection = direction === "left" ? "normal" : "reverse";
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
className={cn(
|
|
19
|
+
"group flex overflow-hidden [--gap:16px]",
|
|
20
|
+
pauseOnHover && "[&:hover_>_.marquee-track]:paused",
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
style={{ "--gap": `${gap}px` } as CSSProperties}
|
|
24
|
+
{...props}
|
|
25
|
+
>
|
|
26
|
+
{[0, 1].map((i) => (
|
|
27
|
+
<div
|
|
28
|
+
key={i}
|
|
29
|
+
className="marquee-track flex shrink-0 animate-marquee items-center justify-around gap-[var(--gap)]"
|
|
30
|
+
style={{
|
|
31
|
+
animationDirection,
|
|
32
|
+
animationDuration: `${speed}s`,
|
|
33
|
+
}}
|
|
34
|
+
aria-hidden={i === 1 ? "true" : undefined}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</div>
|
|
38
|
+
))}
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
Marquee.displayName = "Marquee";
|
|
44
|
+
|
|
45
|
+
export { Marquee };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
export type MarqueeProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/** Speed in pixels per second */
|
|
6
|
+
speed?: number;
|
|
7
|
+
/** Direction of scroll */
|
|
8
|
+
direction?: "left" | "right";
|
|
9
|
+
/** Pause on hover */
|
|
10
|
+
pauseOnHover?: boolean;
|
|
11
|
+
/** Gap between repeated items */
|
|
12
|
+
gap?: number;
|
|
13
|
+
};
|
|
@@ -38,7 +38,7 @@ export const getMenubarClasses = cva(
|
|
|
38
38
|
);
|
|
39
39
|
|
|
40
40
|
export const getMenubarTriggerClasses = cva(
|
|
41
|
-
"flex cursor-default select-none items-center rounded-xs px-3 py-1 text-sm font-medium outline-hidden",
|
|
41
|
+
"flex cursor-default select-none items-center rounded-xs px-3 py-1 text-sm font-medium outline-hidden transition-colors duration-200",
|
|
42
42
|
{
|
|
43
43
|
variants: createVariants({
|
|
44
44
|
variant: triggerVariant,
|
|
@@ -67,7 +67,7 @@ export const getMenubarSubContentClasses = cva(
|
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
export const getMenubarItemClasses = cva(
|
|
70
|
-
"relative flex cursor-default select-none items-center rounded-xs px-2 py-1.5 text-sm outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
70
|
+
"relative flex cursor-default select-none items-center rounded-xs px-2 py-1.5 text-sm outline-hidden transition-colors duration-150 data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
71
71
|
{
|
|
72
72
|
variants: createVariants({
|
|
73
73
|
variant: itemVariant,
|
|
@@ -10,7 +10,7 @@ export const getNavigationMenuListClasses = cva(
|
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
export const getNavigationMenuTriggerClasses = cva(
|
|
13
|
-
"group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-
|
|
13
|
+
"group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-all duration-200 focus:outline-hidden disabled:pointer-events-none disabled:opacity-50",
|
|
14
14
|
{
|
|
15
15
|
variants: createVariants({
|
|
16
16
|
variant: {
|
|
@@ -41,7 +41,7 @@ export const getNavigationMenuContentClasses = cva(
|
|
|
41
41
|
);
|
|
42
42
|
|
|
43
43
|
export const getNavigationMenuViewportClasses = cva(
|
|
44
|
-
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-base-100 shadow-
|
|
44
|
+
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-base-100 shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]"
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
export const getNavigationMenuIndicatorClasses = cva(
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { cn } from "../../utilities";
|
|
3
|
+
import type { MeteorsProps } from "./types";
|
|
4
|
+
|
|
5
|
+
const Meteors = ({ className, count = 20, ...props }: MeteorsProps) => {
|
|
6
|
+
const meteors = useMemo(
|
|
7
|
+
() =>
|
|
8
|
+
Array.from({ length: count }, (_, i) => ({
|
|
9
|
+
id: i,
|
|
10
|
+
left: `${Math.floor(Math.random() * 100)}%`,
|
|
11
|
+
delay: `${Math.random() * 5}s`,
|
|
12
|
+
duration: `${Math.floor(Math.random() * 3 + 2)}s`,
|
|
13
|
+
})),
|
|
14
|
+
[count]
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className={cn("pointer-events-none absolute inset-0 overflow-hidden", className)} {...props}>
|
|
19
|
+
{meteors.map((meteor) => (
|
|
20
|
+
<span
|
|
21
|
+
key={meteor.id}
|
|
22
|
+
className="absolute top-0 h-0.5 w-0.5 rotate-[215deg] animate-meteor rounded-full bg-base-content shadow-[0_0_0_1px_oklch(1_0_0/0.1),0_0_10px_oklch(1_0_0/0.2)]"
|
|
23
|
+
style={{
|
|
24
|
+
left: meteor.left,
|
|
25
|
+
animationDelay: meteor.delay,
|
|
26
|
+
animationDuration: meteor.duration,
|
|
27
|
+
}}
|
|
28
|
+
>
|
|
29
|
+
<span className="pointer-events-none absolute top-1/2 -z-10 h-px w-12 -translate-y-1/2 bg-gradient-to-r from-base-content/80 to-transparent" />
|
|
30
|
+
</span>
|
|
31
|
+
))}
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
Meteors.displayName = "Meteors";
|
|
37
|
+
|
|
38
|
+
export { Meteors };
|