@waveinno/ui 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +30 -12
  3. package/dist/components/brand/waveinno-logo.js +1 -1
  4. package/dist/components/charts/bar-list.js +1 -1
  5. package/dist/components/charts/heatmap.js +1 -1
  6. package/dist/components/patterns/activity-feed.js +1 -1
  7. package/dist/components/patterns/app-launcher.js +1 -1
  8. package/dist/components/patterns/data-table-edit.js +1 -1
  9. package/dist/components/patterns/data-table-filters.js +1 -1
  10. package/dist/components/patterns/data-table.js +1 -1
  11. package/dist/components/patterns/page-header.js +1 -1
  12. package/dist/components/patterns/page-hero.js +1 -1
  13. package/dist/components/patterns/stat-card.js +1 -1
  14. package/dist/components/patterns/timeline.js +1 -1
  15. package/dist/components/ui/alert.d.ts +28 -0
  16. package/dist/components/ui/alert.js +1 -0
  17. package/dist/components/ui/avatar.js +1 -1
  18. package/dist/components/ui/badge.js +1 -1
  19. package/dist/components/ui/button.js +1 -1
  20. package/dist/components/ui/checkbox.js +1 -1
  21. package/dist/components/ui/combobox.js +1 -1
  22. package/dist/components/ui/confirm-dialog.js +1 -1
  23. package/dist/components/ui/dialog.js +1 -1
  24. package/dist/components/ui/dropdown-menu.js +1 -1
  25. package/dist/components/ui/file-upload.d.ts +36 -0
  26. package/dist/components/ui/file-upload.js +1 -0
  27. package/dist/components/ui/index.d.ts +11 -1
  28. package/dist/components/ui/index.js +1 -1
  29. package/dist/components/ui/kbd.d.ts +13 -0
  30. package/dist/components/ui/kbd.js +1 -0
  31. package/dist/components/ui/menu.js +1 -1
  32. package/dist/components/ui/number-input.d.ts +30 -0
  33. package/dist/components/ui/number-input.js +1 -0
  34. package/dist/components/ui/password-input.d.ts +18 -0
  35. package/dist/components/ui/password-input.js +1 -0
  36. package/dist/components/ui/pin-input.d.ts +32 -0
  37. package/dist/components/ui/pin-input.js +1 -0
  38. package/dist/components/ui/popover.js +1 -1
  39. package/dist/components/ui/progress.js +1 -1
  40. package/dist/components/ui/radio-group.d.ts +27 -0
  41. package/dist/components/ui/radio-group.js +1 -0
  42. package/dist/components/ui/segmented.d.ts +1 -1
  43. package/dist/components/ui/segmented.js +1 -1
  44. package/dist/components/ui/sheet.js +1 -1
  45. package/dist/components/ui/slider.d.ts +24 -0
  46. package/dist/components/ui/slider.js +1 -0
  47. package/dist/components/ui/spinner.d.ts +27 -0
  48. package/dist/components/ui/spinner.js +1 -0
  49. package/dist/components/ui/tabs.js +1 -1
  50. package/dist/components/ui/toast.d.ts +13 -0
  51. package/dist/components/ui/toast.js +1 -0
  52. package/dist/hooks/index.d.ts +1 -0
  53. package/dist/hooks/index.js +1 -1
  54. package/dist/hooks/use-router.d.ts +41 -0
  55. package/dist/hooks/use-router.js +1 -0
  56. package/dist/lib/index.d.ts +1 -0
  57. package/dist/lib/index.js +1 -1
  58. package/dist/lib/theme.d.ts +48 -0
  59. package/dist/lib/theme.js +7 -0
  60. package/dist/next/index.d.ts +6 -0
  61. package/dist/next/index.js +1 -0
  62. package/dist/shell/app-shell.js +1 -1
  63. package/dist/shell/app-switcher.js +1 -1
  64. package/dist/shell/command-palette.js +1 -1
  65. package/dist/shell/icon-rail.js +1 -1
  66. package/dist/shell/mobile-nav.js +1 -1
  67. package/dist/shell/module-sidebar.js +1 -1
  68. package/dist/shell/notifications.js +1 -1
  69. package/dist/shell/placeholder-screen.js +1 -1
  70. package/dist/shell/topbar.js +1 -1
  71. package/dist/shell/use-active.js +1 -1
  72. package/dist/shell/user-menu.js +1 -1
  73. package/dist/styles.css +47 -5
  74. package/package.json +13 -1
