@wheelhouse/ui 0.2.0 → 0.2.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 (108) hide show
  1. package/dist/components/accordion/accordion.js +2 -2
  2. package/dist/components/alert/alert.stories.js +4 -4
  3. package/dist/components/alert-dialog/alert-dialog.stories.js +2 -2
  4. package/dist/components/breadcrumb/breadcrumb.d.ts.map +1 -1
  5. package/dist/components/breadcrumb/breadcrumb.js +3 -4
  6. package/dist/components/calendar/calendar.d.ts +34 -0
  7. package/dist/components/calendar/calendar.d.ts.map +1 -0
  8. package/dist/components/calendar/calendar.js +82 -0
  9. package/dist/components/calendar/calendar.stories.d.ts +16 -0
  10. package/dist/components/calendar/calendar.stories.d.ts.map +1 -0
  11. package/dist/components/calendar/calendar.stories.js +33 -0
  12. package/dist/components/calendar/index.d.ts +3 -0
  13. package/dist/components/calendar/index.d.ts.map +1 -0
  14. package/dist/components/calendar/index.js +1 -0
  15. package/dist/components/checkbox/checkbox.js +2 -2
  16. package/dist/components/collapsible/collapsible.stories.js +4 -4
  17. package/dist/components/combobox/combobox.d.ts.map +1 -1
  18. package/dist/components/combobox/combobox.js +5 -7
  19. package/dist/components/command/command.d.ts.map +1 -1
  20. package/dist/components/command/command.js +3 -4
  21. package/dist/components/context-menu/context-menu.d.ts.map +1 -1
  22. package/dist/components/context-menu/context-menu.js +4 -5
  23. package/dist/components/date-selector/date-selector-context.d.ts +6 -0
  24. package/dist/components/date-selector/date-selector-context.d.ts.map +1 -0
  25. package/dist/components/date-selector/date-selector-context.js +11 -0
  26. package/dist/components/date-selector/date-selector-parts.d.ts +68 -0
  27. package/dist/components/date-selector/date-selector-parts.d.ts.map +1 -0
  28. package/dist/components/date-selector/date-selector-parts.js +131 -0
  29. package/dist/components/date-selector/date-selector-types.d.ts +118 -0
  30. package/dist/components/date-selector/date-selector-types.d.ts.map +1 -0
  31. package/dist/components/date-selector/date-selector-types.js +32 -0
  32. package/dist/components/date-selector/date-selector-value.d.ts +47 -0
  33. package/dist/components/date-selector/date-selector-value.d.ts.map +1 -0
  34. package/dist/components/date-selector/date-selector-value.js +183 -0
  35. package/dist/components/date-selector/date-selector.d.ts +6 -0
  36. package/dist/components/date-selector/date-selector.d.ts.map +1 -0
  37. package/dist/components/date-selector/date-selector.js +144 -0
  38. package/dist/components/date-selector/date-selector.stories.d.ts +135 -0
  39. package/dist/components/date-selector/date-selector.stories.d.ts.map +1 -0
  40. package/dist/components/date-selector/date-selector.stories.js +144 -0
  41. package/dist/components/date-selector/index.d.ts +7 -0
  42. package/dist/components/date-selector/index.d.ts.map +1 -0
  43. package/dist/components/date-selector/index.js +5 -0
  44. package/dist/components/date-selector/use-date-selector.d.ts +50 -0
  45. package/dist/components/date-selector/use-date-selector.d.ts.map +1 -0
  46. package/dist/components/date-selector/use-date-selector.js +305 -0
  47. package/dist/components/dialog/dialog.js +2 -2
  48. package/dist/components/dropdown-menu/dropdown-menu.d.ts.map +1 -1
  49. package/dist/components/dropdown-menu/dropdown-menu.js +5 -6
  50. package/dist/components/empty/empty.stories.js +2 -2
  51. package/dist/components/filters/filters.js +4 -4
  52. package/dist/components/filters/filters.stories.js +3 -3
  53. package/dist/components/index.d.ts +5 -0
  54. package/dist/components/index.d.ts.map +1 -1
  55. package/dist/components/index.js +5 -0
  56. package/dist/components/input-group/input-group.stories.js +3 -3
  57. package/dist/components/item/item.stories.d.ts.map +1 -1
  58. package/dist/components/item/item.stories.js +5 -6
  59. package/dist/components/kbd/kbd.stories.js +2 -2
  60. package/dist/components/menubar/menubar.js +3 -3
  61. package/dist/components/native-select/native-select.js +2 -2
  62. package/dist/components/navigation-menu/navigation-menu.js +2 -2
  63. package/dist/components/navigation-pattern-1/index.d.ts +3 -0
  64. package/dist/components/navigation-pattern-1/index.d.ts.map +1 -0
  65. package/dist/components/navigation-pattern-1/index.js +1 -0
  66. package/dist/components/navigation-pattern-1/pattern-1.config.d.ts +47 -0
  67. package/dist/components/navigation-pattern-1/pattern-1.config.d.ts.map +1 -0
  68. package/dist/components/navigation-pattern-1/pattern-1.config.js +55 -0
  69. package/dist/components/navigation-pattern-1/pattern-1.d.ts +7 -0
  70. package/dist/components/navigation-pattern-1/pattern-1.d.ts.map +1 -0
  71. package/dist/components/navigation-pattern-1/pattern-1.js +83 -0
  72. package/dist/components/navigation-pattern-1/pattern-1.stories.d.ts +16 -0
  73. package/dist/components/navigation-pattern-1/pattern-1.stories.d.ts.map +1 -0
  74. package/dist/components/navigation-pattern-1/pattern-1.stories.js +20 -0
  75. package/dist/components/pagination/pagination.js +4 -4
  76. package/dist/components/select/select.js +5 -5
  77. package/dist/components/sheet/sheet.js +2 -2
  78. package/dist/components/sonner/sonner.d.ts +1 -1
  79. package/dist/components/sonner/sonner.js +7 -7
  80. package/dist/components/sortable/index.d.ts +3 -0
  81. package/dist/components/sortable/index.d.ts.map +1 -0
  82. package/dist/components/sortable/index.js +1 -0
  83. package/dist/components/sortable/sortable.d.ts +94 -0
  84. package/dist/components/sortable/sortable.d.ts.map +1 -0
  85. package/dist/components/sortable/sortable.js +210 -0
  86. package/dist/components/sortable/sortable.stories.d.ts +14 -0
  87. package/dist/components/sortable/sortable.stories.d.ts.map +1 -0
  88. package/dist/components/sortable/sortable.stories.js +38 -0
  89. package/dist/components/spinner/spinner.d.ts +3 -3
  90. package/dist/components/spinner/spinner.d.ts.map +1 -1
  91. package/dist/components/spinner/spinner.js +2 -2
  92. package/dist/components/status-indicator/index.d.ts +3 -0
  93. package/dist/components/status-indicator/index.d.ts.map +1 -0
  94. package/dist/components/status-indicator/index.js +1 -0
  95. package/dist/components/status-indicator/status-indicator.d.ts +51 -0
  96. package/dist/components/status-indicator/status-indicator.d.ts.map +1 -0
  97. package/dist/components/status-indicator/status-indicator.js +48 -0
  98. package/dist/components/status-indicator/status-indicator.stories.d.ts +20 -0
  99. package/dist/components/status-indicator/status-indicator.stories.d.ts.map +1 -0
  100. package/dist/components/status-indicator/status-indicator.stories.js +97 -0
  101. package/dist/components/text/text.js +1 -1
  102. package/dist/hooks/use-mobile.d.ts +2 -0
  103. package/dist/hooks/use-mobile.d.ts.map +1 -0
  104. package/dist/hooks/use-mobile.js +15 -0
  105. package/dist/tsconfig.tsbuildinfo +1 -1
  106. package/llms.txt +4 -4
  107. package/package.json +7 -4
  108. package/src/styles/globals.css +4 -12
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { BellIcon } from '@phosphor-icons/react/Bell';
3
- import { UserIcon } from '@phosphor-icons/react/User';
2
+ import { Bell, User } from 'lucide-react';
4
3
  import { Button } from '../button';
