@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.
Files changed (291) hide show
  1. package/dist/components/accordion/accordion-skeleton.js +1 -1
  2. package/dist/components/accordion/accordion.js +2 -1
  3. package/dist/components/action-icon/action-icon.d.ts +12 -0
  4. package/dist/components/action-icon/action-icon.js +35 -0
  5. package/dist/components/action-icon/action-icon.stories.d.ts +9 -0
  6. package/dist/components/action-icon/action-icon.stories.js +42 -0
  7. package/dist/components/action-icon/index.d.ts +1 -0
  8. package/dist/components/action-icon/index.js +1 -0
  9. package/dist/components/alert/alert-skeleton.js +4 -3
  10. package/dist/components/alert/alert.d.ts +2 -2
  11. package/dist/components/alert/alert.js +8 -6
  12. package/dist/components/alert/alert.stories.js +13 -9
  13. package/dist/components/alert/index.d.ts +1 -1
  14. package/dist/components/alert-dialog/alert-dialog.js +8 -5
  15. package/dist/components/app-shell/app-shell.d.ts +58 -0
  16. package/dist/components/app-shell/app-shell.js +111 -0
  17. package/dist/components/app-shell/app-shell.stories.d.ts +8 -0
  18. package/dist/components/app-shell/app-shell.stories.js +35 -0
  19. package/dist/components/app-shell/index.d.ts +1 -0
  20. package/dist/components/app-shell/index.js +1 -0
  21. package/dist/components/avatar/avatar.d.ts +2 -2
  22. package/dist/components/avatar/avatar.stories.js +1 -1
  23. package/dist/components/badge/badge.d.ts +1 -1
  24. package/dist/components/badge/badge.js +1 -1
  25. package/dist/components/badge/badge.stories.js +1 -1
  26. package/dist/components/banner/banner-skeleton.js +1 -1
  27. package/dist/components/banner/banner.d.ts +1 -1
  28. package/dist/components/banner/banner.stories.js +1 -1
  29. package/dist/components/box/box.d.ts +8 -0
  30. package/dist/components/box/box.js +10 -0
  31. package/dist/components/box/box.stories.d.ts +8 -0
  32. package/dist/components/box/box.stories.js +32 -0
  33. package/dist/components/box/index.d.ts +1 -0
  34. package/dist/components/box/index.js +1 -0
  35. package/dist/components/breadcrumbs/breadcrumbs-skeleton.js +1 -1
  36. package/dist/components/breadcrumbs/breadcrumbs.stories.js +1 -1
  37. package/dist/components/burger/burger.d.ts +8 -0
  38. package/dist/components/burger/burger.js +21 -0
  39. package/dist/components/burger/burger.stories.d.ts +8 -0
  40. package/dist/components/burger/burger.stories.js +31 -0
  41. package/dist/components/burger/index.d.ts +1 -0
  42. package/dist/components/burger/index.js +1 -0
  43. package/dist/components/button/button.d.ts +2 -2
  44. package/dist/components/button/button.stories.js +10 -7
  45. package/dist/components/button-group/button-group.stories.js +1 -1
  46. package/dist/components/calendar/calendar-skeleton.js +1 -1
  47. package/dist/components/calendar/calendar.d.ts +1 -1
  48. package/dist/components/calendar/calendar.js +1 -1
  49. package/dist/components/calendar/calendar.types.d.ts +3 -3
  50. package/dist/components/card/card-skeleton.js +2 -2
  51. package/dist/components/card/card.js +17 -14
  52. package/dist/components/card/index.d.ts +1 -1
  53. package/dist/components/center/center.d.ts +7 -0
  54. package/dist/components/center/center.js +10 -0
  55. package/dist/components/center/center.stories.d.ts +7 -0
  56. package/dist/components/center/center.stories.js +25 -0
  57. package/dist/components/center/index.d.ts +1 -0
  58. package/dist/components/center/index.js +1 -0
  59. package/dist/components/charts/area-chart.js +1 -1
  60. package/dist/components/charts/bar-chart.js +1 -1
  61. package/dist/components/charts/donut-chart.js +1 -1
  62. package/dist/components/charts/index.d.ts +2 -2
  63. package/dist/components/charts/index.js +2 -2
  64. package/dist/components/charts/line-chart.js +1 -1
  65. package/dist/components/charts/radial-bar-chart.js +1 -1
  66. package/dist/components/charts/theme-utils.d.ts +1 -1
  67. package/dist/components/charts/use-theme-aware-chart.d.ts +1 -1
  68. package/dist/components/charts/use-theme-aware-chart.js +2 -1
  69. package/dist/components/checkbox/checkbox.js +1 -1
  70. package/dist/components/checkbox/checkbox.stories.js +12 -8
  71. package/dist/components/close-button/close-button.d.ts +7 -0
  72. package/dist/components/close-button/close-button.js +9 -0
  73. package/dist/components/close-button/close-button.stories.d.ts +7 -0
  74. package/dist/components/close-button/close-button.stories.js +18 -0
  75. package/dist/components/close-button/index.d.ts +1 -0
  76. package/dist/components/close-button/index.js +1 -0
  77. package/dist/components/code/code.d.ts +8 -0
  78. package/dist/components/code/code.js +14 -0
  79. package/dist/components/code/code.stories.d.ts +8 -0
  80. package/dist/components/code/code.stories.js +31 -0
  81. package/dist/components/code/index.d.ts +1 -0
  82. package/dist/components/code/index.js +1 -0
  83. package/dist/components/collapse/collapse.d.ts +17 -0
  84. package/dist/components/collapse/collapse.js +34 -0
  85. package/dist/components/collapse/index.d.ts +1 -0
  86. package/dist/components/collapse/index.js +1 -0
  87. package/dist/components/color-input/color-input.d.ts +28 -0
  88. package/dist/components/color-input/color-input.js +35 -0
  89. package/dist/components/color-input/color-input.stories.d.ts +10 -0
  90. package/dist/components/color-input/color-input.stories.js +41 -0
  91. package/dist/components/color-input/index.d.ts +1 -0
  92. package/dist/components/color-input/index.js +1 -0
  93. package/dist/components/combobox/combobox-skeleton.js +1 -1
  94. package/dist/components/combobox/combobox.d.ts +1 -1
  95. package/dist/components/combobox/combobox.js +17 -8
  96. package/dist/components/combobox/combobox.stories.js +1 -1
  97. package/dist/components/command/command.d.ts +2 -2
  98. package/dist/components/command/command.stories.js +14 -19
  99. package/dist/components/container/container.d.ts +1 -1
  100. package/dist/components/container/index.d.ts +1 -1
  101. package/dist/components/container/index.js +1 -1
  102. package/dist/components/data-table/column-header-filter.js +11 -6
  103. package/dist/components/data-table/data-table-skeleton.js +5 -15
  104. package/dist/components/data-table/data-table.js +18 -15
  105. package/dist/components/data-table/data-table.stories.js +3 -5
  106. package/dist/components/date-picker/date-picker.d.ts +1 -1
  107. package/dist/components/date-picker/date-picker.js +3 -3
  108. package/dist/components/date-picker/date-picker.types.d.ts +1 -1
  109. package/dist/components/dialog/dialog-skeleton.js +1 -1
  110. package/dist/components/dialog/dialog.js +6 -4
  111. package/dist/components/dialog/dialog.stories.js +2 -2
  112. package/dist/components/dnd/dnd.d.ts +4 -5
  113. package/dist/components/dnd/dnd.js +5 -5
  114. package/dist/components/dnd/dnd.stories.js +48 -40
  115. package/dist/components/drawer/drawer.stories.js +2 -2
  116. package/dist/components/empty-state/empty-state-skeleton.js +2 -3
  117. package/dist/components/empty-state/empty-state.d.ts +1 -1
  118. package/dist/components/field/field-skeleton.js +1 -1
  119. package/dist/components/field/field.stories.js +1 -1
  120. package/dist/components/file-upload/file-upload-skeleton.js +1 -1
  121. package/dist/components/flex/flex.d.ts +7 -5
  122. package/dist/components/flex/flex.js +2 -2
  123. package/dist/components/flex/index.d.ts +1 -1
  124. package/dist/components/flex/index.js +1 -1
  125. package/dist/components/grid/grid.d.ts +24 -0
  126. package/dist/components/grid/grid.js +136 -0
  127. package/dist/components/grid/grid.stories.d.ts +8 -0
  128. package/dist/components/grid/grid.stories.js +31 -0
  129. package/dist/components/grid/index.d.ts +1 -0
  130. package/dist/components/grid/index.js +1 -0
  131. package/dist/components/group/group.d.ts +2 -2
  132. package/dist/components/group/group.js +1 -1
  133. package/dist/components/group/index.d.ts +1 -1
  134. package/dist/components/group/index.js +1 -1
  135. package/dist/components/header/header-skeleton.js +1 -1
  136. package/dist/components/header/header.d.ts +3 -3
  137. package/dist/components/header/header.js +17 -31
  138. package/dist/components/header/index.d.ts +1 -1
  139. package/dist/components/heading/heading.d.ts +4 -2
  140. package/dist/components/heading/heading.js +3 -7
  141. package/dist/components/heading/index.d.ts +1 -1
  142. package/dist/components/heading/index.js +1 -1
  143. package/dist/components/indicator/index.d.ts +1 -0
  144. package/dist/components/indicator/index.js +1 -0
  145. package/dist/components/indicator/indicator.d.ts +30 -0
  146. package/dist/components/indicator/indicator.js +89 -0
  147. package/dist/components/indicator/indicator.stories.d.ts +10 -0
  148. package/dist/components/indicator/indicator.stories.js +75 -0
  149. package/dist/components/input/input.js +1 -1
  150. package/dist/components/input/input.stories.js +1 -1
  151. package/dist/components/input-group/input-group.stories.js +1 -1
  152. package/dist/components/kbd/index.d.ts +1 -0
  153. package/dist/components/kbd/index.js +1 -0
  154. package/dist/components/kbd/kbd.d.ts +6 -0
  155. package/dist/components/kbd/kbd.js +13 -0
  156. package/dist/components/kbd/kbd.stories.d.ts +9 -0
  157. package/dist/components/kbd/kbd.stories.js +28 -0
  158. package/dist/components/label/label.stories.js +1 -1
  159. package/dist/components/list/list-skeleton.js +2 -2
  160. package/dist/components/list/list.js +1 -1
  161. package/dist/components/list/list.stories.js +1 -1
  162. package/dist/components/list/list.types.d.ts +2 -2
  163. package/dist/components/loading-overlay/index.d.ts +1 -0
  164. package/dist/components/loading-overlay/index.js +1 -0
  165. package/dist/components/loading-overlay/loading-overlay.d.ts +19 -0
  166. package/dist/components/loading-overlay/loading-overlay.js +19 -0
  167. package/dist/components/loading-overlay/loading-overlay.stories.d.ts +8 -0
  168. package/dist/components/loading-overlay/loading-overlay.stories.js +46 -0
  169. package/dist/components/metric-card/metric-card-skeleton.js +2 -2
  170. package/dist/components/metric-card/metric-card.js +1 -1
  171. package/dist/components/multi-select/multi-select-skeleton.js +1 -1
  172. package/dist/components/multi-select/multi-select.stories.js +1 -1
  173. package/dist/components/nav-link/index.d.ts +1 -0
  174. package/dist/components/nav-link/index.js +1 -0
  175. package/dist/components/nav-link/nav-link.d.ts +26 -0
  176. package/dist/components/nav-link/nav-link.js +26 -0
  177. package/dist/components/nav-link/nav-link.stories.d.ts +9 -0
  178. package/dist/components/nav-link/nav-link.stories.js +37 -0
  179. package/dist/components/navigation/navigation-skeleton.js +1 -1
  180. package/dist/components/number-input/index.d.ts +1 -0
  181. package/dist/components/number-input/index.js +1 -0
  182. package/dist/components/number-input/number-input.d.ts +40 -0
  183. package/dist/components/number-input/number-input.js +69 -0
  184. package/dist/components/number-input/number-input.stories.d.ts +11 -0
  185. package/dist/components/number-input/number-input.stories.js +54 -0
  186. package/dist/components/overlay/index.d.ts +1 -0
  187. package/dist/components/overlay/index.js +1 -0
  188. package/dist/components/overlay/overlay.d.ts +22 -0
  189. package/dist/components/overlay/overlay.js +45 -0
  190. package/dist/components/overlay/overlay.stories.d.ts +9 -0
  191. package/dist/components/overlay/overlay.stories.js +47 -0
  192. package/dist/components/page-transition/page-transition.stories.js +1 -1
  193. package/dist/components/pagination/index.d.ts +1 -1
  194. package/dist/components/pagination/index.js +1 -1
  195. package/dist/components/pagination/pagination-skeleton.js +1 -1
  196. package/dist/components/pagination/pagination.d.ts +44 -28
  197. package/dist/components/pagination/pagination.js +53 -79
  198. package/dist/components/pagination/pagination.stories.d.ts +1 -0
  199. package/dist/components/pagination/pagination.stories.js +31 -5
  200. package/dist/components/paper/index.d.ts +1 -0
  201. package/dist/components/paper/index.js +1 -0
  202. package/dist/components/paper/paper.d.ts +12 -0
  203. package/dist/components/paper/paper.js +39 -0
  204. package/dist/components/paper/paper.stories.d.ts +7 -0
  205. package/dist/components/paper/paper.stories.js +30 -0
  206. package/dist/components/password-strength-indicator/password-strength-indicator.stories.js +1 -1
  207. package/dist/components/popover/popover-skeleton.js +1 -1
  208. package/dist/components/popover/popover.stories.js +2 -2
  209. package/dist/components/progress/index.d.ts +1 -1
  210. package/dist/components/progress/progress.d.ts +1 -1
  211. package/dist/components/progress/progress.stories.js +1 -1
  212. package/dist/components/radio-group/radio-group-skeleton.js +1 -1
  213. package/dist/components/radio-group/radio-group.stories.js +1 -1
  214. package/dist/components/resizable/resizable.stories.js +8 -8
  215. package/dist/components/ring-progress/index.d.ts +1 -0
  216. package/dist/components/ring-progress/index.js +1 -0
  217. package/dist/components/ring-progress/ring-progress.d.ts +24 -0
  218. package/dist/components/ring-progress/ring-progress.js +20 -0
  219. package/dist/components/ring-progress/ring-progress.stories.d.ts +9 -0
  220. package/dist/components/ring-progress/ring-progress.stories.js +46 -0
  221. package/dist/components/scroll-area/scroll-area.stories.js +26 -26
  222. package/dist/components/segmented-control/index.d.ts +1 -0
  223. package/dist/components/segmented-control/index.js +1 -0
  224. package/dist/components/segmented-control/segmented-control.d.ts +19 -0
  225. package/dist/components/segmented-control/segmented-control.js +46 -0
  226. package/dist/components/segmented-control/segmented-control.stories.d.ts +10 -0
  227. package/dist/components/segmented-control/segmented-control.stories.js +53 -0
  228. package/dist/components/select/select.js +1 -1
  229. package/dist/components/select/select.stories.js +1 -1
  230. package/dist/components/separator/separator.stories.js +1 -1
  231. package/dist/components/session-card/session-card-skeleton.js +2 -2
  232. package/dist/components/session-card/session-card.js +1 -1
  233. package/dist/components/sidebar/sidebar-skeleton.js +2 -2
  234. package/dist/components/skeleton/index.d.ts +3 -3
  235. package/dist/components/skeleton/index.js +1 -1
  236. package/dist/components/skeleton/skeleton.types.d.ts +0 -249
  237. package/dist/components/slider/index.d.ts +1 -1
  238. package/dist/components/slider/slider.js +1 -1
  239. package/dist/components/slider/slider.stories.js +1 -1
  240. package/dist/components/social-login-button/social-login-button.js +6 -6
  241. package/dist/components/sparkline-chart/sparkline-chart.js +6 -3
  242. package/dist/components/sparkline-chart/sparkline-chart.stories.js +1 -1
  243. package/dist/components/spinner/spinner.d.ts +1 -1
  244. package/dist/components/spoiler/index.d.ts +1 -0
  245. package/dist/components/spoiler/index.js +1 -0
  246. package/dist/components/spoiler/spoiler.d.ts +14 -0
  247. package/dist/components/spoiler/spoiler.js +20 -0
  248. package/dist/components/spoiler/spoiler.stories.d.ts +8 -0
  249. package/dist/components/spoiler/spoiler.stories.js +35 -0
  250. package/dist/components/stack/index.d.ts +1 -1
  251. package/dist/components/stack/index.js +1 -1
  252. package/dist/components/stack/stack.d.ts +2 -2
  253. package/dist/components/stack/stack.js +1 -1
  254. package/dist/components/steps/steps-skeleton.js +1 -1
  255. package/dist/components/steps/steps.js +7 -5
  256. package/dist/components/steps/steps.stories.js +6 -2
  257. package/dist/components/switch/index.d.ts +1 -1
  258. package/dist/components/switch/switch.js +1 -1
  259. package/dist/components/switch/switch.stories.js +1 -1
  260. package/dist/components/table/table-skeleton.js +2 -2
  261. package/dist/components/table/table.js +4 -3
  262. package/dist/components/table/table.stories.js +10 -7
  263. package/dist/components/tabs/tabs-skeleton.js +1 -1
  264. package/dist/components/tabs/tabs.d.ts +3 -3
  265. package/dist/components/tabs/tabs.js +1 -1
  266. package/dist/components/tabs/tabs.stories.js +5 -5
  267. package/dist/components/text/index.d.ts +1 -1
  268. package/dist/components/text/index.js +1 -1
  269. package/dist/components/text/text.d.ts +7 -5
  270. package/dist/components/text/text.js +2 -2
  271. package/dist/components/text/text.stories.js +34 -3
  272. package/dist/components/textarea/textarea.js +1 -1
  273. package/dist/components/textarea/textarea.stories.js +1 -1
  274. package/dist/components/timeline/index.d.ts +1 -0
  275. package/dist/components/timeline/index.js +1 -0
  276. package/dist/components/timeline/timeline.d.ts +35 -0
  277. package/dist/components/timeline/timeline.js +36 -0
  278. package/dist/components/timeline/timeline.stories.d.ts +7 -0
  279. package/dist/components/timeline/timeline.stories.js +21 -0
  280. package/dist/components/toast/toast.js +6 -6
  281. package/dist/components/toggle/toggle.stories.js +1 -1
  282. package/dist/components/tooltip/tooltip.stories.js +1 -1
  283. package/dist/components/user-menu-dropdown/user-menu-dropdown.js +1 -1
  284. package/dist/config/tailwind-base.d.ts +10 -0
  285. package/dist/config/tailwind-base.js +1 -0
  286. package/dist/index.d.ts +25 -0
  287. package/dist/index.js +25 -10
  288. package/dist/lib/animations.js +94 -94
  289. package/dist/primitives/command/Command.js +2 -1
  290. package/dist/styles/globals.css +415 -82
  291. 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