@@ -0,0 +1,27 @@
1
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
2
+ import * as React from "react";
3
+ /**
4
+ * RadioGroup — one choice out of a few, all of them in view. Past five or six
5
+ * options it becomes a Select: a wall of radios is a list nobody reads.
6
+ *
7
+ * Two kinds of item, one group:
8
+ * RadioGroupItem — a dot and a label, with a line under it if it needs one. Forms.
9
+ * RadioCard — the whole card is the target: icon, title, description, and
10
+ * a price or badge on the right. Plans, payment methods, vehicle types.
11
+ * Arrow keys move the choice, as with native radios.
12
+ */
13
+ export declare const RadioGroup: React.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
14
+ export interface RadioGroupItemProps extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {
15
+ label?: React.ReactNode;
16
+ /** A muted line under the label. */
17
+ description?: React.ReactNode;
18
+ }
19
+ export declare const RadioGroupItem: React.ForwardRefExoticComponent<RadioGroupItemProps & React.RefAttributes<HTMLButtonElement>>;
20
+ export interface RadioCardProps extends Omit<React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>, "title"> {
21
+ title: React.ReactNode;
22
+ description?: React.ReactNode;
23
+ icon?: React.ReactNode;
24
+ /** On the right: a price, a time, a badge. */
25
+ aside?: React.ReactNode;
26
+ }
27
+ export declare const RadioCard: React.ForwardRefExoticComponent<RadioCardProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as e,jsxs as s}from"react/jsx-runtime";import*as n from"@radix-ui/react-radio-group";import{Check as m}from"lucide-react";import*as l from"react";import{cn as i}from"../../lib/utils.js";const u=l.forwardRef(({className:o,orientation:r,...a},t)=>e(n.Root,{ref:t,orientation:r,className:i(r==="horizontal"?"flex flex-wrap gap-x-5 gap-y-2":"grid gap-2.5",o),...a}));u.displayName="RadioGroup";const b="peer grid size-4 shrink-0 cursor-pointer place-items-center rounded-full border border-border2 bg-raised outline-none shadow-[inset_0_1px_1px_rgba(5,8,22,.06)] transition-[background-color,border-color,box-shadow] duration-150 hover:border-primary/60 focus-visible:ring-2 focus-visible:ring-primary/30 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:shadow-[0_1px_3px_color-mix(in_srgb,var(--primary)_40%,transparent)] disabled:cursor-not-allowed disabled:opacity-50",x=l.forwardRef(({className:o,label:r,description:a,disabled:t,...d},c)=>{const p=e(n.Item,{ref:c,disabled:t,className:i(b,r?"mt-0.5":null,!r&&o),...d,children:e(n.Indicator,{className:"size-1.5 rounded-full bg-white animate-[wm-pop_180ms_var(--ease)]"})});return r?s("label",{className:i("group flex cursor-pointer items-start gap-2.5",t&&"cursor-not-allowed opacity-60",o),children:[p,s("span",{className:"min-w-0",children:[e("span",{className:"block text-[13px] font-medium leading-5 text-text",children:r}),a?e("span",{className:"block text-[12px] leading-[17px] text-muted",children:a}):null]})]}):p});x.displayName="RadioGroupItem";const R=l.forwardRef(({className:o,title:r,description:a,icon:t,aside:d,...c},p)=>s(n.Item,{ref:p,className:i("group relative flex w-full cursor-pointer items-start gap-3 rounded-[calc(12px*var(--radius-scale))] border border-border bg-raised p-3.5 pr-10 text-left outline-none","transition-[border-color,background-color,box-shadow] duration-200 hover:border-border2","focus-visible:ring-2 focus-visible:ring-primary/35","data-[state=checked]:border-primary data-[state=checked]:bg-[linear-gradient(180deg,var(--primary-subtle),transparent_120%)] data-[state=checked]:shadow-[0_0_0_3px_var(--primary-subtle),0_6px_16px_-8px_color-mix(in_srgb,var(--primary)_35%,transparent)]","disabled:cursor-not-allowed disabled:opacity-50",o),...c,children:[t?e("span",{className:i("grid size-9 shrink-0 place-items-center rounded-[calc(10px*var(--radius-scale))] border border-border bg-surface text-muted transition-colors duration-200 [&_svg]:size-[18px]","group-data-[state=checked]:border-primary/25 group-data-[state=checked]:bg-raised group-data-[state=checked]:text-primary"),children:t}):null,s("span",{className:"min-w-0 flex-1",children:[s("span",{className:"flex items-center justify-between gap-3",children:[e("span",{className:"truncate text-[13.5px] font-semibold text-text",children:r}),d?e("span",{className:"num shrink-0 text-[13px] font-semibold text-text",children:d}):null]}),a?e("span",{className:"mt-0.5 block text-[12px] leading-[17px] text-muted",children:a}):null]}),e("span",{"aria-hidden":!0,className:i("absolute right-3.5 top-3.5 grid size-[18px] place-items-center rounded-full border border-border2 bg-raised text-white transition-[background-color,border-color] duration-200","group-data-[state=checked]:border-primary group-data-[state=checked]:bg-primary"),children:e(m,{className:"size-3 scale-0 transition-transform duration-200 ease-[cubic-bezier(.3,1.6,.5,1)] group-data-[state=checked]:scale-100",strokeWidth:3.2})})]}));R.displayName="RadioCard";export{R as RadioCard,u as RadioGroup,x as RadioGroupItem};
@@ -19,7 +19,7 @@ declare const SIZES: {
19
19
  declare const TRACK: {
20
20
  readonly pill: "rounded-full border border-border bg-hover";
21
21
  readonly solid: "rounded-full border border-border bg-hover";
22
- readonly outline: "rounded-[10px] border border-border2 bg-raised";
22
+ readonly outline: "rounded-[calc(10px*var(--radius-scale))] border border-border2 bg-raised";
23
23
  readonly glass: "rounded-full bg-[rgba(10,7,32,.22)] ring-1 ring-inset ring-white/15 shadow-[inset_0_1px_3px_rgba(5,8,22,.35)] backdrop-blur-md";
24
24
  };
25
25
  /**
@@ -1 +1 @@
1
- "use client";import{jsx as b,jsxs as y}from"react/jsx-runtime";import*as i from"react";import{cn as o}from"../../lib/utils.js";const m={sm:"px-2.5 py-1 text-[11px]",md:"h-8 px-3.5 text-[12.5px]",lg:"h-10 px-5 text-[13.5px]"},v={pill:"rounded-full border border-border bg-hover",solid:"rounded-full border border-border bg-hover",outline:"rounded-[10px] border border-border2 bg-raised",glass:"rounded-full bg-[rgba(10,7,32,.22)] ring-1 ring-inset ring-white/15 shadow-[inset_0_1px_3px_rgba(5,8,22,.35)] backdrop-blur-md"},g={pill:"rounded-full bg-raised shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.08),0_2px_8px_-2px_rgba(5,8,22,.16)]",solid:"rounded-full bg-[linear-gradient(135deg,#1f45ea,#5b4af5)] shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_4px_12px_-4px_rgba(20,55,211,.6)]",outline:"rounded-[7px] bg-primary-subtle ring-1 ring-inset ring-primary/30",glass:"rounded-full bg-[linear-gradient(180deg,rgba(255,255,255,.34),rgba(255,255,255,.16))] ring-1 ring-inset ring-white/45 shadow-[inset_0_1px_0_rgba(255,255,255,.55),0_6px_14px_-6px_rgba(5,8,22,.45)] backdrop-blur-md"},w={pill:"text-text",solid:"text-white",outline:"text-primary",glass:"text-white [text-shadow:0_1px_1px_rgba(5,8,22,.25)]"},T={pill:"text-muted hover:text-text",solid:"text-muted hover:text-text",outline:"text-muted hover:text-text",glass:"text-white/65 hover:text-white"};function k({value:s,onChange:c,options:a,className:f,ariaLabel:_,variant:r="pill",size:d="sm",fullWidth:u=!1}){const p=i.useRef(null),[n,h]=i.useState(null);return i.useLayoutEffect(()=>{const e=p.current;if(!e)return;const t=()=>{const l=e.querySelector('[aria-checked="true"]');h(l?{left:l.offsetLeft,width:l.offsetWidth}:null)};t();const x=new ResizeObserver(t);return x.observe(e),()=>x.disconnect()},[s,a.length,d]),y("div",{ref:p,role:"radiogroup","aria-label":_,className:o("relative isolate items-center gap-0.5 p-[3px]",u?"flex w-full":"inline-flex",v[r],f),children:[n?b("span",{"aria-hidden":!0,className:o("absolute inset-y-[3px] -z-10 transition-[left,width] duration-300 ease-[cubic-bezier(.3,.7,.2,1)]",g[r]),style:{left:n.left,width:n.width}}):null,a.map(e=>{const t=e.value===s;return b("button",{type:"button",role:"radio","aria-checked":t,title:e.title,onClick:()=>c(e.value),className:o("inline-flex cursor-pointer items-center justify-center gap-1.5 rounded-full font-medium leading-none transition-colors duration-200 [&_svg]:size-3.5",m[d],u&&"flex-1",t?w[r]:T[r],t&&!n&&g[r]),children:e.label},e.value)})]})}export{k as Segmented};
1
+ "use client";import{jsx as b,jsxs as y}from"react/jsx-runtime";import*as i from"react";import{cn as o}from"../../lib/utils.js";const h={sm:"px-2.5 py-1 text-[11px]",md:"h-8 px-3.5 text-[12.5px]",lg:"h-10 px-5 text-[13.5px]"},v={pill:"rounded-full border border-border bg-hover",solid:"rounded-full border border-border bg-hover",outline:"rounded-[calc(10px*var(--radius-scale))] border border-border2 bg-raised",glass:"rounded-full bg-[rgba(10,7,32,.22)] ring-1 ring-inset ring-white/15 shadow-[inset_0_1px_3px_rgba(5,8,22,.35)] backdrop-blur-md"},x={pill:"rounded-full bg-raised shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.08),0_2px_8px_-2px_rgba(5,8,22,.16)]",solid:"rounded-full bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_4px_12px_-4px_color-mix(in_srgb,var(--brand-1)_60%,transparent)]",outline:"rounded-[calc(7px*var(--radius-scale))] bg-primary-subtle ring-1 ring-inset ring-primary/30",glass:"rounded-full bg-[linear-gradient(180deg,rgba(255,255,255,.34),rgba(255,255,255,.16))] ring-1 ring-inset ring-white/45 shadow-[inset_0_1px_0_rgba(255,255,255,.55),0_6px_14px_-6px_rgba(5,8,22,.45)] backdrop-blur-md"},w={pill:"text-text",solid:"text-white",outline:"text-primary",glass:"text-white [text-shadow:0_1px_1px_rgba(5,8,22,.25)]"},T={pill:"text-muted hover:text-text",solid:"text-muted hover:text-text",outline:"text-muted hover:text-text",glass:"text-white/65 hover:text-white"};function k({value:a,onChange:g,options:s,className:f,ariaLabel:_,variant:r="pill",size:d="sm",fullWidth:u=!1}){const p=i.useRef(null),[n,m]=i.useState(null);return i.useLayoutEffect(()=>{const e=p.current;if(!e)return;const t=()=>{const l=e.querySelector('[aria-checked="true"]');m(l?{left:l.offsetLeft,width:l.offsetWidth}:null)};t();const c=new ResizeObserver(t);return c.observe(e),()=>c.disconnect()},[a,s.length,d]),y("div",{ref:p,role:"radiogroup","aria-label":_,className:o("relative isolate items-center gap-0.5 p-[3px]",u?"flex w-full":"inline-flex",v[r],f),children:[n?b("span",{"aria-hidden":!0,className:o("absolute inset-y-[3px] -z-10 transition-[left,width] duration-300 ease-[cubic-bezier(.3,.7,.2,1)]",x[r]),style:{left:n.left,width:n.width}}):null,s.map(e=>{const t=e.value===a;return b("button",{type:"button",role:"radio","aria-checked":t,title:e.title,onClick:()=>g(e.value),className:o("inline-flex cursor-pointer items-center justify-center gap-1.5 rounded-full font-medium leading-none transition-colors duration-200 [&_svg]:size-3.5",h[d],u&&"flex-1",t?w[r]:T[r],t&&!n&&x[r]),children:e.label},e.value)})]})}export{k as Segmented};
@@ -1 +1 @@
1
- "use client";import{jsx as t,jsxs as o}from"react/jsx-runtime";import*as e from"@radix-ui/react-dialog";import{X as c}from"lucide-react";import*as p from"react";import{cn as g}from"../../lib/utils.js";const x=e.Root,u=e.Trigger,C=e.Close,b=p.forwardRef(({className:i,children:s,side:r="right",width:l="w-full sm:w-drawer",scrim:a=!0,hideClose:n,...m},d)=>o(e.Portal,{children:[a?t(e.Overlay,{"data-scrim":"",className:"fixed inset-0 z-50 bg-[rgba(5,8,22,.42)] backdrop-blur-[3px]"}):null,o(e.Content,{ref:d,"data-sheet":r,className:g("fixed inset-y-0 z-50 flex max-w-full flex-col border-border bg-raised shadow-elev3 outline-none",r==="right"?"right-0 max-sm:border-l sm:inset-y-2 sm:right-2 sm:rounded-[16px] sm:border":"left-0 max-sm:border-r sm:inset-y-2 sm:left-2 sm:rounded-[16px] sm:border",l,i),...m,children:[s,n?null:o(e.Close,{className:"absolute right-4 top-4 z-10 grid size-8 cursor-pointer place-items-center rounded-full border border-border bg-raised/80 text-muted backdrop-blur transition-[background-color,color,transform] hover:bg-hover hover:text-text active:scale-95",children:[t(c,{className:"size-4"}),t("span",{className:"sr-only",children:"Close"})]})]})]}));b.displayName="SheetContent";const v=e.Title,P=e.Description;export{x as Sheet,C as SheetClose,b as SheetContent,P as SheetDescription,v as SheetTitle,u as SheetTrigger};
1
+ "use client";import{jsx as t,jsxs as r}from"react/jsx-runtime";import*as e from"@radix-ui/react-dialog";import{X as d}from"lucide-react";import*as p from"react";import{cn as g}from"../../lib/utils.js";const u=e.Root,x=e.Trigger,v=e.Close,b=p.forwardRef(({className:i,children:s,side:o="right",width:a="w-full sm:w-drawer",scrim:l=!0,hideClose:n,...m},c)=>r(e.Portal,{children:[l?t(e.Overlay,{"data-scrim":"",className:"fixed inset-0 z-50 bg-[rgba(5,8,22,.42)] backdrop-blur-[3px]"}):null,r(e.Content,{ref:c,"data-sheet":o,className:g("fixed inset-y-0 z-50 flex max-w-full flex-col border-border bg-raised shadow-elev3 outline-none",o==="right"?"right-0 max-sm:border-l sm:inset-y-2 sm:right-2 sm:rounded-[calc(16px*var(--radius-scale))] sm:border":"left-0 max-sm:border-r sm:inset-y-2 sm:left-2 sm:rounded-[calc(16px*var(--radius-scale))] sm:border",a,i),...m,children:[s,n?null:r(e.Close,{className:"absolute right-4 top-4 z-10 grid size-8 cursor-pointer place-items-center rounded-full border border-border bg-raised/80 text-muted backdrop-blur transition-[background-color,color,transform] hover:bg-hover hover:text-text active:scale-95",children:[t(d,{className:"size-4"}),t("span",{className:"sr-only",children:"Close"})]})]})]}));b.displayName="SheetContent";const C=e.Title,P=e.Description;export{u as Sheet,v as SheetClose,b as SheetContent,P as SheetDescription,C as SheetTitle,x as SheetTrigger};
@@ -0,0 +1,24 @@
1
+ import * as SliderPrimitive from "@radix-ui/react-slider";
2
+ import * as React from "react";
3
+ /**
4
+ * Slider — a value along a range, or a range itself (pass two values).
5
+ *
6
+ * The value rides above the thumb while it is held, hovered or focused, so the
7
+ * number is read where the eye already is; `showValue="always"` keeps it up.
8
+ * `marks` put ticks under the track (with labels when given) for the stops
9
+ * that mean something: 0, the free hour, the cap. `variant="gradient"` fills
10
+ * the range in the brand gradient, for the one slider a screen is about.
11
+ */
12
+ export type SliderVariant = "default" | "gradient";
13
+ export interface SliderProps extends Omit<React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>, "children"> {
14
+ variant?: SliderVariant;
15
+ /** Ticks under the track. */
16
+ marks?: {
17
+ value: number;
18
+ label?: React.ReactNode;
19
+ }[];
20
+ /** The value over the thumb: while used (default), always, or never. */
21
+ showValue?: "active" | "always" | "never";
22
+ format?: (value: number) => string;
23
+ }
24
+ export declare const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as t,jsxs as v}from"react/jsx-runtime";import*as n from"@radix-ui/react-slider";import*as f from"react";import{cn as r}from"../../lib/utils.js";const N=18,P=f.forwardRef(({className:g,variant:h="default",marks:i,showValue:s="active",format:x=p=>p.toLocaleString(),value:u,defaultValue:d,onValueChange:_,min:o=0,max:b=100,...c},y)=>{const[p,w]=f.useState(d??[o]),a=u??p,m=e=>(e-o)/(b-o||1)*100,S=e=>`calc(${m(e)}% + ${N/2*(1-m(e)/50)}px)`,R=i?.some(e=>e.label!==void 0);return v(n.Root,{ref:y,value:u,defaultValue:d,onValueChange:e=>{u===void 0&&w(e),_?.(e)},min:o,max:b,className:r("relative flex w-full touch-none select-none items-center py-2 data-[disabled]:opacity-50",s==="always"&&"mt-7",i&&(R?"mb-6":"mb-2"),g),...c,children:[t(n.Track,{className:"relative h-1.5 w-full grow overflow-hidden rounded-full bg-hover shadow-[inset_0_1px_2px_rgba(5,8,22,.08)]",children:t(n.Range,{className:r("absolute h-full rounded-full",h==="gradient"?"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[0_0_10px_color-mix(in_srgb,var(--brand-2)_45%,transparent)]":"bg-primary")})}),i?.map(e=>{const l=a.length>1?e.value>=a[0]&&e.value<=a[a.length-1]:e.value<=a[0];return v("span",{"aria-hidden":!0,className:"pointer-events-none absolute top-full -translate-x-1/2",style:{left:S(e.value)},children:[t("span",{className:r("mx-auto -mt-1.5 block h-1.5 w-px",l?"bg-primary/50":"bg-border2")}),e.label!==void 0?t("span",{className:"num mt-1 block whitespace-nowrap text-[11px] text-muted",children:e.label}):null]},e.value)}),a.map((e,l)=>t(n.Thumb,{"aria-label":a.length>1?l===0?"Minimum":"Maximum":c["aria-label"],className:r("group/thumb relative block size-[18px] cursor-grab rounded-full border-2 border-primary bg-white outline-none active:cursor-grabbing","shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_0_var(--primary-subtle)] transition-[box-shadow,transform] duration-150","hover:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_6px_var(--primary-subtle)] focus-visible:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_6px_var(--primary-subtle)] active:scale-110"),children:s!=="never"?t("span",{className:r("num pointer-events-none absolute bottom-full left-1/2 mb-2.5 -translate-x-1/2 whitespace-nowrap rounded-[calc(7px*var(--radius-scale))] bg-[var(--ink)] px-2 py-1 text-[11.5px] font-semibold leading-none text-white shadow-elev2","after:absolute after:left-1/2 after:top-full after:-translate-x-1/2 after:border-4 after:border-transparent after:border-t-[var(--ink)]","transition-[opacity,transform] duration-150",s==="always"?"opacity-100":"translate-y-1 opacity-0 group-hover/thumb:translate-y-0 group-hover/thumb:opacity-100 group-focus-visible/thumb:translate-y-0 group-focus-visible/thumb:opacity-100 group-active/thumb:translate-y-0 group-active/thumb:opacity-100"),children:x(e)}):null},l))]})});P.displayName="Slider";export{P as Slider};
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Spinner — work under way with no known end. (With a known end, Progress.)
4
+ *
5
+ * ring — the default: an arc that fades into its tail. Buttons, inline.
6
+ * dots — three dots in turn: "typing", "connecting", a chat waiting.
7
+ * wave — bars rising like the WAVEINNO wave: a whole panel or page loading.
8
+ * It colours with `currentColor` unless `tone="brand"`, so it takes the text
9
+ * colour of a button it sits in. The label is read out, not shown.
10
+ */
11
+ export type SpinnerVariant = "ring" | "dots" | "wave";
12
+ declare const SIZE: {
13
+ readonly xs: 12;
14
+ readonly sm: 16;
15
+ readonly md: 20;
16
+ readonly lg: 28;
17
+ readonly xl: 40;
18
+ };
19
+ export declare function Spinner({ variant, size, tone, label, className, }: {
20
+ variant?: SpinnerVariant;
21
+ size?: keyof typeof SIZE;
22
+ /** `current` follows the text colour; `brand` uses the primary (the gradient, for ring). */
23
+ tone?: "current" | "brand";
24
+ label?: string;
25
+ className?: string;
26
+ }): React.JSX.Element;
27
+ export {};
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as g}from"react/jsx-runtime";import{cn as l}from"../../lib/utils.js";const m={xs:12,sm:16,md:20,lg:28,xl:40};function b({variant:i="ring",size:d="md",tone:s="current",label:o="Loading",className:c}){const n=m[d],p=s==="brand"?"text-primary":void 0;let r;if(i==="ring"){const a=Math.max(2,Math.round(n/9));r=e("span",{className:"block animate-spin rounded-full [animation-duration:.75s]",style:{width:n,height:n,background:s==="brand"?"conic-gradient(from 90deg, transparent 10%, var(--brand-1) 60%, var(--brand-2))":"conic-gradient(from 90deg, transparent 10%, currentColor)",mask:`radial-gradient(farthest-side, transparent calc(100% - ${a+.5}px), #000 calc(100% - ${a}px))`,WebkitMask:`radial-gradient(farthest-side, transparent calc(100% - ${a+.5}px), #000 calc(100% - ${a}px))`}})}else if(i==="dots"){const a=Math.max(3,Math.round(n/4.5));r=e("span",{className:"flex items-center",style:{gap:a*.7,height:n},children:[0,1,2].map(t=>e("span",{className:"wm-dot block rounded-full bg-current",style:{width:a,height:a,animationDelay:`${t*140}ms`}},t))})}else{const a=Math.max(2,Math.round(n/8));r=e("span",{className:"flex items-center",style:{gap:a*.8,height:n},children:[0,1,2,3,4].map(t=>e("span",{className:l("wm-bar block h-full rounded-full",s==="brand"?"bg-[linear-gradient(180deg,var(--brand-2),var(--brand-1))]":"bg-current"),style:{width:a,animationDelay:`${t*90}ms`}},t))})}return g("span",{role:"status",className:l("inline-grid shrink-0 place-items-center",p,c),children:[r,e("span",{className:"sr-only",children:o})]})}export{b as Spinner};
@@ -1 +1 @@
1
- "use client";import{jsx as l,jsxs as g}from"react/jsx-runtime";import*as b from"@radix-ui/react-tabs";import*as r from"react";import{cn as d}from"../../lib/utils.js";const f=r.createContext("underline"),L=b.Root,T={underline:"border-b border-border px-1",pill:"rounded-[11px] border border-border bg-hover p-1",solid:"rounded-[11px] border border-border bg-surface p-1",enclosed:"border-b border-border px-1"},h={underline:"bottom-[-1px] h-0.5 rounded-full bg-primary",pill:"inset-y-1 rounded-[8px] bg-raised shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.08),0_2px_8px_-2px_rgba(5,8,22,.14)]",solid:"inset-y-1 rounded-[8px] bg-[linear-gradient(135deg,#1f45ea,#5b4af5)] shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_4px_12px_-4px_rgba(20,55,211,.55)]",enclosed:""},R=r.forwardRef(({className:i,variant:e="underline",children:a,...p},o)=>{const n=r.useRef(null),[s,v]=r.useState(null);return r.useLayoutEffect(()=>{const t=n.current;if(!t||e==="enclosed")return;const u=()=>{const c=t.querySelector('[role="tab"][data-state="active"]');v(c?{left:c.offsetLeft,width:c.offsetWidth}:null)};u();const x=new MutationObserver(u);x.observe(t,{subtree:!0,attributes:!0,attributeFilter:["data-state"]});const m=new ResizeObserver(u);return m.observe(t),()=>{x.disconnect(),m.disconnect()}},[e]),l(f.Provider,{value:e,children:g(b.List,{ref:t=>{n.current=t,typeof o=="function"?o(t):o&&(o.current=t)},className:d("no-bar relative isolate flex items-center gap-0.5 overflow-x-auto",T[e],i),...p,children:[s&&e!=="enclosed"?l("span",{"aria-hidden":!0,className:d("absolute -z-10 transition-[left,width] duration-300 ease-[cubic-bezier(.3,.7,.2,1)]",h[e],e==="underline"&&"z-0"),style:{left:e==="underline"?s.left+6:s.left,width:e==="underline"?s.width-12:s.width}}):null,a]})})});R.displayName="TabsList";const y={underline:"px-2.5 py-2.5 text-muted hover:text-text data-[state=active]:text-primary",pill:"rounded-[8px] px-3 py-1.5 text-muted hover:text-text data-[state=active]:text-text",solid:"rounded-[8px] px-3.5 py-1.5 text-muted hover:text-text data-[state=active]:text-white",enclosed:"-mb-px rounded-t-[9px] border border-transparent px-3.5 py-2 text-muted hover:bg-hover/60 hover:text-text data-[state=active]:border-border data-[state=active]:border-b-canvas data-[state=active]:bg-canvas data-[state=active]:text-text"},w={underline:"bg-hover text-muted group-data-[state=active]/tab:bg-primary-subtle group-data-[state=active]/tab:text-primary",pill:"bg-raised text-muted group-data-[state=active]/tab:bg-primary-subtle group-data-[state=active]/tab:text-primary",solid:"bg-hover text-muted group-data-[state=active]/tab:bg-white/20 group-data-[state=active]/tab:text-white",enclosed:"bg-hover text-muted"},_=r.forwardRef(({className:i,children:e,count:a,...p},o)=>{const n=r.useContext(f);return l(b.Trigger,{ref:o,className:d("group/tab relative shrink-0 cursor-pointer whitespace-nowrap text-[13px] font-medium transition-colors duration-200 [&_svg]:size-4",y[n],i),...p,children:g("span",{className:"flex items-center gap-1.5",children:[e,typeof a=="number"?l("span",{className:d("num rounded-full px-1.5 text-[10px] leading-4 transition-colors",w[n]),children:a}):null]})})});_.displayName="TabsTrigger";const C=r.forwardRef(({className:i,...e},a)=>l(b.Content,{ref:a,className:d("outline-none data-[state=active]:animate-[wave-in_220ms_var(--ease)]",i),...e}));C.displayName="TabsContent";export{L as Tabs,C as TabsContent,R as TabsList,_ as TabsTrigger};
1
+ "use client";import{jsx as l,jsxs as f}from"react/jsx-runtime";import*as c from"@radix-ui/react-tabs";import*as r from"react";import{cn as d}from"../../lib/utils.js";const v=r.createContext("underline"),L=c.Root,T={underline:"border-b border-border px-1",pill:"rounded-[calc(11px*var(--radius-scale))] border border-border bg-hover p-1",solid:"rounded-[calc(11px*var(--radius-scale))] border border-border bg-surface p-1",enclosed:"border-b border-border px-1"},h={underline:"bottom-[-1px] h-0.5 rounded-full bg-primary",pill:"inset-y-1 rounded-[calc(8px*var(--radius-scale))] bg-raised shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.08),0_2px_8px_-2px_rgba(5,8,22,.14)]",solid:"inset-y-1 rounded-[calc(8px*var(--radius-scale))] bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_4px_12px_-4px_color-mix(in_srgb,var(--brand-1)_55%,transparent)]",enclosed:""},R=r.forwardRef(({className:s,variant:e="underline",children:a,...b},o)=>{const i=r.useRef(null),[n,g]=r.useState(null);return r.useLayoutEffect(()=>{const t=i.current;if(!t||e==="enclosed")return;const p=()=>{const u=t.querySelector('[role="tab"][data-state="active"]');g(u?{left:u.offsetLeft,width:u.offsetWidth}:null)};p();const x=new MutationObserver(p);x.observe(t,{subtree:!0,attributes:!0,attributeFilter:["data-state"]});const m=new ResizeObserver(p);return m.observe(t),()=>{x.disconnect(),m.disconnect()}},[e]),l(v.Provider,{value:e,children:f(c.List,{ref:t=>{i.current=t,typeof o=="function"?o(t):o&&(o.current=t)},className:d("no-bar relative isolate flex items-center gap-0.5 overflow-x-auto",T[e],s),...b,children:[n&&e!=="enclosed"?l("span",{"aria-hidden":!0,className:d("absolute -z-10 transition-[left,width] duration-300 ease-[cubic-bezier(.3,.7,.2,1)]",h[e],e==="underline"&&"z-0"),style:{left:e==="underline"?n.left+6:n.left,width:e==="underline"?n.width-12:n.width}}):null,a]})})});R.displayName="TabsList";const y={underline:"px-2.5 py-2.5 text-muted hover:text-text data-[state=active]:text-primary",pill:"rounded-[calc(8px*var(--radius-scale))] px-3 py-1.5 text-muted hover:text-text data-[state=active]:text-text",solid:"rounded-[calc(8px*var(--radius-scale))] px-3.5 py-1.5 text-muted hover:text-text data-[state=active]:text-white",enclosed:"-mb-px rounded-t-[calc(9px*var(--radius-scale))] border border-transparent px-3.5 py-2 text-muted hover:bg-hover/60 hover:text-text data-[state=active]:border-border data-[state=active]:border-b-canvas data-[state=active]:bg-canvas data-[state=active]:text-text"},w={underline:"bg-hover text-muted group-data-[state=active]/tab:bg-primary-subtle group-data-[state=active]/tab:text-primary",pill:"bg-raised text-muted group-data-[state=active]/tab:bg-primary-subtle group-data-[state=active]/tab:text-primary",solid:"bg-hover text-muted group-data-[state=active]/tab:bg-white/20 group-data-[state=active]/tab:text-white",enclosed:"bg-hover text-muted"},_=r.forwardRef(({className:s,children:e,count:a,...b},o)=>{const i=r.useContext(v);return l(c.Trigger,{ref:o,className:d("group/tab relative shrink-0 cursor-pointer whitespace-nowrap text-[13px] font-medium transition-colors duration-200 [&_svg]:size-4",y[i],s),...b,children:f("span",{className:"flex items-center gap-1.5",children:[e,typeof a=="number"?l("span",{className:d("num rounded-full px-1.5 text-[10px] leading-4 transition-colors",w[i]),children:a}):null]})})});_.displayName="TabsTrigger";const C=r.forwardRef(({className:s,...e},a)=>l(c.Content,{ref:a,className:d("outline-none data-[state=active]:animate-[wave-in_220ms_var(--ease)]",s),...e}));C.displayName="TabsContent";export{L as Tabs,C as TabsContent,R as TabsList,_ as TabsTrigger};
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ import { Toaster as Sonner, toast } from "sonner";
3
+ /**
4
+ * Toaster and toast — a message that comes and goes: saved, sent, exported.
5
+ * (One that must stay until it is dealt with is an Alert.)
6
+ *
7
+ * Put <Toaster /> once near the root (AppShell already has one), then call
8
+ * `toast("Saved")`, `toast.success(…)`, `toast.error(…)`, `toast.promise(…)`
9
+ * from anywhere. The toast is sonner's; the look is WAVEINNO's: a raised card,
10
+ * the tone's icon in a soft tile, and the theme's colours in light and dark.
11
+ */
12
+ export { toast };
13
+ export declare function Toaster({ position, ...props }: React.ComponentProps<typeof Sonner>): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as r}from"react/jsx-runtime";import{CircleAlert as o,CircleCheck as n,Info as s,LoaderCircle as i,TriangleAlert as c}from"lucide-react";import{Toaster as d,toast as p}from"sonner";const e=(t,a)=>r("span",{className:"grid size-7 place-items-center rounded-[calc(8px*var(--radius-scale))] [&_svg]:size-4",style:{color:`var(--${t})`,background:`var(--${t}-subtle)`},children:a});function b({position:t="bottom-right",...a}){return r(d,{position:t,gap:10,icons:{success:e("success",r(n,{})),error:e("danger",r(o,{})),warning:e("warning",r(c,{})),info:e("info",r(s,{})),loading:e("primary",r(i,{className:"animate-spin"}))},toastOptions:{unstyled:!0,classNames:{toast:"group flex w-[356px] max-w-[calc(100vw-32px)] items-center gap-3 rounded-[calc(14px*var(--radius-scale))] border border-border bg-raised p-3 pr-4 text-[13px] text-text shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.06),0_16px_40px_-12px_rgba(5,8,22,.28)]",icon:"!m-0 !size-7 shrink-0 [&>svg]:hidden [&>span]:!grid [&>span]:!size-7 [&>span]:place-items-center",content:"min-w-0 flex-1",title:"font-semibold leading-[18px] text-text",description:"mt-0.5 text-[12.5px] leading-[17px] text-muted",actionButton:"ml-auto shrink-0 cursor-pointer self-center rounded-[calc(8px*var(--radius-scale))] bg-primary px-2.5 py-1.5 text-[12px] font-medium text-white transition-colors hover:bg-primary-hover",cancelButton:"shrink-0 cursor-pointer self-center rounded-[calc(8px*var(--radius-scale))] border border-border px-2.5 py-1.5 text-[12px] font-medium text-body transition-colors hover:bg-hover",closeButton:"!border-border !bg-raised !text-muted hover:!text-text",success:"bg-[image:radial-gradient(130%_140%_at_0%_0%,var(--success-subtle),transparent_55%)] border-[color-mix(in_srgb,var(--success)_22%,var(--border))]!",error:"bg-[image:radial-gradient(130%_140%_at_0%_0%,var(--danger-subtle),transparent_55%)] border-[color-mix(in_srgb,var(--danger)_22%,var(--border))]!",warning:"bg-[image:radial-gradient(130%_140%_at_0%_0%,var(--warning-subtle),transparent_55%)] border-[color-mix(in_srgb,var(--warning)_22%,var(--border))]!",info:"bg-[image:radial-gradient(130%_140%_at_0%_0%,var(--info-subtle),transparent_55%)] border-[color-mix(in_srgb,var(--info)_22%,var(--border))]!"}},...a})}export{b as Toaster,p as toast};
@@ -2,3 +2,4 @@
2
2
  export * from "./use-hotkey";