5
4
  import { Switch } from '../switch';
6
5
  import { Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, itemMediaVariantKeys, ItemSeparator, itemSizeKeys, ItemTitle, itemVariantKeys, } from '.';
@@ -23,19 +22,19 @@ const meta = {
23
22
  };
24
23
  export default meta;
25
24
  export const Default = {
26
- render: (args) => (_jsx("div", { className: "w-full max-w-md", children: _jsxs(Item, { ...args, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(BellIcon, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Notifications" }), _jsx(ItemDescription, { children: "Email, push, and in-app alerts." })] }), _jsx(ItemActions, { children: _jsx(Switch, { "aria-label": "Enable notifications", defaultChecked: true }) })] }) })),
25
+ render: (args) => (_jsx("div", { className: "w-full max-w-md", children: _jsxs(Item, { ...args, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(Bell, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Notifications" }), _jsx(ItemDescription, { children: "Email, push, and in-app alerts." })] }), _jsx(ItemActions, { children: _jsx(Switch, { "aria-label": "Enable notifications", defaultChecked: true }) })] }) })),
27
26
  };
28
27
  export const Outline = {
29
28
  args: { variant: 'outline' },
30
- render: (args) => (_jsx("div", { className: "w-full max-w-md", children: _jsxs(Item, { ...args, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(UserIcon, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Profile" }), _jsx(ItemDescription, { children: "Manage your public name and avatar." })] }), _jsx(ItemActions, { children: _jsx(Button, { size: "sm", variant: "outline", children: "Edit" }) })] }) })),
29
+ render: (args) => (_jsx("div", { className: "w-full max-w-md", children: _jsxs(Item, { ...args, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(User, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Profile" }), _jsx(ItemDescription, { children: "Manage your public name and avatar." })] }), _jsx(ItemActions, { children: _jsx(Button, { size: "sm", variant: "outline", children: "Edit" }) })] }) })),
31
30
  };
32
31
  export const AsLink = {
33
32
  render: () => (_jsx("div", { className: "w-full max-w-md", children: _jsxs(Item, { render:
34
33
  // Children are merged from `Item` by useRender; ESLint cannot see them on this JSX node.
35
34
  // eslint-disable-next-line jsx-a11y/anchor-has-content -- runtime children from Item
36
- _jsx("a", { href: "https://example.org", className: "cursor-pointer", rel: "noreferrer", target: "_blank" }), children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(BellIcon, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Open settings" }), _jsxs(ItemDescription, { children: ["Entire row is a link when using ", _jsx("code", { className: "rounded bg-muted px-1", children: "render" }), "."] })] })] }) })),
35
+ _jsx("a", { href: "https://example.org", className: "cursor-pointer", rel: "noreferrer", target: "_blank" }), children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(Bell, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Open settings" }), _jsxs(ItemDescription, { children: ["Entire row is a link when using ", _jsx("code", { className: "rounded bg-muted px-1", children: "render" }), "."] })] })] }) })),
37
36
  };
38
37
  export const Gallery = {
39
38
  parameters: { layout: 'padded' },
40
- render: () => (_jsxs("div", { className: "flex max-w-lg flex-col gap-10", children: [_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Variants" }), _jsx(ItemGroup, { children: itemVariantKeys.map((variant) => (_jsxs(Item, { variant: variant, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(BellIcon, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { className: "capitalize", children: variant }), _jsx(ItemDescription, { children: "Variant preset for list rows." })] })] }, variant))) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Sizes" }), _jsx(ItemGroup, { children: itemSizeKeys.map((size) => (_jsxs(Item, { size: size, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(UserIcon, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { className: "capitalize", children: size }), _jsx(ItemDescription, { children: "Spacing for dense menus or roomy panels." })] })] }, size))) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "With header & footer" }), _jsxs(Item, { variant: "outline", children: [_jsxs(ItemHeader, { children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase", children: "Section" }), _jsx(Button, { size: "xs", variant: "ghost", children: "More" })] }), _jsx(ItemMedia, { variant: "icon", children: _jsx(BellIcon, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Grouped layout" }), _jsx(ItemDescription, { children: "Header and footer span the full width of the item." })] }), _jsx(ItemFooter, { children: _jsx("span", { className: "text-xs text-muted-foreground", children: "Updated today" }) })] })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Media variants" }), _jsx("div", { className: "flex flex-col gap-2", children: itemMediaVariantKeys.map((mv) => (_jsxs(Item, { children: [_jsx(ItemMedia, { variant: mv, children: mv === 'image' ? (_jsx("img", { src: "https://avatars.githubusercontent.com/u/1406596?v=4", alt: "" })) : mv === 'icon' ? (_jsx(BellIcon, {})) : null }), _jsxs(ItemContent, { children: [_jsxs(ItemTitle, { className: "capitalize", children: [mv, " media"] }), _jsx(ItemDescription, { children: "Leading visual treatment." })] })] }, mv))) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Separated list" }), _jsxs(ItemGroup, { children: [_jsx(Item, { size: "sm", children: _jsx(ItemContent, { children: _jsx(ItemTitle, { children: "First" }) }) }), _jsx(ItemSeparator, {}), _jsx(Item, { size: "sm", children: _jsx(ItemContent, { children: _jsx(ItemTitle, { children: "Second" }) }) })] })] })] })),
39
+ render: () => (_jsxs("div", { className: "flex max-w-lg flex-col gap-10", children: [_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Variants" }), _jsx(ItemGroup, { children: itemVariantKeys.map((variant) => (_jsxs(Item, { variant: variant, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(Bell, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { className: "capitalize", children: variant }), _jsx(ItemDescription, { children: "Variant preset for list rows." })] })] }, variant))) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Sizes" }), _jsx(ItemGroup, { children: itemSizeKeys.map((size) => (_jsxs(Item, { size: size, children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(User, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { className: "capitalize", children: size }), _jsx(ItemDescription, { children: "Spacing for dense menus or roomy panels." })] })] }, size))) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "With header & footer" }), _jsxs(Item, { variant: "outline", children: [_jsxs(ItemHeader, { children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase", children: "Section" }), _jsx(Button, { size: "xs", variant: "ghost", children: "More" })] }), _jsx(ItemMedia, { variant: "icon", children: _jsx(Bell, {}) }), _jsxs(ItemContent, { children: [_jsx(ItemTitle, { children: "Grouped layout" }), _jsx(ItemDescription, { children: "Header and footer span the full width of the item." })] }), _jsx(ItemFooter, { children: _jsx("span", { className: "text-xs text-muted-foreground", children: "Updated today" }) })] })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Media variants" }), _jsx("div", { className: "flex flex-col gap-2", children: itemMediaVariantKeys.map((mv) => (_jsxs(Item, { children: [_jsx(ItemMedia, { variant: mv, children: mv === 'image' ? _jsx("img", { src: "https://avatars.githubusercontent.com/u/1406596?v=4", alt: "" }) : mv === 'icon' ? _jsx(Bell, {}) : null }), _jsxs(ItemContent, { children: [_jsxs(ItemTitle, { className: "capitalize", children: [mv, " media"] }), _jsx(ItemDescription, { children: "Leading visual treatment." })] })] }, mv))) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("p", { className: "text-xs font-medium tracking-wide text-muted-foreground uppercase", children: "Separated list" }), _jsxs(ItemGroup, { children: [_jsx(Item, { size: "sm", children: _jsx(ItemContent, { children: _jsx(ItemTitle, { children: "First" }) }) }), _jsx(ItemSeparator, {}), _jsx(Item, { size: "sm", children: _jsx(ItemContent, { children: _jsx(ItemTitle, { children: "Second" }) }) })] })] })] })),
41
40
  };
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { CommandIcon } from '@phosphor-icons/react/Command';
2
+ import { Command } from 'lucide-react';
3
3
  import { Kbd, KbdGroup } from '.';
4
4
  const meta = {
5
5
  title: 'UI/Kbd',
@@ -17,7 +17,7 @@ export const Chord = {
17
17
  render: () => (_jsxs(KbdGroup, { children: [_jsx(Kbd, { children: "\u2318" }), _jsx(Kbd, { children: "K" })] })),
18
18
  };
19
19
  export const WithIcon = {
20
- render: () => (_jsxs(KbdGroup, { children: [_jsx(Kbd, { "aria-label": "Command", children: _jsx(CommandIcon, { className: "size-3", weight: "bold" }) }), _jsx(Kbd, { children: "\u21E7" }), _jsx(Kbd, { children: "P" })] })),
20
+ render: () => (_jsxs(KbdGroup, { children: [_jsx(Kbd, { "aria-label": "Command", children: _jsx(Command, { className: "size-3", strokeWidth: 2.5 }) }), _jsx(Kbd, { children: "\u21E7" }), _jsx(Kbd, { children: "P" })] })),
21
21
  };
22
22
  export const Gallery = {
23
23
  parameters: { layout: 'padded' },
@@ -4,7 +4,7 @@ import { Menu as MenuPrimitive } from '@base-ui/react/menu';
4
4
  import { Menubar as MenubarPrimitive } from '@base-ui/react/menubar';
5
5
  import { cn } from '../../lib/utils';
6
6
  import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from '../dropdown-menu';
7
- import { CheckIcon } from '@phosphor-icons/react/dist/ssr';
7
+ import { Check } from 'lucide-react';
8
8
  function Menubar({ className, ...props }) {
9
9
  return _jsx(MenubarPrimitive, { "data-slot": "menubar", className: cn('flex h-8 items-center gap-0.5 rounded-lg border p-[3px]', className), ...props });
10
10
  }
@@ -27,13 +27,13 @@ function MenubarItem({ className, inset, variant = 'default', ...props }) {
27
27
  return (_jsx(DropdownMenuItem, { "data-slot": "menubar-item", "data-inset": inset, "data-variant": variant, className: cn("group/menubar-item gap-1.5 rounded-md px-1.5 py-1 text-sm focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive!", className), ...props }));
28
28
  }
29
29
  function MenubarCheckboxItem({ className, children, checked, inset, ...props }) {
30
- return (_jsxs(MenuPrimitive.CheckboxItem, { "data-slot": "menubar-checkbox-item", "data-inset": inset, className: cn('relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', className), checked: checked, ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4", children: _jsx(MenuPrimitive.CheckboxItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
30
+ return (_jsxs(MenuPrimitive.CheckboxItem, { "data-slot": "menubar-checkbox-item", "data-inset": inset, className: cn('relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', className), checked: checked, ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4", children: _jsx(MenuPrimitive.CheckboxItemIndicator, { children: _jsx(Check, {}) }) }), children] }));
31
31
  }
32
32
  function MenubarRadioGroup({ ...props }) {
33
33
  return _jsx(DropdownMenuRadioGroup, { "data-slot": "menubar-radio-group", ...props });
34
34
  }
35
35
  function MenubarRadioItem({ className, children, inset, ...props }) {
36
- return (_jsxs(MenuPrimitive.RadioItem, { "data-slot": "menubar-radio-item", "data-inset": inset, className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4", children: _jsx(MenuPrimitive.RadioItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
36
+ return (_jsxs(MenuPrimitive.RadioItem, { "data-slot": "menubar-radio-item", "data-inset": inset, className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [_jsx("span", { className: "pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4", children: _jsx(MenuPrimitive.RadioItemIndicator, { children: _jsx(Check, {}) }) }), children] }));
37
37
  }
38
38
  function MenubarLabel({ className, inset, ...props }) {
39
39
  return (_jsx(DropdownMenuLabel, { "data-slot": "menubar-label", "data-inset": inset, className: cn('px-1.5 py-1 text-sm font-medium data-inset:pl-7', className), ...props }));
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
- import { CaretDownIcon } from '@phosphor-icons/react/ssr';
3
+ import { ChevronDown } from 'lucide-react';
4
4
  import { cn } from '../../lib/utils';
5
5
  function NativeSelect({ className, size = 'default', ...props }) {
6
- return (_jsxs("div", { className: cn('group/native-select relative w-fit has-[select:disabled]:opacity-50', className), "data-slot": "native-select-wrapper", "data-size": size, children: [_jsx("select", { "data-slot": "native-select", "data-size": size, className: "h-8 w-full min-w-0 appearance-none rounded-lg border border-input bg-transparent py-1 pr-8 pl-2.5 text-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-[size=sm]:py-0.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", ...props }), _jsx(CaretDownIcon, { className: "pointer-events-none absolute top-1/2 right-2.5 size-4 -translate-y-1/2 text-muted-foreground select-none", "aria-hidden": "true", "data-slot": "native-select-icon" })] }));
6
+ return (_jsxs("div", { className: cn('group/native-select relative w-fit has-[select:disabled]:opacity-50', className), "data-slot": "native-select-wrapper", "data-size": size, children: [_jsx("select", { "data-slot": "native-select", "data-size": size, className: "h-8 w-full min-w-0 appearance-none rounded-lg border border-input bg-transparent py-1 pr-8 pl-2.5 text-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-[size=sm]:py-0.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", ...props }), _jsx(ChevronDown, { className: "pointer-events-none absolute top-1/2 right-2.5 size-4 -translate-y-1/2 text-muted-foreground select-none", "aria-hidden": "true", "data-slot": "native-select-icon" })] }));
7
7
  }
8
8
  function NativeSelectOption({ className, ...props }) {
9
9
  return _jsx("option", { "data-slot": "native-select-option", className: cn('bg-[Canvas] text-[CanvasText]', className), ...props });
@@ -4,7 +4,7 @@ import * as React from 'react';
4
4
  import { NavigationMenu as NavigationMenuPrimitive } from '@base-ui/react/navigation-menu';
5
5
  import { cva } from 'class-variance-authority';
6
6
  import { cn } from '../../lib/utils';
7
- import { CaretDownIcon } from '@phosphor-icons/react/dist/ssr';
7
+ import { ChevronDown } from 'lucide-react';
8
8
  function NavigationMenu({ align = 'start', className, children, ...props }) {
9
9
  return (_jsxs(NavigationMenuPrimitive.Root, { "data-slot": "navigation-menu", className: cn('group/navigation-menu relative flex max-w-max flex-1 items-center justify-center', className), ...props, children: [children, _jsx(NavigationMenuPositioner, { align: align })] }));
10
10
  }
@@ -16,7 +16,7 @@ function NavigationMenuItem({ className, ...props }) {
16
16
  }
17
17
  const navigationMenuTriggerStyle = cva('group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center rounded-lg px-2.5 py-1.5 text-sm font-medium transition-all outline-none hover:bg-muted focus:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted data-open:bg-muted/50 data-open:hover:bg-muted data-open:focus:bg-muted');
18
18
  function NavigationMenuTrigger({ className, children, ...props }) {
19
- return (_jsxs(NavigationMenuPrimitive.Trigger, { "data-slot": "navigation-menu-trigger", className: cn(navigationMenuTriggerStyle(), 'group', className), ...props, children: [children, ' ', _jsx(CaretDownIcon, { className: "relative top-px ml-1 size-3 transition duration-300 group-data-popup-open/navigation-menu-trigger:rotate-180 group-data-open/navigation-menu-trigger:rotate-180", "aria-hidden": "true" })] }));
19
+ return (_jsxs(NavigationMenuPrimitive.Trigger, { "data-slot": "navigation-menu-trigger", className: cn(navigationMenuTriggerStyle(), 'group', className), ...props, children: [children, ' ', _jsx(ChevronDown, { className: "relative top-px ml-1 size-3 transition duration-300 group-data-popup-open/navigation-menu-trigger:rotate-180 group-data-open/navigation-menu-trigger:rotate-180", "aria-hidden": "true" })] }));
20
20
  }
21
21
  function NavigationMenuContent({ className, ...props }) {
22
22
  return (_jsx(NavigationMenuPrimitive.Content, { "data-slot": "navigation-menu-content", className: cn('data-ending-style:data-activation-direction=left:translate-x-[50%] data-ending-style:data-activation-direction=right:translate-x-[-50%] data-starting-style:data-activation-direction=left:translate-x-[-50%] data-starting-style:data-activation-direction=right:translate-x-[50%] h-full w-auto p-1 transition-[opacity,transform,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:rounded-lg group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:ring-foreground/10 group-data-[viewport=false]/navigation-menu:duration-300 data-ending-style:opacity-0 data-starting-style:opacity-0 data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 data-[motion^=from-]:animate-in data-[motion^=from-]:fade-in data-[motion^=to-]:animate-out data-[motion^=to-]:fade-out **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none group-data-[viewport=false]/navigation-menu:data-open:animate-in group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95', className), ...props }));
@@ -0,0 +1,3 @@
1
+ export { NavigationPattern1 } from './pattern-1';
2
+ export type { NavigationPattern1Props } from './pattern-1';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-pattern-1/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1 @@
1
+ export { NavigationPattern1 } from './pattern-1';
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Navigation data for {@link NavigationPattern1}. Single source for desktop + mobile.
3
+ */
4
+ export type NavBadge = {
5
+ label: string;
6
+ };
7
+ /** Simple top-level link (Dashboard, Performance, …). */
8
+ export type Pattern1PrimaryLink = {
9
+ kind: 'link';
10
+ label: string;
11
+ href: string;
12
+ /** Current / highlighted item (e.g. Dashboard). */
13
+ active?: boolean;
14
+ badge?: NavBadge;
15
+ };
16
+ /** Expandable group (Portfolio + children). */
17
+ export type Pattern1PrimarySubmenu = {
18
+ kind: 'submenu';
19
+ label: string;
20
+ items: readonly {
21
+ label: string;
22
+ href: string;
23
+ }[];
24
+ };
25
+ export type Pattern1PrimaryItem = Pattern1PrimaryLink | Pattern1PrimarySubmenu;
26
+ /** Left cluster: primary app routes. */
27
+ export declare const pattern1PrimaryNav: readonly Pattern1PrimaryItem[];
28
+ export type Pattern1SupportItem = {
29
+ label: string;
30
+ href: string;
31
+ };
32
+ /** Right cluster: Help / Support menu. */
33
+ export declare const pattern1SupportMenu: {
34
+ triggerLabel: string;
35
+ items: readonly Pattern1SupportItem[];
36
+ };
37
+ export type Pattern1UserLink = {
38
+ label: string;
39
+ href: string;
40
+ };
41
+ /** Right cluster: Account menu — grouped sections + log out. */
42
+ export declare const pattern1UserMenu: {
43
+ triggerLabel: string;
44
+ sections: readonly (readonly Pattern1UserLink[])[];
45
+ logOut: Pattern1UserLink;
46
+ };
47
+ //# sourceMappingURL=pattern-1.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-1.config.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-pattern-1/pattern-1.config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,yDAAyD;AACzD,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,QAAQ,CAAC;CACpB,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,sBAAsB,CAAC;AAE/E,wCAAwC;AACxC,eAAO,MAAM,kBAAkB,EAAE,SAAS,mBAAmB,EAiB5D,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,0CAA0C;AAC1C,eAAO,MAAM,mBAAmB,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAO9F,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,EAAE;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC,SAAS,gBAAgB,EAAE,CAAC,EAAE,CAAC;IACnD,MAAM,EAAE,gBAAgB,CAAC;CAuB5B,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Navigation data for {@link NavigationPattern1}. Single source for desktop + mobile.
3
+ */
4
+ /** Left cluster: primary app routes. */
5
+ export const pattern1PrimaryNav = [
6
+ { kind: 'link', label: 'Dashboard', href: '/dashboard', active: true },
7
+ {
8
+ kind: 'submenu',
9
+ label: 'Portfolio',
10
+ items: [
11
+ { label: 'Settings', href: '/portfolio/settings' },
12
+ { label: 'Calendar', href: '/portfolio/calendar' },
13
+ { label: 'Performance', href: '/portfolio/performance' },
14
+ { label: 'Engine Version', href: '/portfolio/engine' },
15
+ ],
16
+ },
17
+ { kind: 'link', label: 'Performance', href: '/products' },
18
+ { kind: 'link', label: 'Reporting', href: '/customers', badge: { label: 'Beta' } },
19
+ { kind: 'link', label: 'Budgets', href: '/settings', badge: { label: 'Beta' } },
20
+ { kind: 'link', label: 'Sets', href: '/settings' },
21
+ { kind: 'link', label: 'Markets', href: '/settings' },
22
+ ];
23
+ /** Right cluster: Help / Support menu. */
24
+ export const pattern1SupportMenu = {
25
+ triggerLabel: 'Support',
26
+ items: [
27
+ { label: 'Live chat', href: '/support/chat' },
28
+ { label: 'Help center', href: '/help' },
29
+ { label: 'Changelog', href: '/changelog' },
30
+ ],
31
+ };
32
+ /** Right cluster: Account menu — grouped sections + log out. */
33
+ export const pattern1UserMenu = {
34
+ triggerLabel: 'User',
35
+ sections: [
36
+ [
37
+ { label: 'Profile', href: '/account/profile' },
38
+ { label: 'Notifications', href: '/account/notifications' },
39
+ { label: 'Email preferences', href: '/account/email-preferences' },
40
+ { label: 'Your referrals', href: '/account/referrals' },
41
+ { label: 'Teams', href: '/account/teams' },
42
+ ],
43
+ [
44
+ { label: 'Connected channels', href: '/connections' },
45
+ { label: 'Add channel', href: '/connections/add' },
46
+ { label: 'API key', href: '/account/api-key' },
47
+ ],
48
+ [
49
+ { label: 'Payment method', href: '/billing/payment' },
50
+ { label: 'Subscriptions', href: '/billing/subscriptions' },
51
+ { label: 'Invoices', href: '/billing/invoices' },
52
+ ],
53
+ ],
54
+ logOut: { label: 'Log out', href: '/logout' },
55
+ };
@@ -0,0 +1,7 @@
1
+ import * as React from 'react';
2
+ export type NavigationPattern1Props = React.ComponentProps<'div'>;
3
+ /**
4
+ * Responsive app header: mobile bar (menu, brand, search, upgrade) plus desktop nav with account actions.
5
+ */
6
+ export declare function NavigationPattern1({ className, ...props }: NavigationPattern1Props): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=pattern-1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-1.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-pattern-1/pattern-1.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAc/B,MAAM,MAAM,uBAAuB,GAAG,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AA4HlE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,uBAAuB,2CAyLlF"}
@@ -0,0 +1,83 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from 'react';
4
+ import { Bell, ChevronDown, Menu, Search, X } from 'lucide-react';
5
+ import { Avatar, AvatarFallback, AvatarImage } from '../avatar';
6
+ import { Badge } from '../badge';
7
+ import { Button } from '../button';
8
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../collapsible';
9
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '../dropdown-menu';
10
+ import { Separator } from '../separator';
11
+ import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '../sheet';
12
+ import { cn } from '../../lib/utils';
13
+ import { pattern1PrimaryNav, pattern1SupportMenu, pattern1UserMenu } from './pattern-1.config';
14
+ /** Demo user — keep in sync between desktop account menu and mobile sheet. */
15
+ const demoUser = {
16
+ name: 'shadcn',
17
+ email: 'm@example.com',
18
+ avatarSrc: 'https://github.com/shadcn.png',
19
+ avatarAlt: '@shadcn',
20
+ initials: 'CN',
21
+ };
22
+ const navLinkClass = 'rounded-md px-3 py-1 text-sm font-medium text-muted-foreground hover:bg-primary/5 outline-none focus-visible:ring-2 focus-visible:ring-ring';
23
+ const sheetNavLinkClass = 'flex items-center gap-2 rounded-md px-3 py-2.5 text-sm font-normal text-muted-foreground hover:bg-accent hover:text-accent-foreground';
24
+ function primaryNavKey(entry, index) {
25
+ return entry.kind === 'link' ? `link-${entry.label}-${entry.href}-${index}` : `submenu-${entry.label}`;
26
+ }
27
+ /** Wheelhouse icon mark — aligned with `marketing_site/public/svg/wh-logo-icon.svg`. */
28
+ function BrandLogo({ className, ...props }) {
29
+ return (_jsxs("svg", { viewBox: "0 0 282 196", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": true, className: cn('h-5 w-auto shrink-0', className), ...props, children: [_jsx("path", { d: "M113.84 192.61L182.63 73.4702C201.1 41.4702 178.01 1.47021 141.07 1.47021H3.4999C3.149 1.47057 2.80437 1.56325 2.50062 1.73893C2.19687 1.91462 1.94468 2.16712 1.76939 2.4711C1.5941 2.77508 1.50186 3.11983 1.50195 3.47073C1.50204 3.82163 1.59445 4.16633 1.7699 4.47021L110.38 192.61C110.556 192.913 110.808 193.165 111.112 193.34C111.415 193.515 111.76 193.607 112.11 193.607C112.46 193.607 112.805 193.515 113.108 193.34C113.412 193.165 113.664 192.913 113.84 192.61Z", fill: "#AA1DA5" }), _jsx("path", { d: "M171.33 192.61L279.93 4.5C280.106 4.19611 280.198 3.85141 280.198 3.50051C280.198 3.14961 280.106 2.80487 279.931 2.50089C279.755 2.19691 279.503 1.9444 279.2 1.76872C278.896 1.59303 278.551 1.50036 278.2 1.5H140.74C103.74 1.5 80.6402 41.5 99.1302 73.57L167.86 192.57C168.032 192.877 168.282 193.134 168.584 193.314C168.887 193.494 169.232 193.591 169.584 193.595C169.936 193.599 170.283 193.51 170.589 193.337C170.896 193.164 171.152 192.913 171.33 192.61V192.61Z", fill: "#D926D2" }), _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M142.811 1.5H140.74C103.74 1.5 80.6402 41.5 99.1302 73.57L140.858 145.817L182.63 73.4702C200.808 41.976 178.729 2.73259 142.811 1.5Z", fill: "#71146D" })] }));
30
+ }
31
+ function MobileNavLinks({ onNavigate }) {
32
+ return (_jsxs("div", { className: "flex flex-col gap-0.5 p-4 pt-2", children: [pattern1PrimaryNav.map((entry, i) => {
33
+ if (entry.kind === 'link') {
34
+ return (_jsxs("a", { className: cn(sheetNavLinkClass, entry.active && 'text-primary'), href: entry.href, onClick: onNavigate, children: [entry.label, entry.badge ? _jsx(Badge, { size: "sm", children: entry.badge.label }) : null] }, primaryNavKey(entry, i)));
35
+ }
36
+ return (_jsxs(Collapsible, { className: "w-full", children: [_jsx(CollapsibleTrigger, { render: _jsxs("button", { type: "button", className: cn(sheetNavLinkClass, 'group flex w-full cursor-default justify-between font-normal text-muted-foreground hover:text-accent-foreground'), children: [_jsx("span", { children: entry.label }), _jsx(ChevronDown, { className: "size-4 shrink-0 opacity-80 transition-transform group-data-[panel-open]:rotate-180" })] }) }), _jsx(CollapsibleContent, { className: "flex flex-col gap-0.5 pt-0.5 pb-1", children: entry.items.map((sub) => (_jsx("a", { className: cn(sheetNavLinkClass, 'py-2 pl-8 text-sm'), href: sub.href, onClick: onNavigate, children: sub.label }, sub.href))) })] }, primaryNavKey(entry, i)));
37
+ }), _jsx(Separator, { className: "my-3" }), _jsxs("div", { className: "flex items-center gap-3 rounded-md px-3 py-2", children: [_jsxs(Avatar, { className: "size-8 border-0 after:hidden", children: [_jsx(AvatarImage, { src: demoUser.avatarSrc, alt: demoUser.avatarAlt }), _jsx(AvatarFallback, { children: demoUser.initials })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "truncate text-sm font-medium text-foreground", children: demoUser.name }), _jsx("p", { className: "truncate text-xs text-muted-foreground", children: demoUser.email })] })] }), pattern1UserMenu.sections.map((section, si) => (_jsxs(React.Fragment, { children: [si > 0 ? _jsx(Separator, { className: "my-2" }) : null, section.map((item) => (_jsx("a", { className: sheetNavLinkClass, href: item.href, onClick: onNavigate, children: item.label }, item.href)))] }, `user-section-${si}`))), _jsx(Separator, { className: "my-2" }), _jsx("a", { className: cn(sheetNavLinkClass, 'text-destructive-foreground hover:bg-destructive/10 hover:text-destructive-foreground'), href: pattern1UserMenu.logOut.href, onClick: onNavigate, children: pattern1UserMenu.logOut.label })] }));
38
+ }
39
+ /**
40
+ * Responsive app header: mobile bar (menu, brand, search, upgrade) plus desktop nav with account actions.
41
+ */
42
+ export function NavigationPattern1({ className, ...props }) {
43
+ const [mobileMenuOpen, setMobileMenuOpen] = React.useState(false);
44
+ // #region agent log
45
+ const agentDbg = React.useCallback((hypothesisId, message, data) => {
46
+ fetch('http://127.0.0.1:7669/ingest/d1992449-3e7e-4566-9281-d4bff7e38fe9', {
47
+ method: 'POST',
48
+ headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '8829e4' },
49
+ body: JSON.stringify({
50
+ sessionId: '8829e4',
51
+ runId: 'pre-fix',
52
+ hypothesisId,
53
+ location: 'pattern-1.tsx:NavigationPattern1',
54
+ message,
55
+ data,
56
+ timestamp: Date.now(),
57
+ }),
58
+ }).catch(() => { });
59
+ }, []);
60
+ React.useEffect(() => {
61
+ const mq = typeof window !== 'undefined' ? window.matchMedia('(min-width: 1024px)') : null;
62
+ agentDbg('A', 'viewport-lg', {
63
+ innerWidth: typeof window !== 'undefined' ? window.innerWidth : null,
64
+ lgMatches: mq?.matches ?? null,
65
+ desktopNavExpectedVisible: mq?.matches ?? null,
66
+ });
67
+ const onResize = () => {
68
+ agentDbg('A', 'viewport-lg-resize', {
69
+ innerWidth: window.innerWidth,
70
+ lgMatches: window.matchMedia('(min-width: 1024px)').matches,
71
+ });
72
+ };
73
+ window.addEventListener('resize', onResize);
74
+ return () => window.removeEventListener('resize', onResize);
75
+ }, [agentDbg]);
76
+ // #endregion
77
+ return (_jsxs("div", { "data-slot": "navigation-pattern-1", className: cn(className), ...props, children: [_jsx("nav", { className: "lg:hidden", "aria-label": "Main", children: _jsxs("div", { className: "relative flex h-14 items-center justify-between border-b border-border bg-background px-4", children: [_jsxs(Button, { type: "button", variant: "ghost", className: "relative -ml-2 h-9 w-9 shrink-0 px-0 [&_svg]:size-5", "aria-expanded": mobileMenuOpen, "aria-controls": "navigation-pattern-1-mobile-sheet", "aria-label": mobileMenuOpen ? 'Close menu' : 'Open menu', onClick: () => setMobileMenuOpen((open) => !open), children: [_jsx("span", { className: cn('absolute transition-all duration-300', mobileMenuOpen ? '-rotate-90 opacity-0' : 'rotate-0 opacity-100'), "aria-hidden": true, children: _jsx(Menu, {}) }), _jsx("span", { className: cn('absolute transition-all duration-300', mobileMenuOpen ? 'rotate-0 opacity-100' : '-rotate-90 opacity-0'), "aria-hidden": true, children: _jsx(X, {}) })] }), _jsx("div", { className: "pointer-events-none absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2", children: _jsx(BrandLogo, { className: "h-6 w-auto" }) }), _jsxs("div", { className: "flex shrink-0 items-center gap-3", children: [_jsx(Button, { type: "button", variant: "ghost", className: "size-9 p-0 [&_svg]:size-5", "aria-label": "Search", children: _jsx(Search, { className: "text-muted-foreground" }) }), _jsx(Button, { type: "button", variant: "ghost", className: "size-9 p-0 [&_svg]:size-5", "aria-label": "Notifications", children: _jsx(Bell, { className: "text-muted-foreground" }) })] })] }) }), _jsx(Sheet, { open: mobileMenuOpen, onOpenChange: setMobileMenuOpen, children: _jsxs(SheetContent, { id: "navigation-pattern-1-mobile-sheet", side: "left", showCloseButton: false, className: "flex h-[100dvh] max-h-[100dvh] w-full flex-col gap-0 overflow-hidden p-0 sm:max-w-sm", children: [_jsxs(SheetHeader, { className: "shrink-0 border-b border-border text-left", children: [_jsx(SheetTitle, { children: "Menu" }), _jsx(SheetDescription, { className: "sr-only", children: "Primary navigation links for the application." })] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto overscroll-contain", children: _jsx(MobileNavLinks, { onNavigate: () => setMobileMenuOpen(false) }) })] }) }), _jsx("nav", { className: "hidden h-12 border-b border-border bg-background lg:block", "aria-label": "Main", children: _jsxs("div", { className: "container flex h-full items-center justify-between px-6", children: [_jsxs("div", { className: "flex items-center gap-x-3", children: [_jsx(BrandLogo, {}), _jsx("div", { className: "flex items-center gap-x-1", children: pattern1PrimaryNav.map((entry, i) => {
78
+ if (entry.kind === 'link') {
79
+ return (_jsxs("a", { className: cn(navLinkClass, entry.active && 'text-primary', entry.badge && 'inline-flex items-center gap-1'), href: entry.href, children: [entry.label, entry.badge ? (_jsx(Badge, { variant: "outline", size: "sm", children: entry.badge.label })) : null] }, primaryNavKey(entry, i)));
80
+ }
81
+ return (_jsxs(DropdownMenu, { onOpenChange: (open) => agentDbg('D', 'menu-open-change', { menu: 'portfolio', open, label: entry.label }), children: [_jsxs(DropdownMenuTrigger, { className: cn(navLinkClass, 'inline-flex cursor-default items-center gap-0 border-0 bg-transparent'), children: [entry.label, _jsx(ChevronDown, { className: "ml-1 size-4 opacity-80" })] }), _jsx(DropdownMenuContent, { align: "start", className: "min-w-48", children: entry.items.map((sub) => (_jsx(DropdownMenuItem, { children: sub.label }, sub.href))) })] }, primaryNavKey(entry, i)));
82
+ }) })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": "Search", children: _jsx(Search, { className: "size-4 text-muted-foreground" }) }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": "Search", children: _jsx(Bell, { className: "size-4 text-muted-foreground" }) }), _jsxs(DropdownMenu, { onOpenChange: (open) => agentDbg('D', 'menu-open-change', { menu: 'support', open }), children: [_jsxs(DropdownMenuTrigger, { className: cn(navLinkClass, 'inline-flex cursor-default items-center gap-0 border-0 bg-transparent'), children: [pattern1SupportMenu.triggerLabel, _jsx(ChevronDown, { className: "ml-1 size-4 opacity-80" })] }), _jsx(DropdownMenuContent, { align: "start", className: "min-w-48", children: pattern1SupportMenu.items.map((item) => (_jsx(DropdownMenuItem, { children: item.label }, item.href))) })] }), _jsxs(DropdownMenu, { onOpenChange: (open) => agentDbg('D', 'menu-open-change', { menu: 'user', open }), children: [_jsxs(DropdownMenuTrigger, { className: cn(navLinkClass, 'inline-flex cursor-default items-center gap-0 border-0 bg-transparent'), children: [pattern1UserMenu.triggerLabel, _jsx(ChevronDown, { className: "ml-1 size-4 opacity-80" })] }), _jsxs(DropdownMenuContent, { align: "end", className: "min-w-56", children: [_jsxs(DropdownMenuLabel, { className: "font-normal", children: [_jsx("span", { className: "block text-sm font-medium", children: demoUser.name }), _jsx("span", { className: "block text-xs text-muted-foreground", children: demoUser.email })] }), _jsx(DropdownMenuSeparator, {}), pattern1UserMenu.sections.map((section, si) => (_jsxs(React.Fragment, { children: [si > 0 ? _jsx(DropdownMenuSeparator, {}) : null, section.map((item) => (_jsx(DropdownMenuItem, { children: item.label }, `${item.href}-${item.label}`)))] }, `user-dd-${si}`))), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { variant: "destructive", children: pattern1UserMenu.logOut.label })] })] })] })] }) })] }));
83
+ }
@@ -0,0 +1,16 @@
1
+ import type { StoryObj } from '@storybook/react';
2
+ import { NavigationPattern1 } from './pattern-1';
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof NavigationPattern1;
6
+ parameters: {
7
+ layout: string;
8
+ };
9
+ };
10
+ export default meta;
11
+ type Story = StoryObj<typeof meta>;
12
+ /** Wide canvas: show the desktop bar only (`hidden lg:block` → forced visible). */
13
+ export declare const Desktop: Story;
14
+ /** Wide canvas: show the mobile bar and sheet trigger (`lg:hidden` → forced visible). */
15
+ export declare const Mobile: Story;
16
+ //# sourceMappingURL=pattern-1.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-1.stories.d.ts","sourceRoot":"","sources":["../../../src/components/navigation-pattern-1/pattern-1.stories.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,QAAA,MAAM,IAAI;;;;;;CAMiC,CAAC;AAE5C,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,mFAAmF;AACnF,eAAO,MAAM,OAAO,EAAE,KAGrB,CAAC;AAEF,yFAAyF;AACzF,eAAO,MAAM,MAAM,EAAE,KAEpB,CAAC"}
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { NavigationPattern1 } from './pattern-1';
4
+ const meta = {
5
+ title: 'UI/Navigation pattern 1',
6
+ component: NavigationPattern1,
7
+ parameters: {
8
+ layout: 'padded',
9
+ },
10
+ };
11
+ export default meta;
12
+ /** Wide canvas: show the desktop bar only (`hidden lg:block` → forced visible). */
13
+ export const Desktop = {
14
+ // className="[&>nav:first-of-type]:hidden [&>nav:last-of-type]:!block"
15
+ render: () => _jsx(NavigationPattern1, {}),
16
+ };
17
+ /** Wide canvas: show the mobile bar and sheet trigger (`lg:hidden` → forced visible). */
18
+ export const Mobile = {
19
+ render: () => _jsx(NavigationPattern1, { className: "[&>nav:first-of-type]:!block [&>nav:last-of-type]:!hidden" }),
20
+ };
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
3
  import { cn } from '../../lib/utils';
4
4
  import { Button } from '../button';
5
- import { CaretLeftIcon, CaretRightIcon, DotsThreeIcon } from '@phosphor-icons/react/dist/ssr';
5
+ import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
6
6
  function Pagination({ className, ...props }) {
7
7
  return _jsx("nav", { role: "navigation", "aria-label": "pagination", "data-slot": "pagination", className: cn('mx-auto flex w-full justify-center', className), ...props });
8
8
  }
@@ -18,12 +18,12 @@ function PaginationLink({ className, isActive, size = 'icon', ...props }) {
18
18
  _jsx("a", { "aria-current": isActive ? 'page' : undefined, "data-slot": "pagination-link", "data-active": isActive, ...props }) }));
19
19
  }
20
20
  function PaginationPrevious({ className, text = 'Previous', ...props }) {
21
- return (_jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn('pl-1.5!', className), ...props, children: [_jsx(CaretLeftIcon, { "data-icon": "inline-start" }), _jsx("span", { className: "hidden sm:block", children: text })] }));
21
+ return (_jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn('pl-1.5!', className), ...props, children: [_jsx(ChevronLeft, { "data-icon": "inline-start" }), _jsx("span", { className: "hidden sm:block", children: text })] }));
22
22
  }
23
23
  function PaginationNext({ className, text = 'Next', ...props }) {
24
- return (_jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn('pr-1.5!', className), ...props, children: [_jsx("span", { className: "hidden sm:block", children: text }), _jsx(CaretRightIcon, { "data-icon": "inline-end" })] }));
24
+ return (_jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn('pr-1.5!', className), ...props, children: [_jsx("span", { className: "hidden sm:block", children: text }), _jsx(ChevronRight, { "data-icon": "inline-end" })] }));
25
25
  }
26
26
  function PaginationEllipsis({ className, ...props }) {
27
- return (_jsxs("span", { "aria-hidden": true, "data-slot": "pagination-ellipsis", className: cn("flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [_jsx(DotsThreeIcon, {}), _jsx("span", { className: "sr-only", children: "More pages" })] }));
27
+ return (_jsxs("span", { "aria-hidden": true, "data-slot": "pagination-ellipsis", className: cn("flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [_jsx(MoreHorizontal, {}), _jsx("span", { className: "sr-only", children: "More pages" })] }));
28
28
  }
29
29
  export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious };
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { Select as SelectPrimitive } from '@base-ui/react/select';
5
- import { CaretDownIcon, CaretUpIcon, CheckIcon } from '@phosphor-icons/react';
5
+ import { Check, ChevronDown, ChevronUp } from 'lucide-react';
6
6
  import { cn } from '../../lib/utils';
7
7
  /**
8
8
  * Root for a native-style select. Compose `SelectTrigger`, `SelectValue`, `SelectContent`,
@@ -21,7 +21,7 @@ function SelectValue({ className, ...props }) {
21
21
  }
22
22
  /** Button that opens the list popup; shows a chevron icon. */
23
23
  function SelectTrigger({ className, size = 'default', children, ...props }) {
24
- return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { render: _jsx(CaretDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" }) })] }));
24
+ return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(SelectPrimitive.Icon, { render: _jsx(ChevronDown, { className: "pointer-events-none size-4 text-muted-foreground" }) })] }));
25
25
  }
26
26
  /** Portal, positioner, and scrollable list surface for options. */
27
27
  function SelectContent({ className, children, side = 'bottom', sideOffset = 4, align = 'center', alignOffset = 0, alignItemWithTrigger = true, ...props }) {
@@ -33,7 +33,7 @@ function SelectLabel({ className, ...props }) {
33
33
  }
34
34
  /** One selectable option; shows a check when selected. */
35
35
  function SelectItem({ className, children, ...props }) {
36
- return (_jsxs(SelectPrimitive.Item, { "data-slot": "select-item", className: cn("relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className), ...props, children: [_jsx(SelectPrimitive.ItemText, { className: "flex flex-1 shrink-0 gap-2 whitespace-nowrap", children: children }), _jsx(SelectPrimitive.ItemIndicator, { render: _jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }), children: _jsx(CheckIcon, { className: "pointer-events-none" }) })] }));
36
+ return (_jsxs(SelectPrimitive.Item, { "data-slot": "select-item", className: cn("relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className), ...props, children: [_jsx(SelectPrimitive.ItemText, { className: "flex flex-1 shrink-0 gap-2 whitespace-nowrap", children: children }), _jsx(SelectPrimitive.ItemIndicator, { render: _jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }), children: _jsx(Check, { className: "pointer-events-none" }) })] }));
37
37
  }
38
38
  /** Horizontal rule between groups or items. */
39
39
  function SelectSeparator({ className, ...props }) {
@@ -41,10 +41,10 @@ function SelectSeparator({ className, ...props }) {
41
41
  }
42
42
  /** Scroll affordance at the top of a long list (pointer/hover). */
43
43
  function SelectScrollUpButton({ className, ...props }) {
44
- return (_jsx(SelectPrimitive.ScrollUpArrow, { "data-slot": "select-scroll-up-button", className: cn("top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: _jsx(CaretUpIcon, {}) }));
44
+ return (_jsx(SelectPrimitive.ScrollUpArrow, { "data-slot": "select-scroll-up-button", className: cn("top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: _jsx(ChevronUp, {}) }));
45
45
  }
46
46
  /** Scroll affordance at the bottom of a long list (pointer/hover). */
47
47
  function SelectScrollDownButton({ className, ...props }) {
48
- return (_jsx(SelectPrimitive.ScrollDownArrow, { "data-slot": "select-scroll-down-button", className: cn("bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: _jsx(CaretDownIcon, {}) }));
48
+ return (_jsx(SelectPrimitive.ScrollDownArrow, { "data-slot": "select-scroll-down-button", className: cn("bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: _jsx(ChevronDown, {}) }));
49
49
  }
50
50
  export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, };
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { Dialog as SheetPrimitive } from '@base-ui/react/dialog';
5
- import { XIcon } from '@phosphor-icons/react/X';
5
+ import { X } from 'lucide-react';
6
6
  import { cn } from '../../lib/utils';
7
7
  import { Button } from '../button';
8
8
  function Sheet({ ...props }) {
@@ -21,7 +21,7 @@ function SheetOverlay({ className, ...props }) {
21
21
  return (_jsx(SheetPrimitive.Backdrop, { "data-slot": "sheet-overlay", className: cn('fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs', className), ...props }));
22
22
  }
23
23
  function SheetContent({ className, children, side = 'right', showCloseButton = true, ...props }) {
24
- return (_jsxs(SheetPortal, { children: [_jsx(SheetOverlay, {}), _jsxs(SheetPrimitive.Popup, { "data-slot": "sheet-content", "data-side": side, className: cn('fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm', className), ...props, children: [children, showCloseButton && (_jsxs(SheetPrimitive.Close, { "data-slot": "sheet-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-3 right-3", size: "icon-sm" }), children: [_jsx(XIcon, {}), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
24
+ return (_jsxs(SheetPortal, { children: [_jsx(SheetOverlay, {}), _jsxs(SheetPrimitive.Popup, { "data-slot": "sheet-content", "data-side": side, className: cn('fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm', className), ...props, children: [children, showCloseButton && (_jsxs(SheetPrimitive.Close, { "data-slot": "sheet-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-3 right-3", size: "icon-sm" }), children: [_jsx(X, {}), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
25
25
  }
26
26
  function SheetHeader({ className, ...props }) {
27
27
  return _jsx("div", { "data-slot": "sheet-header", className: cn('flex flex-col gap-0.5 p-4', className), ...props });
@@ -1,6 +1,6 @@
1
1
  import { type ToasterProps } from 'sonner';
2
2
  /**
3
- * Opinionated [Sonner](https://sonner.emilkowal.ski/) toaster: Wheelhouse popover tokens, Phosphor icons,
3
+ * Opinionated [Sonner](https://sonner.emilkowal.ski/) toaster: Wheelhouse popover tokens, Lucide icons,
4
4
  * and `cn-toast` class for styling. Mount once near the app root.
5
5
  *
6
6
  * Defaults to **`theme="system"`** so light/dark follows the OS; in Next.js with `next-themes`, pass
@@ -2,9 +2,9 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { Toaster as Sonner } from 'sonner';
5
- import { CheckCircleIcon, InfoIcon, SpinnerIcon, WarningIcon, XCircleIcon } from '@phosphor-icons/react';
5
+ import { AlertTriangle, CheckCircle, Info, Loader2, XCircle } from 'lucide-react';
6
6
  /**
7
- * Opinionated [Sonner](https://sonner.emilkowal.ski/) toaster: Wheelhouse popover tokens, Phosphor icons,
7
+ * Opinionated [Sonner](https://sonner.emilkowal.ski/) toaster: Wheelhouse popover tokens, Lucide icons,
8
8
  * and `cn-toast` class for styling. Mount once near the app root.
9
9
  *
10
10
  * Defaults to **`theme="system"`** so light/dark follows the OS; in Next.js with `next-themes`, pass
@@ -13,11 +13,11 @@ import { CheckCircleIcon, InfoIcon, SpinnerIcon, WarningIcon, XCircleIcon } from
13
13
  */
14
14
  function Toaster({ theme = 'system', ...props }) {
15
15
  return (_jsx(Sonner, { theme: theme, className: "toaster group", icons: {
16
- success: _jsx(CheckCircleIcon, { className: "size-4" }),
17
- info: _jsx(InfoIcon, { className: "size-4" }),
18
- warning: _jsx(WarningIcon, { className: "size-4" }),
19
- error: _jsx(XCircleIcon, { className: "size-4" }),
20
- loading: _jsx(SpinnerIcon, { className: "size-4 animate-spin" }),
16
+ success: _jsx(CheckCircle, { className: "size-4" }),
17
+ info: _jsx(Info, { className: "size-4" }),
18
+ warning: _jsx(AlertTriangle, { className: "size-4" }),
19
+ error: _jsx(XCircle, { className: "size-4" }),
20
+ loading: _jsx(Loader2, { className: "size-4 animate-spin" }),
21
21
  }, style: {
22
22
  '--normal-bg': 'var(--popover)',
23
23
  '--normal-text': 'var(--popover-foreground)',
@@ -0,0 +1,3 @@
1
+ export { Sortable, SortableItem, SortableItemHandle, SortableOverlay } from './sortable';
2
+ export type { SortableItemHandleProps, SortableItemProps, SortableOverlayProps, SortableRootProps } from './sortable';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/sortable/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACzF,YAAY,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ export { Sortable, SortableItem, SortableItemHandle, SortableOverlay } from './sortable';