@kala-ui/react 0.0.1-beta.7 → 0.0.2
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/components/accordion/accordion-skeleton.js +1 -1
- package/dist/components/accordion/accordion.js +2 -1
- package/dist/components/action-icon/action-icon.d.ts +12 -0
- package/dist/components/action-icon/action-icon.js +35 -0
- package/dist/components/action-icon/action-icon.stories.d.ts +9 -0
- package/dist/components/action-icon/action-icon.stories.js +42 -0
- package/dist/components/action-icon/index.d.ts +1 -0
- package/dist/components/action-icon/index.js +1 -0
- package/dist/components/alert/alert-skeleton.js +4 -3
- package/dist/components/alert/alert.d.ts +2 -2
- package/dist/components/alert/alert.js +8 -6
- package/dist/components/alert/alert.stories.js +13 -9
- package/dist/components/alert/index.d.ts +1 -1
- package/dist/components/alert-dialog/alert-dialog.js +8 -5
- package/dist/components/app-shell/app-shell.d.ts +58 -0
- package/dist/components/app-shell/app-shell.js +111 -0
- package/dist/components/app-shell/app-shell.stories.d.ts +8 -0
- package/dist/components/app-shell/app-shell.stories.js +35 -0
- package/dist/components/app-shell/index.d.ts +1 -0
- package/dist/components/app-shell/index.js +1 -0
- package/dist/components/avatar/avatar.d.ts +2 -2
- package/dist/components/avatar/avatar.stories.js +1 -1
- package/dist/components/badge/badge.d.ts +1 -1
- package/dist/components/badge/badge.js +1 -1
- package/dist/components/badge/badge.stories.js +1 -1
- package/dist/components/banner/banner-skeleton.js +1 -1
- package/dist/components/banner/banner.d.ts +1 -1
- package/dist/components/banner/banner.stories.js +1 -1
- package/dist/components/box/box.d.ts +8 -0
- package/dist/components/box/box.js +10 -0
- package/dist/components/box/box.stories.d.ts +8 -0
- package/dist/components/box/box.stories.js +32 -0
- package/dist/components/box/index.d.ts +1 -0
- package/dist/components/box/index.js +1 -0
- package/dist/components/breadcrumbs/breadcrumbs-skeleton.js +1 -1
- package/dist/components/breadcrumbs/breadcrumbs.stories.js +1 -1
- package/dist/components/burger/burger.d.ts +8 -0
- package/dist/components/burger/burger.js +21 -0
- package/dist/components/burger/burger.stories.d.ts +8 -0
- package/dist/components/burger/burger.stories.js +31 -0
- package/dist/components/burger/index.d.ts +1 -0
- package/dist/components/burger/index.js +1 -0
- package/dist/components/button/button.d.ts +2 -2
- package/dist/components/button/button.stories.js +10 -7
- package/dist/components/button-group/button-group.stories.js +1 -1
- package/dist/components/calendar/calendar-skeleton.js +1 -1
- package/dist/components/calendar/calendar.d.ts +1 -1
- package/dist/components/calendar/calendar.js +1 -1
- package/dist/components/calendar/calendar.types.d.ts +3 -3
- package/dist/components/card/card-skeleton.js +2 -2
- package/dist/components/card/card.js +17 -14
- package/dist/components/card/index.d.ts +1 -1
- package/dist/components/center/center.d.ts +7 -0
- package/dist/components/center/center.js +10 -0
- package/dist/components/center/center.stories.d.ts +7 -0
- package/dist/components/center/center.stories.js +25 -0
- package/dist/components/center/index.d.ts +1 -0
- package/dist/components/center/index.js +1 -0
- package/dist/components/charts/area-chart.js +1 -1
- package/dist/components/charts/bar-chart.js +1 -1
- package/dist/components/charts/donut-chart.js +1 -1
- package/dist/components/charts/index.d.ts +2 -2
- package/dist/components/charts/index.js +2 -2
- package/dist/components/charts/line-chart.js +1 -1
- package/dist/components/charts/radial-bar-chart.js +1 -1
- package/dist/components/charts/theme-utils.d.ts +1 -1
- package/dist/components/charts/use-theme-aware-chart.d.ts +1 -1
- package/dist/components/charts/use-theme-aware-chart.js +2 -1
- package/dist/components/checkbox/checkbox.js +1 -1
- package/dist/components/checkbox/checkbox.stories.js +12 -8
- package/dist/components/close-button/close-button.d.ts +7 -0
- package/dist/components/close-button/close-button.js +9 -0
- package/dist/components/close-button/close-button.stories.d.ts +7 -0
- package/dist/components/close-button/close-button.stories.js +18 -0
- package/dist/components/close-button/index.d.ts +1 -0
- package/dist/components/close-button/index.js +1 -0
- package/dist/components/code/code.d.ts +8 -0
- package/dist/components/code/code.js +14 -0
- package/dist/components/code/code.stories.d.ts +8 -0
- package/dist/components/code/code.stories.js +31 -0
- package/dist/components/code/index.d.ts +1 -0
- package/dist/components/code/index.js +1 -0
- package/dist/components/collapse/collapse.d.ts +17 -0
- package/dist/components/collapse/collapse.js +34 -0
- package/dist/components/collapse/index.d.ts +1 -0
- package/dist/components/collapse/index.js +1 -0
- package/dist/components/color-input/color-input.d.ts +28 -0
- package/dist/components/color-input/color-input.js +35 -0
- package/dist/components/color-input/color-input.stories.d.ts +10 -0
- package/dist/components/color-input/color-input.stories.js +41 -0
- package/dist/components/color-input/index.d.ts +1 -0
- package/dist/components/color-input/index.js +1 -0
- package/dist/components/combobox/combobox-skeleton.js +1 -1
- package/dist/components/combobox/combobox.d.ts +1 -1
- package/dist/components/combobox/combobox.js +17 -8
- package/dist/components/combobox/combobox.stories.js +1 -1
- package/dist/components/command/command.d.ts +2 -2
- package/dist/components/command/command.stories.js +14 -19
- package/dist/components/container/container.d.ts +1 -1
- package/dist/components/container/index.d.ts +1 -1
- package/dist/components/container/index.js +1 -1
- package/dist/components/data-table/column-header-filter.js +11 -6
- package/dist/components/data-table/data-table-skeleton.js +5 -15
- package/dist/components/data-table/data-table.js +18 -15
- package/dist/components/data-table/data-table.stories.js +3 -5
- package/dist/components/date-picker/date-picker.d.ts +1 -1
- package/dist/components/date-picker/date-picker.js +3 -3
- package/dist/components/date-picker/date-picker.types.d.ts +1 -1
- package/dist/components/dialog/dialog-skeleton.js +1 -1
- package/dist/components/dialog/dialog.js +6 -4
- package/dist/components/dialog/dialog.stories.js +2 -2
- package/dist/components/dnd/dnd.d.ts +4 -5
- package/dist/components/dnd/dnd.js +5 -5
- package/dist/components/dnd/dnd.stories.js +48 -40
- package/dist/components/drawer/drawer.stories.js +2 -2
- package/dist/components/empty-state/empty-state-skeleton.js +2 -3
- package/dist/components/empty-state/empty-state.d.ts +1 -1
- package/dist/components/field/field-skeleton.js +1 -1
- package/dist/components/field/field.stories.js +1 -1
- package/dist/components/file-upload/file-upload-skeleton.js +1 -1
- package/dist/components/flex/flex.d.ts +7 -5
- package/dist/components/flex/flex.js +2 -2
- package/dist/components/flex/index.d.ts +1 -1
- package/dist/components/flex/index.js +1 -1
- package/dist/components/grid/grid.d.ts +24 -0
- package/dist/components/grid/grid.js +136 -0
- package/dist/components/grid/grid.stories.d.ts +8 -0
- package/dist/components/grid/grid.stories.js +31 -0
- package/dist/components/grid/index.d.ts +1 -0
- package/dist/components/grid/index.js +1 -0
- package/dist/components/group/group.d.ts +2 -2
- package/dist/components/group/group.js +1 -1
- package/dist/components/group/index.d.ts +1 -1
- package/dist/components/group/index.js +1 -1
- package/dist/components/header/header-skeleton.js +1 -1
- package/dist/components/header/header.d.ts +3 -3
- package/dist/components/header/header.js +17 -31
- package/dist/components/header/index.d.ts +1 -1
- package/dist/components/heading/heading.d.ts +4 -2
- package/dist/components/heading/heading.js +3 -7
- package/dist/components/heading/index.d.ts +1 -1
- package/dist/components/heading/index.js +1 -1
- package/dist/components/indicator/index.d.ts +1 -0
- package/dist/components/indicator/index.js +1 -0
- package/dist/components/indicator/indicator.d.ts +30 -0
- package/dist/components/indicator/indicator.js +89 -0
- package/dist/components/indicator/indicator.stories.d.ts +10 -0
- package/dist/components/indicator/indicator.stories.js +75 -0
- package/dist/components/input/input.js +1 -1
- package/dist/components/input/input.stories.js +1 -1
- package/dist/components/input-group/input-group.stories.js +1 -1
- package/dist/components/kbd/index.d.ts +1 -0
- package/dist/components/kbd/index.js +1 -0
- package/dist/components/kbd/kbd.d.ts +6 -0
- package/dist/components/kbd/kbd.js +13 -0
- package/dist/components/kbd/kbd.stories.d.ts +9 -0
- package/dist/components/kbd/kbd.stories.js +28 -0
- package/dist/components/label/label.stories.js +1 -1
- package/dist/components/list/list-skeleton.js +2 -2
- package/dist/components/list/list.js +1 -1
- package/dist/components/list/list.stories.js +1 -1
- package/dist/components/list/list.types.d.ts +2 -2
- package/dist/components/loading-overlay/index.d.ts +1 -0
- package/dist/components/loading-overlay/index.js +1 -0
- package/dist/components/loading-overlay/loading-overlay.d.ts +19 -0
- package/dist/components/loading-overlay/loading-overlay.js +19 -0
- package/dist/components/loading-overlay/loading-overlay.stories.d.ts +8 -0
- package/dist/components/loading-overlay/loading-overlay.stories.js +46 -0
- package/dist/components/metric-card/metric-card-skeleton.js +2 -2
- package/dist/components/metric-card/metric-card.js +1 -1
- package/dist/components/multi-select/multi-select-skeleton.js +1 -1
- package/dist/components/multi-select/multi-select.stories.js +1 -1
- package/dist/components/nav-link/index.d.ts +1 -0
- package/dist/components/nav-link/index.js +1 -0
- package/dist/components/nav-link/nav-link.d.ts +26 -0
- package/dist/components/nav-link/nav-link.js +26 -0
- package/dist/components/nav-link/nav-link.stories.d.ts +9 -0
- package/dist/components/nav-link/nav-link.stories.js +37 -0
- package/dist/components/navigation/navigation-skeleton.js +1 -1
- package/dist/components/number-input/index.d.ts +1 -0
- package/dist/components/number-input/index.js +1 -0
- package/dist/components/number-input/number-input.d.ts +40 -0
- package/dist/components/number-input/number-input.js +69 -0
- package/dist/components/number-input/number-input.stories.d.ts +11 -0
- package/dist/components/number-input/number-input.stories.js +54 -0
- package/dist/components/overlay/index.d.ts +1 -0
- package/dist/components/overlay/index.js +1 -0
- package/dist/components/overlay/overlay.d.ts +22 -0
- package/dist/components/overlay/overlay.js +45 -0
- package/dist/components/overlay/overlay.stories.d.ts +9 -0
- package/dist/components/overlay/overlay.stories.js +47 -0
- package/dist/components/page-transition/page-transition.stories.js +1 -1
- package/dist/components/pagination/index.d.ts +1 -1
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/pagination/pagination-skeleton.js +1 -1
- package/dist/components/pagination/pagination.d.ts +44 -28
- package/dist/components/pagination/pagination.js +53 -79
- package/dist/components/pagination/pagination.stories.d.ts +1 -0
- package/dist/components/pagination/pagination.stories.js +31 -5
- package/dist/components/paper/index.d.ts +1 -0
- package/dist/components/paper/index.js +1 -0
- package/dist/components/paper/paper.d.ts +12 -0
- package/dist/components/paper/paper.js +39 -0
- package/dist/components/paper/paper.stories.d.ts +7 -0
- package/dist/components/paper/paper.stories.js +30 -0
- package/dist/components/password-strength-indicator/password-strength-indicator.stories.js +1 -1
- package/dist/components/popover/popover-skeleton.js +1 -1
- package/dist/components/popover/popover.stories.js +2 -2
- package/dist/components/progress/index.d.ts +1 -1
- package/dist/components/progress/progress.d.ts +1 -1
- package/dist/components/progress/progress.stories.js +1 -1
- package/dist/components/radio-group/radio-group-skeleton.js +1 -1
- package/dist/components/radio-group/radio-group.stories.js +1 -1
- package/dist/components/resizable/resizable.stories.js +8 -8
- package/dist/components/ring-progress/index.d.ts +1 -0
- package/dist/components/ring-progress/index.js +1 -0
- package/dist/components/ring-progress/ring-progress.d.ts +24 -0
- package/dist/components/ring-progress/ring-progress.js +20 -0
- package/dist/components/ring-progress/ring-progress.stories.d.ts +9 -0
- package/dist/components/ring-progress/ring-progress.stories.js +46 -0
- package/dist/components/scroll-area/scroll-area.stories.js +26 -26
- package/dist/components/segmented-control/index.d.ts +1 -0
- package/dist/components/segmented-control/index.js +1 -0
- package/dist/components/segmented-control/segmented-control.d.ts +19 -0
- package/dist/components/segmented-control/segmented-control.js +46 -0
- package/dist/components/segmented-control/segmented-control.stories.d.ts +10 -0
- package/dist/components/segmented-control/segmented-control.stories.js +53 -0
- package/dist/components/select/select.js +1 -1
- package/dist/components/select/select.stories.js +1 -1
- package/dist/components/separator/separator.stories.js +1 -1
- package/dist/components/session-card/session-card-skeleton.js +2 -2
- package/dist/components/session-card/session-card.js +1 -1
- package/dist/components/sidebar/sidebar-skeleton.js +2 -2
- package/dist/components/skeleton/index.d.ts +3 -3
- package/dist/components/skeleton/index.js +1 -1
- package/dist/components/skeleton/skeleton.types.d.ts +0 -249
- package/dist/components/slider/index.d.ts +1 -1
- package/dist/components/slider/slider.js +1 -1
- package/dist/components/slider/slider.stories.js +1 -1
- package/dist/components/social-login-button/social-login-button.js +6 -6
- package/dist/components/sparkline-chart/sparkline-chart.js +6 -3
- package/dist/components/sparkline-chart/sparkline-chart.stories.js +1 -1
- package/dist/components/spinner/spinner.d.ts +1 -1
- package/dist/components/spoiler/index.d.ts +1 -0
- package/dist/components/spoiler/index.js +1 -0
- package/dist/components/spoiler/spoiler.d.ts +14 -0
- package/dist/components/spoiler/spoiler.js +20 -0
- package/dist/components/spoiler/spoiler.stories.d.ts +8 -0
- package/dist/components/spoiler/spoiler.stories.js +35 -0
- package/dist/components/stack/index.d.ts +1 -1
- package/dist/components/stack/index.js +1 -1
- package/dist/components/stack/stack.d.ts +2 -2
- package/dist/components/stack/stack.js +1 -1
- package/dist/components/steps/steps-skeleton.js +1 -1
- package/dist/components/steps/steps.js +7 -5
- package/dist/components/steps/steps.stories.js +6 -2
- package/dist/components/switch/index.d.ts +1 -1
- package/dist/components/switch/switch.js +1 -1
- package/dist/components/switch/switch.stories.js +1 -1
- package/dist/components/table/table-skeleton.js +2 -2
- package/dist/components/table/table.js +4 -3
- package/dist/components/table/table.stories.js +10 -7
- package/dist/components/tabs/tabs-skeleton.js +1 -1
- package/dist/components/tabs/tabs.d.ts +3 -3
- package/dist/components/tabs/tabs.js +1 -1
- package/dist/components/tabs/tabs.stories.js +5 -5
- package/dist/components/text/index.d.ts +1 -1
- package/dist/components/text/index.js +1 -1
- package/dist/components/text/text.d.ts +7 -5
- package/dist/components/text/text.js +2 -2
- package/dist/components/text/text.stories.js +34 -3
- package/dist/components/textarea/textarea.js +1 -1
- package/dist/components/textarea/textarea.stories.js +1 -1
- package/dist/components/timeline/index.d.ts +1 -0
- package/dist/components/timeline/index.js +1 -0
- package/dist/components/timeline/timeline.d.ts +35 -0
- package/dist/components/timeline/timeline.js +36 -0
- package/dist/components/timeline/timeline.stories.d.ts +7 -0
- package/dist/components/timeline/timeline.stories.js +21 -0
- package/dist/components/toast/toast.js +6 -6
- package/dist/components/toggle/toggle.stories.js +1 -1
- package/dist/components/tooltip/tooltip.stories.js +1 -1
- package/dist/components/user-menu-dropdown/user-menu-dropdown.js +1 -1
- package/dist/config/tailwind-base.d.ts +10 -0
- package/dist/config/tailwind-base.js +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +25 -10
- package/dist/lib/animations.js +94 -94
- package/dist/primitives/command/Command.js +2 -1
- package/dist/styles/globals.css +415 -82
- package/package.json +101 -24
|
@@ -1,35 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMounted, useScrollLock } from "@kala-ui/react-hooks";
|
|
3
4
|
import { Bell, ChevronDown, Menu, Settings, X } from "lucide-react";
|
|
4
5
|
import * as React from "react";
|
|
5
6
|
import { createPortal } from "react-dom";
|
|
6
7
|
import { cn } from "../../lib/utils";
|
|
8
|
+
import { Box } from "../box";
|
|
7
9
|
import { Button } from "../button";
|
|
10
|
+
import { Flex } from "../flex";
|
|
11
|
+
import { List } from "../list";
|
|
8
12
|
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, } from "../navigation-menu";
|
|
13
|
+
import { Stack } from "../stack";
|
|
9
14
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../tabs";
|
|
15
|
+
import { Text } from "../text";
|
|
10
16
|
export const Header = React.forwardRef(({ className, logo, navLinks = [], userMenu, userProfile, searchBar, notifications, mobileNotifications, themeSwitcher, themeSwitcherMobile, languageSwitcher, languageSwitcherMobile, onMobileMenuToggle, isMobileMenuOpen, variant = "default", ...props }, ref) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (isMobileMenuOpen) {
|
|
14
|
-
// Calculate scrollbar width
|
|
15
|
-
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
16
|
-
document.body.style.setProperty("--removed-body-scroll-bar-size", `${scrollbarWidth}px`);
|
|
17
|
-
document.body.setAttribute("data-scroll-locked", "1");
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
document.body.removeAttribute("data-scroll-locked");
|
|
21
|
-
document.body.style.removeProperty("--removed-body-scroll-bar-size");
|
|
22
|
-
}
|
|
23
|
-
// Cleanup on unmount
|
|
24
|
-
return () => {
|
|
25
|
-
document.body.removeAttribute("data-scroll-locked");
|
|
26
|
-
document.body.style.removeProperty("--removed-body-scroll-bar-size");
|
|
27
|
-
};
|
|
28
|
-
}, [isMobileMenuOpen]);
|
|
29
|
-
const [mounted, setMounted] = React.useState(false);
|
|
30
|
-
React.useEffect(() => {
|
|
31
|
-
setMounted(true);
|
|
32
|
-
}, []);
|
|
17
|
+
useScrollLock(!!isMobileMenuOpen);
|
|
18
|
+
const mounted = useMounted();
|
|
33
19
|
// Track expanded mobile menu items
|
|
34
20
|
const [expandedItems, setExpandedItems] = React.useState(new Set());
|
|
35
21
|
const toggleExpanded = (label) => {
|
|
@@ -44,19 +30,19 @@ export const Header = React.forwardRef(({ className, logo, navLinks = [], userMe
|
|
|
44
30
|
return next;
|
|
45
31
|
});
|
|
46
32
|
};
|
|
47
|
-
return (_jsxs("header",
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
33
|
+
return (_jsxs(Box, { as: "header", ref: ref, "data-comp": "header", className: cn("w-full bg-popover border-b sticky top-0 z-20 theme-popover", className), ...props, children: [_jsx(Box, { className: "container mx-auto px-3 sm:px-4 lg:px-6 xl:px-8", children: _jsxs(Flex, { align: "center", justify: "between", className: "h-14 sm:h-16 gap-2 sm:gap-4", children: [_jsx(Box, { className: "shrink-0 min-w-0 max-w-[120px] sm:max-w-none", children: logo }), _jsx(Flex, { align: "center", gap: variant === "default" ? 3 : 6, className: cn("hidden lg:flex", variant === "default" ? "flex-1" : ""), children: _jsx(Box, { className: cn("flex", variant === "default" ? "mx-auto" : ""), children: _jsxs(NavigationMenu, { children: [_jsx(NavigationMenuList, { children: navLinks.map((link) => (_jsx(NavigationMenuItem, { children: link.children ? (_jsxs(_Fragment, { children: [_jsx(NavigationMenuTrigger, { className: cn("text-sm lg:text-base", link.active && "text-primary"), children: link.label }), _jsx(NavigationMenuContent, { children: _jsx(Box, { className: "py-2", children: _jsx(List, { divided: false, className: cn("bg-transparent border-none", link.children.length <= 3
|
|
34
|
+
? "w-[220px]"
|
|
35
|
+
: "w-[440px] grid grid-cols-2"), children: link.children.map((child) => (_jsx(Box, { as: "li", children: _jsx(NavigationMenuLink, { asChild: true, children: _jsx(Box, { as: "a", href: child.href, className: cn("block px-4 py-2.5 text-sm font-normal no-underline outline-none transition-colors", "text-foreground", "hover:bg-accent hover:text-accent-foreground", "focus:bg-accent focus:text-accent-foreground", child.active &&
|
|
36
|
+
"text-primary bg-primary/10"), children: child.label }) }) }, child.href))) }) }) })] })) : (_jsx(NavigationMenuLink, { href: link.href, className: cn("px-4 py-2 text-sm lg:text-base", link.active && "text-primary"), "aria-current": link.active ? "page" : undefined, children: link.label })) }, link.href))) }), _jsx(NavigationMenuViewport, {})] }) }) }), _jsxs(Flex, { align: "center", gap: 1.5, className: "sm:gap-2 lg:gap-3 shrink-0", children: [searchBar && (_jsx(Box, { className: "hidden lg:block w-48 xl:w-64", children: searchBar })), languageSwitcher && (_jsx(Box, { className: "hidden lg:block", children: languageSwitcher })), themeSwitcher && (_jsx(Box, { className: "hidden lg:block", children: themeSwitcher })), notifications && (_jsx(Box, { className: "hidden lg:block", children: notifications })), userMenu && _jsx(Box, { className: "hidden lg:block", children: userMenu }), onMobileMenuToggle && (_jsx(Button, { variant: "ghost", size: "icon", className: "lg:hidden h-9 w-9 sm:h-10 sm:w-10", onClick: onMobileMenuToggle, "aria-label": "Toggle mobile menu", "aria-expanded": isMobileMenuOpen, children: isMobileMenuOpen ? (_jsx(X, { className: "w-5 h-5 sm:w-6 sm:h-6" })) : (_jsx(Menu, { className: "w-5 h-5 sm:w-6 sm:h-6" })) }))] })] }) }), isMobileMenuOpen &&
|
|
51
37
|
mounted &&
|
|
52
|
-
createPortal(_jsxs(_Fragment, { children: [_jsx(
|
|
38
|
+
createPortal(_jsxs(_Fragment, { children: [_jsx(Box, { className: "fixed inset-0 bg-black/20 backdrop-blur-sm z-40 lg:hidden", onClick: onMobileMenuToggle, "aria-hidden": "true" }), _jsxs(Box, { as: "nav", className: "fixed top-0 left-0 right-0 bottom-0 bg-popover z-40 lg:hidden overflow-hidden flex flex-col theme-popover", "aria-label": "Mobile navigation", children: [_jsxs(Flex, { align: "center", justify: "between", className: "px-4 h-14 sm:h-16 border-b shrink-0", children: [_jsx(Box, { className: "shrink-0 min-w-0 max-w-[120px] sm:max-w-none", children: logo }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-9 w-9 sm:h-10 sm:w-10", onClick: onMobileMenuToggle, "aria-label": "Close mobile menu", children: _jsx(X, { className: "w-5 h-5 sm:w-6 sm:h-6" }) })] }), _jsxs(Tabs, { defaultValue: "menu", className: "flex flex-col flex-1 overflow-hidden", children: [_jsx(Box, { className: "px-4 py-2 border-b shrink-0", children: _jsxs(TabsList, { className: "w-full grid grid-cols-3", children: [_jsx(TabsTrigger, { value: "menu", children: _jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Menu, { className: "w-4 h-4" }), _jsx(Text, { children: "Menu" })] }) }), _jsx(TabsTrigger, { value: "notifications", children: _jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Bell, { className: "w-4 h-4" }), _jsx(Text, { children: "Alerts" })] }) }), _jsx(TabsTrigger, { value: "preferences", children: _jsxs(Flex, { align: "center", gap: 2, children: [_jsx(Settings, { className: "w-4 h-4" }), _jsx(Text, { children: "Preferences" })] }) })] }) }), _jsxs(Box, { className: "flex-1 overflow-y-auto", children: [_jsxs(TabsContent, { value: "menu", className: "mt-0 h-full", children: [searchBar && (_jsx(Box, { className: "px-4 py-3 border-b", children: searchBar })), userProfile ? (_jsxs(Box, { className: "border-b", children: [_jsxs(Flex, { align: "center", gap: 3, className: "px-4 py-4 bg-muted", children: [userProfile.avatar ? (_jsx(Box, { as: "img", src: userProfile.avatar, alt: userProfile.name, className: "w-10 h-10 rounded-full object-cover" })) : (_jsx(Flex, { align: "center", justify: "center", className: "w-10 h-10 rounded-full bg-primary/10 text-primary font-semibold", children: userProfile.name.charAt(0).toUpperCase() })), _jsxs(Stack, { gap: 0, className: "min-w-0", children: [_jsx(Text, { size: "sm", weight: "medium", className: "truncate", children: userProfile.name }), _jsx(Text, { size: "xs", className: "text-muted-foreground truncate", children: userProfile.email })] })] }), _jsx(Box, { className: "py-2", children: userProfile.links.map((link, index) => (_jsxs(React.Fragment, { children: [link.divider && index > 0 && (_jsx(Box, { className: "my-2 border-t" })), link.href ? (_jsxs(Box, { as: "a", href: link.href, className: cn("flex items-center gap-3 px-4 py-2.5 text-sm transition-colors hover:bg-accent", link.variant === "danger"
|
|
53
39
|
? "text-destructive hover:bg-destructive/10"
|
|
54
|
-
: "text-foreground hover:text-foreground"), onClick: onMobileMenuToggle, children: [link.icon && (_jsx("span",
|
|
40
|
+
: "text-foreground hover:text-foreground"), onClick: onMobileMenuToggle, children: [link.icon && (_jsx(Box, { as: "span", className: "w-4 h-4", children: link.icon })), link.label] })) : (_jsxs(Button, { variant: "ghost", className: cn("w-full flex items-center gap-3 px-4 py-2.5 text-sm transition-colors hover:bg-accent text-left justify-start font-normal h-auto rounded-none", link.variant === "danger"
|
|
55
41
|
? "text-destructive hover:bg-destructive/10"
|
|
56
42
|
: "text-foreground hover:text-foreground"), onClick: () => {
|
|
57
43
|
link.onClick?.();
|
|
58
44
|
onMobileMenuToggle?.();
|
|
59
|
-
}, children: [link.icon && (_jsx("span",
|
|
45
|
+
}, children: [link.icon && (_jsx(Box, { as: "span", className: "w-4 h-4", children: link.icon })), link.label] }))] }, link.label))) })] })) : userMenu ? (_jsxs(Box, { className: "px-4 py-3 border-b", children: [_jsx(Text, { size: "xs", weight: "semibold", className: "text-muted-foreground uppercase mb-2", children: "Account" }), userMenu] })) : null, _jsx(Box, { className: "py-2", children: navLinks.map((link) => (_jsx(React.Fragment, { children: _jsxs(Flex, { direction: "column", children: [_jsxs(Box, { as: "a", href: link.href, className: cn("text-sm font-medium px-4 py-3 flex items-center justify-between transition-colors hover:bg-accent border-l-4", link.active
|
|
60
46
|
? "bg-primary/10 text-primary border-primary"
|
|
61
47
|
: "text-foreground border-transparent hover:border-border"), "aria-current": link.active ? "page" : undefined, onClick: (e) => {
|
|
62
48
|
if (link.children || link.href === "#") {
|
|
@@ -69,8 +55,8 @@ export const Header = React.forwardRef(({ className, logo, navLinks = [], userMe
|
|
|
69
55
|
}, children: [link.label, link.children && (_jsx(ChevronDown, { className: cn("w-4 h-4 transition-transform duration-200", expandedItems.has(link.label)
|
|
70
56
|
? "rotate-180"
|
|
71
57
|
: "") }))] }), link.children &&
|
|
72
|
-
expandedItems.has(link.label) && (_jsx(
|
|
58
|
+
expandedItems.has(link.label) && (_jsx(Box, { className: "bg-muted animate-in slide-in-from-top-2 duration-200", children: link.children.map((child) => (_jsx(Box, { as: "a", href: child.href, className: cn("block text-sm px-8 py-2.5 transition-colors hover:bg-accent border-l-4 border-transparent", child.active
|
|
73
59
|
? "text-primary font-medium"
|
|
74
|
-
: "text-muted-foreground hover:text-foreground"), onClick: onMobileMenuToggle, children: child.label }, child.label))) }))] }) }, link.label))) })] }), _jsx(TabsContent, { value: "notifications", className: "mt-0 h-full", children: mobileNotifications || notifications ? (_jsx(
|
|
60
|
+
: "text-muted-foreground hover:text-foreground"), onClick: onMobileMenuToggle, children: child.label }, child.label))) }))] }) }, link.label))) })] }), _jsx(TabsContent, { value: "notifications", className: "mt-0 h-full", children: mobileNotifications || notifications ? (_jsx(Box, { className: "p-0", children: mobileNotifications || notifications })) : (_jsxs(Flex, { direction: "column", align: "center", justify: "center", className: "h-64 text-muted-foreground", children: [_jsx(Bell, { className: "w-12 h-12 mb-4 opacity-20" }), _jsx(Text, { children: "No notifications" })] })) }), _jsx(TabsContent, { value: "preferences", className: "mt-0 h-full", children: _jsx(Flex, { direction: "column", children: (themeSwitcherMobile || languageSwitcherMobile) && (_jsxs(Stack, { gap: 6, className: "p-4", children: [_jsx(Text, { size: "xs", weight: "semibold", className: "text-muted-foreground uppercase", children: "Preferences" }), _jsxs(Stack, { gap: 6, children: [themeSwitcherMobile && (_jsx(Box, { className: "w-full", children: themeSwitcherMobile })), languageSwitcherMobile && (_jsx(Box, { className: "w-full", children: languageSwitcherMobile }))] })] })) }) })] })] })] })] }), document.body)] }));
|
|
75
61
|
});
|
|
76
62
|
Header.displayName = "Header";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { HeaderNavLink, HeaderProps } from "./header";
|
|
2
2
|
export { Header } from "./header";
|
|
3
3
|
export type { HeaderSkeletonConfig, HeaderSkeletonProps, } from "./header-skeleton";
|
|
4
4
|
export { HeaderSkeleton } from "./header-skeleton";
|
|
@@ -5,8 +5,10 @@ declare const headingVariants: (props?: ({
|
|
|
5
5
|
align?: "center" | "left" | "right" | null | undefined;
|
|
6
6
|
weight?: "default" | "medium" | "semibold" | "extrabold" | null | undefined;
|
|
7
7
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
|
-
export interface HeadingProps extends React.HTMLAttributes<
|
|
8
|
+
export interface HeadingProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof headingVariants> {
|
|
9
9
|
asChild?: boolean;
|
|
10
|
+
as?: React.ElementType;
|
|
11
|
+
[key: string]: any;
|
|
10
12
|
}
|
|
11
|
-
declare const Heading: React.ForwardRefExoticComponent<HeadingProps & React.RefAttributes<
|
|
13
|
+
declare const Heading: React.ForwardRefExoticComponent<Omit<HeadingProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
12
14
|
export { Heading, headingVariants };
|
|
@@ -31,13 +31,9 @@ const headingVariants = cva("font-bold tracking-tight text-foreground", {
|
|
|
31
31
|
weight: "default",
|
|
32
32
|
},
|
|
33
33
|
});
|
|
34
|
-
const Heading = React.forwardRef(({ className, size, align, weight, asChild = false, ...props }, ref) => {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
// But since Comp is determined by asChild, we can't easily change it dynamically if not asChild
|
|
38
|
-
// Unless we map size to tag.
|
|
39
|
-
// Simple mapping if not asChild
|
|
40
|
-
const Tag = asChild ? Slot : size || "h2";
|
|
34
|
+
const Heading = React.forwardRef(({ className, size, align, weight, asChild = false, as, ...props }, ref) => {
|
|
35
|
+
const defaultTag = size || "h2";
|
|
36
|
+
const Tag = asChild ? Slot : (as || defaultTag);
|
|
41
37
|
return (_jsx(Tag, { className: cn(headingVariants({ size, align, weight, className })), ref: ref, ...props }));
|
|
42
38
|
});
|
|
43
39
|
Heading.displayName = "Heading";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./heading";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from "./heading";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./indicator";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./indicator";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
declare const indicatorVariants: (props?: ({
|
|
4
|
+
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "top-center" | "middle-left" | "middle-center" | "middle-right" | "bottom-center" | null | undefined;
|
|
5
|
+
color?: "primary" | "secondary" | "success" | "danger" | "warning" | "info" | null | undefined;
|
|
6
|
+
withBorder?: boolean | null | undefined;
|
|
7
|
+
processing?: boolean | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
9
|
+
export interface IndicatorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "color">, VariantProps<typeof indicatorVariants> {
|
|
10
|
+
/** Indicator position relative to the target element */
|
|
11
|
+
position?: "top-left" | "top-center" | "top-right" | "middle-left" | "middle-center" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
12
|
+
/** Offset from the edge of the target element, in px */
|
|
13
|
+
offset?: number;
|
|
14
|
+
/** Determines whether the indicator should be displayed inline */
|
|
15
|
+
inline?: boolean;
|
|
16
|
+
/** Size of the indicator in px */
|
|
17
|
+
size?: number;
|
|
18
|
+
/** Determines whether the indicator should have a border */
|
|
19
|
+
withBorder?: boolean;
|
|
20
|
+
/** Determines whether the indicator should be disabled (hidden) */
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/** Determines whether the indicator should show a processing animation */
|
|
23
|
+
processing?: boolean;
|
|
24
|
+
/** Indicator label */
|
|
25
|
+
label?: React.ReactNode;
|
|
26
|
+
/** Target element */
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
declare const Indicator: React.ForwardRefExoticComponent<IndicatorProps & React.RefAttributes<HTMLDivElement>>;
|
|
30
|
+
export { Indicator, indicatorVariants };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../../lib/utils";
|
|
5
|
+
import { Box } from "../box";
|
|
6
|
+
const indicatorVariants = cva("absolute flex items-center justify-center font-bold z-50", {
|
|
7
|
+
variants: {
|
|
8
|
+
position: {
|
|
9
|
+
"top-left": "top-0 left-0 -translate-x-1/2 -translate-y-1/2",
|
|
10
|
+
"top-center": "top-0 left-1/2 -translate-x-1/2 -translate-y-1/2",
|
|
11
|
+
"top-right": "top-0 right-0 translate-x-1/2 -translate-y-1/2",
|
|
12
|
+
"middle-left": "top-1/2 left-0 -translate-x-1/2 -translate-y-1/2",
|
|
13
|
+
"middle-center": "top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",
|
|
14
|
+
"middle-right": "top-1/2 right-0 translate-x-1/2 -translate-y-1/2",
|
|
15
|
+
"bottom-left": "bottom-0 left-0 -translate-x-1/2 translate-y-1/2",
|
|
16
|
+
"bottom-center": "bottom-0 left-1/2 -translate-x-1/2 translate-y-1/2",
|
|
17
|
+
"bottom-right": "bottom-0 right-0 translate-x-1/2 translate-y-1/2",
|
|
18
|
+
},
|
|
19
|
+
color: {
|
|
20
|
+
primary: "bg-primary text-primary-foreground",
|
|
21
|
+
secondary: "bg-secondary text-secondary-foreground",
|
|
22
|
+
danger: "bg-destructive text-destructive-foreground",
|
|
23
|
+
success: "bg-success text-success-foreground",
|
|
24
|
+
warning: "bg-warning text-warning-foreground",
|
|
25
|
+
info: "bg-info text-info-foreground",
|
|
26
|
+
},
|
|
27
|
+
withBorder: {
|
|
28
|
+
true: "border-2 border-background",
|
|
29
|
+
},
|
|
30
|
+
processing: {
|
|
31
|
+
true: "animate-pulse",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
position: "top-right",
|
|
36
|
+
color: "primary",
|
|
37
|
+
withBorder: false,
|
|
38
|
+
processing: false,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
const Indicator = React.forwardRef(({ className, position = "top-right", offset = 0, inline = false, size = 10, withBorder = false, disabled = false, processing = false, color = "primary", label, children, style, ...props }, ref) => {
|
|
42
|
+
const getPositionStyles = () => {
|
|
43
|
+
const styles = {};
|
|
44
|
+
if (offset) {
|
|
45
|
+
switch (position) {
|
|
46
|
+
case "top-left":
|
|
47
|
+
styles.top = offset;
|
|
48
|
+
styles.left = offset;
|
|
49
|
+
break;
|
|
50
|
+
case "top-center":
|
|
51
|
+
styles.top = offset;
|
|
52
|
+
break;
|
|
53
|
+
case "top-right":
|
|
54
|
+
styles.top = offset;
|
|
55
|
+
styles.right = offset;
|
|
56
|
+
break;
|
|
57
|
+
case "middle-left":
|
|
58
|
+
styles.left = offset;
|
|
59
|
+
break;
|
|
60
|
+
case "middle-right":
|
|
61
|
+
styles.right = offset;
|
|
62
|
+
break;
|
|
63
|
+
case "bottom-left":
|
|
64
|
+
styles.bottom = offset;
|
|
65
|
+
styles.left = offset;
|
|
66
|
+
break;
|
|
67
|
+
case "bottom-center":
|
|
68
|
+
styles.bottom = offset;
|
|
69
|
+
break;
|
|
70
|
+
case "bottom-right":
|
|
71
|
+
styles.bottom = offset;
|
|
72
|
+
styles.right = offset;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return styles;
|
|
77
|
+
};
|
|
78
|
+
return (_jsxs(Box, { ref: ref, className: cn("relative", inline ? "inline-block" : "block"), children: [!disabled && (_jsx("div", { className: cn(indicatorVariants({ position, color, withBorder, processing }), "rounded-full", className), style: {
|
|
79
|
+
width: label ? "auto" : size,
|
|
80
|
+
height: size,
|
|
81
|
+
minWidth: size,
|
|
82
|
+
padding: label ? `0 ${size / 3}px` : 0,
|
|
83
|
+
fontSize: size * 0.7,
|
|
84
|
+
...getPositionStyles(),
|
|
85
|
+
...style,
|
|
86
|
+
}, ...props, children: label })), children] }));
|
|
87
|
+
});
|
|
88
|
+
Indicator.displayName = "Indicator";
|
|
89
|
+
export { Indicator, indicatorVariants };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Indicator } from "./indicator";
|
|
3
|
+
declare const meta: Meta<typeof Indicator>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Indicator>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const WithLabel: Story;
|
|
8
|
+
export declare const Processing: Story;
|
|
9
|
+
export declare const Positions: Story;
|
|
10
|
+
export declare const Inline: Story;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Avatar, AvatarFallback, AvatarImage } from "../avatar";
|
|
3
|
+
import { Indicator } from "./indicator";
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Components/Indicator",
|
|
6
|
+
component: Indicator,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: "centered",
|
|
9
|
+
},
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
argTypes: {
|
|
12
|
+
color: {
|
|
13
|
+
control: "select",
|
|
14
|
+
options: [
|
|
15
|
+
"primary",
|
|
16
|
+
"secondary",
|
|
17
|
+
"danger",
|
|
18
|
+
"success",
|
|
19
|
+
"warning",
|
|
20
|
+
"info",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
position: {
|
|
24
|
+
control: "select",
|
|
25
|
+
options: [
|
|
26
|
+
"top-left",
|
|
27
|
+
"top-center",
|
|
28
|
+
"top-right",
|
|
29
|
+
"middle-left",
|
|
30
|
+
"middle-center",
|
|
31
|
+
"middle-right",
|
|
32
|
+
"bottom-left",
|
|
33
|
+
"bottom-center",
|
|
34
|
+
"bottom-right",
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
size: {
|
|
38
|
+
control: { type: "number", min: 6, max: 30, step: 2 },
|
|
39
|
+
},
|
|
40
|
+
offset: {
|
|
41
|
+
control: { type: "number", min: -20, max: 20, step: 1 },
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
export default meta;
|
|
46
|
+
export const Default = {
|
|
47
|
+
args: {
|
|
48
|
+
children: (_jsxs(Avatar, { children: [_jsx(AvatarImage, { src: "https://github.com/shadcn.png", alt: "@shadcn" }), _jsx(AvatarFallback, { children: "CN" })] })),
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
export const WithLabel = {
|
|
52
|
+
args: {
|
|
53
|
+
label: "New",
|
|
54
|
+
size: 16,
|
|
55
|
+
children: (_jsx("div", { className: "w-12 h-12 bg-gray-200 rounded-md" })),
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
export const Processing = {
|
|
59
|
+
args: {
|
|
60
|
+
processing: true,
|
|
61
|
+
children: (_jsxs(Avatar, { children: [_jsx(AvatarImage, { src: "https://github.com/shadcn.png", alt: "@shadcn" }), _jsx(AvatarFallback, { children: "CN" })] })),
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
export const Positions = {
|
|
65
|
+
render: () => (_jsxs("div", { className: "grid grid-cols-3 gap-8", children: [_jsx(Indicator, { position: "top-left", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "top-center", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "top-right", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "middle-left", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "middle-center", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "middle-right", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "bottom-left", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "bottom-center", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) }), _jsx(Indicator, { position: "bottom-right", children: _jsx("div", { className: "w-12 h-12 bg-gray-200" }) })] })),
|
|
66
|
+
};
|
|
67
|
+
export const Inline = {
|
|
68
|
+
args: {
|
|
69
|
+
inline: true,
|
|
70
|
+
label: "New",
|
|
71
|
+
size: 16,
|
|
72
|
+
children: _jsx("span", { children: "Label with indicator" }),
|
|
73
|
+
position: "middle-right",
|
|
74
|
+
},
|
|
75
|
+
};
|
|
@@ -14,7 +14,7 @@ import { Eye, EyeOff } from "lucide-react";
|
|
|
14
14
|
import * as React from "react";
|
|
15
15
|
import { inputStyles } from "../../config/input";
|
|
16
16
|
import { cn } from "../../lib/utils";
|
|
17
|
-
import { Skeleton } from "../skeleton
|
|
17
|
+
import { Skeleton } from "../skeleton";
|
|
18
18
|
export const Input = React.forwardRef(({ className, type: typeProp = "text", showPasswordToggle = false, prefixIcon, suffixIcon, hasError = false, hasSuccess = false, unstyled = false, isLoading = false, ...props }, ref) => {
|
|
19
19
|
const [showPassword, setShowPassword] = React.useState(false);
|
|
20
20
|
const [internalType, setInternalType] = React.useState(typeProp);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { fn } from "@storybook/test";
|
|
3
3
|
import { Mail, Search, User } from "lucide-react";
|
|
4
|
-
import { Skeleton } from "../skeleton
|
|
4
|
+
import { Skeleton } from "../skeleton";
|
|
5
5
|
import { Input } from "./input";
|
|
6
6
|
const meta = {
|
|
7
7
|
title: "Forms/Input",
|
|
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { ChevronDown, Copy, Search, User } from "lucide-react";
|
|
3
3
|
import { Button } from "../button";
|
|
4
4
|
import { Checkbox } from "../checkbox";
|
|
5
|
-
import { Skeleton } from "../skeleton/skeleton";
|
|
6
5
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "../dropdown-menu";
|
|
7
6
|
import { Input } from "../input";
|
|
8
7
|
import { RadioGroup, RadioGroupItem } from "../radio-group";
|
|
9
8
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../select";
|
|
9
|
+
import { Skeleton } from "../skeleton";
|
|
10
10
|
import { Textarea } from "../textarea";
|
|
11
11
|
import { InputGroup, InputGroupText } from "./input-group";
|
|
12
12
|
const meta = {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./kbd";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./kbd";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface KbdProps extends React.HTMLAttributes<HTMLElement> {
|
|
3
|
+
/** Size of the keyboard key */
|
|
4
|
+
size?: "xs" | "sm" | "md" | "lg";
|
|
5
|
+
}
|
|
6
|
+
export declare const Kbd: React.ForwardRefExoticComponent<KbdProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
export const Kbd = React.forwardRef(({ className, size = "sm", ...props }, ref) => {
|
|
5
|
+
const sizeClasses = {
|
|
6
|
+
xs: "px-1 text-[10px] h-4 min-w-[16px]",
|
|
7
|
+
sm: "px-1.5 text-xs h-5 min-w-[20px]",
|
|
8
|
+
md: "px-2 text-sm h-6 min-w-[24px]",
|
|
9
|
+
lg: "px-2.5 text-base h-7 min-w-[28px]",
|
|
10
|
+
};
|
|
11
|
+
return (_jsx("kbd", { ref: ref, className: cn("inline-flex items-center justify-center rounded border border-b-2 bg-muted font-mono font-medium text-muted-foreground", sizeClasses[size], className), ...props }));
|
|
12
|
+
});
|
|
13
|
+
Kbd.displayName = "Kbd";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Kbd } from "./kbd";
|
|
3
|
+
declare const meta: Meta<typeof Kbd>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Kbd>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Combination: Story;
|
|
8
|
+
export declare const Sizes: Story;
|
|
9
|
+
export declare const InContext: Story;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Kbd } from "./kbd";
|
|
3
|
+
const meta = {
|
|
4
|
+
title: "Components/Kbd",
|
|
5
|
+
component: Kbd,
|
|
6
|
+
tags: ["autodocs"],
|
|
7
|
+
argTypes: {
|
|
8
|
+
size: {
|
|
9
|
+
control: { type: "select" },
|
|
10
|
+
options: ["xs", "sm", "md", "lg"],
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
export const Default = {
|
|
16
|
+
args: {
|
|
17
|
+
children: "Ctrl",
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export const Combination = {
|
|
21
|
+
render: () => (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Kbd, { children: "\u2318" }), _jsx("span", { children: "+" }), _jsx(Kbd, { children: "Shift" }), _jsx("span", { children: "+" }), _jsx(Kbd, { children: "M" })] })),
|
|
22
|
+
};
|
|
23
|
+
export const Sizes = {
|
|
24
|
+
render: () => (_jsxs("div", { className: "flex items-end gap-2", children: [_jsx(Kbd, { size: "xs", children: "xs" }), _jsx(Kbd, { size: "sm", children: "sm" }), _jsx(Kbd, { size: "md", children: "md" }), _jsx(Kbd, { size: "lg", children: "lg" })] })),
|
|
25
|
+
};
|
|
26
|
+
export const InContext = {
|
|
27
|
+
render: () => (_jsxs("div", { className: "text-sm", children: ["Press ", _jsx(Kbd, { children: "Ctrl" }), " + ", _jsx(Kbd, { children: "C" }), " to copy"] })),
|
|
28
|
+
};
|
|
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
6
6
|
* Provides zero-CLS skeleton states that match actual list layouts.
|
|
7
7
|
*/
|
|
8
8
|
import { cn } from "../../lib/utils";
|
|
9
|
-
import { Skeleton } from "../skeleton
|
|
9
|
+
import { Skeleton } from "../skeleton";
|
|
10
10
|
import { SkeletonAvatar, SkeletonCircle } from "../skeleton/skeleton-patterns";
|
|
11
11
|
/**
|
|
12
12
|
* List skeleton component with multiple variants
|
|
@@ -19,7 +19,7 @@ import { SkeletonAvatar, SkeletonCircle } from "../skeleton/skeleton-patterns";
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
export function ListSkeleton({ variant = "simple", itemCount = 3, showDividers = true, dense = false, className, "data-testid": dataTestId, }) {
|
|
22
|
-
return (_jsx("ul", { "data-testid": dataTestId || "list-skeleton", className: cn("flex flex-col bg-card rounded-lg border overflow-hidden", showDividers && "[&>li:not(:last-child)]:border-b", className), children: Array.from({ length: itemCount }).map((_, index) => (_jsxs("li", { className: cn("flex items-center gap-3 w-full", dense ? "px-3 py-2" : "px-4 py-3"), children: [variant === "simple" && _jsx(SimpleListItemSkeleton, { dense: dense }), variant === "withAvatar" && _jsx(AvatarListItemSkeleton, { dense: dense }), variant === "withIcon" && _jsx(IconListItemSkeleton, { dense: dense }), variant === "withBadge" && _jsx(BadgeListItemSkeleton, { dense: dense }), variant === "multiLine" && _jsx(MultiLineListItemSkeleton, { dense: dense })] }, index))) }));
|
|
22
|
+
return (_jsx("ul", { "data-testid": dataTestId || "list-skeleton", className: cn("flex flex-col bg-card rounded-lg border overflow-hidden", showDividers && "[&>li:not(:last-child)]:border-b", className), children: Array.from({ length: itemCount }).map((_, index) => (_jsxs("li", { className: cn("flex items-center gap-3 w-full", dense ? "px-3 py-2" : "px-4 py-3"), children: [variant === "simple" && _jsx(SimpleListItemSkeleton, { dense: dense }), variant === "withAvatar" && _jsx(AvatarListItemSkeleton, { dense: dense }), variant === "withIcon" && _jsx(IconListItemSkeleton, { dense: dense }), variant === "withBadge" && _jsx(BadgeListItemSkeleton, { dense: dense }), variant === "multiLine" && (_jsx(MultiLineListItemSkeleton, { dense: dense }))] }, index))) }));
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Simple variant: text only items
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cn } from "../../lib/utils";
|
|
4
|
-
import { Badge } from "../badge
|
|
4
|
+
import { Badge } from "../badge";
|
|
5
5
|
import { ListSkeleton } from "./list-skeleton";
|
|
6
6
|
function List({ className, divided = true, dense = false, isLoading = false, skeletonConfig, skeleton, children, ...props }) {
|
|
7
7
|
if (isLoading) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CheckCircle, ChevronRight, Home, Info, Mail, MessageCircle, Settings, Trash2, User, UserPlus, } from "lucide-react";
|
|
3
|
-
import { Skeleton } from "../skeleton/skeleton";
|
|
4
3
|
import { Button } from "../button";
|
|
4
|
+
import { Skeleton } from "../skeleton";
|
|
5
5
|
import { List, ListItem, ListItemAction, ListItemAvatar, ListItemBadge, ListItemContent, ListItemIcon, ListItemText, ListItemTitle, } from "./list";
|
|
6
6
|
const meta = {
|
|
7
7
|
title: "Data Display/List",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type * as React from "react";
|
|
2
|
-
import type { badgeVariants } from "../badge/badge";
|
|
3
1
|
import type { VariantProps } from "class-variance-authority";
|
|
2
|
+
import type * as React from "react";
|
|
3
|
+
import type { badgeVariants } from "../badge";
|
|
4
4
|
import type { ListSkeletonConfig } from "../skeleton/skeleton.types";
|
|
5
5
|
export interface ListProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
6
6
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./loading-overlay";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./loading-overlay";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type OverlayProps } from "../overlay";
|
|
3
|
+
import { Spinner } from "../spinner";
|
|
4
|
+
export interface LoadingOverlayProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
/** If set loading overlay will be visible */
|
|
6
|
+
visible?: boolean;
|
|
7
|
+
/** Overlay z-index */
|
|
8
|
+
zIndex?: number;
|
|
9
|
+
/** Props passed to Overlay component */
|
|
10
|
+
overlayProps?: OverlayProps;
|
|
11
|
+
/** Props passed to Loader component */
|
|
12
|
+
loaderProps?: React.ComponentProps<typeof Spinner> & {
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
};
|
|
15
|
+
/** Transition duration in ms */
|
|
16
|
+
transitionDuration?: number;
|
|
17
|
+
}
|
|
18
|
+
declare const LoadingOverlay: React.ForwardRefExoticComponent<LoadingOverlayProps & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
export { LoadingOverlay };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
import { Box } from "../box";
|
|
5
|
+
import { Overlay } from "../overlay";
|
|
6
|
+
import { Spinner } from "../spinner";
|
|
7
|
+
const LoadingOverlay = React.forwardRef(({ className, visible = false, zIndex = 400, overlayProps, loaderProps, transitionDuration = 0, style, ...props }, ref) => {
|
|
8
|
+
const { children: loaderChildren, ...otherLoaderProps } = loaderProps || {};
|
|
9
|
+
if (!visible && transitionDuration === 0) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return (_jsxs(Box, { ref: ref, className: cn("absolute inset-0 flex items-center justify-center pointer-events-none transition-opacity", visible ? "opacity-100 pointer-events-auto" : "opacity-0", className), style: {
|
|
13
|
+
zIndex,
|
|
14
|
+
transitionDuration: `${transitionDuration}ms`,
|
|
15
|
+
...style,
|
|
16
|
+
}, ...props, children: [_jsx(Overlay, { zIndex: zIndex, ...overlayProps, fixed: false, className: cn(overlayProps?.className) }), _jsx(Box, { className: "relative z-10", children: loaderChildren ? (loaderChildren) : (_jsx(Spinner, { size: "lg", ...otherLoaderProps })) })] }));
|
|
17
|
+
});
|
|
18
|
+
LoadingOverlay.displayName = "LoadingOverlay";
|
|
19
|
+
export { LoadingOverlay };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { LoadingOverlay } from "./loading-overlay";
|
|
3
|
+
declare const meta: Meta<typeof LoadingOverlay>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof LoadingOverlay>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const CustomLoader: Story;
|
|
8
|
+
export declare const WithTransition: Story;
|