@waveinno/ui 0.3.0 → 0.5.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 (94) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +31 -13
  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/index.d.ts +1 -0
  12. package/dist/components/patterns/index.js +1 -1
  13. package/dist/components/patterns/org-chart.d.ts +48 -0
  14. package/dist/components/patterns/org-chart.js +1 -0
  15. package/dist/components/patterns/page-header.js +1 -1
  16. package/dist/components/patterns/page-hero.js +1 -1
  17. package/dist/components/patterns/stat-card.js +1 -1
  18. package/dist/components/patterns/timeline.js +1 -1
  19. package/dist/components/ui/accordion.d.ts +30 -0
  20. package/dist/components/ui/accordion.js +1 -0
  21. package/dist/components/ui/alert.js +1 -1
  22. package/dist/components/ui/avatar.js +1 -1
  23. package/dist/components/ui/badge.js +1 -1
  24. package/dist/components/ui/button.js +1 -1
  25. package/dist/components/ui/calendar.js +1 -1
  26. package/dist/components/ui/carousel.d.ts +27 -0
  27. package/dist/components/ui/carousel.js +1 -0
  28. package/dist/components/ui/checkbox.js +1 -1
  29. package/dist/components/ui/color-picker.d.ts +14 -0
  30. package/dist/components/ui/color-picker.js +1 -0
  31. package/dist/components/ui/combobox.js +1 -1
  32. package/dist/components/ui/confirm-dialog.d.ts +24 -11
  33. package/dist/components/ui/confirm-dialog.js +1 -1
  34. package/dist/components/ui/date-picker.d.ts +18 -1
  35. package/dist/components/ui/date-picker.js +1 -1
  36. package/dist/components/ui/dialog.js +1 -1
  37. package/dist/components/ui/dropdown-menu.js +1 -1
  38. package/dist/components/ui/file-upload.d.ts +12 -4
  39. package/dist/components/ui/file-upload.js +1 -1
  40. package/dist/components/ui/hover-card.d.ts +17 -0
  41. package/dist/components/ui/hover-card.js +1 -0
  42. package/dist/components/ui/index.d.ts +10 -0
  43. package/dist/components/ui/index.js +1 -1
  44. package/dist/components/ui/kbd.js +1 -1
  45. package/dist/components/ui/menu.d.ts +24 -0
  46. package/dist/components/ui/menu.js +1 -1
  47. package/dist/components/ui/pagination.d.ts +51 -0
  48. package/dist/components/ui/pagination.js +1 -0
  49. package/dist/components/ui/password-input.js +1 -1
  50. package/dist/components/ui/pin-input.js +1 -1
  51. package/dist/components/ui/popover.js +1 -1
  52. package/dist/components/ui/progress.js +1 -1
  53. package/dist/components/ui/radio-group.js +1 -1
  54. package/dist/components/ui/rating.d.ts +27 -0
  55. package/dist/components/ui/rating.js +1 -0
  56. package/dist/components/ui/scroll-area.d.ts +17 -0
  57. package/dist/components/ui/scroll-area.js +1 -0
  58. package/dist/components/ui/segmented.d.ts +1 -1
  59. package/dist/components/ui/segmented.js +1 -1
  60. package/dist/components/ui/sheet.js +1 -1
  61. package/dist/components/ui/slider.d.ts +18 -6
  62. package/dist/components/ui/slider.js +1 -1
  63. package/dist/components/ui/spinner.js +1 -1
  64. package/dist/components/ui/steps.d.ts +36 -0
  65. package/dist/components/ui/steps.js +1 -0
  66. package/dist/components/ui/tabs.js +1 -1
  67. package/dist/components/ui/tag-input.d.ts +33 -0
  68. package/dist/components/ui/tag-input.js +1 -0
  69. package/dist/components/ui/toast.js +1 -1
  70. package/dist/components/ui/tree-view.d.ts +38 -0
  71. package/dist/components/ui/tree-view.js +1 -0
  72. package/dist/hooks/index.d.ts +1 -0
  73. package/dist/hooks/index.js +1 -1
  74. package/dist/hooks/use-router.d.ts +41 -0
  75. package/dist/hooks/use-router.js +1 -0
  76. package/dist/lib/index.d.ts +1 -0
  77. package/dist/lib/index.js +1 -1
  78. package/dist/lib/theme.d.ts +48 -0
  79. package/dist/lib/theme.js +7 -0
  80. package/dist/next/index.d.ts +6 -0
  81. package/dist/next/index.js +1 -0
  82. package/dist/shell/app-shell.js +1 -1
  83. package/dist/shell/app-switcher.js +1 -1
  84. package/dist/shell/command-palette.js +1 -1
  85. package/dist/shell/icon-rail.js +1 -1
  86. package/dist/shell/mobile-nav.js +1 -1
  87. package/dist/shell/module-sidebar.js +1 -1
  88. package/dist/shell/notifications.js +1 -1
  89. package/dist/shell/placeholder-screen.js +1 -1
  90. package/dist/shell/topbar.js +1 -1
  91. package/dist/shell/use-active.js +1 -1
  92. package/dist/shell/user-menu.js +1 -1
  93. package/dist/styles.css +91 -5
  94. package/package.json +14 -1