3
3
  export * from "./use-media-query";
4
4
  export * from "./use-mounted";
5
+ export * from "./use-router";
@@ -1 +1 @@
1
- export*from"./use-hotkey.js";export*from"./use-media-query.js";export*from"./use-mounted.js";
1
+ export*from"./use-hotkey.js";export*from"./use-media-query.js";export*from"./use-mounted.js";export*from"./use-router.js";
@@ -0,0 +1,41 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Routing without tying the package to one router.
4
+ *
5
+ * The shell and a few patterns need three things from the app's router: a
6
+ * link, the current path, and a way to navigate. They ask this adapter, and
7
+ * the app says which router answers:
8
+ *
9
+ * Next.js <NextRouterProvider> from "@waveinno/ui/next"
10
+ * React Router <RouterProvider adapter={{ Link, usePathname, useNavigate }}>
11
+ * nothing plain <a> links and full page loads, which work anywhere
12
+ *
13
+ * so the same components run in Next.js, Vite or any React app.
14
+ */
15
+ export type RouterLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> & {
16
+ href: string;
17
+ ref?: React.Ref<HTMLAnchorElement>;
18
+ };
19
+ export interface RouterAdapter {
20
+ /** Renders a link: gets `href`, `className`, `children` and anchor props. */
21
+ Link: React.ComponentType<RouterLinkProps>;
22
+ /** A hook returning the current path (Next's usePathname, React Router's useLocation().pathname). */
23
+ usePathname: () => string;
24
+ /** A hook returning a navigate function (Next's useRouter().push, React Router's useNavigate()). */
25
+ useNavigate: () => (href: string) => void;
26
+ }
27
+ /** The adapter used when none is provided: plain links, the browser's own location. */
28
+ export declare const browserRouter: RouterAdapter;
29
+ /** Tell the package which router the app uses. Put it above AppShell (or anything that links). */
30
+ export declare function RouterProvider({ adapter, children }: {
31
+ adapter: RouterAdapter;
32
+ children: React.ReactNode;
33
+ }): React.JSX.Element;
34
+ /** The app's router, through the adapter: `{ Link, pathname, navigate }`. */
35
+ export declare function useRouterAdapter(): {
36
+ Link: React.ComponentType<RouterLinkProps>;
37
+ pathname: string;
38
+ navigate: (href: string) => void;
39
+ };
40
+ /** A link through the app's router: Next's Link in Next.js, React Router's in a Vite app, <a> otherwise. */
41
+ export declare function RouterLink(props: RouterLinkProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as o}from"react/jsx-runtime";import*as r from"react";const i=e=>(window.addEventListener("popstate",e),()=>window.removeEventListener("popstate",e));function s(e){return o("a",{...e})}const u={Link:s,usePathname:()=>r.useSyncExternalStore(i,()=>window.location.pathname,()=>"/"),useNavigate:()=>r.useCallback(e=>window.location.assign(e),[])},n=r.createContext(u);function c({adapter:e,children:t}){return o(n.Provider,{value:e,children:t})}function p(){const e=r.useContext(n),t=e.usePathname(),a=e.useNavigate();return{Link:e.Link,pathname:t,navigate:a}}function R(e){const{Link:t}=r.useContext(n);return o(t,{...e})}export{R as RouterLink,c as RouterProvider,u as browserRouter,p as useRouterAdapter};
@@ -3,3 +3,4 @@ export * from "./currency";
3
3
  export * from "./format";
4
4
  export * from "./utils";
5
5
  export * from "./boot-script";
