@trackany-device/components 1.0.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/package.json +185 -0
- package/src/assets/logo.png +0 -0
- package/src/assets/map/arrows/map-arrow-blue.png +0 -0
- package/src/assets/map/arrows/map-arrow-green.png +0 -0
- package/src/assets/map/arrows/map-arrow-purple.png +0 -0
- package/src/assets/map/arrows/map-arrow-red.png +0 -0
- package/src/assets/map/flags/flag-blue.png +0 -0
- package/src/assets/map/flags/flag-green.png +0 -0
- package/src/assets/map/flags/flag-red.png +0 -0
- package/src/assets/map/flags/flag-yellow.png +0 -0
- package/src/assets/map/pins/map-pin-blue.png +0 -0
- package/src/assets/map/pins/map-pin-green.png +0 -0
- package/src/assets/map/pins/map-pin-purple.png +0 -0
- package/src/assets/map/pins/map-pin-red.png +0 -0
- package/src/components/Card.tsx +9 -0
- package/src/components/alert-error.tsx +24 -0
- package/src/components/app-content.tsx +22 -0
- package/src/components/app-header.tsx +153 -0
- package/src/components/app-logo-icon.tsx +13 -0
- package/src/components/app-logo.tsx +21 -0
- package/src/components/app-shell.tsx +19 -0
- package/src/components/app-sidebar-header.tsx +68 -0
- package/src/components/app-sidebar.tsx +106 -0
- package/src/components/appearance-tabs.tsx +46 -0
- package/src/components/breadcrumbs.tsx +50 -0
- package/src/components/cms/blurred-image.tsx +111 -0
- package/src/components/cms/section-bg.tsx +473 -0
- package/src/components/cms/section-button.tsx +127 -0
- package/src/components/cms/sections/banner-5050-section.tsx +135 -0
- package/src/components/cms/sections/blogs-listing-section.tsx +270 -0
- package/src/components/cms/sections/cards-grid-section.tsx +185 -0
- package/src/components/cms/sections/contact-form-section.tsx +157 -0
- package/src/components/cms/sections/cta-section.tsx +101 -0
- package/src/components/cms/sections/featured-blog-slider-section.tsx +256 -0
- package/src/components/cms/sections/featured-products-grid-section.tsx +173 -0
- package/src/components/cms/sections/featured-solutions-grid-section.tsx +183 -0
- package/src/components/cms/sections/hero-section.tsx +180 -0
- package/src/components/cms/sections/solutions-with-filter-section.tsx +234 -0
- package/src/components/cms/sections/text-section.tsx +77 -0
- package/src/components/cutout-image.tsx +228 -0
- package/src/components/devices/devices-mini-map.tsx +275 -0
- package/src/components/docs/docs-shell.tsx +280 -0
- package/src/components/fleet-hero-animated.tsx +383 -0
- package/src/components/input-error.tsx +17 -0
- package/src/components/keenicons/assets/duotone/Read Me.txt +7 -0
- package/src/components/keenicons/assets/duotone/demo-files/demo.css +160 -0
- package/src/components/keenicons/assets/duotone/demo-files/demo.js +32 -0
- package/src/components/keenicons/assets/duotone/demo.html +12424 -0
- package/src/components/keenicons/assets/duotone/fonts/keenicons-duotone.svg +1109 -0
- package/src/components/keenicons/assets/duotone/fonts/keenicons-duotone.ttf +0 -0
- package/src/components/keenicons/assets/duotone/fonts/keenicons-duotone.woff +0 -0
- package/src/components/keenicons/assets/duotone/selection.json +17313 -0
- package/src/components/keenicons/assets/duotone/style.css +4931 -0
- package/src/components/keenicons/assets/filled/Read Me.txt +7 -0
- package/src/components/keenicons/assets/filled/demo-files/demo.css +160 -0
- package/src/components/keenicons/assets/filled/demo-files/demo.js +32 -0
- package/src/components/keenicons/assets/filled/demo.html +12370 -0
- package/src/components/keenicons/assets/filled/fonts/keenicons-filled.svg +1082 -0
- package/src/components/keenicons/assets/filled/fonts/keenicons-filled.ttf +0 -0
- package/src/components/keenicons/assets/filled/fonts/keenicons-filled.woff +0 -0
- package/src/components/keenicons/assets/filled/selection.json +17096 -0
- package/src/components/keenicons/assets/filled/style.css +4769 -0
- package/src/components/keenicons/assets/outline/Read Me.txt +7 -0
- package/src/components/keenicons/assets/outline/demo-files/demo.css +160 -0
- package/src/components/keenicons/assets/outline/demo-files/demo.js +32 -0
- package/src/components/keenicons/assets/outline/demo.html +11356 -0
- package/src/components/keenicons/assets/outline/fonts/keenicons-outline.svg +575 -0
- package/src/components/keenicons/assets/outline/fonts/keenicons-outline.ttf +0 -0
- package/src/components/keenicons/assets/outline/fonts/keenicons-outline.woff +0 -0
- package/src/components/keenicons/assets/outline/selection.json +13054 -0
- package/src/components/keenicons/assets/outline/style.css +1721 -0
- package/src/components/keenicons/assets/solid/Read Me.txt +7 -0
- package/src/components/keenicons/assets/solid/demo-files/demo.css +160 -0
- package/src/components/keenicons/assets/solid/demo-files/demo.js +32 -0
- package/src/components/keenicons/assets/solid/demo.html +11356 -0
- package/src/components/keenicons/assets/solid/fonts/keenicons-solid.svg +575 -0
- package/src/components/keenicons/assets/solid/fonts/keenicons-solid.ttf +0 -0
- package/src/components/keenicons/assets/solid/fonts/keenicons-solid.woff +0 -0
- package/src/components/keenicons/assets/solid/selection.json +13048 -0
- package/src/components/keenicons/assets/solid/style.css +1721 -0
- package/src/components/keenicons/assets/styles.css +4 -0
- package/src/components/keenicons/index.ts +2 -0
- package/src/components/keenicons/keenicons.tsx +16 -0
- package/src/components/keenicons/types.ts +7 -0
- package/src/components/nav-footer.tsx +49 -0
- package/src/components/nav-main.tsx +53 -0
- package/src/components/nav-user.tsx +59 -0
- package/src/components/notification-bell.tsx +190 -0
- package/src/components/products/product-card.tsx +159 -0
- package/src/components/text-link.tsx +23 -0
- package/src/components/ui/accordion-menu.tsx +322 -0
- package/src/components/ui/accordion.tsx +133 -0
- package/src/components/ui/alert-dialog.tsx +82 -0
- package/src/components/ui/alert.tsx +63 -0
- package/src/components/ui/avatar-group.tsx +129 -0
- package/src/components/ui/avatar.tsx +67 -0
- package/src/components/ui/badge.tsx +230 -0
- package/src/components/ui/breadcrumb.tsx +88 -0
- package/src/components/ui/button.tsx +412 -0
- package/src/components/ui/calendar.tsx +56 -0
- package/src/components/ui/card.tsx +147 -0
- package/src/components/ui/chart.tsx +290 -0
- package/src/components/ui/checkbox.tsx +47 -0
- package/src/components/ui/code.tsx +45 -0
- package/src/components/ui/collapsible.tsx +31 -0
- package/src/components/ui/command-palette.tsx +189 -0
- package/src/components/ui/command.tsx +138 -0
- package/src/components/ui/cookie-banner.tsx +220 -0
- package/src/components/ui/copy-button.tsx +60 -0
- package/src/components/ui/data-grid-column-filter.tsx +124 -0
- package/src/components/ui/data-grid-column-header.tsx +284 -0
- package/src/components/ui/data-grid-column-visibility.tsx +38 -0
- package/src/components/ui/data-grid-pagination.tsx +206 -0
- package/src/components/ui/data-grid-table-dnd-rows.tsx +147 -0
- package/src/components/ui/data-grid-table-dnd.tsx +175 -0
- package/src/components/ui/data-grid-table.tsx +500 -0
- package/src/components/ui/data-grid.tsx +193 -0
- package/src/components/ui/data-list.tsx +76 -0
- package/src/components/ui/datefield.tsx +91 -0
- package/src/components/ui/dialog.tsx +139 -0
- package/src/components/ui/divider.tsx +41 -0
- package/src/components/ui/drawer.tsx +59 -0
- package/src/components/ui/dropdown-menu.tsx +224 -0
- package/src/components/ui/empty-state.tsx +54 -0
- package/src/components/ui/file-upload.tsx +152 -0
- package/src/components/ui/form.tsx +88 -0
- package/src/components/ui/icon.tsx +14 -0
- package/src/components/ui/input-otp.tsx +71 -0
- package/src/components/ui/input.tsx +155 -0
- package/src/components/ui/kbd.tsx +26 -0
- package/src/components/ui/label.tsx +31 -0
- package/src/components/ui/navigation-menu.tsx +168 -0
- package/src/components/ui/pagination.tsx +37 -0
- package/src/components/ui/placeholder-pattern.tsx +21 -0
- package/src/components/ui/popover.tsx +50 -0
- package/src/components/ui/progress.tsx +65 -0
- package/src/components/ui/radio-group.tsx +73 -0
- package/src/components/ui/resizable.tsx +39 -0
- package/src/components/ui/scroll-area.tsx +50 -0
- package/src/components/ui/select.tsx +234 -0
- package/src/components/ui/separator.tsx +24 -0
- package/src/components/ui/sheet.tsx +147 -0
- package/src/components/ui/sidebar.tsx +721 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/slider.tsx +35 -0
- package/src/components/ui/sonner.tsx +28 -0
- package/src/components/ui/sortable.tsx +724 -0
- package/src/components/ui/spinner.tsx +17 -0
- package/src/components/ui/stat-card.tsx +82 -0
- package/src/components/ui/stepper.tsx +410 -0
- package/src/components/ui/switch.tsx +68 -0
- package/src/components/ui/table.tsx +42 -0
- package/src/components/ui/tabs.tsx +196 -0
- package/src/components/ui/timeline.tsx +90 -0
- package/src/components/ui/toggle-group.tsx +73 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/components/ui/tooltip.tsx +55 -0
- package/src/components/user-info.tsx +33 -0
- package/src/components/user-menu-content.tsx +53 -0
- package/src/components/web/SiteFooter.tsx +154 -0
- package/src/components/web/SiteHeader.tsx +159 -0
- package/src/components/workflows/workflow-canvas.tsx +321 -0
- package/src/controls/Blockquote.tsx +25 -0
- package/src/controls/Button.tsx +101 -0
- package/src/controls/Checkbox.tsx +29 -0
- package/src/controls/DateField.tsx +37 -0
- package/src/controls/FormField.tsx +20 -0
- package/src/controls/Heading.tsx +28 -0
- package/src/controls/Input.tsx +21 -0
- package/src/controls/Label.tsx +18 -0
- package/src/controls/Paragraph.tsx +39 -0
- package/src/controls/PasswordInput.tsx +40 -0
- package/src/controls/RadioGroup.tsx +70 -0
- package/src/controls/Select.tsx +24 -0
- package/src/controls/Slider.tsx +33 -0
- package/src/controls/Switch.tsx +31 -0
- package/src/controls/Textarea.tsx +22 -0
- package/src/elements/ConfirmPasswordForm.tsx +43 -0
- package/src/elements/DeviceStatusBadge.tsx +38 -0
- package/src/elements/DriverCard.tsx +67 -0
- package/src/elements/ForgotPasswordForm.tsx +64 -0
- package/src/elements/IncidentCard.tsx +67 -0
- package/src/elements/LoginForm.tsx +100 -0
- package/src/elements/OtpForm.tsx +71 -0
- package/src/elements/RegisterForm.tsx +150 -0
- package/src/elements/ResetPasswordForm.tsx +72 -0
- package/src/elements/SmsChallengeForm.tsx +104 -0
- package/src/elements/VehicleCard.tsx +73 -0
- package/src/elements/VerifyEmailForm.tsx +39 -0
- package/src/hooks/use-appearance.tsx +117 -0
- package/src/hooks/use-applied-theme.ts +98 -0
- package/src/hooks/use-clipboard.ts +34 -0
- package/src/hooks/use-current-url.ts +83 -0
- package/src/hooks/use-dark-mode.ts +48 -0
- package/src/hooks/use-flash-toast.ts +29 -0
- package/src/hooks/use-initials.tsx +24 -0
- package/src/hooks/use-mobile-navigation.ts +12 -0
- package/src/hooks/use-mobile.tsx +38 -0
- package/src/index.ts +408 -0
- package/src/layouts/AppLayout.tsx +60 -0
- package/src/layouts/AuthLayout.tsx +32 -0
- package/src/layouts/SettingsLayout.tsx +21 -0
- package/src/layouts/app/AIChatLayout.tsx +73 -0
- package/src/layouts/app/AsideSidebarLayout.tsx +3 -0
- package/src/layouts/app/CalendarSidebarLayout.tsx +69 -0
- package/src/layouts/app/CommunitiesNavbarLayout.tsx +3 -0
- package/src/layouts/app/DualNavbarSidebarLayout.tsx +3 -0
- package/src/layouts/app/FocusSidebarLayout.tsx +75 -0
- package/src/layouts/app/MailLayout.tsx +69 -0
- package/src/layouts/app/MegaMenuHeaderLayout.tsx +3 -0
- package/src/layouts/app/MegaMenuLayout.tsx +81 -0
- package/src/layouts/app/MegaMenuNavbarLayout.tsx +88 -0
- package/src/layouts/app/MegaMenuSearchNavbarLayout.tsx +3 -0
- package/src/layouts/app/NavbarCollapsibleLayout.tsx +88 -0
- package/src/layouts/app/NavbarCollapsibleLinksLayout.tsx +3 -0
- package/src/layouts/app/NavbarMinimalLayout.tsx +3 -0
- package/src/layouts/app/NavbarMinimalSidebarLayout.tsx +3 -0
- package/src/layouts/app/NavbarSidebarDashboardLayout.tsx +3 -0
- package/src/layouts/app/NavbarSidebarLayout.tsx +92 -0
- package/src/layouts/app/NavbarSimpleSidebarLayout.tsx +3 -0
- package/src/layouts/app/NavbarTitledSidebarLayout.tsx +3 -0
- package/src/layouts/app/PanelSidebarLayout.tsx +3 -0
- package/src/layouts/app/SearchNavbarSidebarLayout.tsx +3 -0
- package/src/layouts/app/SidebarBreadcrumbLayout.tsx +3 -0
- package/src/layouts/app/SidebarCleanLayout.tsx +3 -0
- package/src/layouts/app/SidebarCommunitiesLayout.tsx +3 -0
- package/src/layouts/app/SidebarContentLayout.tsx +3 -0
- package/src/layouts/app/SidebarDualMenuLayout.tsx +104 -0
- package/src/layouts/app/SidebarFixedLayout.tsx +166 -0
- package/src/layouts/app/SidebarFooterNavbarLayout.tsx +3 -0
- package/src/layouts/app/SidebarHeaderMenuLayout.tsx +3 -0
- package/src/layouts/app/SidebarMegaMenuLayout.tsx +4 -0
- package/src/layouts/app/SidebarMinimalLayout.tsx +70 -0
- package/src/layouts/app/SidebarMobileSearchLayout.tsx +3 -0
- package/src/layouts/app/SidebarMultiPanelLayout.tsx +3 -0
- package/src/layouts/app/SidebarPrimarySecondaryLayout.tsx +3 -0
- package/src/layouts/app/SidebarSearchHeaderLayout.tsx +103 -0
- package/src/layouts/app/SidebarSearchToolbarLayout.tsx +3 -0
- package/src/layouts/app/SidebarTabsDualLayout.tsx +3 -0
- package/src/layouts/app/SidebarTabsLayout.tsx +98 -0
- package/src/layouts/app/SidebarTreeLayout.tsx +3 -0
- package/src/layouts/app/SplitNavbarLayout.tsx +3 -0
- package/src/layouts/app/SplitSidebarDashboardLayout.tsx +3 -0
- package/src/layouts/app/SplitSidebarLayout.tsx +99 -0
- package/src/layouts/app/TopNavLayout.tsx +105 -0
- package/src/layouts/app/TopNavLinksLayout.tsx +3 -0
- package/src/layouts/app/WorkspaceBreadcrumbLayout.tsx +3 -0
- package/src/layouts/app/WorkspaceCommunitiesLayout.tsx +3 -0
- package/src/layouts/app/WorkspaceNavbarLayout.tsx +3 -0
- package/src/layouts/app/WorkspaceSidebarLayout.tsx +98 -0
- package/src/layouts/app/WorkspaceSidebarTitleLayout.tsx +3 -0
- package/src/layouts/app/app-header-layout.tsx +45 -0
- package/src/layouts/app/app-sidebar-layout.tsx +56 -0
- package/src/layouts/app/layout-context.tsx +44 -0
- package/src/layouts/app/layout-types.ts +47 -0
- package/src/layouts/app/partials/Footer.tsx +35 -0
- package/src/layouts/app/partials/HeaderTopbar.tsx +96 -0
- package/src/layouts/app/partials/Navbar.tsx +85 -0
- package/src/layouts/app/partials/Toolbar.tsx +47 -0
- package/src/layouts/app-layout.tsx +29 -0
- package/src/layouts/auth/AuthBrandedLayout.tsx +58 -0
- package/src/layouts/auth/AuthCardLayout.tsx +31 -0
- package/src/layouts/auth/AuthCenteredLayout.tsx +41 -0
- package/src/layouts/auth/AuthClassicLayout.tsx +41 -0
- package/src/layouts/auth/AuthSimpleLayout.tsx +33 -0
- package/src/layouts/auth/AuthSplitLayout.tsx +89 -0
- package/src/layouts/web-app-layout.tsx +162 -0
- package/src/layouts/web-layout.tsx +23 -0
- package/src/lib/datetime.ts +188 -0
- package/src/lib/google-maps-loader.ts +99 -0
- package/src/lib/location.ts +127 -0
- package/src/lib/lucide-icon-map.ts +132 -0
- package/src/lib/map-markers.ts +124 -0
- package/src/lib/map-styles.ts +351 -0
- package/src/lib/utils.ts +11 -0
- package/src/platform/adapters/default.tsx +156 -0
- package/src/platform/adapters/inertia.tsx +88 -0
- package/src/platform/adapters/nextjs.ts +86 -0
- package/src/platform/context.tsx +106 -0
- package/src/platform/index.ts +27 -0
- package/src/platform/types.ts +105 -0
- package/src/styles/layouts/sidebar-fixed.css +161 -0
- package/src/styles/themes.css +583 -0
- package/src/types/assets.d.ts +5 -0
- package/src/types/auth.ts +25 -0
- package/src/types/global.d.ts +13 -0
- package/src/types/index.ts +9 -0
- package/src/types/navigation.ts +15 -0
- package/src/types/ui.ts +32 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '../../lib/utils';
|
|
3
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
+
|
|
5
|
+
// Define input size variants
|
|
6
|
+
const inputVariants = cva(
|
|
7
|
+
`
|
|
8
|
+
flex w-full bg-background border border-input shadow-xs shadow-black/5 transition-[color,box-shadow] text-foreground placeholder:text-muted-foreground/80
|
|
9
|
+
focus-visible:ring-ring/30 focus-visible:border-ring focus-visible:outline-none focus-visible:ring-[3px]
|
|
10
|
+
disabled:cursor-not-allowed disabled:opacity-60
|
|
11
|
+
[&[readonly]]:bg-muted/80 [&[readonly]]:cursor-not-allowed
|
|
12
|
+
file:h-full [&[type=file]]:py-0 file:border-solid file:border-input file:bg-transparent
|
|
13
|
+
file:font-medium file:not-italic file:text-foreground file:p-0 file:border-0 file:border-e
|
|
14
|
+
aria-invalid:border-destructive/60 aria-invalid:ring-destructive/10 dark:aria-invalid:border-destructive dark:aria-invalid:ring-destructive/20
|
|
15
|
+
`,
|
|
16
|
+
{
|
|
17
|
+
variants: {
|
|
18
|
+
variant: {
|
|
19
|
+
lg: 'h-10 px-4 text-sm rounded-md file:pe-4 file:me-4',
|
|
20
|
+
md: 'h-8.5 px-3 text-[0.8125rem] leading-(--text-sm--line-height) rounded-md file:pe-3 file:me-3',
|
|
21
|
+
sm: 'h-7 px-2.5 text-xs rounded-md file:pe-2.5 file:me-2.5',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
variant: 'md',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const inputAddonVariants = cva(
|
|
31
|
+
'flex items-center shrink-0 justify-center bg-muted border border-input shadow-xs shadow-[rgba(0,0,0,0.05)] text-secondary-foreground [&_svg]:text-secondary-foreground/60',
|
|
32
|
+
{
|
|
33
|
+
variants: {
|
|
34
|
+
variant: {
|
|
35
|
+
sm: 'rounded-md h-7 min-w-7 text-xs px-2.5 [&_svg:not([class*=size-])]:size-3.5',
|
|
36
|
+
md: 'rounded-md h-8.5 min-w-8.5 px-3 text-[0.8125rem] leading-(--text-sm--line-height) [&_svg:not([class*=size-])]:size-4.5',
|
|
37
|
+
lg: 'rounded-md h-10 min-w-10 px-4 text-sm [&_svg:not([class*=size-])]:size-4.5',
|
|
38
|
+
},
|
|
39
|
+
mode: {
|
|
40
|
+
default: '',
|
|
41
|
+
icon: 'px-0 justify-center',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
defaultVariants: {
|
|
45
|
+
variant: 'md',
|
|
46
|
+
mode: 'default',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const inputGroupVariants = cva(
|
|
52
|
+
`
|
|
53
|
+
flex items-stretch
|
|
54
|
+
[&_[data-slot=input]]:grow
|
|
55
|
+
[&_[data-slot=input-addon]:has(+[data-slot=input])]:rounded-e-none [&_[data-slot=input-addon]:has(+[data-slot=input])]:border-e-0
|
|
56
|
+
[&_[data-slot=input-addon]:has(+[data-slot=datefield])]:rounded-e-none [&_[data-slot=input-addon]:has(+[data-slot=datefield])]:border-e-0
|
|
57
|
+
[&_[data-slot=input]+[data-slot=input-addon]]:rounded-s-none [&_[data-slot=input]+[data-slot=input-addon]]:border-s-0
|
|
58
|
+
[&_[data-slot=input-addon]:has(+[data-slot=button])]:rounded-e-none
|
|
59
|
+
[&_[data-slot=input]+[data-slot=button]]:rounded-s-none
|
|
60
|
+
[&_[data-slot=button]+[data-slot=input]]:rounded-s-none
|
|
61
|
+
[&_[data-slot=input-addon]+[data-slot=input]]:rounded-s-none
|
|
62
|
+
[&_[data-slot=input-addon]+[data-slot=datefield]]:[&_[data-slot=input]]:rounded-s-none
|
|
63
|
+
[&_[data-slot=datefield]:has(+[data-slot=input-addon])]:[&_[data-slot=input]]:rounded-e-none
|
|
64
|
+
[&_[data-slot=input]:has(+[data-slot=button])]:rounded-e-none
|
|
65
|
+
[&_[data-slot=input]:has(+[data-slot=input-addon])]:rounded-e-none
|
|
66
|
+
[&_[data-slot=datefield]]:grow
|
|
67
|
+
[&_[data-slot=datefield]+[data-slot=input-addon]]:rounded-s-none [&_[data-slot=datefield]+[data-slot=input-addon]]:border-s-0
|
|
68
|
+
`,
|
|
69
|
+
{
|
|
70
|
+
variants: {},
|
|
71
|
+
defaultVariants: {},
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const inputWrapperVariants = cva(
|
|
76
|
+
`
|
|
77
|
+
flex items-center gap-1.5
|
|
78
|
+
has-[:focus-visible]:ring-ring/30
|
|
79
|
+
has-[:focus-visible]:border-ring
|
|
80
|
+
has-[:focus-visible]:outline-none
|
|
81
|
+
has-[:focus-visible]:ring-[3px]
|
|
82
|
+
|
|
83
|
+
[&_[data-slot=datefield]]:grow
|
|
84
|
+
[&_[data-slot=input]]:data-focus-within:ring-transparent
|
|
85
|
+
[&_[data-slot=input]]:data-focus-within:ring-0
|
|
86
|
+
[&_[data-slot=input]]:data-focus-within:border-0
|
|
87
|
+
[&_[data-slot=input]]:flex
|
|
88
|
+
[&_[data-slot=input]]:w-full
|
|
89
|
+
[&_[data-slot=input]]:outline-none
|
|
90
|
+
[&_[data-slot=input]]:transition-colors
|
|
91
|
+
[&_[data-slot=input]]:text-foreground
|
|
92
|
+
[&_[data-slot=input]]:placeholder:text-muted-foreground
|
|
93
|
+
[&_[data-slot=input]]:border-0
|
|
94
|
+
[&_[data-slot=input]]:bg-transparent
|
|
95
|
+
[&_[data-slot=input]]:p-0
|
|
96
|
+
[&_[data-slot=input]]:shadow-none
|
|
97
|
+
[&_[data-slot=input]]:focus-visible:ring-0
|
|
98
|
+
[&_[data-slot=input]]:h-auto
|
|
99
|
+
[&_[data-slot=input]]:disabled:cursor-not-allowed
|
|
100
|
+
[&_[data-slot=input]]:disabled:opacity-50
|
|
101
|
+
|
|
102
|
+
[&_svg]:text-muted-foreground
|
|
103
|
+
[&_svg]:shrink-0
|
|
104
|
+
`,
|
|
105
|
+
{
|
|
106
|
+
variants: {
|
|
107
|
+
variant: {
|
|
108
|
+
sm: 'gap-1.25 [&_svg:not([class*=size-])]:size-3.5',
|
|
109
|
+
md: 'gap-1.5 [&_svg:not([class*=size-])]:size-4',
|
|
110
|
+
lg: 'gap-1.5 [&_svg:not([class*=size-])]:size-4',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
defaultVariants: {
|
|
114
|
+
variant: 'md',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
function Input({
|
|
120
|
+
className,
|
|
121
|
+
type,
|
|
122
|
+
variant,
|
|
123
|
+
...props
|
|
124
|
+
}: React.ComponentProps<'input'> & VariantProps<typeof inputVariants>) {
|
|
125
|
+
return <input data-slot="input" type={type} className={cn(inputVariants({ variant }), className)} {...props} />;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function InputAddon({
|
|
129
|
+
className,
|
|
130
|
+
variant,
|
|
131
|
+
mode,
|
|
132
|
+
...props
|
|
133
|
+
}: React.ComponentProps<'div'> & VariantProps<typeof inputAddonVariants>) {
|
|
134
|
+
return <div data-slot="input-addon" className={cn(inputAddonVariants({ variant, mode }), className)} {...props} />;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function InputGroup({ className, ...props }: React.ComponentProps<'div'> & VariantProps<typeof inputGroupVariants>) {
|
|
138
|
+
return <div data-slot="input-group" className={cn(inputGroupVariants(), className)} {...props} />;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function InputWrapper({
|
|
142
|
+
className,
|
|
143
|
+
variant,
|
|
144
|
+
...props
|
|
145
|
+
}: React.ComponentProps<'div'> & VariantProps<typeof inputWrapperVariants>) {
|
|
146
|
+
return (
|
|
147
|
+
<div
|
|
148
|
+
data-slot="input-wrapper"
|
|
149
|
+
className={cn(inputVariants({ variant }), inputWrapperVariants({ variant }), className)}
|
|
150
|
+
{...props}
|
|
151
|
+
/>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export { Input, InputAddon, InputGroup, InputWrapper, inputVariants, inputAddonVariants };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kbd — keyboard shortcut notation.
|
|
3
|
+
*
|
|
4
|
+
* <Kbd>⌘K</Kbd> <Kbd>Ctrl + /</Kbd>
|
|
5
|
+
*/
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
|
|
8
|
+
import { cn } from '../../lib/utils';
|
|
9
|
+
|
|
10
|
+
export function Kbd({
|
|
11
|
+
className,
|
|
12
|
+
children,
|
|
13
|
+
...props
|
|
14
|
+
}: React.HTMLAttributes<HTMLElement>) {
|
|
15
|
+
return (
|
|
16
|
+
<kbd
|
|
17
|
+
className={cn(
|
|
18
|
+
'pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground',
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
{children}
|
|
24
|
+
</kbd>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
6
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
7
|
+
|
|
8
|
+
const labelVariants = cva(
|
|
9
|
+
'text-sm leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
primary: 'font-medium',
|
|
14
|
+
secondary: 'font-normal',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: 'primary',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
function Label({
|
|
24
|
+
className,
|
|
25
|
+
variant,
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>) {
|
|
28
|
+
return <LabelPrimitive.Root data-slot="label" className={cn(labelVariants({ variant }), className)} {...props} />;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { Label };
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
|
|
2
|
+
import { cva } from "class-variance-authority"
|
|
3
|
+
import { ChevronDownIcon } from "lucide-react"
|
|
4
|
+
import * as React from "react"
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils"
|
|
7
|
+
|
|
8
|
+
function NavigationMenu({
|
|
9
|
+
className,
|
|
10
|
+
children,
|
|
11
|
+
viewport = true,
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
|
|
14
|
+
viewport?: boolean
|
|
15
|
+
}) {
|
|
16
|
+
return (
|
|
17
|
+
<NavigationMenuPrimitive.Root
|
|
18
|
+
data-slot="navigation-menu"
|
|
19
|
+
data-viewport={viewport}
|
|
20
|
+
className={cn(
|
|
21
|
+
"group/navigation-menu relative flex max-w-max flex-1 items-center justify-center",
|
|
22
|
+
className
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
>
|
|
26
|
+
{children}
|
|
27
|
+
{viewport && <NavigationMenuViewport />}
|
|
28
|
+
</NavigationMenuPrimitive.Root>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function NavigationMenuList({
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {
|
|
36
|
+
return (
|
|
37
|
+
<NavigationMenuPrimitive.List
|
|
38
|
+
data-slot="navigation-menu-list"
|
|
39
|
+
className={cn(
|
|
40
|
+
"group flex flex-1 list-none items-center justify-center gap-1",
|
|
41
|
+
className
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function NavigationMenuItem({
|
|
49
|
+
className,
|
|
50
|
+
...props
|
|
51
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {
|
|
52
|
+
return (
|
|
53
|
+
<NavigationMenuPrimitive.Item
|
|
54
|
+
data-slot="navigation-menu-item"
|
|
55
|
+
className={cn("relative", className)}
|
|
56
|
+
{...props}
|
|
57
|
+
/>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const navigationMenuTriggerStyle = cva(
|
|
62
|
+
"group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[active=true]:bg-accent/50 data-[state=open]:bg-accent/50 data-[active=true]:text-accent-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
function NavigationMenuTrigger({
|
|
66
|
+
className,
|
|
67
|
+
children,
|
|
68
|
+
...props
|
|
69
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>) {
|
|
70
|
+
return (
|
|
71
|
+
<NavigationMenuPrimitive.Trigger
|
|
72
|
+
data-slot="navigation-menu-trigger"
|
|
73
|
+
className={cn(navigationMenuTriggerStyle(), "group", className)}
|
|
74
|
+
{...props}
|
|
75
|
+
>
|
|
76
|
+
{children}{" "}
|
|
77
|
+
<ChevronDownIcon
|
|
78
|
+
className="relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180"
|
|
79
|
+
aria-hidden="true"
|
|
80
|
+
/>
|
|
81
|
+
</NavigationMenuPrimitive.Trigger>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function NavigationMenuContent({
|
|
86
|
+
className,
|
|
87
|
+
...props
|
|
88
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Content>) {
|
|
89
|
+
return (
|
|
90
|
+
<NavigationMenuPrimitive.Content
|
|
91
|
+
data-slot="navigation-menu-content"
|
|
92
|
+
className={cn(
|
|
93
|
+
"data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto",
|
|
94
|
+
"group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none",
|
|
95
|
+
className
|
|
96
|
+
)}
|
|
97
|
+
{...props}
|
|
98
|
+
/>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function NavigationMenuViewport({
|
|
103
|
+
className,
|
|
104
|
+
...props
|
|
105
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {
|
|
106
|
+
return (
|
|
107
|
+
<div
|
|
108
|
+
className={cn(
|
|
109
|
+
"absolute top-full left-0 isolate z-50 flex justify-center"
|
|
110
|
+
)}
|
|
111
|
+
>
|
|
112
|
+
<NavigationMenuPrimitive.Viewport
|
|
113
|
+
data-slot="navigation-menu-viewport"
|
|
114
|
+
className={cn(
|
|
115
|
+
"origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow md:w-[var(--radix-navigation-menu-viewport-width)]",
|
|
116
|
+
className
|
|
117
|
+
)}
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function NavigationMenuLink({
|
|
125
|
+
className,
|
|
126
|
+
...props
|
|
127
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {
|
|
128
|
+
return (
|
|
129
|
+
<NavigationMenuPrimitive.Link
|
|
130
|
+
data-slot="navigation-menu-link"
|
|
131
|
+
className={cn(
|
|
132
|
+
"hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4",
|
|
133
|
+
className
|
|
134
|
+
)}
|
|
135
|
+
{...props}
|
|
136
|
+
/>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function NavigationMenuIndicator({
|
|
141
|
+
className,
|
|
142
|
+
...props
|
|
143
|
+
}: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>) {
|
|
144
|
+
return (
|
|
145
|
+
<NavigationMenuPrimitive.Indicator
|
|
146
|
+
data-slot="navigation-menu-indicator"
|
|
147
|
+
className={cn(
|
|
148
|
+
"data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden",
|
|
149
|
+
className
|
|
150
|
+
)}
|
|
151
|
+
{...props}
|
|
152
|
+
>
|
|
153
|
+
<div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
|
|
154
|
+
</NavigationMenuPrimitive.Indicator>
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export {
|
|
159
|
+
NavigationMenu,
|
|
160
|
+
NavigationMenuList,
|
|
161
|
+
NavigationMenuItem,
|
|
162
|
+
NavigationMenuContent,
|
|
163
|
+
NavigationMenuTrigger,
|
|
164
|
+
NavigationMenuLink,
|
|
165
|
+
NavigationMenuIndicator,
|
|
166
|
+
NavigationMenuViewport,
|
|
167
|
+
navigationMenuTriggerStyle,
|
|
168
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
import { MoreHorizontal } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => (
|
|
8
|
+
<nav
|
|
9
|
+
data-slot="pagination"
|
|
10
|
+
role="navigation"
|
|
11
|
+
aria-label="pagination"
|
|
12
|
+
className={cn('mx-auto flex w-full justify-center', className)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
function PaginationContent({ className, ...props }: React.ComponentProps<'ul'>) {
|
|
18
|
+
return <ul data-slot="pagination-content" className={cn('flex flex-row items-center gap-1', className)} {...props} />;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function PaginationItem({ className, ...props }: React.ComponentProps<'li'>) {
|
|
22
|
+
return <li data-slot="pagination-item" className={cn('', className)} {...props} />;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<'span'>) => (
|
|
26
|
+
<span
|
|
27
|
+
data-slot="pagination-ellipsis"
|
|
28
|
+
aria-hidden
|
|
29
|
+
className={cn('flex h-9 w-9 items-center justify-center', className)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
<MoreHorizontal className="h-4 w-4" />
|
|
33
|
+
<span className="sr-only">More pages</span>
|
|
34
|
+
</span>
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useId } from 'react';
|
|
3
|
+
|
|
4
|
+
interface PlaceholderPatternProps {
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function PlaceholderPattern({ className }: PlaceholderPatternProps) {
|
|
9
|
+
const patternId = useId();
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<svg className={className} fill="none">
|
|
13
|
+
<defs>
|
|
14
|
+
<pattern id={patternId} x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse">
|
|
15
|
+
<path d="M-3 13 15-5M-5 5l18-18M-1 21 17 3"></path>
|
|
16
|
+
</pattern>
|
|
17
|
+
</defs>
|
|
18
|
+
<rect stroke="none" fill={`url(#${patternId})`} width="100%" height="100%"></rect>
|
|
19
|
+
</svg>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
|
|
6
|
+
function Popover({
|
|
7
|
+
...props
|
|
8
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
|
9
|
+
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function PopoverTrigger({
|
|
13
|
+
...props
|
|
14
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
15
|
+
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function PopoverContent({
|
|
19
|
+
className,
|
|
20
|
+
align = 'center',
|
|
21
|
+
sideOffset = 4,
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
|
24
|
+
return (
|
|
25
|
+
<PopoverPrimitive.Portal>
|
|
26
|
+
<PopoverPrimitive.Content
|
|
27
|
+
data-slot="popover-content"
|
|
28
|
+
align={align}
|
|
29
|
+
sideOffset={sideOffset}
|
|
30
|
+
className={cn(
|
|
31
|
+
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out',
|
|
32
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95',
|
|
33
|
+
'data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
|
|
34
|
+
'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
35
|
+
'z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden',
|
|
36
|
+
className,
|
|
37
|
+
)}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
</PopoverPrimitive.Portal>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function PopoverAnchor({
|
|
45
|
+
...props
|
|
46
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
|
47
|
+
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { Popover, PopoverAnchor, PopoverContent, PopoverTrigger };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
5
|
+
import { cn } from '../../lib/utils';
|
|
6
|
+
|
|
7
|
+
function Progress({
|
|
8
|
+
className,
|
|
9
|
+
indicatorClassName,
|
|
10
|
+
value,
|
|
11
|
+
...props
|
|
12
|
+
}: React.ComponentProps<typeof ProgressPrimitive.Root> & { indicatorClassName?: string }) {
|
|
13
|
+
return (
|
|
14
|
+
<ProgressPrimitive.Root
|
|
15
|
+
data-slot="progress"
|
|
16
|
+
className={cn('relative h-1.5 w-full overflow-hidden rounded-full bg-secondary', className)}
|
|
17
|
+
{...props}
|
|
18
|
+
>
|
|
19
|
+
<ProgressPrimitive.Indicator
|
|
20
|
+
data-slot="progress-indicator"
|
|
21
|
+
className={cn('h-full w-full flex-1 bg-primary transition-all', indicatorClassName)}
|
|
22
|
+
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
23
|
+
/>
|
|
24
|
+
</ProgressPrimitive.Root>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function ProgressCircle({
|
|
29
|
+
className,
|
|
30
|
+
indicatorClassName,
|
|
31
|
+
trackClassName,
|
|
32
|
+
value = 0,
|
|
33
|
+
size = 48,
|
|
34
|
+
strokeWidth = 4,
|
|
35
|
+
children,
|
|
36
|
+
...props
|
|
37
|
+
}: React.ComponentProps<'div'> & {
|
|
38
|
+
value?: number;
|
|
39
|
+
size?: number;
|
|
40
|
+
strokeWidth?: number;
|
|
41
|
+
indicatorClassName?: string;
|
|
42
|
+
trackClassName?: string;
|
|
43
|
+
children?: React.ReactNode;
|
|
44
|
+
}) {
|
|
45
|
+
const radius = (size - strokeWidth) / 2;
|
|
46
|
+
const circumference = radius * 2 * Math.PI;
|
|
47
|
+
const offset = circumference - (value / 100) * circumference;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
data-slot="progress-circle"
|
|
52
|
+
className={cn('relative inline-flex items-center justify-center', className)}
|
|
53
|
+
style={{ width: size, height: size }}
|
|
54
|
+
{...props}
|
|
55
|
+
>
|
|
56
|
+
<svg className="absolute inset-0 -rotate-90" width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
|
|
57
|
+
<circle cx={size / 2} cy={size / 2} r={radius} stroke="currentColor" strokeWidth={strokeWidth} fill="none" className={cn('text-secondary', trackClassName)} />
|
|
58
|
+
<circle cx={size / 2} cy={size / 2} r={radius} stroke="currentColor" strokeWidth={strokeWidth} fill="none" strokeDasharray={circumference} strokeDashoffset={offset} strokeLinecap="round" className={cn('text-primary transition-all duration-300 ease-in-out', indicatorClassName)} />
|
|
59
|
+
</svg>
|
|
60
|
+
{children && <div className="relative z-10 flex items-center justify-center text-sm font-medium">{children}</div>}
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { Progress, ProgressCircle };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
5
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
6
|
+
import { Circle } from 'lucide-react';
|
|
7
|
+
import { cn } from '../../lib/utils';
|
|
8
|
+
|
|
9
|
+
const radioGroupVariants = cva('grid gap-2.5', {
|
|
10
|
+
variants: {
|
|
11
|
+
variant: { primary: '', mono: '' },
|
|
12
|
+
size: { sm: '', md: '', lg: '' },
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: { variant: 'primary', size: 'md' },
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const RadioGroupContext = React.createContext<{ variant: 'primary' | 'mono'; size: 'sm' | 'md' | 'lg' }>({
|
|
18
|
+
variant: 'primary',
|
|
19
|
+
size: 'md',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
function RadioGroup({
|
|
23
|
+
className,
|
|
24
|
+
variant,
|
|
25
|
+
size,
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Root> & VariantProps<typeof radioGroupVariants>) {
|
|
28
|
+
return (
|
|
29
|
+
<RadioGroupContext.Provider value={{ variant: variant ?? 'primary', size: size ?? 'md' }}>
|
|
30
|
+
<RadioGroupPrimitive.Root
|
|
31
|
+
data-slot="radio-group"
|
|
32
|
+
className={cn(radioGroupVariants({ variant, size }), className)}
|
|
33
|
+
{...props}
|
|
34
|
+
/>
|
|
35
|
+
</RadioGroupContext.Provider>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const radioItemVariants = cva(
|
|
40
|
+
'peer aspect-square rounded-full border outline-hidden ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 border-input text-primary data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=checked]:text-primary-foreground',
|
|
41
|
+
{
|
|
42
|
+
variants: {
|
|
43
|
+
size: {
|
|
44
|
+
sm: 'size-4.5 [&_svg]:size-2',
|
|
45
|
+
md: 'size-5 [&_svg]:size-2.5',
|
|
46
|
+
lg: 'size-5.5 [&_svg]:size-3',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
defaultVariants: { size: 'md' },
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
function RadioGroupItem({
|
|
54
|
+
className,
|
|
55
|
+
size,
|
|
56
|
+
...props
|
|
57
|
+
}: React.ComponentProps<typeof RadioGroupPrimitive.Item> & VariantProps<typeof radioItemVariants>) {
|
|
58
|
+
const { size: contextSize } = React.useContext(RadioGroupContext);
|
|
59
|
+
const effectiveSize = size ?? contextSize;
|
|
60
|
+
return (
|
|
61
|
+
<RadioGroupPrimitive.Item
|
|
62
|
+
data-slot="radio-group-item"
|
|
63
|
+
className={cn(radioItemVariants({ size: effectiveSize }), className)}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
|
|
67
|
+
<Circle className="fill-current text-current" />
|
|
68
|
+
</RadioGroupPrimitive.Indicator>
|
|
69
|
+
</RadioGroupPrimitive.Item>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { RadioGroup, RadioGroupItem };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as ResizablePrimitive from 'react-resizable-panels';
|
|
5
|
+
import { GripVertical } from 'lucide-react';
|
|
6
|
+
import { cn } from '../../lib/utils';
|
|
7
|
+
|
|
8
|
+
const ResizablePanelGroup = ({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => (
|
|
9
|
+
<ResizablePrimitive.PanelGroup
|
|
10
|
+
data-slot="resizable-panel-group"
|
|
11
|
+
className={cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', className)}
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const ResizablePanel = ResizablePrimitive.Panel;
|
|
17
|
+
|
|
18
|
+
const ResizableHandle = ({
|
|
19
|
+
withHandle,
|
|
20
|
+
className,
|
|
21
|
+
...props
|
|
22
|
+
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & { withHandle?: boolean }) => (
|
|
23
|
+
<ResizablePrimitive.PanelResizeHandle
|
|
24
|
+
data-slot="resizable-handle"
|
|
25
|
+
className={cn(
|
|
26
|
+
'relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90',
|
|
27
|
+
className,
|
|
28
|
+
)}
|
|
29
|
+
{...props}
|
|
30
|
+
>
|
|
31
|
+
{withHandle && (
|
|
32
|
+
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
|
|
33
|
+
<GripVertical className="h-2.5 w-2.5" />
|
|
34
|
+
</div>
|
|
35
|
+
)}
|
|
36
|
+
</ResizablePrimitive.PanelResizeHandle>
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export { ResizableHandle, ResizablePanel, ResizablePanelGroup };
|