@@ -0,0 +1 @@
1
+ "use client";import{jsx as t,jsxs as w}from"react/jsx-runtime";import*as r from"@radix-ui/react-scroll-area";import*as a from"react";import{cn as f}from"../../lib/utils.js";function v({orientation:o}){return t(r.Scrollbar,{orientation:o,className:f("z-10 flex touch-none select-none p-0.5 transition-[background-color,opacity] duration-200 hover:bg-hover/60","data-[state=hidden]:opacity-0 data-[state=visible]:opacity-100",o==="vertical"?"h-full w-2.5":"h-2.5 flex-col"),children:t(r.Thumb,{className:"relative flex-1 rounded-full bg-border2 transition-colors hover:bg-muted/60 before:absolute before:left-1/2 before:top-1/2 before:size-full before:min-h-11 before:min-w-11 before:-translate-x-1/2 before:-translate-y-1/2"})})}const A=a.forwardRef(({className:o,children:b,orientation:p="vertical",fade:n=!1,viewportClassName:h,type:g="hover",...S},R)=>{const m=a.useRef(null),[l,x]=a.useState({top:!1,bottom:!1,left:!1,right:!1});a.useEffect(()=>{const e=m.current;if(!n||!e)return;const i=()=>x({top:e.scrollTop>2,bottom:e.scrollTop+e.clientHeight<e.scrollHeight-2,left:e.scrollLeft>2,right:e.scrollLeft+e.clientWidth<e.scrollWidth-2});i(),e.addEventListener("scroll",i,{passive:!0});const c=new ResizeObserver(i);return c.observe(e),e.firstElementChild&&c.observe(e.firstElementChild),()=>{e.removeEventListener("scroll",i),c.disconnect()}},[n]);const d=p!=="horizontal",u=p!=="vertical",s=n?[d?`linear-gradient(to bottom, ${l.top?"transparent":"#000"}, #000 28px, #000 calc(100% - 28px), ${l.bottom?"transparent":"#000"})`:null,u?`linear-gradient(to right, ${l.left?"transparent":"#000"}, #000 28px, #000 calc(100% - 28px), ${l.right?"transparent":"#000"})`:null].filter(Boolean).join(", "):void 0;return w(r.Root,{ref:R,type:g,className:f("relative overflow-hidden",o),...S,children:[t(r.Viewport,{ref:m,className:f("size-full rounded-[inherit]",h),style:s?{maskImage:s,WebkitMaskImage:s,maskComposite:"intersect",WebkitMaskComposite:"source-in"}:void 0,children:b}),d?t(v,{orientation:"vertical"}):null,u?t(v,{orientation:"horizontal"}):null,t(r.Corner,{})]})});A.displayName="ScrollArea";export{A as ScrollArea};
@@ -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};
@@ -3,13 +3,21 @@ import * as React from "react";
3
3
  /**
4
4
  * Slider — a value along a range, or a range itself (pass two values).
5
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.
6
+ * Smooth by default: while dragged the thumb follows the pointer exactly and
7
+ * the value it reports snaps to `step`; let go and the thumb settles onto the
8
+ * step. Clicks on the track and arrow keys glide rather than jump. The value
9
+ * rides above the thumb while it is held, hovered or focused
10
+ * (`showValue="always"` keeps it up); `marks` put labelled ticks under it.
11
+ *
12
+ * Looks:
13
+ * default — a slim track and a ringed thumb. Forms.
14
+ * gradient — the brand gradient with a soft glow. The one slider a screen is about.
15
+ * fat — a thick pill that fills, the value inside it (volume, brightness, capacity).
16
+ * glow — luminous fill and thumb, for dark panels and hero controls.
17
+ * stepped — a dot for every step: few, discrete choices (1–10, hours of a shift).
18
+ * minimal — a hairline and a small dot that grows when touched. Dense settings.
11
19
  */
12
- export type SliderVariant = "default" | "gradient";
20
+ export type SliderVariant = "default" | "gradient" | "fat" | "glow" | "stepped" | "minimal";
13
21
  export interface SliderProps extends Omit<React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>, "children"> {
14
22
  variant?: SliderVariant;
15
23
  /** Ticks under the track. */
@@ -20,5 +28,9 @@ export interface SliderProps extends Omit<React.ComponentPropsWithoutRef<typeof
20
28
  /** The value over the thumb: while used (default), always, or never. */
21
29
  showValue?: "active" | "always" | "never";
22
30
  format?: (value: number) => string;
31
+ /** Follow the pointer between steps while dragging (default), or move in steps. */
32
+ smooth?: boolean;
33
+ /** `fat` only: an icon at the start of the fill. */
34
+ icon?: React.ReactNode;
23
35
  }
24
36
  export declare const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<HTMLSpanElement>>;