- // Lock body scroll when mobile menu is open
12
- React.useEffect(() => {
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", { ref: ref, "data-comp": "header", className: cn("w-full bg-popover border-b sticky top-0 z-20 theme-popover", className), ...props, children: [_jsx("div", { className: "container mx-auto px-3 sm:px-4 lg:px-6 xl:px-8", children: _jsxs("div", { className: "flex items-center justify-between h-14 sm:h-16 gap-2 sm:gap-4", children: [_jsx("div", { className: "shrink-0 min-w-0 max-w-[120px] sm:max-w-none", children: logo }), _jsx("div", { className: cn("hidden lg:flex items-center gap-3 lg:gap-6", variant === "default" ? "flex-1" : ""), children: _jsx("div", { 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("ul", { className: cn("py-2", link.children.length <= 3
48
- ? "w-[220px]"
49
- : "w-[440px] grid grid-cols-2"), children: link.children.map((child) => (_jsx("li", { children: _jsx(NavigationMenuLink, { asChild: true, children: _jsx("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 &&
50
- "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("div", { className: "flex items-center gap-1.5 sm:gap-2 lg:gap-3 shrink-0", children: [searchBar && (_jsx("div", { className: "hidden lg:block w-48 xl:w-64", children: searchBar })), languageSwitcher && (_jsx("div", { className: "hidden lg:block", children: languageSwitcher })), themeSwitcher && (_jsx("div", { className: "hidden lg:block", children: themeSwitcher })), notifications && (_jsx("div", { className: "hidden lg:block", children: notifications })), userMenu && _jsx("div", { 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 &&
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("div", { className: "fixed inset-0 bg-black/20 backdrop-blur-sm z-40 lg:hidden", onClick: onMobileMenuToggle, "aria-hidden": "true" }), _jsxs("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("div", { className: "flex items-center justify-between px-4 h-14 sm:h-16 border-b shrink-0", children: [_jsx("div", { 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("div", { 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("span", { className: "flex items-center gap-2", children: [_jsx(Menu, { className: "w-4 h-4" }), _jsx("span", { children: "Menu" })] }) }), _jsx(TabsTrigger, { value: "notifications", children: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(Bell, { className: "w-4 h-4" }), _jsx("span", { children: "Alerts" })] }) }), _jsx(TabsTrigger, { value: "preferences", children: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(Settings, { className: "w-4 h-4" }), _jsx("span", { children: "Preferences" })] }) })] }) }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [_jsxs(TabsContent, { value: "menu", className: "mt-0 h-full", children: [searchBar && (_jsx("div", { className: "px-4 py-3 border-b", children: searchBar })), userProfile ? (_jsxs("div", { className: "border-b", children: [_jsxs("div", { className: "px-4 py-4 flex items-center gap-3 bg-muted", children: [userProfile.avatar ? (_jsx("img", { src: userProfile.avatar, alt: userProfile.name, className: "w-10 h-10 rounded-full object-cover" })) : (_jsx("div", { className: "w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary font-semibold", children: userProfile.name.charAt(0).toUpperCase() })), _jsxs("div", { className: "flex flex-col min-w-0", children: [_jsx("span", { className: "text-sm font-medium text-foreground truncate", children: userProfile.name }), _jsx("span", { className: "text-xs text-muted-foreground truncate", children: userProfile.email })] })] }), _jsx("div", { className: "py-2", children: userProfile.links.map((link, index) => (_jsxs(React.Fragment, { children: [link.divider && index > 0 && (_jsx("div", { className: "my-2 border-t" })), link.href ? (_jsxs("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"
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", { className: "w-4 h-4", children: link.icon })), link.label] })) : (_jsxs("button", { type: "button", className: cn("w-full flex items-center gap-3 px-4 py-2.5 text-sm transition-colors hover:bg-accent text-left", link.variant === "danger"
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", { className: "w-4 h-4", children: link.icon })), link.label] }))] }, link.label))) })] })) : userMenu ? (_jsxs("div", { className: "px-4 py-3 border-b", children: [_jsx("div", { className: "text-xs font-semibold text-muted-foreground uppercase mb-2", children: "Account" }), userMenu] })) : null, _jsx("div", { className: "py-2", children: navLinks.map((link) => (_jsx(React.Fragment, { children: _jsxs("div", { className: "flex flex-col", children: [_jsxs("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
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("div", { className: "bg-muted animate-in slide-in-from-top-2 duration-200", children: link.children.map((child) => (_jsx("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
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("div", { className: "p-0", children: mobileNotifications || notifications })) : (_jsxs("div", { className: "flex flex-col items-center justify-center h-64 text-muted-foreground", children: [_jsx(Bell, { className: "w-12 h-12 mb-4 opacity-20" }), _jsx("p", { children: "No notifications" })] })) }), _jsx(TabsContent, { value: "preferences", className: "mt-0 h-full", children: _jsx("div", { className: "flex flex-col", children: (themeSwitcherMobile || languageSwitcherMobile) && (_jsxs("div", { className: "p-4 space-y-6", children: [_jsx("div", { className: "text-xs font-semibold text-muted-foreground uppercase", children: "Preferences" }), _jsxs("div", { className: "flex flex-col gap-6", children: [themeSwitcherMobile && (_jsx("div", { className: "w-full", children: themeSwitcherMobile })), languageSwitcherMobile && (_jsx("div", { className: "w-full", children: languageSwitcherMobile }))] })] })) }) })] })] })] })] }), document.body)] }));
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 { HeaderProps, NavLink } from "./header";
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<HTMLHeadingElement>, VariantProps<typeof headingVariants> {
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<HTMLHeadingElement>>;
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 _Comp = asChild ? Slot : "h2";
36
- // If asChild is false, we try to use the appropriate heading tag based on size
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 './heading';
1
+ export * from "./heading";
@@ -1 +1 @@
1
- export * from './heading';
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/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/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
+ };
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Skeleton } from "../skeleton/skeleton";
2
+ import { Skeleton } from "../skeleton";
3
3
  import { Label } from "./label";
4
4
  const meta = {
5
5
  title: "Forms/Label",
@@ -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/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/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;