6
+ export * from "./theme";
package/dist/lib/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./currency.js";export*from"./format.js";export*from"./utils.js";export*from"./boot-script.js";
1
+ export*from"./currency.js";export*from"./format.js";export*from"./utils.js";export*from"./boot-script.js";export*from"./theme.js";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * createTheme — a whole palette from one brand colour.
3
+ *
4
+ * Every component reads the semantic tokens in styles.css (`--primary`,
5
+ * `--brand-1`, `--r-card`, …), so a theme is nothing but new values for them.
6
+ * Give it the brand colour and it derives the rest in OKLCH, where "lighter"
7
+ * and "darker" look evenly lighter and darker across hues: the hover step, the
8
+ * soft tint, the brand gradient, the ink for dark panels, and a dark-mode set
9
+ * that stays readable on a near-black canvas. Radius and fonts ride along.
10
+ *
11
+ * const { css } = createTheme({ primary: "#0f9d7a", radius: "lg", fontSans: "Manrope" });
12
+ * // paste `css` after @import "@waveinno/ui/styles.css", or inject it at runtime.
13
+ *
14
+ * Framework-free: the docs' theme builder and a product's build script use the same function.
15
+ */
16
+ export type ThemeRadius = "none" | "sm" | "md" | "lg" | "xl";
17
+ export interface ThemeOptions {
18
+ /** The brand colour: buttons, links, the chosen item. Hex, e.g. "#4f46e5". */
19
+ primary: string;
20
+ /** The two stops of the brand gradient. Default: drawn from `primary`. */
21
+ brand?: [string, string];
22
+ /** A second colour for charts and highlights. Default: `primary` turned a little round the wheel. */
23
+ accent?: string;
24
+ /** The deep colour of dark panels and value bubbles. Default: `primary` at night. */
25
+ ink?: string;
26
+ radius?: ThemeRadius;
27
+ /** Body font family name, e.g. "Manrope". Bangla falls back to Noto Sans Bengali. */
28
+ fontSans?: string;
29
+ /** Headings and big numbers. */
30
+ fontDisplay?: string;
31
+ fontMono?: string;
32
+ }
33
+ export interface CreatedTheme {
34
+ light: Record<string, string>;
35
+ dark: Record<string, string>;
36
+ /** `:root { … }` and `[data-theme="dark"] { … }`, ready to paste. */
37
+ css: string;
38
+ }
39
+ type Lch = {
40
+ l: number;
41
+ c: number;
42
+ h: number;
43
+ };
44
+ export declare function hexToOklch(hex: string): Lch;
45
+ /** Back to hex, lowering chroma (never hue or lightness) until it fits in sRGB. */
46
+ export declare function oklchToHex(lch: Lch): string;
47
+ export declare function createTheme(options: ThemeOptions): CreatedTheme;
48
+ export {};
@@ -0,0 +1,7 @@
1
+ const j=t=>t<=.04045?t/12.92:((t+.055)/1.055)**2.4,I=t=>t<=.0031308?12.92*t:1.055*t**.4166666666666667-.055;function y(t){let r=t.trim().replace(/^#/,"");r.length===3&&(r=[...r].map(e=>e+e).join(""));const n=parseInt(r.slice(0,6),16);if(Number.isNaN(n))throw new Error(`createTheme: "${t}" is not a hex colour`);return[n>>16&255,n>>8&255,n&255].map(e=>e/255)}function f(t){const[r,n,e]=y(t).map(j),i=Math.cbrt(.4122214708*r+.5363325363*n+.0514459929*e),a=Math.cbrt(.2119034982*r+.6806995451*n+.1073969566*e),c=Math.cbrt(.0883024619*r+.2817188376*n+.6299787005*e),m=.2104542553*i+.793617785*a-.0040720468*c,o=1.9779984951*i-2.428592205*a+.4505937099*c,l=.0259040371*i+.7827717662*a-.808675766*c;return{l:m,c:Math.hypot(o,l),h:(Math.atan2(l,o)*180/Math.PI+360)%360}}function M({l:t,c:r,h:n}){const e=r*Math.cos(n*Math.PI/180),i=r*Math.sin(n*Math.PI/180),a=(t+.3963377774*e+.2158037573*i)**3,c=(t-.1055613458*e-.0638541728*i)**3,m=(t-.0894841775*e-1.291485548*i)**3;return[4.0767416621*a-3.3077115913*c+.2309699292*m,-1.2684380046*a+2.6097574011*c-.3413193965*m,-.0041960863*a-.7034186147*c+1.707614701*m]}const k=t=>t.every(r=>r>=-5e-4&&r<=1.0005);function s(t){const r=Math.min(1,Math.max(0,t.l));let n=0,e=Math.max(0,t.c);if(!k(M({l:r,c:e,h:t.h}))){for(let a=0;a<24;a++){const c=(n+e)/2;k(M({l:r,c,h:t.h}))?n=c:e=c}e=n}return`#${M({l:r,c:e,h:t.h}).map(a=>Math.round(Math.min(1,Math.max(0,I(Math.min(1,Math.max(0,a)))))*255)).map(a=>a.toString(16).padStart(2,"0")).join("")}`}const b=(t,r)=>({l:t.l+(r.l??0),c:Math.max(0,t.c+(r.c??0)),h:(t.h+(r.h??0)+360)%360}),h=(t,r)=>({...t,...r}),d=(t,r)=>{const[n,e,i]=y(t).map(a=>Math.round(a*255));return`rgba(${n}, ${e}, ${i}, ${r})`},N={none:0,sm:.75,md:1,lg:1.4,xl:1.8},T='"Noto Sans Bengali"',p=t=>/^[\w-]+$/.test(t)?t:`"${t.replace(/"/g,"")}"`;function P(t){const r=f(t.primary),n=r.l>.62?h(r,{l:.58}):r.l<.32?h(r,{l:.38}):r,e=s(n),i=t.brand?.[0]??s(b(n,{l:-.04,c:.03,h:-10})),a=t.brand?.[1]??s(b(n,{l:.08,c:.02,h:28})),c=t.accent??s(b(n,{l:.02,h:32})),m=t.ink??s(h(n,{l:.2,c:Math.min(.09,n.c*.5)})),o={"--primary":e,"--primary-hover":s(b(n,{l:-.07})),"--primary-subtle":s(h(n,{l:.96,c:Math.min(.03,n.c*.25)})),"--primary-muted":s(h(n,{l:.87,c:Math.min(.08,n.c*.45)})),"--accent":c,"--info":e,"--info-subtle":s(h(n,{l:.96,c:Math.min(.03,n.c*.25)})),"--selected":s(h(n,{l:.955,c:Math.min(.035,n.c*.3)})),"--brand-1":i,"--brand-2":a,"--ink":m},l=h(n,{l:Math.max(.66,n.l+.1)}),g=s(l),x={"--primary":g,"--primary-hover":s(b(l,{l:.07})),"--primary-subtle":d(g,.16),"--primary-muted":d(s(b(l,{l:.12})),.38),"--accent":s(h(f(c),{l:Math.max(.7,f(c).l+.1)})),"--info":g,"--info-subtle":d(g,.14),"--selected":d(g,.16)};if(t.radius){const u=N[t.radius];o["--radius-scale"]=String(u),o["--r-ctl"]=`${Math.round(8*u)}px`,o["--r-card"]=`${Math.round(10*u)}px`,o["--r-dlg"]=`${Math.round(14*u)}px`}t.fontSans&&(o["--font-inter"]=`${p(t.fontSans)}, ${T}`),t.fontDisplay&&(o["--font-jakarta"]=`${p(t.fontDisplay)}, ${T}`),t.fontMono&&(o["--font-jetbrains"]=p(t.fontMono));const $=(u,L)=>`${u} {
2
+ ${Object.entries(L).map(([R,S])=>` ${R}: ${S};`).join(`
3
+ `)}
4
+ }`;return{light:o,dark:x,css:`${$(":root",o)}
5
+
6
+ ${$('[data-theme="dark"]',x)}
7
+ `}}export{P as createTheme,f as hexToOklch,s as oklchToHex};
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ import { type RouterAdapter } from "../hooks/use-router";
3
+ export declare const nextRouter: RouterAdapter;
4
+ export declare function NextRouterProvider({ children }: {
5
+ children: React.ReactNode;
6
+ }): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as p}from"react/jsx-runtime";import t from"next/link";import{usePathname as o,useRouter as u}from"next/navigation";import*as a from"react";import{RouterProvider as n}from"../hooks/use-router.js";const i={Link:t,usePathname:()=>o()??"/",useNavigate:()=>{const e=u();return a.useCallback(r=>e.push(r),[e])}};function m({children:e}){return p(n,{adapter:i,children:e})}export{m as NextRouterProvider,i as nextRouter};
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as u}from"react/jsx-runtime";import{useRouter as g}from"next/navigation";import*as i from"react";import{Toaster as v}from"sonner";import{TooltipProvider as R}from"../components/ui/tooltip.js";import{useHotkey as x,useNumberHotkeys as N}from"../hooks/use-hotkey.js";import{useApp as c}from"../store/app-store.js";import{useUi as f}from"../store/ui-store.js";import{CommandPalette as S}from"./command-palette.js";import{ShellProvider as w}from"./config.js";import{IconRail as P}from"./icon-rail.js";import{MobileNav as k}from"./mobile-nav.js";import{ModuleSidebar as A}from"./module-sidebar.js";import{RecordDrawer as C}from"./record-drawer.js";import{Topbar as D}from"./topbar.js";import{useActive as F}from"./use-active.js";function V({config:t,children:r}){return e(w,{config:t,children:e(T,{children:r})})}function T({children:t}){const r=f(o=>o.hydrate),a=c(o=>o.hydrate),m=c(o=>o.syncFromRoute),h=f(o=>o.togglePanel),l=g(),{cfg:p,pathname:y,mod:s,rail:b}=F();i.useEffect(()=>{r(),a(p.apps.map(o=>o.id))},[r,a,p.apps]),i.useEffect(()=>{m(s.app)},[s.app,m]),x({key:"b",mod:!0},h);const n=b.order;return N(i.useCallback(o=>{const d=n[o];d&&l.push(d.href)},[n,l])),u(R,{delayDuration:400,skipDelayDuration:200,children:[u("div",{className:"shell-grid overflow-hidden",children:[e(P,{}),e(A,{}),e(D,{}),e("main",{id:"main",className:"col-start-3 col-end-4 row-start-2 overflow-y-auto px-4 pb-16 pt-5 sm:px-6",children:e("div",{className:"page-in mx-auto w-full max-w-[1600px]",children:t},y)})]}),e(C,{}),e(S,{}),e(k,{}),e(v,{position:"bottom-right",toastOptions:{className:"!rounded-ctl !border !border-border !bg-raised !text-text !shadow-elev3 !text-[13px]"}})]})}export{V as AppShell};
1
+ "use client";import{jsx as e,jsxs as u}from"react/jsx-runtime";import{useRouterAdapter as g}from"../hooks/use-router.js";import*as a from"react";import{Toaster as R}from"../components/ui/toast.js";import{TooltipProvider as b}from"../components/ui/tooltip.js";import{useHotkey as S,useNumberHotkeys as N}from"../hooks/use-hotkey.js";import{useApp as d}from"../store/app-store.js";import{useUi as f}from"../store/ui-store.js";import{CommandPalette as P}from"./command-palette.js";import{ShellProvider as k}from"./config.js";import{IconRail as w}from"./icon-rail.js";import{MobileNav as x}from"./mobile-nav.js";import{ModuleSidebar as A}from"./module-sidebar.js";import{RecordDrawer as C}from"./record-drawer.js";import{Topbar as D}from"./topbar.js";import{useActive as F}from"./use-active.js";function V({config:t,children:r}){return e(k,{config:t,children:e(T,{children:r})})}function T({children:t}){const r=f(o=>o.hydrate),i=d(o=>o.hydrate),m=d(o=>o.syncFromRoute),h=f(o=>o.togglePanel),{navigate:l}=g(),{cfg:p,pathname:y,mod:n,rail:v}=F();a.useEffect(()=>{r(),i(p.apps.map(o=>o.id))},[r,i,p.apps]),a.useEffect(()=>{m(n.app)},[n.app,m]),S({key:"b",mod:!0},h);const s=v.order;return N(a.useCallback(o=>{const c=s[o];c&&l(c.href)},[s,l])),u(b,{delayDuration:400,skipDelayDuration:200,children:[u("div",{className:"shell-grid overflow-hidden",children:[e(w,{}),e(A,{}),e(D,{}),e("main",{id:"main",className:"col-start-3 col-end-4 row-start-2 overflow-y-auto px-4 pb-16 pt-5 sm:px-6",children:e("div",{className:"page-in mx-auto w-full max-w-[1600px]",children:t},y)})]}),e(C,{}),e(P,{}),e(x,{}),e(R,{})]})}export{V as AppShell};
@@ -1 +1 @@
1
- "use client";import{Fragment as _,jsx as t,jsxs as s}from"react/jsx-runtime";import{ArrowRight as E,Check as I,CornerDownLeft as R}from"lucide-react";import{useRouter as S}from"next/navigation";import*as f from"react";import{WaveWordmark as T}from"../components/brand/logo.js";import{StatusBadge as K}from"../components/ui/badge.js";import{Button as B}from"../components/ui/button.js";import{Dialog as O,DialogContent as L,DialogDescription as H,DialogTitle as U}from"../components/ui/dialog.js";import{Tooltip as W}from"../components/ui/tooltip.js";import{useHotkey as q}from"../hooks/use-hotkey.js";import{cn as y}from"../lib/utils.js";import{useApp as F}from"../store/app-store.js";import{useUi as k}from"../store/ui-store.js";import{useActive as P}from"./use-active.js";function ae(){const i=k(e=>e.launcherOpen),l=k(e=>e.setLauncher),w=F(e=>e.setApp),{cfg:p,app:n}=P(),D=S(),r=p.apps,x=p.isEntitled??(()=>!0),c=Math.max(0,r.findIndex(e=>e.id===n.id)),[m,d]=f.useState(c),h=f.useRef(null);q({key:"k",mod:!0,shift:!0},()=>l(!i)),f.useEffect(()=>{i&&d(c)},[i,c]);const o=r[m]??r[c],b=p.modules.filter(e=>e.app===o.id&&x(e)),v=e=>{const a=r[e];a&&(w(a.id),l(!1),D.push(a.href))},A=e=>{e.key==="ArrowDown"?(e.preventDefault(),d(a=>Math.min(a+1,r.length-1))):e.key==="ArrowUp"?(e.preventDefault(),d(a=>Math.max(a-1,0))):e.key==="Enter"&&(e.preventDefault(),v(m))},z=n.icon,C=o.icon;return s(_,{children:[t(W,{label:"Switch app",shortcut:"\u2318\u21E7K",children:s(B,{variant:"secondary",size:"sm",onClick:()=>l(!0),className:"h-8 shrink-0 rounded-full pl-1.5","aria-label":`App: ${n.name}. Switch app`,children:[t("span",{className:"grid size-5 shrink-0 place-items-center rounded-full text-white",style:{background:n.tint},"aria-hidden":!0,children:t(z,{className:"size-3"})}),t("span",{className:"hidden max-w-[110px] truncate md:inline",children:n.name})]})}),t(O,{open:i,onOpenChange:l,children:s(L,{variant:"center",width:"max-w-[720px]",hideClose:!0,className:"overflow-hidden p-0",onKeyDown:A,onOpenAutoFocus:e=>{e.preventDefault(),h.current?.focus()},children:[t(U,{className:"sr-only",children:"Switch app"}),t(H,{className:"sr-only",children:"Choose which app to open. The rail carries that app\u2019s modules."}),s("div",{className:"grid h-[60dvh] max-h-[400px] grid-cols-1 md:h-[400px] md:grid-cols-[260px_minmax(0,1fr)]",children:[s("div",{className:"flex min-h-0 flex-col border-border bg-surface md:border-r",children:[t("div",{className:"shrink-0 border-b border-border px-4 pb-3 pt-3.5",children:t(T,{size:"sm",suffix:"Apps you can operate"})}),t("ul",{className:"min-h-0 flex-1 overflow-y-auto p-1.5 pb-3",children:r.map((e,a)=>{const M=e.icon,u=e.id===n.id,g=a===m;return t("li",{children:s("button",{type:"button",ref:u?h:void 0,onMouseMove:()=>d(a),onClick:()=>v(a),className:y("flex w-full cursor-pointer items-center gap-2.5 rounded-ctl px-2.5 py-2 text-left transition-colors",g?"bg-raised shadow-elev2":"hover:bg-hover"),children:[t("span",{className:"grid size-7 shrink-0 place-items-center rounded-[7px] text-white",style:{background:e.tint},"aria-hidden":!0,children:t(M,{className:"size-3.5"})}),s("span",{className:"min-w-0 flex-1",children:[t("span",{className:y("block truncate text-[13px]",u?"font-semibold text-primary":"text-text"),children:e.name}),s("span",{className:"num block text-[11px] text-muted",children:[p.modules.filter(N=>N.app===e.id&&x(N)).length," modules"]})]}),u?t(I,{className:"size-3.5 shrink-0 text-primary"}):g?t(E,{className:"size-3.5 shrink-0 text-muted"}):null]})},e.id)})})]}),s("div",{className:"hidden min-h-0 flex-col md:flex",children:[s("div",{className:"flex shrink-0 items-start gap-3 border-b border-border px-5 py-4",children:[t("span",{className:"grid size-9 shrink-0 place-items-center rounded-ctl text-white",style:{background:o.tint},"aria-hidden":!0,children:t(C,{className:"size-4"})}),s("div",{className:"min-w-0 flex-1",children:[t("h2",{className:"disp text-[15px] font-semibold",children:o.name}),t("p",{className:"mt-0.5 text-xs text-muted",children:o.tagline})]}),o.status?t(K,{label:o.status.label,tone:o.status.tone}):null]}),s("div",{className:"min-h-0 flex-1 overflow-y-auto px-5 py-4",children:[s("div",{className:"ov mb-2.5",children:[b.length," modules"]}),t("ul",{className:"grid grid-cols-1 gap-x-4 gap-y-0.5 sm:grid-cols-2",children:b.map(e=>{const a=e.icon;return s("li",{className:"flex items-center gap-2.5 rounded-ctl px-1.5 py-1.5",children:[t(a,{className:"size-3.5 shrink-0 text-body"}),t("span",{className:"min-w-0 flex-1 truncate text-[13px] text-text",children:e.title})]},e.key)})})]})]})]}),s("div",{className:"flex items-center gap-4 border-t border-border bg-surface px-4 py-2 text-[11px] text-muted",children:[s("span",{className:"flex items-center gap-1",children:[t("kbd",{className:"rounded border border-border2 px-1",children:"\u2191"}),t("kbd",{className:"rounded border border-border2 px-1",children:"\u2193"})," navigate"]}),s("span",{className:"flex items-center gap-1",children:[t(R,{className:"size-3"})," open"]}),t("span",{className:"ml-auto hidden sm:inline",children:"Every screen stays in \u2318K"})]})]})})]})}export{ae as AppSwitcher};
1
+ "use client";import{Fragment as _,jsx as t,jsxs as s}from"react/jsx-runtime";import{ArrowRight as E,Check as I,CornerDownLeft as R}from"lucide-react";import{useRouterAdapter as S}from"../hooks/use-router.js";import*as f from"react";import{WaveWordmark as T}from"../components/brand/logo.js";import{StatusBadge as K}from"../components/ui/badge.js";import{Button as B}from"../components/ui/button.js";import{Dialog as O,DialogContent as L,DialogDescription as H,DialogTitle as U}from"../components/ui/dialog.js";import{Tooltip as W}from"../components/ui/tooltip.js";import{useHotkey as q}from"../hooks/use-hotkey.js";import{cn as y}from"../lib/utils.js";import{useApp as F}from"../store/app-store.js";import{useUi as k}from"../store/ui-store.js";import{useActive as P}from"./use-active.js";function ae(){const i=k(e=>e.launcherOpen),l=k(e=>e.setLauncher),w=F(e=>e.setApp),{cfg:p,app:o}=P(),{navigate:D}=S(),r=p.apps,x=p.isEntitled??(()=>!0),c=Math.max(0,r.findIndex(e=>e.id===o.id)),[m,d]=f.useState(c),h=f.useRef(null);q({key:"k",mod:!0,shift:!0},()=>l(!i)),f.useEffect(()=>{i&&d(c)},[i,c]);const n=r[m]??r[c],b=p.modules.filter(e=>e.app===n.id&&x(e)),v=e=>{const a=r[e];a&&(w(a.id),l(!1),D(a.href))},A=e=>{e.key==="ArrowDown"?(e.preventDefault(),d(a=>Math.min(a+1,r.length-1))):e.key==="ArrowUp"?(e.preventDefault(),d(a=>Math.max(a-1,0))):e.key==="Enter"&&(e.preventDefault(),v(m))},z=o.icon,C=n.icon;return s(_,{children:[t(W,{label:"Switch app",shortcut:"\u2318\u21E7K",children:s(B,{variant:"secondary",size:"sm",onClick:()=>l(!0),className:"h-8 shrink-0 rounded-full pl-1.5","aria-label":`App: ${o.name}. Switch app`,children:[t("span",{className:"grid size-5 shrink-0 place-items-center rounded-full text-white",style:{background:o.tint},"aria-hidden":!0,children:t(z,{className:"size-3"})}),t("span",{className:"hidden max-w-[110px] truncate md:inline",children:o.name})]})}),t(O,{open:i,onOpenChange:l,children:s(L,{variant:"center",width:"max-w-[720px]",hideClose:!0,className:"overflow-hidden p-0",onKeyDown:A,onOpenAutoFocus:e=>{e.preventDefault(),h.current?.focus()},children:[t(U,{className:"sr-only",children:"Switch app"}),t(H,{className:"sr-only",children:"Choose which app to open. The rail carries that app\u2019s modules."}),s("div",{className:"grid h-[60dvh] max-h-[400px] grid-cols-1 md:h-[400px] md:grid-cols-[260px_minmax(0,1fr)]",children:[s("div",{className:"flex min-h-0 flex-col border-border bg-surface md:border-r",children:[t("div",{className:"shrink-0 border-b border-border px-4 pb-3 pt-3.5",children:t(T,{size:"sm",suffix:"Apps you can operate"})}),t("ul",{className:"min-h-0 flex-1 overflow-y-auto p-1.5 pb-3",children:r.map((e,a)=>{const M=e.icon,u=e.id===o.id,g=a===m;return t("li",{children:s("button",{type:"button",ref:u?h:void 0,onMouseMove:()=>d(a),onClick:()=>v(a),className:y("flex w-full cursor-pointer items-center gap-2.5 rounded-ctl px-2.5 py-2 text-left transition-colors",g?"bg-raised shadow-elev2":"hover:bg-hover"),children:[t("span",{className:"grid size-7 shrink-0 place-items-center rounded-[calc(7px*var(--radius-scale))] text-white",style:{background:e.tint},"aria-hidden":!0,children:t(M,{className:"size-3.5"})}),s("span",{className:"min-w-0 flex-1",children:[t("span",{className:y("block truncate text-[13px]",u?"font-semibold text-primary":"text-text"),children:e.name}),s("span",{className:"num block text-[11px] text-muted",children:[p.modules.filter(N=>N.app===e.id&&x(N)).length," modules"]})]}),u?t(I,{className:"size-3.5 shrink-0 text-primary"}):g?t(E,{className:"size-3.5 shrink-0 text-muted"}):null]})},e.id)})})]}),s("div",{className:"hidden min-h-0 flex-col md:flex",children:[s("div",{className:"flex shrink-0 items-start gap-3 border-b border-border px-5 py-4",children:[t("span",{className:"grid size-9 shrink-0 place-items-center rounded-ctl text-white",style:{background:n.tint},"aria-hidden":!0,children:t(C,{className:"size-4"})}),s("div",{className:"min-w-0 flex-1",children:[t("h2",{className:"disp text-[15px] font-semibold",children:n.name}),t("p",{className:"mt-0.5 text-xs text-muted",children:n.tagline})]}),n.status?t(K,{label:n.status.label,tone:n.status.tone}):null]}),s("div",{className:"min-h-0 flex-1 overflow-y-auto px-5 py-4",children:[s("div",{className:"ov mb-2.5",children:[b.length," modules"]}),t("ul",{className:"grid grid-cols-1 gap-x-4 gap-y-0.5 sm:grid-cols-2",children:b.map(e=>{const a=e.icon;return s("li",{className:"flex items-center gap-2.5 rounded-ctl px-1.5 py-1.5",children:[t(a,{className:"size-3.5 shrink-0 text-body"}),t("span",{className:"min-w-0 flex-1 truncate text-[13px] text-text",children:e.title})]},e.key)})})]})]})]}),s("div",{className:"flex items-center gap-4 border-t border-border bg-surface px-4 py-2 text-[11px] text-muted",children:[s("span",{className:"flex items-center gap-1",children:[t("kbd",{className:"rounded border border-border2 px-1",children:"\u2191"}),t("kbd",{className:"rounded border border-border2 px-1",children:"\u2193"})," navigate"]}),s("span",{className:"flex items-center gap-1",children:[t(R,{className:"size-3"})," open"]}),t("span",{className:"ml-auto hidden sm:inline",children:"Every screen stays in \u2318K"})]})]})})]})}export{ae as AppSwitcher};
@@ -1 +1 @@
1
- "use client";import{jsx as o,jsxs as a}from"react/jsx-runtime";import{CornerDownLeft as M,Moon as E,Search as I,Sparkles as R,Sun as A}from"lucide-react";import{useRouter as L}from"next/navigation";import*as s from"react";import{Dialog as T,DialogContent as O,DialogTitle as z}from"../components/ui/dialog.js";import{useHotkey as C}from"../hooks/use-hotkey.js";import{cn as D}from"../lib/utils.js";import{useUi as h}from"../store/ui-store.js";import{useShell as $}from"./config.js";function Q(){const l=$(),i=h(e=>e.paletteOpen),c=h(e=>e.setPalette),g=h(e=>e.toggleTheme),x=h(e=>e.theme),k=L(),[d,v]=s.useState(""),[u,m]=s.useState(0),y=s.useRef(null);C({key:"k",mod:!0},()=>c(!i)),C({key:"/"},()=>c(!0));const b=s.useMemo(()=>{const e=[...l.commands??[]];e.push({id:"act-theme",label:x==="dark"?"Switch to light theme":"Switch to dark theme",group:"Actions",icon:x==="dark"?A:E,run:g});const n=l.isEntitled??(()=>!0);for(const t of l.modules.filter(n)){e.push({id:`mod-${t.key}`,label:t.title,hint:t.description,group:"Modules",icon:t.icon,href:t.href});for(const r of t.nav)r.kind==="item"&&e.push({id:`scr-${t.key}-${r.href}`,label:r.label,hint:t.title,group:"Screens",icon:t.icon,href:r.href})}return e},[l.commands,l.modules,l.isEntitled,x,g]),p=s.useMemo(()=>{const e=d.trim().toLowerCase(),n=e?b.filter(r=>r.label.toLowerCase().includes(e)||r.hint?.toLowerCase().includes(e)):b.filter(r=>r.group!=="Screens"),t=["Actions","AI","Screens","Modules","Records"];return n.slice().sort((r,f)=>t.indexOf(r.group)-t.indexOf(f.group)).slice(0,40)},[b,d]);s.useEffect(()=>m(0),[d]),s.useEffect(()=>{i||v("")},[i]);const N=s.useCallback(e=>{e&&(c(!1),e.run?e.run():e.href&&k.push(e.href))},[k,c]),S=e=>{e.key==="ArrowDown"?(e.preventDefault(),m(n=>Math.min(n+1,p.length-1))):e.key==="ArrowUp"?(e.preventDefault(),m(n=>Math.max(n-1,0))):e.key==="Enter"&&(e.preventDefault(),N(p[u]))};s.useEffect(()=>{y.current?.querySelector(`[data-index="${u}"]`)?.scrollIntoView({block:"nearest"})},[u]);let w="";return o(T,{open:i,onOpenChange:c,children:a(O,{variant:"center",width:"max-w-[580px]",hideClose:!0,className:"top-[14vh] translate-y-0 overflow-hidden p-0 shadow-elev3",onKeyDown:S,children:[o(z,{className:"sr-only",children:"Command palette"}),a("div",{className:"flex items-center gap-2.5 border-b border-border px-4",children:[o(I,{className:"size-4 shrink-0 text-muted"}),o("input",{autoFocus:!0,value:d,onChange:e=>v(e.target.value),placeholder:"Search screens, run an agent, or ask\u2026",className:"h-12 flex-1 bg-transparent text-sm text-text outline-none placeholder:text-placeholder"}),o("kbd",{className:"rounded border border-border2 px-1.5 text-[11px] text-muted",children:"esc"})]}),o("div",{ref:y,className:"max-h-[54vh] overflow-y-auto p-1.5",children:p.length===0?a("p",{className:"px-3 py-8 text-center text-[13px] text-muted",children:["Nothing matches \u201C",d,"\u201D."]}):p.map((e,n)=>{const t=e.icon,r=e.group!==w?e.group:null;w=e.group;const f=n===u;return a(s.Fragment,{children:[r?o("div",{className:"ov px-2.5 pb-1 pt-2.5",children:r}):null,a("button",{type:"button","data-index":n,onMouseMove:()=>m(n),onClick:()=>N(e),className:D("flex w-full cursor-pointer items-center gap-2.5 rounded-ctl px-2.5 py-2 text-left text-[13px] transition-colors",f?"bg-hover text-text":"text-body"),children:[t?o(t,{className:D("size-4 shrink-0",e.group==="AI"?"text-accent":"text-muted")}):null,o("span",{className:"flex-1 truncate",children:e.label}),e.hint?o("span",{className:"hidden max-w-[45%] truncate text-[11px] text-muted sm:inline",children:e.hint}):null,f?o(M,{className:"size-3.5 shrink-0 text-muted"}):null]})]},e.id)})}),a("div",{className:"flex items-center gap-4 border-t border-border bg-surface px-4 py-2 text-[11px] text-muted",children:[a("span",{className:"flex items-center gap-1",children:[o("kbd",{className:"rounded border border-border2 px-1",children:"\u2191"}),o("kbd",{className:"rounded border border-border2 px-1",children:"\u2193"})," navigate"]}),a("span",{className:"flex items-center gap-1",children:[o("kbd",{className:"rounded border border-border2 px-1",children:"\u21B5"})," open"]}),a("span",{className:"ml-auto flex items-center gap-1",children:[o(R,{className:"size-3 text-accent"})," agents run with a credit estimate first"]})]})]})})}export{Q as CommandPalette};
1
+ "use client";import{jsx as o,jsxs as a}from"react/jsx-runtime";import{CornerDownLeft as M,Moon as E,Search as I,Sparkles as A,Sun as R}from"lucide-react";import{useRouterAdapter as L}from"../hooks/use-router.js";import*as s from"react";import{Dialog as T,DialogContent as O,DialogTitle as z}from"../components/ui/dialog.js";import{useHotkey as C}from"../hooks/use-hotkey.js";import{cn as D}from"../lib/utils.js";import{useUi as h}from"../store/ui-store.js";import{useShell as $}from"./config.js";function Q(){const l=$(),i=h(e=>e.paletteOpen),c=h(e=>e.setPalette),g=h(e=>e.toggleTheme),x=h(e=>e.theme),{navigate:k}=L(),[d,v]=s.useState(""),[u,m]=s.useState(0),y=s.useRef(null);C({key:"k",mod:!0},()=>c(!i)),C({key:"/"},()=>c(!0));const b=s.useMemo(()=>{const e=[...l.commands??[]];e.push({id:"act-theme",label:x==="dark"?"Switch to light theme":"Switch to dark theme",group:"Actions",icon:x==="dark"?R:E,run:g});const n=l.isEntitled??(()=>!0);for(const t of l.modules.filter(n)){e.push({id:`mod-${t.key}`,label:t.title,hint:t.description,group:"Modules",icon:t.icon,href:t.href});for(const r of t.nav)r.kind==="item"&&e.push({id:`scr-${t.key}-${r.href}`,label:r.label,hint:t.title,group:"Screens",icon:t.icon,href:r.href})}return e},[l.commands,l.modules,l.isEntitled,x,g]),p=s.useMemo(()=>{const e=d.trim().toLowerCase(),n=e?b.filter(r=>r.label.toLowerCase().includes(e)||r.hint?.toLowerCase().includes(e)):b.filter(r=>r.group!=="Screens"),t=["Actions","AI","Screens","Modules","Records"];return n.slice().sort((r,f)=>t.indexOf(r.group)-t.indexOf(f.group)).slice(0,40)},[b,d]);s.useEffect(()=>m(0),[d]),s.useEffect(()=>{i||v("")},[i]);const N=s.useCallback(e=>{e&&(c(!1),e.run?e.run():e.href&&k(e.href))},[k,c]),S=e=>{e.key==="ArrowDown"?(e.preventDefault(),m(n=>Math.min(n+1,p.length-1))):e.key==="ArrowUp"?(e.preventDefault(),m(n=>Math.max(n-1,0))):e.key==="Enter"&&(e.preventDefault(),N(p[u]))};s.useEffect(()=>{y.current?.querySelector(`[data-index="${u}"]`)?.scrollIntoView({block:"nearest"})},[u]);let w="";return o(T,{open:i,onOpenChange:c,children:a(O,{variant:"center",width:"max-w-[580px]",hideClose:!0,className:"top-[14vh] translate-y-0 overflow-hidden p-0 shadow-elev3",onKeyDown:S,children:[o(z,{className:"sr-only",children:"Command palette"}),a("div",{className:"flex items-center gap-2.5 border-b border-border px-4",children:[o(I,{className:"size-4 shrink-0 text-muted"}),o("input",{autoFocus:!0,value:d,onChange:e=>v(e.target.value),placeholder:"Search screens, run an agent, or ask\u2026",className:"h-12 flex-1 bg-transparent text-sm text-text outline-none placeholder:text-placeholder"}),o("kbd",{className:"rounded border border-border2 px-1.5 text-[11px] text-muted",children:"esc"})]}),o("div",{ref:y,className:"max-h-[54vh] overflow-y-auto p-1.5",children:p.length===0?a("p",{className:"px-3 py-8 text-center text-[13px] text-muted",children:["Nothing matches \u201C",d,"\u201D."]}):p.map((e,n)=>{const t=e.icon,r=e.group!==w?e.group:null;w=e.group;const f=n===u;return a(s.Fragment,{children:[r?o("div",{className:"ov px-2.5 pb-1 pt-2.5",children:r}):null,a("button",{type:"button","data-index":n,onMouseMove:()=>m(n),onClick:()=>N(e),className:D("flex w-full cursor-pointer items-center gap-2.5 rounded-ctl px-2.5 py-2 text-left text-[13px] transition-colors",f?"bg-hover text-text":"text-body"),children:[t?o(t,{className:D("size-4 shrink-0",e.group==="AI"?"text-accent":"text-muted")}):null,o("span",{className:"flex-1 truncate",children:e.label}),e.hint?o("span",{className:"hidden max-w-[45%] truncate text-[11px] text-muted sm:inline",children:e.hint}):null,f?o(M,{className:"size-3.5 shrink-0 text-muted"}):null]})]},e.id)})}),a("div",{className:"flex items-center gap-4 border-t border-border bg-surface px-4 py-2 text-[11px] text-muted",children:[a("span",{className:"flex items-center gap-1",children:[o("kbd",{className:"rounded border border-border2 px-1",children:"\u2191"}),o("kbd",{className:"rounded border border-border2 px-1",children:"\u2193"})," navigate"]}),a("span",{className:"flex items-center gap-1",children:[o("kbd",{className:"rounded border border-border2 px-1",children:"\u21B5"})," open"]}),a("span",{className:"ml-auto flex items-center gap-1",children:[o(A,{className:"size-3 text-accent"})," agents run with a credit estimate first"]})]})]})})}export{Q as CommandPalette};
@@ -1 +1 @@
1
- "use client";import{Fragment as W,jsx as e,jsxs as c}from"react/jsx-runtime";import x from"next/link";import*as i from"react";import{WaveMark as T}from"../components/brand/logo.js";import{CountBadge as $}from"../components/ui/badge.js";import{Tooltip as f}from"../components/ui/tooltip.js";import{cn as v}from"../lib/utils.js";import{useUi as E}from"../store/ui-store.js";import{useActive as R}from"./use-active.js";function d({mod:l,active:r,index:n,visiting:t}){const u=l.icon;return e("li",{className:"relative w-full","data-active":r||void 0,children:e(f,{label:t?`${l.title} \u2014 outside this app`:l.title,shortcut:n<9?`Alt+${n+1}`:void 0,side:"right",children:c(x,{href:l.href,"aria-current":r?"page":void 0,className:v("relative mx-auto flex min-h-14 w-[60px] flex-col items-center justify-center gap-[3px] rounded-ctl px-0.5 py-1.5","transition-colors duration-150",r?"bg-primary-subtle text-primary":"text-muted hover:bg-hover hover:text-text"),children:[e(u,{className:"size-[19px]",strokeWidth:r?2.2:1.8}),e("span",{className:"w-full truncate px-0.5 text-center text-[10px] font-medium leading-3",children:l.label}),l.badge?e($,{value:l.badge,tone:l.badgeTone==="danger"?"danger":"neutral",className:"absolute right-1.5 top-1"}):null,t?e("span",{className:"absolute left-1.5 top-1.5 size-1.5 rounded-full bg-accent","aria-hidden":!0}):null]})})})}function C(){const{cfg:l,pathname:r,mod:n,app:t,rail:u}=R(),y=E(a=>a.setLauncher),N=t.icon,{modules:o,platform:k,visiting:p}=u,w=l.showAppSwitcher!==!1&&l.apps.length>1,h=i.useRef(null),[m,A]=i.useState(null),b=i.useRef(t.id),[I,L]=i.useState(!1);i.useLayoutEffect(()=>{const a=h.current?.querySelector('[data-active="true"]'),s=b.current===t.id;b.current=t.id,L(s),A(a?{y:a.offsetTop+10,h:a.offsetHeight-20}:null)},[r,t.id,o.length]);const g=c("span",{className:"relative block",children:[e(T,{}),e("span",{className:"absolute -bottom-1 -right-1 grid size-[17px] place-items-center rounded-full text-white ring-2 ring-surface",style:{background:t.tint},children:e(N,{className:"size-2.5"})})]});return c("nav",{ref:h,"data-shell-rail":"","aria-label":`${t.name} modules`,className:"rail-fade relative col-start-1 row-start-1 row-span-2 flex flex-col items-center gap-0.5 overflow-y-auto overflow-x-hidden border-r border-border bg-surface py-2",children:[m?e("span",{"aria-hidden":!0,className:v("pointer-events-none absolute left-0 top-0 w-[3px] rounded-r-[3px] bg-primary",I&&"transition-[transform,height] duration-[220ms] ease-wave"),style:{transform:`translateY(${m.y}px)`,height:m.h}}):null,w?e(f,{label:`WAVEINNO \xB7 ${t.name} \u2014 switch app`,shortcut:"\u2318\u21E7K",side:"right",children:e("button",{type:"button",onClick:()=>y(!0),"aria-label":`WAVEINNO, ${t.name}. Switch app`,className:"relative mb-3 shrink-0 cursor-pointer transition-transform duration-150 hover:scale-105",children:g})}):e(f,{label:`WAVEINNO \xB7 ${t.name}`,side:"right",children:e(x,{href:t.href,"aria-label":`WAVEINNO ${t.name} home`,className:"relative mb-3 shrink-0 transition-transform duration-150 hover:scale-105",children:g})}),e("ul",{className:"flex w-full flex-col items-center gap-0.5",children:o.map((a,s)=>e(d,{mod:a,index:s,active:a.key===n.key},a.key))}),p?c(W,{children:[e("span",{className:"my-1.5 h-px w-8 shrink-0 bg-border2","aria-hidden":!0}),e("ul",{className:"flex w-full flex-col items-center",children:e(d,{mod:p,index:o.length,active:!0,visiting:!0})})]}):null,e("div",{className:"min-h-6 flex-1"}),e("ul",{className:"flex w-full flex-col items-center gap-0.5 pb-1",children:k.map((a,s)=>e(d,{mod:a,index:o.length+(p?1:0)+s,active:a.key===n.key},a.key))})]})}export{C as IconRail};
1
+ "use client";import{Fragment as W,jsx as e,jsxs as c}from"react/jsx-runtime";import*as i from"react";import{WaveMark as T}from"../components/brand/logo.js";import{CountBadge as $}from"../components/ui/badge.js";import{Tooltip as f}from"../components/ui/tooltip.js";import{RouterLink as x}from"../hooks/use-router.js";import{cn as v}from"../lib/utils.js";import{useUi as E}from"../store/ui-store.js";import{useActive as R}from"./use-active.js";function d({mod:l,active:r,index:n,visiting:t}){const u=l.icon;return e("li",{className:"relative w-full","data-active":r||void 0,children:e(f,{label:t?`${l.title} \u2014 outside this app`:l.title,shortcut:n<9?`Alt+${n+1}`:void 0,side:"right",children:c(x,{href:l.href,"aria-current":r?"page":void 0,className:v("relative mx-auto flex min-h-14 w-[60px] flex-col items-center justify-center gap-[3px] rounded-ctl px-0.5 py-1.5","transition-colors duration-150",r?"bg-primary-subtle text-primary":"text-muted hover:bg-hover hover:text-text"),children:[e(u,{className:"size-[19px]",strokeWidth:r?2.2:1.8}),e("span",{className:"w-full truncate px-0.5 text-center text-[10px] font-medium leading-3",children:l.label}),l.badge?e($,{value:l.badge,tone:l.badgeTone==="danger"?"danger":"neutral",className:"absolute right-1.5 top-1"}):null,t?e("span",{className:"absolute left-1.5 top-1.5 size-1.5 rounded-full bg-accent","aria-hidden":!0}):null]})})})}function C(){const{cfg:l,pathname:r,mod:n,app:t,rail:u}=R(),y=E(a=>a.setLauncher),N=t.icon,{modules:o,platform:k,visiting:p}=u,w=l.showAppSwitcher!==!1&&l.apps.length>1,h=i.useRef(null),[m,A]=i.useState(null),b=i.useRef(t.id),[L,I]=i.useState(!1);i.useLayoutEffect(()=>{const a=h.current?.querySelector('[data-active="true"]'),s=b.current===t.id;b.current=t.id,I(s),A(a?{y:a.offsetTop+10,h:a.offsetHeight-20}:null)},[r,t.id,o.length]);const g=c("span",{className:"relative block",children:[e(T,{}),e("span",{className:"absolute -bottom-1 -right-1 grid size-[17px] place-items-center rounded-full text-white ring-2 ring-surface",style:{background:t.tint},children:e(N,{className:"size-2.5"})})]});return c("nav",{ref:h,"data-shell-rail":"","aria-label":`${t.name} modules`,className:"rail-fade relative col-start-1 row-start-1 row-span-2 flex flex-col items-center gap-0.5 overflow-y-auto overflow-x-hidden border-r border-border bg-surface py-2",children:[m?e("span",{"aria-hidden":!0,className:v("pointer-events-none absolute left-0 top-0 w-[3px] rounded-r-[3px] bg-primary",L&&"transition-[transform,height] duration-[220ms] ease-wave"),style:{transform:`translateY(${m.y}px)`,height:m.h}}):null,w?e(f,{label:`WAVEINNO \xB7 ${t.name} \u2014 switch app`,shortcut:"\u2318\u21E7K",side:"right",children:e("button",{type:"button",onClick:()=>y(!0),"aria-label":`WAVEINNO, ${t.name}. Switch app`,className:"relative mb-3 shrink-0 cursor-pointer transition-transform duration-150 hover:scale-105",children:g})}):e(f,{label:`WAVEINNO \xB7 ${t.name}`,side:"right",children:e(x,{href:t.href,"aria-label":`WAVEINNO ${t.name} home`,className:"relative mb-3 shrink-0 transition-transform duration-150 hover:scale-105",children:g})}),e("ul",{className:"flex w-full flex-col items-center gap-0.5",children:o.map((a,s)=>e(d,{mod:a,index:s,active:a.key===n.key},a.key))}),p?c(W,{children:[e("span",{className:"my-1.5 h-px w-8 shrink-0 bg-border2","aria-hidden":!0}),e("ul",{className:"flex w-full flex-col items-center",children:e(d,{mod:p,index:o.length,active:!0,visiting:!0})})]}):null,e("div",{className:"min-h-6 flex-1"}),e("ul",{className:"flex w-full flex-col items-center gap-0.5 pb-1",children:k.map((a,s)=>e(d,{mod:a,index:o.length+(p?1:0)+s,active:a.key===n.key},a.key))})]})}export{C as IconRail};
@@ -1 +1 @@
1
- "use client";import{jsx as t,jsxs as s}from"react/jsx-runtime";import l from"next/link";import*as k from"react";import{WaveWordmark as N}from"../components/brand/logo.js";import{CountBadge as y}from"../components/ui/badge.js";import{Sheet as w,SheetContent as A,SheetTitle as S}from"../components/ui/sheet.js";import{cn as p}from"../lib/utils.js";import{useApp as C}from"../store/app-store.js";import{useUi as f}from"../store/ui-store.js";import{useActive as L}from"./use-active.js";function R(){const u=f(e=>e.mobileNavOpen),n=f(e=>e.setMobileNav),h=C(e=>e.setApp),{cfg:o,pathname:d,mod:b,app:c,rail:x,isEntitled:v}=L(),g=x.order;return k.useEffect(()=>{n(!1)},[d,n]),t(w,{open:u,onOpenChange:n,children:s(A,{side:"left",width:"w-[300px]",className:"lg:hidden",children:[s("div",{className:"shrink-0 border-b border-border px-4 py-3",children:[t(S,{asChild:!0,children:t(N,{size:"sm",suffix:c.name})}),o.scopeLabelled??o.scope?t("div",{className:"mt-2",children:o.scopeLabelled??o.scope}):null]}),o.apps.length>1&&o.showAppSwitcher!==!1?t("div",{className:"flex shrink-0 gap-1.5 overflow-x-auto border-b border-border px-3 py-2.5",children:o.apps.map(e=>{const a=e.icon,i=e.id===c.id,r=o.modules.find(m=>m.app===e.id&&v(m));return t(l,{href:r?.href??e.href,onClick:()=>h(e.id),"aria-label":e.name,"aria-current":i?"true":void 0,className:p("grid size-9 shrink-0 place-items-center rounded-ctl text-white transition-[box-shadow,transform] duration-150",i?"ring-2 ring-text ring-offset-2 ring-offset-raised":"opacity-90 hover:opacity-100"),style:{background:e.tint},children:t(a,{className:"size-4"})},e.id)})}):null,t("div",{className:"flex-1 overflow-y-auto p-2",children:g.map(e=>{const a=e.icon,i=e.key===b.key;return s("div",{children:[s(l,{href:e.href,className:p("flex h-item items-center gap-2.5 rounded-ctl px-2.5 text-[13px] transition-colors",i?"bg-primary-subtle font-medium text-primary":"text-body hover:bg-hover"),children:[t(a,{className:"size-4 shrink-0"}),t("span",{className:"flex-1 truncate",children:e.title}),e.badge?t(y,{value:e.badge,tone:e.badgeTone==="danger"?"danger":"neutral"}):null]}),i?t("ul",{className:"mb-2 ml-[26px] mt-0.5 border-l border-border pl-2",children:e.nav.filter(r=>r.kind==="item").map(r=>t("li",{children:s(l,{href:r.href,className:p("flex h-8 items-center gap-2 rounded-ctl px-2 text-[13px] transition-colors",d===r.href?"font-medium text-primary":"text-muted hover:bg-hover hover:text-text"),children:[t("span",{className:"flex-1 truncate",children:r.label}),r.count?t("span",{className:"num text-[11px]",children:r.count}):null]})},r.href))}):null]},e.key)})})]})})}export{R as MobileNav};
1
+ "use client";import{jsx as t,jsxs as s}from"react/jsx-runtime";import*as k from"react";import{WaveWordmark as N}from"../components/brand/logo.js";import{CountBadge as y}from"../components/ui/badge.js";import{Sheet as w,SheetContent as A,SheetTitle as L}from"../components/ui/sheet.js";import{RouterLink as l}from"../hooks/use-router.js";import{cn as p}from"../lib/utils.js";import{useApp as S}from"../store/app-store.js";import{useUi as f}from"../store/ui-store.js";import{useActive as C}from"./use-active.js";function B(){const u=f(e=>e.mobileNavOpen),n=f(e=>e.setMobileNav),h=S(e=>e.setApp),{cfg:o,pathname:d,mod:b,app:c,rail:x,isEntitled:v}=C(),g=x.order;return k.useEffect(()=>{n(!1)},[d,n]),t(w,{open:u,onOpenChange:n,children:s(A,{side:"left",width:"w-[300px]",className:"lg:hidden",children:[s("div",{className:"shrink-0 border-b border-border px-4 py-3",children:[t(L,{asChild:!0,children:t(N,{size:"sm",suffix:c.name})}),o.scopeLabelled??o.scope?t("div",{className:"mt-2",children:o.scopeLabelled??o.scope}):null]}),o.apps.length>1&&o.showAppSwitcher!==!1?t("div",{className:"flex shrink-0 gap-1.5 overflow-x-auto border-b border-border px-3 py-2.5",children:o.apps.map(e=>{const a=e.icon,i=e.id===c.id,r=o.modules.find(m=>m.app===e.id&&v(m));return t(l,{href:r?.href??e.href,onClick:()=>h(e.id),"aria-label":e.name,"aria-current":i?"true":void 0,className:p("grid size-9 shrink-0 place-items-center rounded-ctl text-white transition-[box-shadow,transform] duration-150",i?"ring-2 ring-text ring-offset-2 ring-offset-raised":"opacity-90 hover:opacity-100"),style:{background:e.tint},children:t(a,{className:"size-4"})},e.id)})}):null,t("div",{className:"flex-1 overflow-y-auto p-2",children:g.map(e=>{const a=e.icon,i=e.key===b.key;return s("div",{children:[s(l,{href:e.href,className:p("flex h-item items-center gap-2.5 rounded-ctl px-2.5 text-[13px] transition-colors",i?"bg-primary-subtle font-medium text-primary":"text-body hover:bg-hover"),children:[t(a,{className:"size-4 shrink-0"}),t("span",{className:"flex-1 truncate",children:e.title}),e.badge?t(y,{value:e.badge,tone:e.badgeTone==="danger"?"danger":"neutral"}):null]}),i?t("ul",{className:"mb-2 ml-[26px] mt-0.5 border-l border-border pl-2",children:e.nav.filter(r=>r.kind==="item").map(r=>t("li",{children:s(l,{href:r.href,className:p("flex h-8 items-center gap-2 rounded-ctl px-2 text-[13px] transition-colors",d===r.href?"font-medium text-primary":"text-muted hover:bg-hover hover:text-text"),children:[t("span",{className:"flex-1 truncate",children:r.label}),r.count?t("span",{className:"num text-[11px]",children:r.count}):null]})},r.href))}):null]},e.key)})})]})})}export{B as MobileNav};
@@ -1 +1 @@
1
- "use client";import{jsx as a,jsxs as o}from"react/jsx-runtime";import d from"next/link";import*as r from"react";import{cn as i}from"../lib/utils.js";import{useActive as b}from"./use-active.js";function k(){const{pathname:c,mod:t,item:p}=b(),u=r.useRef(null),[s,f]=r.useState(null),m=r.useRef(t.key),[x,h]=r.useState(!1);return r.useLayoutEffect(()=>{const e=u.current?.querySelector('li[data-active="true"]'),n=m.current===t.key;m.current=t.key,h(n),f(e?{y:e.offsetTop,h:e.offsetHeight}:null)},[c,t.key]),o("nav",{"data-shell-panel":"","aria-label":`${t.title} sections`,className:"col-start-2 row-start-1 row-span-2 overflow-y-auto overflow-x-hidden border-r border-border bg-surface px-2.5 py-3",children:[a("h2",{className:"px-2.5 pb-2.5 pt-1.5 text-[13px] font-semibold leading-[18px] text-text",children:t.title}),o("ul",{ref:u,className:"relative",children:[s?a("li",{"aria-hidden":!0,className:i("pointer-events-none absolute inset-x-0 top-0 rounded-ctl bg-primary-subtle",x&&"transition-[transform,height] duration-[220ms] ease-wave"),style:{transform:`translateY(${s.y}px)`,height:s.h}}):null,t.nav.map((e,n)=>{if(e.kind==="group")return a("li",{className:"ov px-2.5 pb-1.5 pt-3.5",children:e.label},`g-${n}`);const l=p?.href===e.href;return a("li",{"data-active":l||void 0,children:o(d,{href:e.href,"aria-current":l?"page":void 0,className:i("relative mb-px flex h-item items-center gap-2.5 rounded-ctl px-2.5 text-[13px] transition-colors duration-150",l?"font-medium text-primary":"text-body hover:bg-hover hover:text-text"),children:[a("span",{className:"truncate",children:e.label}),e.count?a("span",{className:i("num ml-auto shrink-0 text-xs",l?"text-primary":e.hot?"font-semibold text-text":"text-muted"),children:e.count}):null]})},e.href)})]})]})}export{k as ModuleSidebar};
1
+ "use client";import{jsx as a,jsxs as o}from"react/jsx-runtime";import*as r from"react";import{RouterLink as d}from"../hooks/use-router.js";import{cn as i}from"../lib/utils.js";import{useActive as b}from"./use-active.js";function k(){const{pathname:c,mod:t,item:p}=b(),u=r.useRef(null),[s,f]=r.useState(null),m=r.useRef(t.key),[x,h]=r.useState(!1);return r.useLayoutEffect(()=>{const e=u.current?.querySelector('li[data-active="true"]'),n=m.current===t.key;m.current=t.key,h(n),f(e?{y:e.offsetTop,h:e.offsetHeight}:null)},[c,t.key]),o("nav",{"data-shell-panel":"","aria-label":`${t.title} sections`,className:"col-start-2 row-start-1 row-span-2 overflow-y-auto overflow-x-hidden border-r border-border bg-surface px-2.5 py-3",children:[a("h2",{className:"px-2.5 pb-2.5 pt-1.5 text-[13px] font-semibold leading-[18px] text-text",children:t.title}),o("ul",{ref:u,className:"relative",children:[s?a("li",{"aria-hidden":!0,className:i("pointer-events-none absolute inset-x-0 top-0 rounded-ctl bg-primary-subtle",x&&"transition-[transform,height] duration-[220ms] ease-wave"),style:{transform:`translateY(${s.y}px)`,height:s.h}}):null,t.nav.map((e,n)=>{if(e.kind==="group")return a("li",{className:"ov px-2.5 pb-1.5 pt-3.5",children:e.label},`g-${n}`);const l=p?.href===e.href;return a("li",{"data-active":l||void 0,children:o(d,{href:e.href,"aria-current":l?"page":void 0,className:i("relative mb-px flex h-item items-center gap-2.5 rounded-ctl px-2.5 text-[13px] transition-colors duration-150",l?"font-medium text-primary":"text-body hover:bg-hover hover:text-text"),children:[a("span",{className:"truncate",children:e.label}),e.count?a("span",{className:i("num ml-auto shrink-0 text-xs",l?"text-primary":e.hot?"font-semibold text-text":"text-muted"),children:e.count}):null]})},e.href)})]})]})}export{k as ModuleSidebar};
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Bell as p}from"lucide-react";import n from"next/link";import{Badge as m}from"../components/ui/badge.js";import{Button as s}from"../components/ui/button.js";import{Popover as c,PopoverContent as d,PopoverTrigger as x}from"../components/ui/popover.js";import{Tooltip as f}from"../components/ui/tooltip.js";import{fmtRelative as u}from"../lib/format.js";import{useShell as N}from"./config.js";function C(){const o=N(),r=o.notifications??[],i=r.filter(t=>!t.read).length,l=o.now??new Date;return a(c,{onOpenChange:t=>t&&o.onNotificationsOpen?.(),children:[e(f,{label:"Notifications",children:e(x,{asChild:!0,children:a(s,{variant:"ghost",size:"icon",className:"relative","aria-label":`Notifications, ${i} unread`,children:[e(p,{}),i>0?e("span",{className:"num absolute right-[3px] top-[3px] grid h-4 min-w-4 place-items-center rounded-full bg-danger px-1 text-[10px] font-semibold leading-none text-white ring-2 ring-canvas","aria-hidden":!0,children:i>9?"9+":i}):null]})})}),a(d,{align:"end",className:"w-[380px] max-w-[calc(100vw-32px)] p-0",children:[a("div",{className:"flex items-center justify-between border-b border-border px-3.5 py-2.5",children:[e("span",{className:"text-[13px] font-semibold text-text",children:"Notifications"}),i>0&&o.onNotificationsRead?e(s,{variant:"link",size:"sm",className:"h-auto",onClick:()=>o.onNotificationsRead?.("all"),children:"Mark all read"}):null]}),r.length===0?e("p",{className:"px-3.5 py-8 text-center text-[13px] text-muted",children:"You are all caught up."}):e("ul",{className:"max-h-[420px] overflow-y-auto",children:r.map(t=>e("li",{children:a(n,{href:t.href,onClick:()=>!t.read&&o.onNotificationsRead?.([t.id]),className:"flex gap-2.5 border-b border-border px-3.5 py-3 transition-colors last:border-0 hover:bg-hover",children:[e(m,{tone:t.tone,className:"mt-0.5 h-[18px] px-1.5",children:e("span",{className:"sr-only",children:t.tone})}),a("div",{className:"min-w-0 flex-1",children:[e("p",{className:"text-[13px] font-medium leading-[18px] text-text",children:t.title}),e("p",{className:"mt-0.5 truncate text-xs text-muted",children:t.detail}),a("p",{className:"mt-1 text-[11px] text-muted",children:[u(t.at,l)," \xB7 ",t.source]})]}),t.read?null:e("span",{className:"mt-2 size-1.5 shrink-0 rounded-full bg-primary","aria-label":"unread"})]})},t.id))}),o.notificationsHref?e("div",{className:"border-t border-border px-3.5 py-2",children:e(n,{href:o.notificationsHref,className:"text-xs font-medium text-primary hover:underline",children:o.notificationsHrefLabel??"Open activity"})}):null]})]})}export{C as Notifications};
1
+ "use client";import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Bell as p}from"lucide-react";import{Badge as m}from"../components/ui/badge.js";import{Button as n}from"../components/ui/button.js";import{Popover as c,PopoverContent as d,PopoverTrigger as x}from"../components/ui/popover.js";import{Tooltip as f}from"../components/ui/tooltip.js";import{RouterLink as s}from"../hooks/use-router.js";import{fmtRelative as u}from"../lib/format.js";import{useShell as N}from"./config.js";function C(){const o=N(),r=o.notifications??[],i=r.filter(t=>!t.read).length,l=o.now??new Date;return a(c,{onOpenChange:t=>t&&o.onNotificationsOpen?.(),children:[e(f,{label:"Notifications",children:e(x,{asChild:!0,children:a(n,{variant:"ghost",size:"icon",className:"relative","aria-label":`Notifications, ${i} unread`,children:[e(p,{}),i>0?e("span",{className:"num absolute right-[3px] top-[3px] grid h-4 min-w-4 place-items-center rounded-full bg-danger px-1 text-[10px] font-semibold leading-none text-white ring-2 ring-canvas","aria-hidden":!0,children:i>9?"9+":i}):null]})})}),a(d,{align:"end",className:"w-[380px] max-w-[calc(100vw-32px)] p-0",children:[a("div",{className:"flex items-center justify-between border-b border-border px-3.5 py-2.5",children:[e("span",{className:"text-[13px] font-semibold text-text",children:"Notifications"}),i>0&&o.onNotificationsRead?e(n,{variant:"link",size:"sm",className:"h-auto",onClick:()=>o.onNotificationsRead?.("all"),children:"Mark all read"}):null]}),r.length===0?e("p",{className:"px-3.5 py-8 text-center text-[13px] text-muted",children:"You are all caught up."}):e("ul",{className:"max-h-[420px] overflow-y-auto",children:r.map(t=>e("li",{children:a(s,{href:t.href,onClick:()=>!t.read&&o.onNotificationsRead?.([t.id]),className:"flex gap-2.5 border-b border-border px-3.5 py-3 transition-colors last:border-0 hover:bg-hover",children:[e(m,{tone:t.tone,className:"mt-0.5 h-[18px] px-1.5",children:e("span",{className:"sr-only",children:t.tone})}),a("div",{className:"min-w-0 flex-1",children:[e("p",{className:"text-[13px] font-medium leading-[18px] text-text",children:t.title}),e("p",{className:"mt-0.5 truncate text-xs text-muted",children:t.detail}),a("p",{className:"mt-1 text-[11px] text-muted",children:[u(t.at,l)," \xB7 ",t.source]})]}),t.read?null:e("span",{className:"mt-2 size-1.5 shrink-0 rounded-full bg-primary","aria-label":"unread"})]})},t.id))}),o.notificationsHref?e("div",{className:"border-t border-border px-3.5 py-2",children:e(s,{href:o.notificationsHref,className:"text-xs font-medium text-primary hover:underline",children:o.notificationsHrefLabel??"Open activity"})}):null]})]})}export{C as Notifications};
@@ -1 +1 @@
1
- "use client";import{Fragment as y,jsx as a,jsxs as t}from"react/jsx-runtime";import{ArrowRight as h,Check as x,Database as f}from"lucide-react";import g from"next/link";import{PageHeader as u}from"../components/patterns/page-header.js";import{Card as m}from"../components/ui/card.js";import{useShell as b}from"./config.js";import{moduleFromPath as N,navItemFromPath as v}from"./registry.js";function I({pathname:n,plannedIn:o}){const i=b(),s=N(i.modules,n),d=v(n,s),l=d?.label??s.title,r=i.apps.find(e=>e.id===s.app),c=s.nav.filter(e=>e.kind==="item").filter(e=>e.href!==d?.href).slice(0,6),p=["Navigation, breadcrumb and page header","Plan / role gating from the registry","Data table \u2014 sort, pin, resize, export","Record drawer and command palette","Empty, loading and error states"];return t(y,{children:[a(u,{crumbs:[...i.homeCrumb?[i.homeCrumb]:[],...r&&r.href!==i.homeCrumb?.href?[{label:r.name,href:r.href}]:[],{label:s.title,href:s.href},{label:l}],title:l,description:s.description}),t("div",{className:"grid grid-cols-1 items-start gap-3 lg:grid-cols-[minmax(0,1fr)_320px]",children:[a(m,{className:"px-6 py-8",children:t("div",{className:"flex items-start gap-3.5",children:[a("span",{className:"grid size-9 shrink-0 place-items-center rounded-ctl bg-hover text-muted","aria-hidden":!0,children:a(f,{className:"size-4"})}),t("div",{className:"min-w-0",children:[t("h2",{className:"text-[15px] font-semibold text-text",children:[l," is designed but not built yet"]}),t("p",{className:"mt-1.5 max-w-[60ch] text-[13px] leading-5 text-muted",children:["The screen is in the navigation registry and inherits the page template. Its data contract is in the API specification; the page ships with its milestone",o?` (${o})`:"","."]})]})]})}),t("div",{className:"space-y-3",children:[t(m,{children:[a("h3",{className:"text-[13px] font-semibold text-text",children:"Already wired"}),a("ul",{className:"mt-2.5 space-y-2",children:p.map(e=>t("li",{className:"flex items-start gap-2 text-[13px] text-body",children:[a(x,{className:"mt-0.5 size-3.5 shrink-0 text-success"}),e]},e))})]}),c.length?t(m,{children:[t("h3",{className:"text-[13px] font-semibold text-text",children:["Elsewhere in ",s.title]}),a("ul",{className:"-mx-1.5 mt-2",children:c.map(e=>e.kind==="item"?a("li",{children:t(g,{href:e.href,className:"flex items-center gap-2 rounded-ctl px-1.5 py-1.5 text-[13px] text-body transition-colors hover:bg-hover hover:text-text",children:[a("span",{className:"min-w-0 flex-1 truncate",children:e.label}),a(h,{className:"size-3 shrink-0 text-muted"})]})},e.href):null)})]}):null]})]})]})}export{I as PlaceholderScreen};
1
+ "use client";import{Fragment as y,jsx as a,jsxs as t}from"react/jsx-runtime";import{ArrowRight as h,Check as x,Database as f}from"lucide-react";import{PageHeader as g}from"../components/patterns/page-header.js";import{Card as m}from"../components/ui/card.js";import{RouterLink as u}from"../hooks/use-router.js";import{useShell as b}from"./config.js";import{moduleFromPath as N,navItemFromPath as v}from"./registry.js";function I({pathname:n,plannedIn:o}){const i=b(),s=N(i.modules,n),d=v(n,s),l=d?.label??s.title,r=i.apps.find(e=>e.id===s.app),c=s.nav.filter(e=>e.kind==="item").filter(e=>e.href!==d?.href).slice(0,6),p=["Navigation, breadcrumb and page header","Plan / role gating from the registry","Data table \u2014 sort, pin, resize, export","Record drawer and command palette","Empty, loading and error states"];return t(y,{children:[a(g,{crumbs:[...i.homeCrumb?[i.homeCrumb]:[],...r&&r.href!==i.homeCrumb?.href?[{label:r.name,href:r.href}]:[],{label:s.title,href:s.href},{label:l}],title:l,description:s.description}),t("div",{className:"grid grid-cols-1 items-start gap-3 lg:grid-cols-[minmax(0,1fr)_320px]",children:[a(m,{className:"px-6 py-8",children:t("div",{className:"flex items-start gap-3.5",children:[a("span",{className:"grid size-9 shrink-0 place-items-center rounded-ctl bg-hover text-muted","aria-hidden":!0,children:a(f,{className:"size-4"})}),t("div",{className:"min-w-0",children:[t("h2",{className:"text-[15px] font-semibold text-text",children:[l," is designed but not built yet"]}),t("p",{className:"mt-1.5 max-w-[60ch] text-[13px] leading-5 text-muted",children:["The screen is in the navigation registry and inherits the page template. Its data contract is in the API specification; the page ships with its milestone",o?` (${o})`:"","."]})]})]})}),t("div",{className:"space-y-3",children:[t(m,{children:[a("h3",{className:"text-[13px] font-semibold text-text",children:"Already wired"}),a("ul",{className:"mt-2.5 space-y-2",children:p.map(e=>t("li",{className:"flex items-start gap-2 text-[13px] text-body",children:[a(x,{className:"mt-0.5 size-3.5 shrink-0 text-success"}),e]},e))})]}),c.length?t(m,{children:[t("h3",{className:"text-[13px] font-semibold text-text",children:["Elsewhere in ",s.title]}),a("ul",{className:"-mx-1.5 mt-2",children:c.map(e=>e.kind==="item"?a("li",{children:t(u,{href:e.href,className:"flex items-center gap-2 rounded-ctl px-1.5 py-1.5 text-[13px] text-body transition-colors hover:bg-hover hover:text-text",children:[a("span",{className:"min-w-0 flex-1 truncate",children:e.label}),a(h,{className:"size-3 shrink-0 text-muted"})]})},e.href):null)})]}):null]})]})]})}export{I as PlaceholderScreen};
@@ -1 +1 @@
1
- "use client";import{jsx as e,jsxs as o}from"react/jsx-runtime";import{Menu as x,PanelLeft as h,Search as p}from"lucide-react";import{WaveMark as f}from"../components/brand/logo.js";import{Button as l}from"../components/ui/button.js";import{Tooltip as g}from"../components/ui/tooltip.js";import{cn as v}from"../lib/utils.js";import{useUi as s}from"../store/ui-store.js";import{AppSwitcher as N}from"./app-switcher.js";import{Notifications as k}from"./notifications.js";import{UserMenu as w}from"./user-menu.js";import{useActive as z}from"./use-active.js";function I(){const m=s(a=>a.togglePanel),i=s(a=>a.setPalette),c=s(a=>a.setMobileNav),u=s(a=>a.setLauncher),{cfg:t,app:r}=z(),b=r.icon,n=t.showAppSwitcher!==!1&&t.apps.length>1,d=t.searchClearance==="wide";return e("header",{className:"col-start-3 col-end-4 row-start-1 flex border-b border-border bg-canvas px-4 sm:px-6",children:o("div",{className:"@container relative mx-auto flex w-full max-w-[1600px] items-center gap-2 sm:gap-2.5",children:[o("div",{className:"flex min-w-0 items-center gap-2",children:[e(g,{label:"Toggle panel",shortcut:"\u2318B",children:e(l,{variant:"ghost",size:"icon",onClick:m,className:"-ml-2.5 hidden lg:inline-flex","aria-label":"Toggle module panel",children:e(h,{})})}),e(l,{variant:"ghost",size:"icon",onClick:()=>c(!0),className:"-ml-2.5 lg:hidden","aria-label":"Open navigation",children:e(x,{})}),o("button",{type:"button",onClick:()=>n?u(!0):c(!0),"aria-label":`WAVEINNO, ${r.name}`,className:"flex min-w-0 shrink items-center gap-2 rounded-full py-1 pl-0.5 pr-2 transition-colors hover:bg-hover lg:hidden",children:[o("span",{className:"relative shrink-0",children:[e(f,{size:"sm"}),e("span",{className:"absolute -bottom-0.5 -right-0.5 grid size-[13px] place-items-center rounded-full text-white ring-2 ring-canvas",style:{background:r.tint},children:e(b,{className:"size-2"})})]}),e("span",{className:`disp truncate text-[13px] font-semibold text-text ${n?"md:hidden":""}`,children:r.name})]})]}),o("button",{type:"button",onClick:()=>i(!0),className:v("absolute left-1/2 top-1/2 hidden h-[38px] -translate-x-1/2 -translate-y-1/2 cursor-text items-center gap-2.5 rounded-full border border-border bg-surface px-[15px] text-left transition-[background-color,border-color,box-shadow] hover:border-border2 focus-visible:border-primary focus-visible:bg-raised focus-visible:shadow-elev2",d?"w-[clamp(260px,calc(100%-960px),560px)] @min-[1220px]:flex":"w-[clamp(260px,calc(100%-720px),560px)] @min-[980px]:flex"),children:[e(p,{className:"size-4 shrink-0 text-muted"}),e("span",{className:"flex-1 truncate text-sm text-placeholder",children:t.searchPlaceholder??"Search screens and records\u2026"}),e("kbd",{className:"hidden rounded-[5px] border border-border2 px-1.5 text-[11px] font-medium text-muted md:inline",children:"\u2318K"})]}),o("div",{className:"ml-auto flex items-center gap-2 sm:gap-2.5",children:[e(l,{variant:"ghost",size:"icon",onClick:()=>i(!0),className:d?"@min-[1220px]:hidden":"@min-[980px]:hidden","aria-label":"Search",children:e(p,{})}),t.topbarExtra?e("div",{className:"hidden sm:block",children:t.topbarExtra}):null,t.scope?e("div",{className:"hidden sm:block",children:t.scope}):null,n?e("div",{className:"hidden md:block",children:e(N,{})}):null,e(k,{}),e(w,{})]})]})})}export{I as Topbar};
1
+ "use client";import{jsx as e,jsxs as o}from"react/jsx-runtime";import{Menu as x,PanelLeft as h,Search as p}from"lucide-react";import{WaveMark as f}from"../components/brand/logo.js";import{Button as n}from"../components/ui/button.js";import{Tooltip as g}from"../components/ui/tooltip.js";import{cn as v}from"../lib/utils.js";import{useUi as s}from"../store/ui-store.js";import{AppSwitcher as N}from"./app-switcher.js";import{Notifications as k}from"./notifications.js";import{UserMenu as w}from"./user-menu.js";import{useActive as z}from"./use-active.js";function I(){const m=s(a=>a.togglePanel),i=s(a=>a.setPalette),c=s(a=>a.setMobileNav),u=s(a=>a.setLauncher),{cfg:t,app:r}=z(),b=r.icon,l=t.showAppSwitcher!==!1&&t.apps.length>1,d=t.searchClearance==="wide";return e("header",{className:"col-start-3 col-end-4 row-start-1 flex border-b border-border bg-canvas px-4 sm:px-6",children:o("div",{className:"@container relative mx-auto flex w-full max-w-[1600px] items-center gap-2 sm:gap-2.5",children:[o("div",{className:"flex min-w-0 items-center gap-2",children:[e(g,{label:"Toggle panel",shortcut:"\u2318B",children:e(n,{variant:"ghost",size:"icon",onClick:m,className:"-ml-2.5 hidden lg:inline-flex","aria-label":"Toggle module panel",children:e(h,{})})}),e(n,{variant:"ghost",size:"icon",onClick:()=>c(!0),className:"-ml-2.5 lg:hidden","aria-label":"Open navigation",children:e(x,{})}),o("button",{type:"button",onClick:()=>l?u(!0):c(!0),"aria-label":`WAVEINNO, ${r.name}`,className:"flex min-w-0 shrink items-center gap-2 rounded-full py-1 pl-0.5 pr-2 transition-colors hover:bg-hover lg:hidden",children:[o("span",{className:"relative shrink-0",children:[e(f,{size:"sm"}),e("span",{className:"absolute -bottom-0.5 -right-0.5 grid size-[13px] place-items-center rounded-full text-white ring-2 ring-canvas",style:{background:r.tint},children:e(b,{className:"size-2"})})]}),e("span",{className:`disp truncate text-[13px] font-semibold text-text ${l?"md:hidden":""}`,children:r.name})]})]}),o("button",{type:"button",onClick:()=>i(!0),className:v("absolute left-1/2 top-1/2 hidden h-[38px] -translate-x-1/2 -translate-y-1/2 cursor-text items-center gap-2.5 rounded-full border border-border bg-surface px-[15px] text-left transition-[background-color,border-color,box-shadow] hover:border-border2 focus-visible:border-primary focus-visible:bg-raised focus-visible:shadow-elev2",d?"w-[clamp(260px,calc(100%-960px),560px)] @min-[1220px]:flex":"w-[clamp(260px,calc(100%-720px),560px)] @min-[980px]:flex"),children:[e(p,{className:"size-4 shrink-0 text-muted"}),e("span",{className:"flex-1 truncate text-sm text-placeholder",children:t.searchPlaceholder??"Search screens and records\u2026"}),e("kbd",{className:"hidden rounded-[calc(5px*var(--radius-scale))] border border-border2 px-1.5 text-[11px] font-medium text-muted md:inline",children:"\u2318K"})]}),o("div",{className:"ml-auto flex items-center gap-2 sm:gap-2.5",children:[e(n,{variant:"ghost",size:"icon",onClick:()=>i(!0),className:d?"@min-[1220px]:hidden":"@min-[980px]:hidden","aria-label":"Search",children:e(p,{})}),t.topbarExtra?e("div",{className:"hidden sm:block",children:t.topbarExtra}):null,t.scope?e("div",{className:"hidden sm:block",children:t.scope}):null,l?e("div",{className:"hidden md:block",children:e(N,{})}):null,e(k,{}),e(w,{})]})]})})}export{I as Topbar};
@@ -1 +1 @@
1
- "use client";import{usePathname as l}from"next/navigation";import{useApp as u}from"../store/app-store.js";import{useShell as f}from"./config.js";import{moduleFromPath as h,navItemFromPath as v,railModules as I}from"./registry.js";function F(){const t=f(),e=l(),p=u(o=>o.appId),s=h(t.modules,e),m=v(e,s),a=o=>!!o&&t.apps.some(c=>c.id===o),r=s.app??(a(p)?p:t.apps[0].id),n=t.apps.find(o=>o.id===r)??t.apps[0],i=t.isEntitled??(()=>!0),d=I(t.modules,n.id,s.key,i);return{cfg:t,pathname:e,mod:s,item:m,app:n,rail:d,isEntitled:i}}export{F as useActive};
1
+ "use client";import{useRouterAdapter as l}from"../hooks/use-router.js";import{useApp as u}from"../store/app-store.js";import{useShell as f}from"./config.js";import{moduleFromPath as h,navItemFromPath as v,railModules as A}from"./registry.js";function P(){const t=f(),{pathname:e}=l(),p=u(o=>o.appId),s=h(t.modules,e),r=v(e,s),m=o=>!!o&&t.apps.some(c=>c.id===o),a=s.app??(m(p)?p:t.apps[0].id),n=t.apps.find(o=>o.id===a)??t.apps[0],i=t.isEntitled??(()=>!0),d=A(t.modules,n.id,s.key,i);return{cfg:t,pathname:e,mod:s,item:r,app:n,rail:d,isEntitled:i}}export{P as useActive};
@@ -1 +1 @@
1
- "use client";import{Fragment as D,jsx as e,jsxs as t}from"react/jsx-runtime";import{LogOut as l}from"lucide-react";import c from"next/link";import{Avatar as s}from"../components/ui/avatar.js";import{DropdownMenu as u,DropdownMenuContent as d,DropdownMenuItem as m,DropdownMenuLabel as x,DropdownMenuSeparator as a,DropdownMenuTrigger as g}from"../components/ui/dropdown-menu.js";import{DensityPicker as f,ThemeToggle as w}from"./appearance-controls.js";import{useShell as v}from"./config.js";function L(){const{user:n,userLinks:r=[],onSignOut:p}=v();return t(u,{children:[e(g,{className:"shrink-0 cursor-pointer rounded-full","aria-label":"Account menu",children:e(s,{name:n.name,src:n.avatar})}),t(d,{align:"end",className:"w-72",children:[t("div",{className:"flex items-center gap-2.5 px-2.5 py-2.5",children:[e(s,{name:n.name,size:"lg"}),t("div",{className:"min-w-0",children:[e("p",{className:"truncate text-[13px] font-semibold text-text",children:n.name}),e("p",{className:"truncate text-[11px] text-muted",children:n.email})]})]}),t("div",{className:"mx-2.5 mb-1 rounded-ctl bg-hover px-2.5 py-2",children:[e("p",{className:"ov",children:"Signed in as"}),e("p",{className:"mt-0.5 text-xs text-text",children:n.role}),n.context?e("p",{className:"mt-0.5 text-[11px] text-muted",children:n.context}):null]}),e(a,{}),e(x,{children:"Appearance"}),t("div",{className:"flex items-center justify-between gap-2 px-2.5 py-1.5",onClick:o=>o.stopPropagation(),children:[e("span",{className:"text-[13px] text-body",children:"Theme"}),e(w,{})]}),t("div",{className:"flex items-center justify-between gap-2 px-2.5 pb-2 pt-1",onClick:o=>o.stopPropagation(),children:[e("span",{className:"text-[13px] text-body",children:"Density"}),e(f,{compact:!0})]}),r.length?e(a,{}):null,r.map(o=>{const i=o.icon;return e(m,{asChild:!0,children:t(c,{href:o.href,children:[e(i,{}),o.label]})},o.href)}),p?t(D,{children:[e(a,{}),t(m,{danger:!0,onSelect:p,children:[e(l,{}),"Sign out"]})]}):null]})]})}export{L as UserMenu};
1
+ "use client";import{Fragment as D,jsx as e,jsxs as t}from"react/jsx-runtime";import{LogOut as l}from"lucide-react";import{Avatar as s}from"../components/ui/avatar.js";import{DropdownMenu as c,DropdownMenuContent as u,DropdownMenuItem as m,DropdownMenuLabel as d,DropdownMenuSeparator as a,DropdownMenuTrigger as x}from"../components/ui/dropdown-menu.js";import{RouterLink as g}from"../hooks/use-router.js";import{DensityPicker as f,ThemeToggle as w}from"./appearance-controls.js";import{useShell as v}from"./config.js";function L(){const{user:n,userLinks:r=[],onSignOut:p}=v();return t(c,{children:[e(x,{className:"shrink-0 cursor-pointer rounded-full","aria-label":"Account menu",children:e(s,{name:n.name,src:n.avatar})}),t(u,{align:"end",className:"w-72",children:[t("div",{className:"flex items-center gap-2.5 px-2.5 py-2.5",children:[e(s,{name:n.name,size:"lg"}),t("div",{className:"min-w-0",children:[e("p",{className:"truncate text-[13px] font-semibold text-text",children:n.name}),e("p",{className:"truncate text-[11px] text-muted",children:n.email})]})]}),t("div",{className:"mx-2.5 mb-1 rounded-ctl bg-hover px-2.5 py-2",children:[e("p",{className:"ov",children:"Signed in as"}),e("p",{className:"mt-0.5 text-xs text-text",children:n.role}),n.context?e("p",{className:"mt-0.5 text-[11px] text-muted",children:n.context}):null]}),e(a,{}),e(d,{children:"Appearance"}),t("div",{className:"flex items-center justify-between gap-2 px-2.5 py-1.5",onClick:o=>o.stopPropagation(),children:[e("span",{className:"text-[13px] text-body",children:"Theme"}),e(w,{})]}),t("div",{className:"flex items-center justify-between gap-2 px-2.5 pb-2 pt-1",onClick:o=>o.stopPropagation(),children:[e("span",{className:"text-[13px] text-body",children:"Density"}),e(f,{compact:!0})]}),r.length?e(a,{}):null,r.map(o=>{const i=o.icon;return e(m,{asChild:!0,children:t(g,{href:o.href,children:[e(i,{}),o.label]})},o.href)}),p?t(D,{children:[e(a,{}),t(m,{danger:!0,onSelect:p,children:[e(l,{}),"Sign out"]})]}):null]})]})}export{L as UserMenu};