@@ -1 +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:y,min:o=0,max:b=100,...c},_)=>{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:_,value:u,defaultValue:d,onValueChange:e=>{u===void 0&&w(e),y?.(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,#1f45ea,#7560fd)] shadow-[0_0_10px_rgba(91,74,245,.45)]":"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-[7px] bg-[#140d33] 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-[#140d33]","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};
1
+ "use client";import{jsx as s,jsxs as m}from"react/jsx-runtime";import*as f from"@radix-ui/react-slider";import*as u from"react";import{cn as l}from"../../lib/utils.js";const K={default:18,gradient:18,fat:0,glow:18,stepped:12,minimal:12},W={default:"h-1.5 bg-hover shadow-[inset_0_1px_2px_rgba(5,8,22,.08)]",gradient:"h-1.5 bg-hover shadow-[inset_0_1px_2px_rgba(5,8,22,.08)]",fat:"h-9 rounded-[calc(12px*var(--radius-scale))] bg-hover shadow-[inset_0_1px_3px_rgba(5,8,22,.1)]",glow:"h-2 bg-[color-mix(in_srgb,var(--brand-1)_14%,var(--hover))]",stepped:"h-1 bg-hover",minimal:"h-0.5 bg-border2"},Z={default:"bg-primary",gradient:"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[0_0_10px_color-mix(in_srgb,var(--brand-2)_45%,transparent)]",fat:"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[inset_0_1px_0_rgba(255,255,255,.25)]",glow:"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[0_0_14px_2px_color-mix(in_srgb,var(--brand-2)_60%,transparent),0_0_4px_color-mix(in_srgb,var(--brand-1)_80%,transparent)]",stepped:"bg-primary",minimal:"bg-text"},q={default:"size-[18px] rounded-full border-2 border-primary bg-white shadow-[0_1px_3px_rgba(5,8,22,.25)] 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)]",gradient:"size-[18px] rounded-full border-2 border-white bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] shadow-[0_2px_8px_color-mix(in_srgb,var(--brand-1)_55%,transparent)] hover:shadow-[0_2px_8px_color-mix(in_srgb,var(--brand-1)_55%,transparent),0_0_0_6px_var(--primary-subtle)] focus-visible:shadow-[0_2px_8px_color-mix(in_srgb,var(--brand-1)_55%,transparent),0_0_0_6px_var(--primary-subtle)]",fat:"h-9 w-3 -translate-x-1.5 rounded-full before:absolute before:inset-y-2.5 before:left-1/2 before:w-1 before:-translate-x-1/2 before:rounded-full before:bg-white/85 before:shadow-[0_1px_2px_rgba(5,8,22,.3)]",glow:"size-[18px] rounded-full bg-white shadow-[0_0_0_3px_color-mix(in_srgb,var(--brand-2)_55%,transparent),0_0_16px_4px_color-mix(in_srgb,var(--brand-2)_55%,transparent)] hover:shadow-[0_0_0_5px_color-mix(in_srgb,var(--brand-2)_45%,transparent),0_0_22px_6px_color-mix(in_srgb,var(--brand-2)_60%,transparent)]",stepped:"h-5 w-3 rounded-full border-2 border-primary bg-white shadow-[0_1px_3px_rgba(5,8,22,.25)] hover:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_5px_var(--primary-subtle)]",minimal:"size-3 rounded-full bg-text shadow-[0_0_0_3px_var(--canvas)] hover:scale-150 focus-visible:scale-150 active:scale-150"},J=u.forwardRef(({className:T,variant:t="default",marks:c,showValue:h="active",format:x=w=>w.toLocaleString(),smooth:v=!0,icon:V,value:N,defaultValue:L,onValueChange:A,onValueCommit:F,min:r=0,max:_=100,step:o=1,orientation:k="horizontal",...z},B)=>{const[w,D]=u.useState(L??[r]),y=N??w,[H,S]=u.useState(null),[d,R]=u.useState(!1),a=H??y,n=k==="vertical",p=t==="fat",O=(String(o).split(".")[1]??"").length,b=e=>Number(Math.min(_,Math.max(r,Math.round((e-r)/o)*o+r)).toFixed(O)),U=e=>{e.length===y.length&&e.every((i,g)=>i===y[g])||(N===void 0&&D(e),A?.(e))};u.useEffect(()=>{if(!d)return;const e=()=>{R(!1),S(null)};return window.addEventListener("pointerup",e),window.addEventListener("pointercancel",e),()=>{window.removeEventListener("pointerup",e),window.removeEventListener("pointercancel",e)}},[d]);const P=e=>(e-r)/(_-r||1)*100,$=K[t]/2,M=e=>`calc(${P(e)}% + ${$*(1-P(e)/50)}px)`,G=c?.some(e=>e.label!==void 0),C=Math.round((_-r)/o),E=e=>a.length>1?e>=a[0]-1e-9&&e<=a[a.length-1]+1e-9:e<=a[0]+1e-9,I=e=>h==="never"||p?null:s("span",{className:l("num pointer-events-none absolute whitespace-nowrap rounded-[7px] bg-ink px-2 py-1 text-[11.5px] font-semibold leading-none text-white shadow-elev2","transition-[opacity,transform] duration-200 ease-[cubic-bezier(.3,1.4,.5,1)]",n?"left-full top-1/2 ml-3 -translate-y-1/2 after:absolute after:right-full after:top-1/2 after:-translate-y-1/2 after:border-4 after:border-transparent after:border-r-[var(--ink)]":"bottom-full left-1/2 mb-2.5 -translate-x-1/2 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)]",h==="always"||d?"opacity-100":"scale-75 opacity-0 group-hover/thumb:scale-100 group-hover/thumb:opacity-100 group-focus-visible/thumb:scale-100 group-focus-visible/thumb:opacity-100"),children:x(b(e))});return m(f.Root,{ref:B,value:a,min:r,max:_,step:v&&d?o/50:o,orientation:k,"data-dragging":d?"":void 0,onPointerDownCapture:()=>{v&&R(!0)},onValueChange:e=>{v&&d&&S(e),U(e.map(b))},onValueCommit:e=>{R(!1),S(null),F?.(e.map(b))},className:l("group/slider relative flex touch-none select-none items-center data-[disabled]:opacity-50",n?"h-full min-h-40 w-fit flex-col px-2":"w-full py-2",h==="always"&&!p&&!n&&"mt-7",c&&!n&&(G?"mb-6":"mb-2"),"[&>span:has(>[role=slider])]:transition-[left,bottom] [&>span:has(>[role=slider])]:duration-200 [&>span:has(>[role=slider])]:ease-[cubic-bezier(.3,.7,.2,1)]","data-[dragging]:[&>span:has(>[role=slider])]:transition-none",T),...z,children:[m(f.Track,{className:l("relative grow overflow-hidden rounded-full",W[t],n&&"!h-full w-1.5"),children:[s(f.Range,{className:l("absolute transition-[left,right,top,bottom] duration-200 ease-[cubic-bezier(.3,.7,.2,1)] group-data-[dragging]/slider:transition-none",n?"w-full":"h-full",p?"rounded-[inherit]":"rounded-full",Z[t])}),p?m("span",{className:"pointer-events-none absolute inset-y-0 left-3 flex items-center gap-2 text-[13px] font-semibold text-white [&_svg]:size-4",children:[V,s("span",{className:"num drop-shadow-[0_1px_1px_rgba(5,8,22,.3)]",children:x(b(a[a.length-1]??r))})]}):null]}),t==="stepped"&&C<=40&&!n?Array.from({length:C+1},(e,i)=>{const g=r+i*o;return s("span",{"aria-hidden":!0,className:l("pointer-events-none absolute top-1/2 size-1.5 -translate-x-1/2 -translate-y-1/2 rounded-full transition-colors duration-200",E(g)?"bg-primary":"bg-border2"),style:{left:M(g)}},i)}):null,c&&!n?c.map(e=>m("span",{"aria-hidden":!0,className:"pointer-events-none absolute top-full -translate-x-1/2",style:{left:M(e.value)},children:[s("span",{className:l("mx-auto -mt-1.5 block h-1.5 w-px",E(e.value)?"bg-primary/50":"bg-border2")}),e.label!==void 0?s("span",{className:"num mt-1 block whitespace-nowrap text-[11px] text-muted",children:e.label}):null]},e.value)):null,a.map((e,i)=>s(f.Thumb,{"aria-label":a.length>1?i===0?"Minimum":"Maximum":z["aria-label"],"aria-valuetext":x(b(e)),className:l("group/thumb relative block cursor-grab outline-none transition-[box-shadow,transform] duration-150 active:cursor-grabbing",t!=="fat"&&t!=="minimal"&&"active:scale-110",p&&"focus-visible:ring-2 focus-visible:ring-white/70",q[t]),children:I(e)},i))]})});J.displayName="Slider";export{J as Slider};
@@ -1 +1 @@
1
- import{jsx as n,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 u({variant:i="ring",size:o="md",tone:s="current",label:c="Loading",className:d}){const e=m[o],p=s==="brand"?"text-primary":void 0;let r;if(i==="ring"){const a=Math.max(2,Math.round(e/9));r=n("span",{className:"block animate-spin rounded-full [animation-duration:.75s]",style:{width:e,height:e,background:s==="brand"?"conic-gradient(from 90deg, transparent 10%, #1f45ea 60%, #7560fd)":"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(e/4.5));r=n("span",{className:"flex items-center",style:{gap:a*.7,height:e},children:[0,1,2].map(t=>n("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(e/8));r=n("span",{className:"flex items-center",style:{gap:a*.8,height:e},children:[0,1,2,3,4].map(t=>n("span",{className:l("wm-bar block h-full rounded-full",s==="brand"?"bg-[linear-gradient(180deg,#7560fd,#1f45ea)]":"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,d),children:[r,n("span",{className:"sr-only",children:c})]})}export{u as Spinner};
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};
@@ -0,0 +1,36 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Steps — where a person is in a flow of a few parts: sign-up, adding a site,
4
+ * a booking. Done steps carry a tick, the current one is ringed, the rest wait.
5
+ *
6
+ * Looks:
7
+ * circle — the default: a numbered disc per step on a line that fills.
8
+ * glow — gradient discs, the current one pulsing with light. Onboarding, hero flows.
9
+ * dot — small markers: many steps, or a narrow column.
10
+ * bar — segments that fill, labels under them. A wizard's header.
11
+ * card — a card per step, the current one lifted. Set-up screens with room.
12
+ * chevron — arrow-shaped segments joined end to end. Checkout and process flows.
13
+ * circle, glow and dot also run vertically, with each step's description (and,
14
+ * if given, its `content`) beside its marker. Pass `onStepClick` and finished
15
+ * steps become links back.
16
+ */
17
+ export type StepsVariant = "circle" | "glow" | "dot" | "bar" | "card" | "chevron";
18
+ export interface StepItem {
19
+ title: React.ReactNode;
20
+ description?: React.ReactNode;
21
+ /** Replaces the number in the disc. */
22
+ icon?: React.ReactNode;
23
+ /** Vertical only: shown under the current step. */
24
+ content?: React.ReactNode;
25
+ }
26
+ export interface StepsProps {
27
+ steps: StepItem[];
28
+ /** Index of the current step, from 0. Equal to steps.length when all are done. */
29
+ current: number;
30
+ variant?: StepsVariant;
31
+ orientation?: "horizontal" | "vertical";
32
+ /** Makes finished steps clickable. */
33
+ onStepClick?: (index: number) => void;
34
+ className?: string;
35
+ }
36
+ export declare function Steps({ steps, current, variant, orientation, onStepClick, className }: StepsProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{Fragment as _,jsx as e,jsxs as l}from"react/jsx-runtime";import{Check as x}from"lucide-react";import{cn as n}from"../../lib/utils.js";function N({state:o,index:d,icon:i,variant:b}){return b==="dot"?l("span",{className:"relative grid size-4 shrink-0 place-items-center",children:[o==="current"?e("span",{className:"absolute inset-0 animate-ping rounded-full bg-primary/30 [animation-duration:2s]"}):null,e("span",{className:n("relative rounded-full transition-all duration-300",o==="todo"?"size-2.5 border-2 border-border2 bg-raised":"size-3 bg-primary shadow-[0_0_0_4px_var(--primary-subtle)]")})]}):b==="glow"?l("span",{className:"relative grid size-9 shrink-0 place-items-center",children:[o==="current"?l(_,{children:[e("span",{className:"absolute inset-0 animate-ping rounded-full bg-[color-mix(in_srgb,var(--brand-2)_35%,transparent)] [animation-duration:2.2s]"}),e("span",{className:"absolute -inset-1 rounded-full bg-[conic-gradient(from_0deg,var(--brand-1),var(--brand-2),var(--brand-1))] opacity-60 blur-[6px]"})]}):null,e("span",{className:n("relative grid size-9 place-items-center rounded-full text-[12.5px] font-semibold transition-[background,box-shadow,color] duration-300 [&_svg]:size-4",o==="todo"?"border border-border2 bg-raised text-muted":"bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_6px_16px_-6px_var(--brand-1)]",o==="current"&&"ring-[3px] ring-[var(--raised)]"),children:o==="done"?e(x,{strokeWidth:3,className:"animate-[wm-pop_220ms_var(--ease)]"}):i??e("span",{className:"num",children:d+1})})]}):e("span",{className:n("relative grid size-8 shrink-0 place-items-center rounded-full border text-[12.5px] font-semibold transition-[background-color,border-color,color,box-shadow] duration-300 [&_svg]:size-4",o==="done"&&"border-transparent bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_4px_10px_-4px_color-mix(in_srgb,var(--brand-1)_70%,transparent)]",o==="current"&&"border-primary bg-raised text-primary shadow-[0_0_0_4px_var(--primary-subtle)]",o==="todo"&&"border-border2 bg-raised text-muted"),children:o==="done"?e(x,{strokeWidth:3,className:"animate-[wm-pop_220ms_var(--ease)]"}):i??e("span",{className:"num",children:d+1})})}function R({steps:o,current:d,variant:i="circle",orientation:b="horizontal",onStepClick:p,className:u}){const m=a=>a<d?"done":a===d?"current":"todo",g=(a,t)=>{const r=m(a),s=!!p&&r==="done",c=l(_,{children:[e("span",{className:n("block text-[13px] font-semibold leading-5",r==="todo"?"text-muted":"text-text"),children:t.title}),t.description?e("span",{className:"block text-[12px] leading-[17px] text-muted",children:t.description}):null]});return s?e("button",{type:"button",onClick:()=>p(a),className:"cursor-pointer rounded-[6px] text-left outline-none hover:[&>span:first-child]:text-primary focus-visible:ring-2 focus-visible:ring-primary/40",children:c}):e("div",{children:c})};if(i==="card")return e("ol",{className:n("grid gap-3",u),style:{gridTemplateColumns:`repeat(${o.length}, minmax(0, 1fr))`},children:o.map((a,t)=>{const r=m(t),s=!!p&&r==="done";return e("li",{"aria-current":r==="current"?"step":void 0,className:"min-w-0",children:l(s?"button":"div",{...s?{type:"button",onClick:()=>p(t)}:{},className:n("relative flex h-full w-full flex-col gap-2 overflow-hidden rounded-[calc(14px*var(--radius-scale))] border p-3.5 text-left outline-none transition-[border-color,box-shadow,transform,background-color] duration-300",s&&"cursor-pointer hover:border-primary/40 focus-visible:ring-2 focus-visible:ring-primary/40",r==="current"&&"-translate-y-0.5 border-primary bg-raised shadow-[0_0_0_3px_var(--primary-subtle),0_12px_28px_-16px_color-mix(in_srgb,var(--primary)_60%,transparent)]",r==="done"&&"border-border bg-raised",r==="todo"&&"border-dashed border-border2 bg-surface"),children:[r==="current"?e("span",{"aria-hidden":!0,className:"absolute inset-x-0 top-0 h-[3px] bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))]"}):null,l("span",{className:"flex items-center justify-between gap-2",children:[l("span",{className:n("text-[10.5px] font-semibold uppercase tracking-[0.08em]",r==="todo"?"text-placeholder":"text-primary"),children:["Step ",t+1]}),r==="done"?e("span",{className:"grid size-5 place-items-center rounded-full bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white [&_svg]:size-3",children:e(x,{strokeWidth:3.5})}):r==="current"?e("span",{className:"size-2 animate-pulse rounded-full bg-primary"}):null]}),a.icon?e("span",{className:n("[&_svg]:size-5",r==="todo"?"text-muted":"text-primary"),children:a.icon}):null,l("span",{children:[e("span",{className:n("block text-[13.5px] font-semibold leading-5",r==="todo"?"text-muted":"text-text"),children:a.title}),a.description?e("span",{className:"block text-[12px] leading-[17px] text-muted",children:a.description}):null]})]})},t)})});if(i==="chevron")return e("ol",{className:n("flex w-full",u),children:o.map((t,r)=>{const s=m(r),c=r===0,f=r===o.length-1,w=`polygon(0 0, ${f?"100%":"calc(100% - 14px)"} 0, 100% 50%, ${f?"100%":"calc(100% - 14px)"} 100%, 0 100%, ${c?"0":"14px"} 50%)`,v=!!p&&s==="done";return e("li",{"aria-current":s==="current"?"step":void 0,className:n("relative min-w-0 flex-1",!c&&"-ml-1.5"),style:{zIndex:o.length-r},children:l("button",{type:"button",disabled:!v,onClick:v?()=>p(r):void 0,style:{clipPath:w},className:n("flex h-12 w-full items-center gap-2.5 text-left outline-none transition-[background,color,filter] duration-300 disabled:cursor-default",c?"pl-4":"pl-7",f?"pr-4":"pr-6",v&&"cursor-pointer hover:brightness-95",s==="current"&&"bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white",s==="done"&&"bg-primary-subtle text-primary",s==="todo"&&"bg-hover text-muted"),children:[e("span",{className:n("grid size-6 shrink-0 place-items-center rounded-full text-[11.5px] font-semibold [&_svg]:size-3.5",s==="current"?"bg-white/20 text-white":s==="done"?"bg-primary text-white":"border border-border2 bg-raised"),children:s==="done"?e(x,{strokeWidth:3.5}):e("span",{className:"num",children:r+1})}),l("span",{className:"min-w-0",children:[e("span",{className:"block truncate text-[13px] font-semibold",children:t.title}),t.description?e("span",{className:n("block truncate text-[11px]",s==="current"?"text-white/80":"text-muted"),children:t.description}):null]})]})},r)})});if(i==="bar")return e("ol",{className:n("grid gap-3",u),style:{gridTemplateColumns:`repeat(${o.length}, minmax(0, 1fr))`},children:o.map((a,t)=>{const r=m(t);return l("li",{"aria-current":r==="current"?"step":void 0,className:"min-w-0",children:[e("span",{className:"block h-1.5 overflow-hidden rounded-full bg-hover",children:e("span",{className:n("block h-full rounded-full bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] transition-[width] duration-500 ease-[var(--ease)]",r==="todo"?"w-0":r==="current"?"w-1/2":"w-full")})}),l("span",{className:n("mt-2 block text-[11px] font-semibold uppercase tracking-[0.06em]",r==="todo"?"text-placeholder":"text-primary"),children:["Step ",t+1]}),e("div",{className:"mt-0.5",children:g(t,a)})]},t)})});if(b==="vertical")return e("ol",{className:n("relative",u),children:o.map((a,t)=>{const r=m(t),s=t===o.length-1;return l("li",{"aria-current":r==="current"?"step":void 0,className:"relative flex gap-3.5 pb-6 last:pb-0",children:[s?null:e("span",{"aria-hidden":!0,className:n("absolute w-0.5 overflow-hidden rounded-full bg-border",i==="dot"?"bottom-0 left-[7px] top-5":i==="glow"?"bottom-1 left-[17px] top-11":"bottom-1 left-[15px] top-10"),children:e("span",{className:n("block w-full bg-[linear-gradient(180deg,var(--brand-1),var(--brand-2))] transition-[height] duration-500 ease-[var(--ease)]",r==="done"?"h-full":"h-0")})}),e(N,{state:r,index:t,icon:a.icon,variant:i}),l("div",{className:n("min-w-0 flex-1",i==="circle"?"pt-1.5":i==="glow"?"pt-2":"-mt-0.5"),children:[g(t,a),a.content&&r==="current"?e("div",{className:"mt-3 animate-[wave-in_220ms_var(--ease)]",children:a.content}):null]})]},t)})});const h=(a,t)=>e("span",{className:n("relative h-0.5 flex-1 overflow-hidden bg-border",t&&"invisible"),children:e("span",{className:n("absolute inset-y-0 left-0 bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] transition-[width] duration-500 ease-[var(--ease)]",a?"w-full":"w-0")})});return e("ol",{className:n("flex items-start",u),children:o.map((a,t)=>{const r=m(t);return l("li",{"aria-current":r==="current"?"step":void 0,className:"flex min-w-0 flex-1 flex-col items-center text-center",children:[l("div",{className:"flex w-full items-center gap-1.5",children:[h(t<=d,t===0),e(N,{state:r,index:t,icon:a.icon,variant:i}),h(t<d,t===o.length-1)]}),e("div",{className:"mt-2 max-w-[180px] px-1",children:g(t,a)})]},t)})})}export{R as Steps};
@@ -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,33 @@
1
+ import * as React from "react";
2
+ import { type InputState } from "./input";
3
+ /**
4
+ * TagInput — a field that holds several short values: plates on a pass,
5
+ * emails to notify, labels on a site.
6
+ *
7
+ * Enter, comma or Tab turns the text into a tag; a pasted list ("a, b, c" or
8
+ * one per line) becomes several at once. Backspace in an empty field first
9
+ * marks the last tag, then removes it, so nothing goes by accident. Duplicates
10
+ * are refused, `max` caps the count, and `validate` can reject a value with a
11
+ * reason that shows under the field. `suggestions` offers completions as you type.
12
+ *
13
+ * Tag looks: `soft` (default), `outline`, `solid`.
14
+ */
15
+ export type TagVariant = "soft" | "outline" | "solid";
16
+ export interface TagInputProps {
17
+ value?: string[];
18
+ defaultValue?: string[];
19
+ onValueChange?: (tags: string[]) => void;
20
+ placeholder?: string;
21
+ suggestions?: string[];
22
+ max?: number;
23
+ /** Return a reason to refuse a tag, or nothing to accept it. */
24
+ validate?: (tag: string) => string | void | undefined | null;
25
+ /** Change a tag before it is added: trim, upper-case a plate. */
26
+ transform?: (tag: string) => string;
27
+ variant?: TagVariant;
28
+ state?: InputState;
29
+ disabled?: boolean;
30
+ "aria-label"?: string;
31
+ className?: string;
32
+ }
33
+ export declare function TagInput({ value, defaultValue, onValueChange, placeholder, suggestions, max, validate, transform, variant, state, disabled, "aria-label": ariaLabel, className, }: TagInputProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as i,jsxs as g}from"react/jsx-runtime";import{Plus as O,X}from"lucide-react";import*as o from"react";import{cn as f}from"../../lib/utils.js";const J={soft:"bg-primary-subtle text-primary",outline:"border border-border2 bg-raised text-text",solid:"bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.2)]"};function Z({value:C,defaultValue:P=[],onValueChange:V,placeholder:z="Add\u2026",suggestions:l,max:s,validate:R,transform:$=v=>v.trim(),variant:I="soft",state:h="default",disabled:T,"aria-label":U,className:B}){const[v,F]=o.useState(P),r=C??v,[a,m]=o.useState(""),[_,u]=o.useState(!1),[d,w]=o.useState(null),[y,k]=o.useState(0),[q,L]=o.useState(!1),N=o.useRef(null),S=o.useId(),A=o.useId(),D=e=>{C===void 0&&F(e),V?.(e)},E=s!==void 0&&r.length>=s,b=e=>{const t=[...r];let n=null;for(const H of e){const p=$(H);if(!p)continue;if(s!==void 0&&t.length>=s){n=`Up to ${s}`;break}if(t.some(K=>K.toLowerCase()===p.toLowerCase())){n=`\u201C${p}\u201D is already in`;continue}const M=R?.(p);if(M){n=M;continue}t.push(p)}w(n),t.length!==r.length&&D(t)},c=o.useMemo(()=>{if(!l||!a.trim())return[];const e=a.trim().toLowerCase();return l.filter(t=>t.toLowerCase().includes(e)&&!r.some(n=>n.toLowerCase()===t.toLowerCase())).slice(0,6)},[l,a,r]),x=q&&c.length>0,G=e=>{D(r.filter((t,n)=>n!==e)),w(null),N.current?.focus()};return g("div",{className:f("relative w-full",B),children:[g("div",{onClick:()=>N.current?.focus(),className:f("flex min-h-ctl w-full cursor-text flex-wrap items-center gap-1.5 rounded-ctl border border-border2 bg-raised px-1.5 py-1 transition-[border-color,box-shadow] duration-150","focus-within:border-primary focus-within:ring-2 focus-within:ring-primary/20",(h==="error"||d)&&"border-danger focus-within:border-danger focus-within:ring-danger/20",h==="success"&&"border-success",T&&"pointer-events-none bg-hover opacity-60"),children:[r.map((e,t)=>g("span",{className:f("inline-flex h-6 max-w-full animate-[wm-pop_180ms_var(--ease)] items-center gap-1 rounded-[calc(6px*var(--radius-scale))] pl-2 pr-0.5 text-[12.5px] font-medium transition-shadow",J[I],_&&t===r.length-1&&"ring-2 ring-danger/60 ring-offset-1 ring-offset-[var(--raised)]"),children:[i("span",{className:"truncate",children:e}),i("button",{type:"button","aria-label":`Remove ${e}`,onClick:n=>{n.stopPropagation(),G(t)},className:f("grid size-5 cursor-pointer place-items-center rounded-[5px] opacity-70 transition-[opacity,background-color] hover:opacity-100",I==="solid"?"hover:bg-white/20":"hover:bg-black/5 dark:hover:bg-white/10"),children:i(X,{className:"size-3"})})]},e)),i("input",{ref:N,value:a,disabled:T||E,"aria-label":U,"aria-invalid":!!d||h==="error"||void 0,"aria-describedby":d?A:void 0,role:l?"combobox":void 0,"aria-expanded":l?x:void 0,"aria-controls":l?S:void 0,placeholder:E?`Up to ${s}`:r.length?"":z,onFocus:()=>L(!0),onBlur:()=>{L(!1),u(!1),a.trim()&&(b([a]),m(""))},onChange:e=>{m(e.target.value),u(!1),k(0),d&&w(null)},onPaste:e=>{const t=e.clipboardData.getData("text");/[,\n;]/.test(t)&&(e.preventDefault(),b(t.split(/[,\n;]+/)))},onKeyDown:e=>{if(x&&(e.key==="ArrowDown"||e.key==="ArrowUp")){e.preventDefault(),k(t=>(t+(e.key==="ArrowDown"?1:-1)+c.length)%c.length);return}if(e.key==="Enter"||e.key===","||e.key==="Tab"&&a.trim()){if(!a.trim()&&e.key!==",")return;e.preventDefault(),b([x&&e.key==="Enter"?c[y]:a]),m("")}else e.key==="Backspace"&&!a&&r.length?(e.preventDefault(),_?(D(r.slice(0,-1)),u(!1)):u(!0)):e.key==="Escape"&&u(!1)},className:"h-6 min-w-[80px] flex-1 bg-transparent px-1 text-[13px] text-text outline-none placeholder:text-placeholder disabled:cursor-not-allowed"}),s!==void 0?g("span",{className:"num ml-auto shrink-0 px-1 text-[11px] text-muted",children:[r.length,"/",s]}):null]}),x?i("ul",{id:S,role:"listbox",className:"absolute inset-x-0 top-full z-30 mt-1 overflow-hidden rounded-[calc(10px*var(--radius-scale))] border border-border bg-raised p-1 shadow-elev3 animate-[wave-in_160ms_var(--ease)]",children:c.map((e,t)=>g("li",{role:"option","aria-selected":t===y,onMouseDown:n=>{n.preventDefault(),b([e]),m("")},onMouseEnter:()=>k(t),className:f("flex cursor-pointer items-center gap-2 rounded-[calc(7px*var(--radius-scale))] px-2.5 py-1.5 text-[13px]",t===y?"bg-hover text-text":"text-body"),children:[i(O,{className:"size-3.5 text-muted"})," ",e]},e))}):null,d?i("p",{id:A,role:"alert",className:"mt-1.5 text-[12px] text-danger",children:d}):null]})}export{Z as TagInput};
@@ -1 +1 @@
1
- "use client";import{jsx as r}from"react/jsx-runtime";import{CircleAlert as a,CircleCheck as n,Info as i,LoaderCircle as s,TriangleAlert as d}from"lucide-react";import{Toaster as p,toast as c}from"sonner";const e=(t,o)=>r("span",{className:"grid size-7 place-items-center rounded-[8px] [&_svg]:size-4",style:{color:`var(--${t})`,background:`var(--${t}-subtle)`},children:o});function b({position:t="bottom-right",...o}){return r(p,{position:t,gap:10,icons:{success:e("success",r(n,{})),error:e("danger",r(a,{})),warning:e("warning",r(d,{})),info:e("info",r(i,{})),loading:e("primary",r(s,{className:"animate-spin"}))},toastOptions:{unstyled:!0,classNames:{toast:"group flex w-[356px] max-w-[calc(100vw-32px)] items-start gap-3 rounded-[14px] 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:"mt-px shrink-0 [&>svg]:hidden [&>span]:flex",content:"min-w-0 flex-1 pt-[5px]",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-[8px] 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-[8px] 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))]!"}},...o})}export{b as Toaster,c as toast};
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};
@@ -0,0 +1,38 @@
1
+ import * as React from "react";
2
+ /**
3
+ * TreeView — things inside things: sites → levels → bays, folders, an org.
4
+ *
5
+ * Branches fold with a turning chevron and guide lines show the depth.
6
+ * `selectable` picks one node; `checkable` adds checkboxes where a parent is
7
+ * ticked when all its children are, and half-ticked when some are (ticking a
8
+ * parent ticks everything under it). Keyboard follows the WAI-ARIA tree: ↑ ↓
9
+ * move, → opens or steps in, ← closes or steps out, Home / End, Enter / Space.
10
+ */
11
+ export interface TreeNode {
12
+ id: string;
13
+ label: React.ReactNode;
14
+ icon?: React.ReactNode;
15
+ /** On the right: a count, a status. */
16
+ badge?: React.ReactNode;
17
+ children?: TreeNode[];
18
+ disabled?: boolean;
19
+ }
20
+ export interface TreeViewProps {
21
+ data: TreeNode[];
22
+ expanded?: string[];
23
+ defaultExpanded?: string[];
24
+ onExpandedChange?: (ids: string[]) => void;
25
+ selected?: string | null;
26
+ defaultSelected?: string | null;
27
+ onSelectedChange?: (id: string) => void;
28
+ /** Checkboxes with tri-state parents. The value holds leaf ids. */
29
+ checkable?: boolean;
30
+ checked?: string[];
31
+ defaultChecked?: string[];
32
+ onCheckedChange?: (leafIds: string[]) => void;
33
+ /** Lines from each branch to its children. */
34
+ guides?: boolean;
35
+ "aria-label"?: string;
36
+ className?: string;
37
+ }
38
+ export declare function TreeView({ data, expanded: expandedProp, defaultExpanded, onExpandedChange, selected: selectedProp, defaultSelected, onSelectedChange, checkable, checked: checkedProp, defaultChecked, onCheckedChange, guides, "aria-label": ariaLabel, className, }: TreeViewProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as d,jsxs as R}from"react/jsx-runtime";import{Check as X,ChevronRight as Y,Minus as Z}from"lucide-react";import*as T from"react";import{cn as u}from"../../lib/utils.js";const k=o=>o.children?.length?o.children.flatMap(k):[o.id];function S(o,x,b){const[v,N]=T.useState(x);return[o!==void 0?o:v,r=>{o===void 0&&N(r),b?.(r)}]}function te({data:o,expanded:x,defaultExpanded:b=[],onExpandedChange:v,selected:N,defaultSelected:C=null,onSelectedChange:E,checkable:r,checked:O,defaultChecked:U=[],onCheckedChange:W,guides:q=!0,"aria-label":_="Tree",className:$}){const[z,B]=S(x,b,v),[L,A]=S(N,C,e=>e&&E?.(e)),[D,G]=S(O,U,W),[y,I]=T.useState(null),M=T.useRef(null),m=new Set(z),H=new Set(D),a=[],K=(e,i)=>{for(const n of e)a.push({node:n,parent:i}),n.children?.length&&m.has(n.id)&&K(n.children,n.id)};K(o,null);const J=y&&a.some(e=>e.node.id===y)?y:L??a[0]?.node.id,f=(e,i)=>{const n=new Set(z);i??!n.has(e)?n.add(e):n.delete(e),B([...n])},P=e=>{const i=k(e),n=i.every(s=>H.has(s)),t=new Set(D);i.forEach(s=>n?t.delete(s):t.add(s)),G([...t])},c=e=>{e&&(I(e),M.current?.querySelector(`[data-tree-id="${CSS.escape(e)}"]`)?.focus())},Q=(e,i,n)=>{const t=a.findIndex(h=>h.node.id===i.id),s=!!i.children?.length;let l=!0;if(e.key==="ArrowDown")c(a[t+1]?.node.id);else if(e.key==="ArrowUp")c(a[t-1]?.node.id);else if(e.key==="Home")c(a[0]?.node.id);else if(e.key==="End")c(a[a.length-1]?.node.id);else if(e.key==="ArrowRight")s&&!m.has(i.id)?f(i.id,!0):s&&c(i.children[0].id);else if(e.key==="ArrowLeft")s&&m.has(i.id)?f(i.id,!1):n&&c(n);else if(e.key==="Enter"||e.key===" "){if(i.disabled)return;r?P(i):A(i.id),s&&!r&&e.key==="Enter"&&f(i.id)}else l=!1;l&&e.preventDefault()},V=(e,i,n)=>e.map(t=>{const s=!!t.children?.length,l=s&&m.has(t.id),h=r?k(t):[],F=h.filter(g=>H.has(g)).length,p=r?F===0?!1:F===h.length?!0:"mixed":null,w=!r&&L===t.id;return R("li",{role:"none",children:[R("div",{role:"treeitem","data-tree-id":t.id,"aria-level":i+1,"aria-expanded":s?l:void 0,"aria-selected":r?void 0:w,"aria-checked":r?p==="mixed"?"mixed":!!p:void 0,"aria-disabled":t.disabled||void 0,tabIndex:t.id===J?0:-1,onFocus:()=>I(t.id),onKeyDown:g=>Q(g,t,n),onClick:()=>{t.disabled||(r?P(t):A(t.id),s&&!r&&f(t.id))},className:u("group/tree relative flex min-h-[32px] cursor-pointer select-none items-center gap-1.5 rounded-[calc(8px*var(--radius-scale))] pr-2 text-[13px] outline-none transition-colors","focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary/40",w?"bg-primary-subtle font-medium text-primary":"text-body hover:bg-hover hover:text-text",t.disabled&&"pointer-events-none opacity-45"),style:{paddingLeft:6+i*18},children:[s?d("span",{role:"presentation",onClick:g=>{r&&(g.stopPropagation(),f(t.id))},className:"grid size-5 shrink-0 place-items-center rounded-[5px] text-muted hover:bg-border/60",children:d(Y,{className:u("size-3.5 transition-transform duration-200 ease-[var(--ease)]",l&&"rotate-90")})}):d("span",{className:"size-5 shrink-0"}),r?d("span",{"aria-hidden":!0,className:u("grid size-4 shrink-0 place-items-center rounded-[4px] border transition-colors",p?"border-primary bg-primary text-white":"border-border2 bg-raised"),children:p==="mixed"?d(Z,{className:"size-3",strokeWidth:3}):p?d(X,{className:"size-3",strokeWidth:3}):null}):null,t.icon?d("span",{className:u("grid shrink-0 place-items-center [&_svg]:size-4",w?"text-primary":"text-muted group-hover/tree:text-text"),children:t.icon}):null,d("span",{className:"min-w-0 flex-1 truncate",children:t.label}),t.badge]}),s?d("div",{className:u("grid transition-[grid-template-rows] duration-250 ease-[var(--ease)]",l?"grid-rows-[1fr]":"grid-rows-[0fr]"),children:R("div",{className:"relative min-h-0 overflow-hidden",children:[q?d("span",{"aria-hidden":!0,className:"absolute bottom-1.5 top-0 w-px bg-border",style:{left:15+i*18}}):null,d("ul",{role:"group",inert:!l,children:V(t.children,i+1,t.id)})]})}):null]},t.id)});return d("ul",{ref:M,role:"tree","aria-label":_,"aria-multiselectable":r||void 0,className:u("space-y-px",$),children:V(o,0,null)})}export{te as TreeView};
@@ -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 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),a=d(o=>o.hydrate),m=d(o=>o.syncFromRoute),h=f(o=>o.togglePanel),l=g(),{cfg:p,pathname:y,mod:n,rail:v}=F();i.useEffect(()=>{r(),a(p.apps.map(o=>o.id))},[r,a,p.apps]),i.useEffect(()=>{m(n.app)},[n.app,m]),S({key:"b",mod:!0},h);const s=v.order;return N(i.useCallback(o=>{const c=s[o];c&&l.push(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
+ "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};