@invergent/ui-sdk 2.19.1 → 2.19.3

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 (40) hide show
  1. package/README.md +3 -2
  2. package/dist/chip.cjs +3 -3
  3. package/dist/chip.cjs.map +1 -1
  4. package/dist/chip.d.cts +2 -4
  5. package/dist/chip.d.ts +2 -4
  6. package/dist/chip.js +3 -3
  7. package/dist/chip.js.map +1 -1
  8. package/dist/{chunk-IVMZANP7.cjs → chunk-ILCP5QXL.cjs} +6 -3
  9. package/dist/chunk-ILCP5QXL.cjs.map +1 -0
  10. package/dist/{chunk-CPAFEXKR.js → chunk-WO2SXSNH.js} +6 -3
  11. package/dist/chunk-WO2SXSNH.js.map +1 -0
  12. package/dist/collapsible-header.cjs +14 -3
  13. package/dist/collapsible-header.cjs.map +1 -1
  14. package/dist/collapsible-header.d.cts +4 -1
  15. package/dist/collapsible-header.d.ts +4 -1
  16. package/dist/collapsible-header.js +14 -3
  17. package/dist/collapsible-header.js.map +1 -1
  18. package/dist/confirm-dialog.cjs +5 -3
  19. package/dist/confirm-dialog.cjs.map +1 -1
  20. package/dist/confirm-dialog.d.cts +4 -1
  21. package/dist/confirm-dialog.d.ts +4 -1
  22. package/dist/confirm-dialog.js +5 -3
  23. package/dist/confirm-dialog.js.map +1 -1
  24. package/dist/tab-strip.cjs +74 -0
  25. package/dist/tab-strip.cjs.map +1 -0
  26. package/dist/tab-strip.d.cts +22 -0
  27. package/dist/tab-strip.d.ts +22 -0
  28. package/dist/tab-strip.js +71 -0
  29. package/dist/tab-strip.js.map +1 -0
  30. package/dist/toggle-group.cjs +4 -2
  31. package/dist/toggle-group.cjs.map +1 -1
  32. package/dist/toggle-group.js +3 -1
  33. package/dist/toggle-group.js.map +1 -1
  34. package/dist/toggle.cjs +4 -4
  35. package/dist/toggle.d.cts +1 -1
  36. package/dist/toggle.d.ts +1 -1
  37. package/dist/toggle.js +1 -1
  38. package/package.json +1 -1
  39. package/dist/chunk-CPAFEXKR.js.map +0 -1
  40. package/dist/chunk-IVMZANP7.cjs.map +0 -1
package/README.md CHANGED
@@ -48,12 +48,13 @@ the kit carries Work's own components:
48
48
  | `sidebar` | `Sidebar`, `SidebarBrand`, `SidebarUserBar`, `SidebarAction`, `useSidebar` | The desktop sidebar: open, or an icon rail that opens on hover, with the pin toggle at its bottom. `ListRow` and `SectionLabel` inside it collapse with the rail; outside it (a phone drawer) the parts draw open. |
49
49
  | `list-row` | `ListRow`, `ListGroup` | A list entry (icon, label, description, count, chevron) in three densities; a button, or any link via `asChild`. |
50
50
  | `section-label` | `SectionLabel` | A rule and a quiet word starting a group of rows. |
51
- | `collapsible-header` | `CollapsibleHeader` | A styled `CollapsibleTrigger`: `nav` (a group in a list of rows) or `section` (a disclosure). |
52
- | `chip` | `Chip`, `TonePill`, `TagPill`, `TONE` | Round chips by tone (`ok`, `warn`, `bad`, `muted`), removable with `onRemove`. |
51
+ | `collapsible-header` | `CollapsibleHeader` | A styled `CollapsibleTrigger`: `nav` (a group in a list of rows) or `section` (a disclosure; `size="sm"` for the compact one). |
52
+ | `chip` | `Chip`, `TonePill`, `TagPill`, `TONE` | Round chips by tone (`ok`, `warn`, `bad`, `info`, `muted`), removable with `onRemove`. |
53
53
  | `choice-card` | `ChoiceCard` | A selectable option card (`aria-pressed`), amber when picked. |
54
54
  | `text-link` | `TextLink` | Amber or muted text link; `asChild` for router links. |
55
55
  | `segmented-control` | `SegmentedControl` | The Work / Dev mode switch, for any two or three peers. |
56
56
  | `toggle`, `toggle-group` | `FilterPill`, `ViewSwitch`, `useRememberedView` | A list filter pill; a tab's view switch. |
57
+ | `tab-strip` | `TabStrip`, `TabStripTab` | A compact strip of tabs that close (a browser's open pages). |
57
58
  | `pill-tabs` | `PillTabs` | A page's section tabs as a bare strip (`tabs` draws the same over Radix). |
58
59
  | `empty-state` | `EmptyState`, `EmptyStateLogo` | The brand badge, a heading, copy and actions for an empty list. |
59
60
  | `stat-card` | `StatCard`, `InfoHint`, `ChannelChip` | A stat tile: label, value, hint, detail. |
package/dist/chip.cjs CHANGED
@@ -9,6 +9,7 @@ var TONE = {
9
9
  ok: "bg-emerald-500/12 text-emerald-700 dark:text-emerald-300",
10
10
  warn: "bg-amber-500/14 text-amber-700 dark:text-amber-300",
11
11
  bad: "bg-red-500/12 text-red-700 dark:text-red-300",
12
+ info: "bg-sky-500/12 text-sky-700 dark:text-sky-300",
12
13
  muted: "bg-foreground/[0.06] text-muted-foreground"
13
14
  };
14
15
  var chipVariants = classVarianceAuthority.cva(
@@ -60,10 +61,9 @@ function Chip({
60
61
  }
61
62
  function TonePill({
62
63
  tone,
63
- className,
64
- children
64
+ ...props
65
65
  }) {
66
- return /* @__PURE__ */ jsxRuntime.jsx(Chip, { tone, size: "sm", className, children });
66
+ return /* @__PURE__ */ jsxRuntime.jsx(Chip, { tone, size: "sm", ...props });
67
67
  }
68
68
  function TagPill({
69
69
  label,
package/dist/chip.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chip.tsx"],"names":["cva","jsxs","cn","jsx","XIcon"],"mappings":";;;;;;;AAUO,IAAM,IAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,0DAAA;AAAA,EACJ,IAAA,EAAM,oDAAA;AAAA,EACN,GAAA,EAAK,8CAAA;AAAA,EACL,KAAA,EAAO;AACT;AAIA,IAAM,YAAA,GAAeA,0BAAA;AAAA,EACnB,uIAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,IAAA;AAAA,MACN,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,2BAAA;AAAA,QACJ,OAAA,EAAS,qBAAA;AAAA,QACT,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,SAAA;AAAU;AAEtD;AAEA,SAAS,IAAA,CAAK;AAAA,EACZ,IAAA,GAAO,OAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,QAAA;AAAA,EACA,WAAA,GAAc,QAAA;AAAA,EACd,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAOG;AACD,EAAA,uBACEC,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,MAAA;AAAA,MACV,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAWC,oBAAA,CAAG,YAAA,CAAa,EAAE,IAAA,EAAM,MAAM,CAAA,EAAG,QAAA,IAAY,MAAA,EAAQ,SAAS,CAAA;AAAA,MACxE,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,QACA,QAAA,oBACCC,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YAGL,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,EAAe;AAAA,YACrC,OAAA,EAAS,QAAA;AAAA,YACT,YAAA,EAAY,WAAA;AAAA,YAEZ,SAAA,EAAU,mSAAA;AAAA,YAEV,QAAA,kBAAAA,cAAA,CAACC,iBAAA,EAAA,EAAM,SAAA,EAAU,UAAA,EAAW;AAAA;AAAA;AAC9B;AAAA;AAAA,GAEJ;AAEJ;AAGA,SAAS,QAAA,CAAS;AAAA,EAChB,IAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,sCACG,IAAA,EAAA,EAAK,IAAA,EAAY,IAAA,EAAK,IAAA,EAAK,WACzB,QAAA,EACH,CAAA;AAEJ;AAGA,SAAS,OAAA,CAAQ;AAAA,EACf,KAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAKG;AACD,EAAA,uBACED,cAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,IAAA,KAAS,IAAA,GAAO,SAAA,GAAY,IAAA;AAAA,MAClC,QAAA;AAAA,MACA,WAAA,EAAa,cAAc,KAAK,CAAA,CAAA;AAAA,MAChC,SAAA,EAAWD,oBAAA,CAAG,aAAA,EAAe,SAAS,CAAA;AAAA,MAErC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ","file":"chip.cjs","sourcesContent":["import * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\nexport type Tone = \"ok\" | \"warn\" | \"bad\" | \"muted\"\n\n// The Work console's status tones: a faint wash of the colour with text a\n// step darker in light mode and a step lighter in dark.\nexport const TONE: Record<Tone, string> = {\n ok: \"bg-emerald-500/12 text-emerald-700 dark:text-emerald-300\",\n warn: \"bg-amber-500/14 text-amber-700 dark:text-amber-300\",\n bad: \"bg-red-500/12 text-red-700 dark:text-red-300\",\n muted: \"bg-foreground/[0.06] text-muted-foreground\",\n}\n\n// One chip for statuses (TonePill), tags and removable values (TagPill):\n// round, medium weight, tinted by tone.\nconst chipVariants = cva(\n \"inline-flex w-fit shrink-0 items-center gap-1 rounded-full font-medium whitespace-nowrap [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n tone: TONE,\n size: {\n sm: \"px-2 py-0.5 text-[11.5px]\",\n default: \"px-2 py-0.5 text-xs\",\n lg: \"px-2.5 py-0.5 text-sm\",\n },\n },\n defaultVariants: { tone: \"muted\", size: \"default\" },\n }\n)\n\nfunction Chip({\n tone = \"muted\",\n size = \"default\",\n onRemove,\n removeLabel = \"Remove\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"span\"> & {\n tone?: Tone\n size?: \"sm\" | \"default\" | \"lg\"\n /** Shows an × that calls this. */\n onRemove?: () => void\n /** The ×'s accessible name. */\n removeLabel?: string\n}) {\n return (\n <span\n data-slot=\"chip\"\n data-tone={tone}\n className={cn(chipVariants({ tone, size }), onRemove && \"pr-1\", className)}\n {...props}\n >\n {children}\n {onRemove && (\n <button\n type=\"button\"\n // preventDefault on mousedown keeps the adjacent input focused so\n // removing a chip doesn't trigger its blur-to-commit handler.\n onMouseDown={(e) => e.preventDefault()}\n onClick={onRemove}\n aria-label={removeLabel}\n // The × is 10px; the overlay gives it a usable hit area.\n className=\"relative inline-flex cursor-pointer items-center justify-center rounded-full border-none bg-transparent p-0.5 text-current opacity-60 transition-opacity outline-none after:absolute after:-inset-1.5 hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring/40\"\n >\n <XIcon className=\"size-2.5\" />\n </button>\n )}\n </span>\n )\n}\n\n/** A status chip (\"Active\", \"Paused\") in one of the tones. */\nfunction TonePill({\n tone,\n className,\n children,\n}: {\n tone?: Tone\n className?: string\n children: React.ReactNode\n}) {\n return (\n <Chip tone={tone} size=\"sm\" className={className}>\n {children}\n </Chip>\n )\n}\n\n/** A tag, removable when `onRemove` is given. */\nfunction TagPill({\n label,\n onRemove,\n size = \"xs\",\n className,\n}: {\n label: string\n onRemove?: () => void\n size?: \"xs\" | \"sm\"\n className?: string\n}) {\n return (\n <Chip\n size={size === \"xs\" ? \"default\" : \"lg\"}\n onRemove={onRemove}\n removeLabel={`Remove tag ${label}`}\n className={cn(\"font-normal\", className)}\n >\n {label}\n </Chip>\n )\n}\n\nexport { Chip, TonePill, TagPill, chipVariants }\n"]}
1
+ {"version":3,"sources":["../src/chip.tsx"],"names":["cva","jsxs","cn","jsx","XIcon"],"mappings":";;;;;;;AAUO,IAAM,IAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,0DAAA;AAAA,EACJ,IAAA,EAAM,oDAAA;AAAA,EACN,GAAA,EAAK,8CAAA;AAAA,EACL,IAAA,EAAM,8CAAA;AAAA,EACN,KAAA,EAAO;AACT;AAIA,IAAM,YAAA,GAAeA,0BAAA;AAAA,EACnB,uIAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,IAAA;AAAA,MACN,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,2BAAA;AAAA,QACJ,OAAA,EAAS,qBAAA;AAAA,QACT,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,SAAA;AAAU;AAEtD;AAEA,SAAS,IAAA,CAAK;AAAA,EACZ,IAAA,GAAO,OAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,QAAA;AAAA,EACA,WAAA,GAAc,QAAA;AAAA,EACd,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAOG;AACD,EAAA,uBACEC,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,MAAA;AAAA,MACV,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAWC,oBAAA,CAAG,YAAA,CAAa,EAAE,IAAA,EAAM,MAAM,CAAA,EAAG,QAAA,IAAY,MAAA,EAAQ,SAAS,CAAA;AAAA,MACxE,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,QACA,QAAA,oBACCC,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YAGL,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,EAAe;AAAA,YACrC,OAAA,EAAS,QAAA;AAAA,YACT,YAAA,EAAY,WAAA;AAAA,YAEZ,SAAA,EAAU,mSAAA;AAAA,YAEV,QAAA,kBAAAA,cAAA,CAACC,iBAAA,EAAA,EAAM,SAAA,EAAU,UAAA,EAAW;AAAA;AAAA;AAC9B;AAAA;AAAA,GAEJ;AAEJ;AAGA,SAAS,QAAA,CAAS;AAAA,EAChB,IAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAqE;AACnE,EAAA,sCAAQ,IAAA,EAAA,EAAK,IAAA,EAAY,IAAA,EAAK,IAAA,EAAM,GAAG,KAAA,EAAO,CAAA;AAChD;AAGA,SAAS,OAAA,CAAQ;AAAA,EACf,KAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAKG;AACD,EAAA,uBACED,cAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,IAAA,KAAS,IAAA,GAAO,SAAA,GAAY,IAAA;AAAA,MAClC,QAAA;AAAA,MACA,WAAA,EAAa,cAAc,KAAK,CAAA,CAAA;AAAA,MAChC,SAAA,EAAWD,oBAAA,CAAG,aAAA,EAAe,SAAS,CAAA;AAAA,MAErC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ","file":"chip.cjs","sourcesContent":["import * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\nexport type Tone = \"ok\" | \"warn\" | \"bad\" | \"info\" | \"muted\"\n\n// The Work console's status tones: a faint wash of the colour with text a\n// step darker in light mode and a step lighter in dark.\nexport const TONE: Record<Tone, string> = {\n ok: \"bg-emerald-500/12 text-emerald-700 dark:text-emerald-300\",\n warn: \"bg-amber-500/14 text-amber-700 dark:text-amber-300\",\n bad: \"bg-red-500/12 text-red-700 dark:text-red-300\",\n info: \"bg-sky-500/12 text-sky-700 dark:text-sky-300\",\n muted: \"bg-foreground/[0.06] text-muted-foreground\",\n}\n\n// One chip for statuses (TonePill), tags and removable values (TagPill):\n// round, medium weight, tinted by tone.\nconst chipVariants = cva(\n \"inline-flex w-fit shrink-0 items-center gap-1 rounded-full font-medium whitespace-nowrap [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n tone: TONE,\n size: {\n sm: \"px-2 py-0.5 text-[11.5px]\",\n default: \"px-2 py-0.5 text-xs\",\n lg: \"px-2.5 py-0.5 text-sm\",\n },\n },\n defaultVariants: { tone: \"muted\", size: \"default\" },\n }\n)\n\nfunction Chip({\n tone = \"muted\",\n size = \"default\",\n onRemove,\n removeLabel = \"Remove\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"span\"> & {\n tone?: Tone\n size?: \"sm\" | \"default\" | \"lg\"\n /** Shows an × that calls this. */\n onRemove?: () => void\n /** The ×'s accessible name. */\n removeLabel?: string\n}) {\n return (\n <span\n data-slot=\"chip\"\n data-tone={tone}\n className={cn(chipVariants({ tone, size }), onRemove && \"pr-1\", className)}\n {...props}\n >\n {children}\n {onRemove && (\n <button\n type=\"button\"\n // preventDefault on mousedown keeps the adjacent input focused so\n // removing a chip doesn't trigger its blur-to-commit handler.\n onMouseDown={(e) => e.preventDefault()}\n onClick={onRemove}\n aria-label={removeLabel}\n // The × is 10px; the overlay gives it a usable hit area.\n className=\"relative inline-flex cursor-pointer items-center justify-center rounded-full border-none bg-transparent p-0.5 text-current opacity-60 transition-opacity outline-none after:absolute after:-inset-1.5 hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring/40\"\n >\n <XIcon className=\"size-2.5\" />\n </button>\n )}\n </span>\n )\n}\n\n/** A status chip (\"Active\", \"Paused\") in one of the tones. */\nfunction TonePill({\n tone,\n ...props\n}: Omit<React.ComponentProps<\"span\">, \"onRemove\"> & { tone?: Tone }) {\n return <Chip tone={tone} size=\"sm\" {...props} />\n}\n\n/** A tag, removable when `onRemove` is given. */\nfunction TagPill({\n label,\n onRemove,\n size = \"xs\",\n className,\n}: {\n label: string\n onRemove?: () => void\n size?: \"xs\" | \"sm\"\n className?: string\n}) {\n return (\n <Chip\n size={size === \"xs\" ? \"default\" : \"lg\"}\n onRemove={onRemove}\n removeLabel={`Remove tag ${label}`}\n className={cn(\"font-normal\", className)}\n >\n {label}\n </Chip>\n )\n}\n\nexport { Chip, TonePill, TagPill, chipVariants }\n"]}
package/dist/chip.d.cts CHANGED
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as class_variance_authority_types from 'class-variance-authority/types';
3
3
  import * as React from 'react';
4
4
 
5
- type Tone = "ok" | "warn" | "bad" | "muted";
5
+ type Tone = "ok" | "warn" | "bad" | "info" | "muted";
6
6
  declare const TONE: Record<Tone, string>;
7
7
  declare const chipVariants: (props?: ({
8
8
  tone?: Tone | null | undefined;
@@ -17,10 +17,8 @@ declare function Chip({ tone, size, onRemove, removeLabel, className, children,
17
17
  removeLabel?: string;
18
18
  }): react_jsx_runtime.JSX.Element;
19
19
  /** A status chip ("Active", "Paused") in one of the tones. */
20
- declare function TonePill({ tone, className, children, }: {
20
+ declare function TonePill({ tone, ...props }: Omit<React.ComponentProps<"span">, "onRemove"> & {
21
21
  tone?: Tone;
22
- className?: string;
23
- children: React.ReactNode;
24
22
  }): react_jsx_runtime.JSX.Element;
25
23
  /** A tag, removable when `onRemove` is given. */
26
24
  declare function TagPill({ label, onRemove, size, className, }: {
package/dist/chip.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as class_variance_authority_types from 'class-variance-authority/types';
3
3
  import * as React from 'react';
4
4
 
5
- type Tone = "ok" | "warn" | "bad" | "muted";
5
+ type Tone = "ok" | "warn" | "bad" | "info" | "muted";
6
6
  declare const TONE: Record<Tone, string>;
7
7
  declare const chipVariants: (props?: ({
8
8
  tone?: Tone | null | undefined;
@@ -17,10 +17,8 @@ declare function Chip({ tone, size, onRemove, removeLabel, className, children,
17
17
  removeLabel?: string;
18
18
  }): react_jsx_runtime.JSX.Element;
19
19
  /** A status chip ("Active", "Paused") in one of the tones. */
20
- declare function TonePill({ tone, className, children, }: {
20
+ declare function TonePill({ tone, ...props }: Omit<React.ComponentProps<"span">, "onRemove"> & {
21
21
  tone?: Tone;
22
- className?: string;
23
- children: React.ReactNode;
24
22
  }): react_jsx_runtime.JSX.Element;
25
23
  /** A tag, removable when `onRemove` is given. */
26
24
  declare function TagPill({ label, onRemove, size, className, }: {
package/dist/chip.js CHANGED
@@ -7,6 +7,7 @@ var TONE = {
7
7
  ok: "bg-emerald-500/12 text-emerald-700 dark:text-emerald-300",
8
8
  warn: "bg-amber-500/14 text-amber-700 dark:text-amber-300",
9
9
  bad: "bg-red-500/12 text-red-700 dark:text-red-300",
10
+ info: "bg-sky-500/12 text-sky-700 dark:text-sky-300",
10
11
  muted: "bg-foreground/[0.06] text-muted-foreground"
11
12
  };
12
13
  var chipVariants = cva(
@@ -58,10 +59,9 @@ function Chip({
58
59
  }
59
60
  function TonePill({
60
61
  tone,
61
- className,
62
- children
62
+ ...props
63
63
  }) {
64
- return /* @__PURE__ */ jsx(Chip, { tone, size: "sm", className, children });
64
+ return /* @__PURE__ */ jsx(Chip, { tone, size: "sm", ...props });
65
65
  }
66
66
  function TagPill({
67
67
  label,
package/dist/chip.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chip.tsx"],"names":[],"mappings":";;;;;AAUO,IAAM,IAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,0DAAA;AAAA,EACJ,IAAA,EAAM,oDAAA;AAAA,EACN,GAAA,EAAK,8CAAA;AAAA,EACL,KAAA,EAAO;AACT;AAIA,IAAM,YAAA,GAAe,GAAA;AAAA,EACnB,uIAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,IAAA;AAAA,MACN,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,2BAAA;AAAA,QACJ,OAAA,EAAS,qBAAA;AAAA,QACT,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,SAAA;AAAU;AAEtD;AAEA,SAAS,IAAA,CAAK;AAAA,EACZ,IAAA,GAAO,OAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,QAAA;AAAA,EACA,WAAA,GAAc,QAAA;AAAA,EACd,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAOG;AACD,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,MAAA;AAAA,MACV,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA,CAAG,YAAA,CAAa,EAAE,IAAA,EAAM,MAAM,CAAA,EAAG,QAAA,IAAY,MAAA,EAAQ,SAAS,CAAA;AAAA,MACxE,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,QACA,QAAA,oBACC,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YAGL,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,EAAe;AAAA,YACrC,OAAA,EAAS,QAAA;AAAA,YACT,YAAA,EAAY,WAAA;AAAA,YAEZ,SAAA,EAAU,mSAAA;AAAA,YAEV,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,UAAA,EAAW;AAAA;AAAA;AAC9B;AAAA;AAAA,GAEJ;AAEJ;AAGA,SAAS,QAAA,CAAS;AAAA,EAChB,IAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,2BACG,IAAA,EAAA,EAAK,IAAA,EAAY,IAAA,EAAK,IAAA,EAAK,WACzB,QAAA,EACH,CAAA;AAEJ;AAGA,SAAS,OAAA,CAAQ;AAAA,EACf,KAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAKG;AACD,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,IAAA,KAAS,IAAA,GAAO,SAAA,GAAY,IAAA;AAAA,MAClC,QAAA;AAAA,MACA,WAAA,EAAa,cAAc,KAAK,CAAA,CAAA;AAAA,MAChC,SAAA,EAAW,EAAA,CAAG,aAAA,EAAe,SAAS,CAAA;AAAA,MAErC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ","file":"chip.js","sourcesContent":["import * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\nexport type Tone = \"ok\" | \"warn\" | \"bad\" | \"muted\"\n\n// The Work console's status tones: a faint wash of the colour with text a\n// step darker in light mode and a step lighter in dark.\nexport const TONE: Record<Tone, string> = {\n ok: \"bg-emerald-500/12 text-emerald-700 dark:text-emerald-300\",\n warn: \"bg-amber-500/14 text-amber-700 dark:text-amber-300\",\n bad: \"bg-red-500/12 text-red-700 dark:text-red-300\",\n muted: \"bg-foreground/[0.06] text-muted-foreground\",\n}\n\n// One chip for statuses (TonePill), tags and removable values (TagPill):\n// round, medium weight, tinted by tone.\nconst chipVariants = cva(\n \"inline-flex w-fit shrink-0 items-center gap-1 rounded-full font-medium whitespace-nowrap [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n tone: TONE,\n size: {\n sm: \"px-2 py-0.5 text-[11.5px]\",\n default: \"px-2 py-0.5 text-xs\",\n lg: \"px-2.5 py-0.5 text-sm\",\n },\n },\n defaultVariants: { tone: \"muted\", size: \"default\" },\n }\n)\n\nfunction Chip({\n tone = \"muted\",\n size = \"default\",\n onRemove,\n removeLabel = \"Remove\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"span\"> & {\n tone?: Tone\n size?: \"sm\" | \"default\" | \"lg\"\n /** Shows an × that calls this. */\n onRemove?: () => void\n /** The ×'s accessible name. */\n removeLabel?: string\n}) {\n return (\n <span\n data-slot=\"chip\"\n data-tone={tone}\n className={cn(chipVariants({ tone, size }), onRemove && \"pr-1\", className)}\n {...props}\n >\n {children}\n {onRemove && (\n <button\n type=\"button\"\n // preventDefault on mousedown keeps the adjacent input focused so\n // removing a chip doesn't trigger its blur-to-commit handler.\n onMouseDown={(e) => e.preventDefault()}\n onClick={onRemove}\n aria-label={removeLabel}\n // The × is 10px; the overlay gives it a usable hit area.\n className=\"relative inline-flex cursor-pointer items-center justify-center rounded-full border-none bg-transparent p-0.5 text-current opacity-60 transition-opacity outline-none after:absolute after:-inset-1.5 hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring/40\"\n >\n <XIcon className=\"size-2.5\" />\n </button>\n )}\n </span>\n )\n}\n\n/** A status chip (\"Active\", \"Paused\") in one of the tones. */\nfunction TonePill({\n tone,\n className,\n children,\n}: {\n tone?: Tone\n className?: string\n children: React.ReactNode\n}) {\n return (\n <Chip tone={tone} size=\"sm\" className={className}>\n {children}\n </Chip>\n )\n}\n\n/** A tag, removable when `onRemove` is given. */\nfunction TagPill({\n label,\n onRemove,\n size = \"xs\",\n className,\n}: {\n label: string\n onRemove?: () => void\n size?: \"xs\" | \"sm\"\n className?: string\n}) {\n return (\n <Chip\n size={size === \"xs\" ? \"default\" : \"lg\"}\n onRemove={onRemove}\n removeLabel={`Remove tag ${label}`}\n className={cn(\"font-normal\", className)}\n >\n {label}\n </Chip>\n )\n}\n\nexport { Chip, TonePill, TagPill, chipVariants }\n"]}
1
+ {"version":3,"sources":["../src/chip.tsx"],"names":[],"mappings":";;;;;AAUO,IAAM,IAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,0DAAA;AAAA,EACJ,IAAA,EAAM,oDAAA;AAAA,EACN,GAAA,EAAK,8CAAA;AAAA,EACL,IAAA,EAAM,8CAAA;AAAA,EACN,KAAA,EAAO;AACT;AAIA,IAAM,YAAA,GAAe,GAAA;AAAA,EACnB,uIAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,IAAA;AAAA,MACN,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,2BAAA;AAAA,QACJ,OAAA,EAAS,qBAAA;AAAA,QACT,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,SAAA;AAAU;AAEtD;AAEA,SAAS,IAAA,CAAK;AAAA,EACZ,IAAA,GAAO,OAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,QAAA;AAAA,EACA,WAAA,GAAc,QAAA;AAAA,EACd,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAOG;AACD,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,MAAA;AAAA,MACV,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA,CAAG,YAAA,CAAa,EAAE,IAAA,EAAM,MAAM,CAAA,EAAG,QAAA,IAAY,MAAA,EAAQ,SAAS,CAAA;AAAA,MACxE,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,QACA,QAAA,oBACC,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YAGL,WAAA,EAAa,CAAC,CAAA,KAAM,CAAA,CAAE,cAAA,EAAe;AAAA,YACrC,OAAA,EAAS,QAAA;AAAA,YACT,YAAA,EAAY,WAAA;AAAA,YAEZ,SAAA,EAAU,mSAAA;AAAA,YAEV,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,UAAA,EAAW;AAAA;AAAA;AAC9B;AAAA;AAAA,GAEJ;AAEJ;AAGA,SAAS,QAAA,CAAS;AAAA,EAChB,IAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAqE;AACnE,EAAA,2BAAQ,IAAA,EAAA,EAAK,IAAA,EAAY,IAAA,EAAK,IAAA,EAAM,GAAG,KAAA,EAAO,CAAA;AAChD;AAGA,SAAS,OAAA,CAAQ;AAAA,EACf,KAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAKG;AACD,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,IAAA,KAAS,IAAA,GAAO,SAAA,GAAY,IAAA;AAAA,MAClC,QAAA;AAAA,MACA,WAAA,EAAa,cAAc,KAAK,CAAA,CAAA;AAAA,MAChC,SAAA,EAAW,EAAA,CAAG,aAAA,EAAe,SAAS,CAAA;AAAA,MAErC,QAAA,EAAA;AAAA;AAAA,GACH;AAEJ","file":"chip.js","sourcesContent":["import * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\nexport type Tone = \"ok\" | \"warn\" | \"bad\" | \"info\" | \"muted\"\n\n// The Work console's status tones: a faint wash of the colour with text a\n// step darker in light mode and a step lighter in dark.\nexport const TONE: Record<Tone, string> = {\n ok: \"bg-emerald-500/12 text-emerald-700 dark:text-emerald-300\",\n warn: \"bg-amber-500/14 text-amber-700 dark:text-amber-300\",\n bad: \"bg-red-500/12 text-red-700 dark:text-red-300\",\n info: \"bg-sky-500/12 text-sky-700 dark:text-sky-300\",\n muted: \"bg-foreground/[0.06] text-muted-foreground\",\n}\n\n// One chip for statuses (TonePill), tags and removable values (TagPill):\n// round, medium weight, tinted by tone.\nconst chipVariants = cva(\n \"inline-flex w-fit shrink-0 items-center gap-1 rounded-full font-medium whitespace-nowrap [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n tone: TONE,\n size: {\n sm: \"px-2 py-0.5 text-[11.5px]\",\n default: \"px-2 py-0.5 text-xs\",\n lg: \"px-2.5 py-0.5 text-sm\",\n },\n },\n defaultVariants: { tone: \"muted\", size: \"default\" },\n }\n)\n\nfunction Chip({\n tone = \"muted\",\n size = \"default\",\n onRemove,\n removeLabel = \"Remove\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"span\"> & {\n tone?: Tone\n size?: \"sm\" | \"default\" | \"lg\"\n /** Shows an × that calls this. */\n onRemove?: () => void\n /** The ×'s accessible name. */\n removeLabel?: string\n}) {\n return (\n <span\n data-slot=\"chip\"\n data-tone={tone}\n className={cn(chipVariants({ tone, size }), onRemove && \"pr-1\", className)}\n {...props}\n >\n {children}\n {onRemove && (\n <button\n type=\"button\"\n // preventDefault on mousedown keeps the adjacent input focused so\n // removing a chip doesn't trigger its blur-to-commit handler.\n onMouseDown={(e) => e.preventDefault()}\n onClick={onRemove}\n aria-label={removeLabel}\n // The × is 10px; the overlay gives it a usable hit area.\n className=\"relative inline-flex cursor-pointer items-center justify-center rounded-full border-none bg-transparent p-0.5 text-current opacity-60 transition-opacity outline-none after:absolute after:-inset-1.5 hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:ring-ring/40\"\n >\n <XIcon className=\"size-2.5\" />\n </button>\n )}\n </span>\n )\n}\n\n/** A status chip (\"Active\", \"Paused\") in one of the tones. */\nfunction TonePill({\n tone,\n ...props\n}: Omit<React.ComponentProps<\"span\">, \"onRemove\"> & { tone?: Tone }) {\n return <Chip tone={tone} size=\"sm\" {...props} />\n}\n\n/** A tag, removable when `onRemove` is given. */\nfunction TagPill({\n label,\n onRemove,\n size = \"xs\",\n className,\n}: {\n label: string\n onRemove?: () => void\n size?: \"xs\" | \"sm\"\n className?: string\n}) {\n return (\n <Chip\n size={size === \"xs\" ? \"default\" : \"lg\"}\n onRemove={onRemove}\n removeLabel={`Remove tag ${label}`}\n className={cn(\"font-normal\", className)}\n >\n {label}\n </Chip>\n )\n}\n\nexport { Chip, TonePill, TagPill, chipVariants }\n"]}
@@ -16,7 +16,10 @@ var toggleVariants = classVarianceAuthority.cva(
16
16
  size: {
17
17
  default: "min-h-10 px-3 text-[13px] pointer-fine:min-h-8",
18
18
  sm: "min-h-9 px-3 text-[12px] pointer-fine:min-h-7",
19
- lg: "min-h-11 px-4 text-sm pointer-fine:min-h-9"
19
+ lg: "min-h-11 px-4 text-sm pointer-fine:min-h-9",
20
+ // Square, as the Button's icon sizes: 44px on touch.
21
+ icon: "size-9 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0",
22
+ "icon-xs": "size-7 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0"
20
23
  }
21
24
  },
22
25
  defaultVariants: {
@@ -63,5 +66,5 @@ function FilterPill({
63
66
  exports.FilterPill = FilterPill;
64
67
  exports.Toggle = Toggle;
65
68
  exports.toggleVariants = toggleVariants;
66
- //# sourceMappingURL=chunk-IVMZANP7.cjs.map
67
- //# sourceMappingURL=chunk-IVMZANP7.cjs.map
69
+ //# sourceMappingURL=chunk-ILCP5QXL.cjs.map
70
+ //# sourceMappingURL=chunk-ILCP5QXL.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/toggle.tsx"],"names":["cva","jsx","TogglePrimitive","cn"],"mappings":";;;;;;;AAWA,IAAM,cAAA,GAAiBA,0BAAA;AAAA,EACrB,oVAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,6NAAA;AAAA,QACF,OAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,gDAAA;AAAA,QACT,EAAA,EAAI,+CAAA;AAAA,QACJ,EAAA,EAAI,4CAAA;AAAA;AAAA,QAEJ,IAAA,EAAM,yEAAA;AAAA,QACN,SAAA,EACE;AAAA;AACJ,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EACuC;AACrC,EAAA,uBACEC,cAAA;AAAA,IAACC,cAAA,CAAgB,IAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAWC,qBAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,UAAA,CAAW;AAAA,EAClB,EAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAQG;AACD,EAAA,uBACEF,cAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,SAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MACL,OAAA,EAAS,EAAA;AAAA,MACT,eAAA,EAAiB,MAAM,OAAA,EAAQ;AAAA,MAC/B,WAAWE,oBAAA,CAAG,GAAA,IAAO,CAAC,EAAA,IAAM,cAAc,SAAS,CAAA;AAAA,MAClD,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-ILCP5QXL.cjs","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's pressed-state toggles. `default` is the 9px chip its\n// forms use for a choice that is on or off (Once / Repeating, the days of the\n// week): a faint box, amber-tinted once pressed. `outline` is its filter\n// pill: round, bordered, a neutral fill once on. Muted text brightens on\n// hover. Touch keeps 40px or more, a mouse the compact height.\nconst toggleVariants = cva(\n \"group/toggle inline-flex shrink-0 items-center justify-center gap-1.5 border whitespace-nowrap transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5\",\n {\n variants: {\n variant: {\n default:\n \"rounded-[9px] border-foreground/[0.08] bg-foreground/[0.04] font-medium text-muted-foreground hover:text-foreground data-[state=on]:border-amber-500/40 data-[state=on]:bg-amber-500/[0.12] data-[state=on]:text-foreground\",\n outline:\n \"rounded-full border-foreground/10 text-muted-foreground hover:text-foreground data-[state=on]:border-foreground/30 data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n },\n size: {\n default: \"min-h-10 px-3 text-[13px] pointer-fine:min-h-8\",\n sm: \"min-h-9 px-3 text-[12px] pointer-fine:min-h-7\",\n lg: \"min-h-11 px-4 text-sm pointer-fine:min-h-9\",\n // Square, as the Button's icon sizes: 44px on touch.\n icon: \"size-9 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0\",\n \"icon-xs\":\n \"size-7 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Toggle({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\n/**\n * The Work filter pill (a row of them filters a list: \"All channels\",\n * \"Slack 3\"…). An empty filter stays clickable, just quieter.\n */\nfunction FilterPill({\n on,\n onClick,\n dim,\n className,\n ...props\n}: Omit<\n React.ComponentProps<typeof TogglePrimitive.Root>,\n \"pressed\" | \"onPressedChange\" | \"onClick\"\n> & {\n on: boolean\n onClick: () => void\n /** Nothing behind it yet: still clickable, just quieter. */\n dim?: boolean\n}) {\n return (\n <Toggle\n variant=\"outline\"\n size=\"sm\"\n pressed={on}\n onPressedChange={() => onClick()}\n className={cn(dim && !on && \"opacity-55\", className)}\n {...props}\n />\n )\n}\n\nexport { Toggle, FilterPill, toggleVariants }\n"]}
@@ -14,7 +14,10 @@ var toggleVariants = cva(
14
14
  size: {
15
15
  default: "min-h-10 px-3 text-[13px] pointer-fine:min-h-8",
16
16
  sm: "min-h-9 px-3 text-[12px] pointer-fine:min-h-7",
17
- lg: "min-h-11 px-4 text-sm pointer-fine:min-h-9"
17
+ lg: "min-h-11 px-4 text-sm pointer-fine:min-h-9",
18
+ // Square, as the Button's icon sizes: 44px on touch.
19
+ icon: "size-9 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0",
20
+ "icon-xs": "size-7 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0"
18
21
  }
19
22
  },
20
23
  defaultVariants: {
@@ -59,5 +62,5 @@ function FilterPill({
59
62
  }
60
63
 
61
64
  export { FilterPill, Toggle, toggleVariants };
62
- //# sourceMappingURL=chunk-CPAFEXKR.js.map
63
- //# sourceMappingURL=chunk-CPAFEXKR.js.map
65
+ //# sourceMappingURL=chunk-WO2SXSNH.js.map
66
+ //# sourceMappingURL=chunk-WO2SXSNH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/toggle.tsx"],"names":["TogglePrimitive"],"mappings":";;;;;AAWA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,oVAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,6NAAA;AAAA,QACF,OAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,gDAAA;AAAA,QACT,EAAA,EAAI,+CAAA;AAAA,QACJ,EAAA,EAAI,4CAAA;AAAA;AAAA,QAEJ,IAAA,EAAM,yEAAA;AAAA,QACN,SAAA,EACE;AAAA;AACJ,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EACuC;AACrC,EAAA,uBACE,GAAA;AAAA,IAACA,QAAA,CAAgB,IAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,UAAA,CAAW;AAAA,EAClB,EAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAQG;AACD,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,SAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MACL,OAAA,EAAS,EAAA;AAAA,MACT,eAAA,EAAiB,MAAM,OAAA,EAAQ;AAAA,MAC/B,WAAW,EAAA,CAAG,GAAA,IAAO,CAAC,EAAA,IAAM,cAAc,SAAS,CAAA;AAAA,MAClD,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-WO2SXSNH.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's pressed-state toggles. `default` is the 9px chip its\n// forms use for a choice that is on or off (Once / Repeating, the days of the\n// week): a faint box, amber-tinted once pressed. `outline` is its filter\n// pill: round, bordered, a neutral fill once on. Muted text brightens on\n// hover. Touch keeps 40px or more, a mouse the compact height.\nconst toggleVariants = cva(\n \"group/toggle inline-flex shrink-0 items-center justify-center gap-1.5 border whitespace-nowrap transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5\",\n {\n variants: {\n variant: {\n default:\n \"rounded-[9px] border-foreground/[0.08] bg-foreground/[0.04] font-medium text-muted-foreground hover:text-foreground data-[state=on]:border-amber-500/40 data-[state=on]:bg-amber-500/[0.12] data-[state=on]:text-foreground\",\n outline:\n \"rounded-full border-foreground/10 text-muted-foreground hover:text-foreground data-[state=on]:border-foreground/30 data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n },\n size: {\n default: \"min-h-10 px-3 text-[13px] pointer-fine:min-h-8\",\n sm: \"min-h-9 px-3 text-[12px] pointer-fine:min-h-7\",\n lg: \"min-h-11 px-4 text-sm pointer-fine:min-h-9\",\n // Square, as the Button's icon sizes: 44px on touch.\n icon: \"size-9 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0\",\n \"icon-xs\":\n \"size-7 min-h-11 min-w-11 px-0 pointer-fine:min-h-0 pointer-fine:min-w-0\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Toggle({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\n/**\n * The Work filter pill (a row of them filters a list: \"All channels\",\n * \"Slack 3\"…). An empty filter stays clickable, just quieter.\n */\nfunction FilterPill({\n on,\n onClick,\n dim,\n className,\n ...props\n}: Omit<\n React.ComponentProps<typeof TogglePrimitive.Root>,\n \"pressed\" | \"onPressedChange\" | \"onClick\"\n> & {\n on: boolean\n onClick: () => void\n /** Nothing behind it yet: still clickable, just quieter. */\n dim?: boolean\n}) {\n return (\n <Toggle\n variant=\"outline\"\n size=\"sm\"\n pressed={on}\n onPressedChange={() => onClick()}\n className={cn(dim && !on && \"opacity-55\", className)}\n {...props}\n />\n )\n}\n\nexport { Toggle, FilterPill, toggleVariants }\n"]}
@@ -13,14 +13,22 @@ var collapsibleHeaderVariants = classVarianceAuthority.cva(
13
13
  variant: {
14
14
  nav: "gap-2.25 rounded-[7px] px-2 py-1.75 text-[13px] font-normal text-foreground/80 hover:bg-foreground/6 hover:text-foreground pointer-coarse:min-h-11 pointer-coarse:gap-2.5 pointer-coarse:rounded-lg pointer-coarse:px-2.5 pointer-coarse:text-[14px]",
15
15
  section: "min-h-11 gap-2 rounded-[10px] px-3 text-[13px] font-medium text-foreground"
16
+ },
17
+ size: {
18
+ default: "",
19
+ sm: ""
16
20
  }
17
21
  },
18
- defaultVariants: { variant: "nav" }
22
+ compoundVariants: [
23
+ { variant: "section", size: "sm", className: "gap-1.5 px-2.5 pointer-fine:min-h-8" }
24
+ ],
25
+ defaultVariants: { variant: "nav", size: "default" }
19
26
  }
20
27
  );
21
28
  function CollapsibleHeader({
22
29
  icon: Icon,
23
30
  variant = "nav",
31
+ size = "default",
24
32
  className,
25
33
  children,
26
34
  ...props
@@ -30,7 +38,7 @@ function CollapsibleHeader({
30
38
  {
31
39
  "data-slot": "collapsible-header",
32
40
  "data-variant": variant,
33
- className: chunk6YHDDRIM_cjs.cn(collapsibleHeaderVariants({ variant }), className),
41
+ className: chunk6YHDDRIM_cjs.cn(collapsibleHeaderVariants({ variant, size }), className),
34
42
  ...props,
35
43
  children: [
36
44
  Icon && /* @__PURE__ */ jsxRuntime.jsx(
@@ -52,7 +60,10 @@ function CollapsibleHeader({
52
60
  lucideReact.ChevronDown,
53
61
  {
54
62
  "aria-hidden": true,
55
- className: "size-4 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180"
63
+ className: chunk6YHDDRIM_cjs.cn(
64
+ "shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180",
65
+ size === "sm" ? "size-3.5" : "size-4"
66
+ )
56
67
  }
57
68
  )
58
69
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/collapsible-header.tsx"],"names":["cva","jsxs","CollapsiblePrimitive","cn","jsx","ChevronRight","ChevronDown"],"mappings":";;;;;;;;AAiBA,IAAM,yBAAA,GAA4BA,0BAAA;AAAA,EAChC,6LAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,GAAA,EAAK,sPAAA;AAAA,QACL,OAAA,EACE;AAAA;AACJ,KACF;AAAA,IACA,eAAA,EAAiB,EAAE,OAAA,EAAS,KAAA;AAAM;AAEtC;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,GAAU,KAAA;AAAA,EACV,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAGG;AACD,EAAA,uBACEC,eAAA;AAAA,IAACC,mBAAA,CAAqB,kBAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,WAAWC,oBAAA,CAAG,yBAAA,CAA0B,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,MAC9D,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,oBACCC,cAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,+DAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf;AAAA,wBAEFA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA4B,QAAA,EAAS,CAAA;AAAA,QACpD,YAAY,KAAA,mBACXA,cAAA;AAAA,UAACC,wBAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAU,qIAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf,mBAEAD,cAAA;AAAA,UAACE,uBAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAU;AAAA;AAAA;AACZ;AAAA;AAAA,GAEJ;AAEJ","file":"collapsible-header.cjs","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\nimport { ChevronDown, ChevronRight, type LucideIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's two collapsible headers, as a styled CollapsibleTrigger\n// (put it inside a `Collapsible`, above its `CollapsibleContent`):\n// nav — a group in a list of rows (\"Sessions\" under an expanded agent):\n// the row's own shape, a right chevron that turns down when open.\n// section — a disclosure on a settings page (\"What the agent knows about\n// them\"): a 44px 13px header with a down chevron that flips.\n// Sits in a bordered box (`rounded-[10px] border\n// border-foreground/[0.08]`) whose content has a top rule.\nconst collapsibleHeaderVariants = cva(\n \"group/collapsible-header flex w-full items-center text-left transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n variant: {\n nav: \"gap-2.25 rounded-[7px] px-2 py-1.75 text-[13px] font-normal text-foreground/80 hover:bg-foreground/6 hover:text-foreground pointer-coarse:min-h-11 pointer-coarse:gap-2.5 pointer-coarse:rounded-lg pointer-coarse:px-2.5 pointer-coarse:text-[14px]\",\n section:\n \"min-h-11 gap-2 rounded-[10px] px-3 text-[13px] font-medium text-foreground\",\n },\n },\n defaultVariants: { variant: \"nav\" },\n }\n)\n\nfunction CollapsibleHeader({\n icon: Icon,\n variant = \"nav\",\n className,\n children,\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger> & {\n icon?: LucideIcon\n variant?: \"nav\" | \"section\"\n}) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-header\"\n data-variant={variant}\n className={cn(collapsibleHeaderVariants({ variant }), className)}\n {...props}\n >\n {Icon && (\n <Icon\n className=\"size-4 shrink-0 text-muted-foreground pointer-coarse:size-4.5\"\n strokeWidth={1.75}\n />\n )}\n <span className=\"min-w-0 flex-1 text-left\">{children}</span>\n {variant === \"nav\" ? (\n <ChevronRight\n aria-hidden={true}\n className=\"size-3.5 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-90 pointer-coarse:size-4\"\n strokeWidth={1.75}\n />\n ) : (\n <ChevronDown\n aria-hidden={true}\n className=\"size-4 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180\"\n />\n )}\n </CollapsiblePrimitive.CollapsibleTrigger>\n )\n}\n\nexport { CollapsibleHeader, collapsibleHeaderVariants }\n"]}
1
+ {"version":3,"sources":["../src/collapsible-header.tsx"],"names":["cva","jsxs","CollapsiblePrimitive","cn","jsx","ChevronRight","ChevronDown"],"mappings":";;;;;;;;AAmBA,IAAM,yBAAA,GAA4BA,0BAAA;AAAA,EAChC,6LAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,GAAA,EAAK,sPAAA;AAAA,QACL,OAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,EAAA;AAAA,QACT,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,gBAAA,EAAkB;AAAA,MAChB,EAAE,OAAA,EAAS,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,WAAW,qCAAA;AAAsC,KACrF;AAAA,IACA,eAAA,EAAiB,EAAE,OAAA,EAAS,KAAA,EAAO,MAAM,SAAA;AAAU;AAEvD;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,GAAU,KAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAKG;AACD,EAAA,uBACEC,eAAA;AAAA,IAACC,mBAAA,CAAqB,kBAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAWC,qBAAG,yBAAA,CAA0B,EAAE,SAAS,IAAA,EAAM,GAAG,SAAS,CAAA;AAAA,MACpE,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,oBACCC,cAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,+DAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf;AAAA,wBAEFA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA4B,QAAA,EAAS,CAAA;AAAA,QACpD,YAAY,KAAA,mBACXA,cAAA;AAAA,UAACC,wBAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAU,qIAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf,mBAEAD,cAAA;AAAA,UAACE,uBAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAWH,oBAAA;AAAA,cACT,uGAAA;AAAA,cACA,IAAA,KAAS,OAAO,UAAA,GAAa;AAAA;AAC/B;AAAA;AACF;AAAA;AAAA,GAEJ;AAEJ","file":"collapsible-header.cjs","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\nimport { ChevronDown, ChevronRight, type LucideIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's two collapsible headers, as a styled CollapsibleTrigger\n// (put it inside a `Collapsible`, above its `CollapsibleContent`):\n// nav — a group in a list of rows (\"Sessions\" under an expanded agent):\n// the row's own shape, a right chevron that turns down when open.\n// section — a disclosure on a settings page (\"What the agent knows about\n// them\"): a 44px 13px header with a down chevron that flips.\n// Sits in a bordered box (`rounded-[10px] border\n// border-foreground/[0.08]`) whose content has a top rule. `sm`\n// is the compact one a card in a thread or a strip above the\n// composer takes: 32px with a mouse, still 44px on touch.\nconst collapsibleHeaderVariants = cva(\n \"group/collapsible-header flex w-full items-center text-left transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n variant: {\n nav: \"gap-2.25 rounded-[7px] px-2 py-1.75 text-[13px] font-normal text-foreground/80 hover:bg-foreground/6 hover:text-foreground pointer-coarse:min-h-11 pointer-coarse:gap-2.5 pointer-coarse:rounded-lg pointer-coarse:px-2.5 pointer-coarse:text-[14px]\",\n section:\n \"min-h-11 gap-2 rounded-[10px] px-3 text-[13px] font-medium text-foreground\",\n },\n size: {\n default: \"\",\n sm: \"\",\n },\n },\n compoundVariants: [\n { variant: \"section\", size: \"sm\", className: \"gap-1.5 px-2.5 pointer-fine:min-h-8\" },\n ],\n defaultVariants: { variant: \"nav\", size: \"default\" },\n }\n)\n\nfunction CollapsibleHeader({\n icon: Icon,\n variant = \"nav\",\n size = \"default\",\n className,\n children,\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger> & {\n icon?: LucideIcon\n variant?: \"nav\" | \"section\"\n /** `section` only: the compact header. */\n size?: \"default\" | \"sm\"\n}) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-header\"\n data-variant={variant}\n className={cn(collapsibleHeaderVariants({ variant, size }), className)}\n {...props}\n >\n {Icon && (\n <Icon\n className=\"size-4 shrink-0 text-muted-foreground pointer-coarse:size-4.5\"\n strokeWidth={1.75}\n />\n )}\n <span className=\"min-w-0 flex-1 text-left\">{children}</span>\n {variant === \"nav\" ? (\n <ChevronRight\n aria-hidden={true}\n className=\"size-3.5 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-90 pointer-coarse:size-4\"\n strokeWidth={1.75}\n />\n ) : (\n <ChevronDown\n aria-hidden={true}\n className={cn(\n \"shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180\",\n size === \"sm\" ? \"size-3.5\" : \"size-4\"\n )}\n />\n )}\n </CollapsiblePrimitive.CollapsibleTrigger>\n )\n}\n\nexport { CollapsibleHeader, collapsibleHeaderVariants }\n"]}
@@ -6,10 +6,13 @@ import { LucideIcon } from 'lucide-react';
6
6
 
7
7
  declare const collapsibleHeaderVariants: (props?: ({
8
8
  variant?: "nav" | "section" | null | undefined;
9
+ size?: "default" | "sm" | null | undefined;
9
10
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
- declare function CollapsibleHeader({ icon: Icon, variant, className, children, ...props }: React.ComponentProps<typeof Collapsible.CollapsibleTrigger> & {
11
+ declare function CollapsibleHeader({ icon: Icon, variant, size, className, children, ...props }: React.ComponentProps<typeof Collapsible.CollapsibleTrigger> & {
11
12
  icon?: LucideIcon;
12
13
  variant?: "nav" | "section";
14
+ /** `section` only: the compact header. */
15
+ size?: "default" | "sm";
13
16
  }): react_jsx_runtime.JSX.Element;
14
17
 
15
18
  export { CollapsibleHeader, collapsibleHeaderVariants };
@@ -6,10 +6,13 @@ import { LucideIcon } from 'lucide-react';
6
6
 
7
7
  declare const collapsibleHeaderVariants: (props?: ({
8
8
  variant?: "nav" | "section" | null | undefined;
9
+ size?: "default" | "sm" | null | undefined;
9
10
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
- declare function CollapsibleHeader({ icon: Icon, variant, className, children, ...props }: React.ComponentProps<typeof Collapsible.CollapsibleTrigger> & {
11
+ declare function CollapsibleHeader({ icon: Icon, variant, size, className, children, ...props }: React.ComponentProps<typeof Collapsible.CollapsibleTrigger> & {
11
12
  icon?: LucideIcon;
12
13
  variant?: "nav" | "section";
14
+ /** `section` only: the compact header. */
15
+ size?: "default" | "sm";
13
16
  }): react_jsx_runtime.JSX.Element;
14
17
 
15
18
  export { CollapsibleHeader, collapsibleHeaderVariants };
@@ -11,14 +11,22 @@ var collapsibleHeaderVariants = cva(
11
11
  variant: {
12
12
  nav: "gap-2.25 rounded-[7px] px-2 py-1.75 text-[13px] font-normal text-foreground/80 hover:bg-foreground/6 hover:text-foreground pointer-coarse:min-h-11 pointer-coarse:gap-2.5 pointer-coarse:rounded-lg pointer-coarse:px-2.5 pointer-coarse:text-[14px]",
13
13
  section: "min-h-11 gap-2 rounded-[10px] px-3 text-[13px] font-medium text-foreground"
14
+ },
15
+ size: {
16
+ default: "",
17
+ sm: ""
14
18
  }
15
19
  },
16
- defaultVariants: { variant: "nav" }
20
+ compoundVariants: [
21
+ { variant: "section", size: "sm", className: "gap-1.5 px-2.5 pointer-fine:min-h-8" }
22
+ ],
23
+ defaultVariants: { variant: "nav", size: "default" }
17
24
  }
18
25
  );
19
26
  function CollapsibleHeader({
20
27
  icon: Icon,
21
28
  variant = "nav",
29
+ size = "default",
22
30
  className,
23
31
  children,
24
32
  ...props
@@ -28,7 +36,7 @@ function CollapsibleHeader({
28
36
  {
29
37
  "data-slot": "collapsible-header",
30
38
  "data-variant": variant,
31
- className: cn(collapsibleHeaderVariants({ variant }), className),
39
+ className: cn(collapsibleHeaderVariants({ variant, size }), className),
32
40
  ...props,
33
41
  children: [
34
42
  Icon && /* @__PURE__ */ jsx(
@@ -50,7 +58,10 @@ function CollapsibleHeader({
50
58
  ChevronDown,
51
59
  {
52
60
  "aria-hidden": true,
53
- className: "size-4 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180"
61
+ className: cn(
62
+ "shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180",
63
+ size === "sm" ? "size-3.5" : "size-4"
64
+ )
54
65
  }
55
66
  )
56
67
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/collapsible-header.tsx"],"names":["CollapsiblePrimitive"],"mappings":";;;;;;AAiBA,IAAM,yBAAA,GAA4B,GAAA;AAAA,EAChC,6LAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,GAAA,EAAK,sPAAA;AAAA,QACL,OAAA,EACE;AAAA;AACJ,KACF;AAAA,IACA,eAAA,EAAiB,EAAE,OAAA,EAAS,KAAA;AAAM;AAEtC;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,GAAU,KAAA;AAAA,EACV,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAGG;AACD,EAAA,uBACE,IAAA;AAAA,IAACA,WAAA,CAAqB,kBAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,WAAW,EAAA,CAAG,yBAAA,CAA0B,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,MAC9D,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,oBACC,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,+DAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf;AAAA,wBAEF,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA4B,QAAA,EAAS,CAAA;AAAA,QACpD,YAAY,KAAA,mBACX,GAAA;AAAA,UAAC,YAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAU,qIAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf,mBAEA,GAAA;AAAA,UAAC,WAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAU;AAAA;AAAA;AACZ;AAAA;AAAA,GAEJ;AAEJ","file":"collapsible-header.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\nimport { ChevronDown, ChevronRight, type LucideIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's two collapsible headers, as a styled CollapsibleTrigger\n// (put it inside a `Collapsible`, above its `CollapsibleContent`):\n// nav — a group in a list of rows (\"Sessions\" under an expanded agent):\n// the row's own shape, a right chevron that turns down when open.\n// section — a disclosure on a settings page (\"What the agent knows about\n// them\"): a 44px 13px header with a down chevron that flips.\n// Sits in a bordered box (`rounded-[10px] border\n// border-foreground/[0.08]`) whose content has a top rule.\nconst collapsibleHeaderVariants = cva(\n \"group/collapsible-header flex w-full items-center text-left transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n variant: {\n nav: \"gap-2.25 rounded-[7px] px-2 py-1.75 text-[13px] font-normal text-foreground/80 hover:bg-foreground/6 hover:text-foreground pointer-coarse:min-h-11 pointer-coarse:gap-2.5 pointer-coarse:rounded-lg pointer-coarse:px-2.5 pointer-coarse:text-[14px]\",\n section:\n \"min-h-11 gap-2 rounded-[10px] px-3 text-[13px] font-medium text-foreground\",\n },\n },\n defaultVariants: { variant: \"nav\" },\n }\n)\n\nfunction CollapsibleHeader({\n icon: Icon,\n variant = \"nav\",\n className,\n children,\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger> & {\n icon?: LucideIcon\n variant?: \"nav\" | \"section\"\n}) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-header\"\n data-variant={variant}\n className={cn(collapsibleHeaderVariants({ variant }), className)}\n {...props}\n >\n {Icon && (\n <Icon\n className=\"size-4 shrink-0 text-muted-foreground pointer-coarse:size-4.5\"\n strokeWidth={1.75}\n />\n )}\n <span className=\"min-w-0 flex-1 text-left\">{children}</span>\n {variant === \"nav\" ? (\n <ChevronRight\n aria-hidden={true}\n className=\"size-3.5 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-90 pointer-coarse:size-4\"\n strokeWidth={1.75}\n />\n ) : (\n <ChevronDown\n aria-hidden={true}\n className=\"size-4 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180\"\n />\n )}\n </CollapsiblePrimitive.CollapsibleTrigger>\n )\n}\n\nexport { CollapsibleHeader, collapsibleHeaderVariants }\n"]}
1
+ {"version":3,"sources":["../src/collapsible-header.tsx"],"names":["CollapsiblePrimitive"],"mappings":";;;;;;AAmBA,IAAM,yBAAA,GAA4B,GAAA;AAAA,EAChC,6LAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,GAAA,EAAK,sPAAA;AAAA,QACL,OAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,EAAA;AAAA,QACT,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,gBAAA,EAAkB;AAAA,MAChB,EAAE,OAAA,EAAS,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,WAAW,qCAAA;AAAsC,KACrF;AAAA,IACA,eAAA,EAAiB,EAAE,OAAA,EAAS,KAAA,EAAO,MAAM,SAAA;AAAU;AAEvD;AAEA,SAAS,iBAAA,CAAkB;AAAA,EACzB,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,GAAU,KAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAKG;AACD,EAAA,uBACE,IAAA;AAAA,IAACA,WAAA,CAAqB,kBAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,oBAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,GAAG,yBAAA,CAA0B,EAAE,SAAS,IAAA,EAAM,GAAG,SAAS,CAAA;AAAA,MACpE,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,oBACC,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,+DAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf;AAAA,wBAEF,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0BAAA,EAA4B,QAAA,EAAS,CAAA;AAAA,QACpD,YAAY,KAAA,mBACX,GAAA;AAAA,UAAC,YAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAU,qIAAA;AAAA,YACV,WAAA,EAAa;AAAA;AAAA,SACf,mBAEA,GAAA;AAAA,UAAC,WAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,IAAA;AAAA,YACb,SAAA,EAAW,EAAA;AAAA,cACT,uGAAA;AAAA,cACA,IAAA,KAAS,OAAO,UAAA,GAAa;AAAA;AAC/B;AAAA;AACF;AAAA;AAAA,GAEJ;AAEJ","file":"collapsible-header.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cva } from \"class-variance-authority\"\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\"\nimport { ChevronDown, ChevronRight, type LucideIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's two collapsible headers, as a styled CollapsibleTrigger\n// (put it inside a `Collapsible`, above its `CollapsibleContent`):\n// nav — a group in a list of rows (\"Sessions\" under an expanded agent):\n// the row's own shape, a right chevron that turns down when open.\n// section — a disclosure on a settings page (\"What the agent knows about\n// them\"): a 44px 13px header with a down chevron that flips.\n// Sits in a bordered box (`rounded-[10px] border\n// border-foreground/[0.08]`) whose content has a top rule. `sm`\n// is the compact one a card in a thread or a strip above the\n// composer takes: 32px with a mouse, still 44px on touch.\nconst collapsibleHeaderVariants = cva(\n \"group/collapsible-header flex w-full items-center text-left transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n variant: {\n nav: \"gap-2.25 rounded-[7px] px-2 py-1.75 text-[13px] font-normal text-foreground/80 hover:bg-foreground/6 hover:text-foreground pointer-coarse:min-h-11 pointer-coarse:gap-2.5 pointer-coarse:rounded-lg pointer-coarse:px-2.5 pointer-coarse:text-[14px]\",\n section:\n \"min-h-11 gap-2 rounded-[10px] px-3 text-[13px] font-medium text-foreground\",\n },\n size: {\n default: \"\",\n sm: \"\",\n },\n },\n compoundVariants: [\n { variant: \"section\", size: \"sm\", className: \"gap-1.5 px-2.5 pointer-fine:min-h-8\" },\n ],\n defaultVariants: { variant: \"nav\", size: \"default\" },\n }\n)\n\nfunction CollapsibleHeader({\n icon: Icon,\n variant = \"nav\",\n size = \"default\",\n className,\n children,\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger> & {\n icon?: LucideIcon\n variant?: \"nav\" | \"section\"\n /** `section` only: the compact header. */\n size?: \"default\" | \"sm\"\n}) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-header\"\n data-variant={variant}\n className={cn(collapsibleHeaderVariants({ variant, size }), className)}\n {...props}\n >\n {Icon && (\n <Icon\n className=\"size-4 shrink-0 text-muted-foreground pointer-coarse:size-4.5\"\n strokeWidth={1.75}\n />\n )}\n <span className=\"min-w-0 flex-1 text-left\">{children}</span>\n {variant === \"nav\" ? (\n <ChevronRight\n aria-hidden={true}\n className=\"size-3.5 shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-90 pointer-coarse:size-4\"\n strokeWidth={1.75}\n />\n ) : (\n <ChevronDown\n aria-hidden={true}\n className={cn(\n \"shrink-0 text-muted-foreground transition-transform group-aria-expanded/collapsible-header:rotate-180\",\n size === \"sm\" ? \"size-3.5\" : \"size-4\"\n )}\n />\n )}\n </CollapsiblePrimitive.CollapsibleTrigger>\n )\n}\n\nexport { CollapsibleHeader, collapsibleHeaderVariants }\n"]}
@@ -15,16 +15,18 @@ function ConfirmDialog({
15
15
  confirmIcon,
16
16
  variant = "destructive",
17
17
  confirmDisabled = false,
18
+ loading: busy = false,
18
19
  onConfirm,
19
20
  onCancel
20
21
  }) {
21
- const [loading, setLoading] = react.useState(false);
22
+ const [pending, setPending] = react.useState(false);
23
+ const loading = busy || pending;
22
24
  const handleConfirm = async () => {
23
- setLoading(true);
25
+ setPending(true);
24
26
  try {
25
27
  await onConfirm();
26
28
  } finally {
27
- setLoading(false);
29
+ setPending(false);
28
30
  }
29
31
  };
30
32
  return /* @__PURE__ */ jsxRuntime.jsx(chunkID7MWMJO_cjs.Dialog, { open, onOpenChange: (o) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/confirm-dialog.tsx"],"names":["useState","jsx","Dialog","jsxs","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter","Button","Loader2"],"mappings":";;;;;;;;;AA8BO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,WAAA;AAAA,EACA,OAAA,GAAU,aAAA;AAAA,EACV,eAAA,GAAkB,KAAA;AAAA,EAClB,SAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA;AAE5C,EAAA,MAAM,gBAAgB,YAAY;AAChC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,EAAU;AAAA,IAClB,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,uBACEC,cAAA,CAACC,wBAAA,EAAA,EAAO,IAAA,EAAY,YAAA,EAAc,CAAC,CAAA,KAAM;AAAE,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,OAAA,EAAS,QAAA,EAAS;AAAA,EAAG,CAAA,EAEzE,QAAA,kBAAAC,eAAA;AAAA,IAACC,+BAAA;AAAA,IAAA;AAAA,MACC,eAAA,EAAiB,KAAA;AAAA,MACjB,SAAA,EAAU,yCAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAAD,eAAA,CAACE,8BAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAJ,cAAA,CAACK,iCAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BACpBL,cAAA,CAACM,uCAAmB,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EAClC,CAAA;AAAA,wBACAJ,eAAA,CAACK,8BAAA,EAAA,EAAa,SAAA,EAAU,QAAA,EACtB,QAAA,EAAA;AAAA,0BAAAP,cAAA;AAAA,YAACQ,wBAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,QAAA,EAAU,OAAA;AAAA,cACV,OAAA,EAAS,QAAA;AAAA,cACV,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACAN,eAAA;AAAA,YAACM,wBAAA;AAAA,YAAA;AAAA,cACC,OAAA;AAAA,cACA,UAAU,OAAA,IAAW,eAAA;AAAA,cACrB,OAAA,EAAS,aAAA;AAAA,cAER,QAAA,EAAA;AAAA,gBAAA,OAAA,kCAAWC,mBAAA,EAAA,EAAQ,SAAA,EAAU,qBAAA,EAAsB,IAAA,EAAM,IAAI,CAAA,GAAK,WAAA;AAAA,gBAClE;AAAA;AAAA;AAAA;AACH,SAAA,EACF;AAAA;AAAA;AAAA,GACF,EACF,CAAA;AAEJ","file":"confirm-dialog.cjs","sourcesContent":["// Copyright (c) 2026, Invergent SA, developed by Flavius Burca\n// SPDX-License-Identifier: AGPL-3.0-only\n//\nimport { useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { Button } from \"./button\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"./dialog\";\n\ninterface ConfirmDialogProps {\n open: boolean;\n title: string;\n description: React.ReactNode;\n confirmLabel?: string;\n confirmIcon?: React.ReactNode;\n variant?: \"destructive\" | \"default\";\n /** Disables the confirm button. Use when the action is known\n * to be invalid (e.g. an in-use entity) and the dialog only\n * exists to explain why. */\n confirmDisabled?: boolean;\n onConfirm: () => Promise<void> | void;\n onCancel: () => void;\n}\n\nexport function ConfirmDialog({\n open,\n title,\n description,\n confirmLabel = \"Confirm\",\n confirmIcon,\n variant = \"destructive\",\n confirmDisabled = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const [loading, setLoading] = useState(false);\n\n const handleConfirm = async () => {\n setLoading(true);\n try {\n await onConfirm();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <Dialog open={open} onOpenChange={(o) => { if (!o && !loading) onCancel(); }}>\n {/* Work's confirm: compact, no close button — Cancel and Escape do it. */}\n <DialogContent\n showCloseButton={false}\n className=\"gap-3.5 px-6 pt-6 pb-5 sm:max-w-[430px]\"\n >\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogFooter className=\"pt-1.5\">\n <Button\n variant=\"outline\"\n disabled={loading}\n onClick={onCancel}\n >\n Cancel\n </Button>\n <Button\n variant={variant}\n disabled={loading || confirmDisabled}\n onClick={handleConfirm}\n >\n {loading ? <Loader2 className=\"animate-spin mr-1.5\" size={14} /> : confirmIcon}\n {confirmLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/confirm-dialog.tsx"],"names":["useState","jsx","Dialog","jsxs","DialogContent","DialogHeader","DialogTitle","DialogDescription","DialogFooter","Button","Loader2"],"mappings":";;;;;;;;;AAiCO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,WAAA;AAAA,EACA,OAAA,GAAU,aAAA;AAAA,EACV,eAAA,GAAkB,KAAA;AAAA,EAClB,SAAS,IAAA,GAAO,KAAA;AAAA,EAChB,SAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,UAAU,IAAA,IAAQ,OAAA;AAExB,EAAA,MAAM,gBAAgB,YAAY;AAChC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,EAAU;AAAA,IAClB,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,uBACEC,cAAA,CAACC,wBAAA,EAAA,EAAO,IAAA,EAAY,YAAA,EAAc,CAAC,CAAA,KAAM;AAAE,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,OAAA,EAAS,QAAA,EAAS;AAAA,EAAG,CAAA,EAEzE,QAAA,kBAAAC,eAAA;AAAA,IAACC,+BAAA;AAAA,IAAA;AAAA,MACC,eAAA,EAAiB,KAAA;AAAA,MACjB,SAAA,EAAU,yCAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAAD,eAAA,CAACE,8BAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAJ,cAAA,CAACK,iCAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BACpBL,cAAA,CAACM,uCAAmB,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EAClC,CAAA;AAAA,wBACAJ,eAAA,CAACK,8BAAA,EAAA,EAAa,SAAA,EAAU,QAAA,EACtB,QAAA,EAAA;AAAA,0BAAAP,cAAA;AAAA,YAACQ,wBAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,QAAA,EAAU,OAAA;AAAA,cACV,OAAA,EAAS,QAAA;AAAA,cACV,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACAN,eAAA;AAAA,YAACM,wBAAA;AAAA,YAAA;AAAA,cACC,OAAA;AAAA,cACA,UAAU,OAAA,IAAW,eAAA;AAAA,cACrB,OAAA,EAAS,aAAA;AAAA,cAER,QAAA,EAAA;AAAA,gBAAA,OAAA,kCAAWC,mBAAA,EAAA,EAAQ,SAAA,EAAU,qBAAA,EAAsB,IAAA,EAAM,IAAI,CAAA,GAAK,WAAA;AAAA,gBAClE;AAAA;AAAA;AAAA;AACH,SAAA,EACF;AAAA;AAAA;AAAA,GACF,EACF,CAAA;AAEJ","file":"confirm-dialog.cjs","sourcesContent":["// Copyright (c) 2026, Invergent SA, developed by Flavius Burca\n// SPDX-License-Identifier: AGPL-3.0-only\n//\nimport { useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { Button } from \"./button\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"./dialog\";\n\ninterface ConfirmDialogProps {\n open: boolean;\n title: string;\n description: React.ReactNode;\n confirmLabel?: string;\n confirmIcon?: React.ReactNode;\n variant?: \"destructive\" | \"default\";\n /** Disables the confirm button. Use when the action is known\n * to be invalid (e.g. an in-use entity) and the dialog only\n * exists to explain why. */\n confirmDisabled?: boolean;\n /** Busy from outside: work that outlives the dialog (held in a store a\n * remounted dialog reads) keeps it locked, as its own pending confirm does. */\n loading?: boolean;\n onConfirm: () => Promise<void> | void;\n onCancel: () => void;\n}\n\nexport function ConfirmDialog({\n open,\n title,\n description,\n confirmLabel = \"Confirm\",\n confirmIcon,\n variant = \"destructive\",\n confirmDisabled = false,\n loading: busy = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const [pending, setPending] = useState(false);\n const loading = busy || pending;\n\n const handleConfirm = async () => {\n setPending(true);\n try {\n await onConfirm();\n } finally {\n setPending(false);\n }\n };\n\n return (\n <Dialog open={open} onOpenChange={(o) => { if (!o && !loading) onCancel(); }}>\n {/* Work's confirm: compact, no close button — Cancel and Escape do it. */}\n <DialogContent\n showCloseButton={false}\n className=\"gap-3.5 px-6 pt-6 pb-5 sm:max-w-[430px]\"\n >\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogFooter className=\"pt-1.5\">\n <Button\n variant=\"outline\"\n disabled={loading}\n onClick={onCancel}\n >\n Cancel\n </Button>\n <Button\n variant={variant}\n disabled={loading || confirmDisabled}\n onClick={handleConfirm}\n >\n {loading ? <Loader2 className=\"animate-spin mr-1.5\" size={14} /> : confirmIcon}\n {confirmLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
@@ -11,9 +11,12 @@ interface ConfirmDialogProps {
11
11
  * to be invalid (e.g. an in-use entity) and the dialog only
12
12
  * exists to explain why. */
13
13
  confirmDisabled?: boolean;
14
+ /** Busy from outside: work that outlives the dialog (held in a store a
15
+ * remounted dialog reads) keeps it locked, as its own pending confirm does. */
16
+ loading?: boolean;
14
17
  onConfirm: () => Promise<void> | void;
15
18
  onCancel: () => void;
16
19
  }
17
- declare function ConfirmDialog({ open, title, description, confirmLabel, confirmIcon, variant, confirmDisabled, onConfirm, onCancel, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
20
+ declare function ConfirmDialog({ open, title, description, confirmLabel, confirmIcon, variant, confirmDisabled, loading: busy, onConfirm, onCancel, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
18
21
 
19
22
  export { ConfirmDialog };
@@ -11,9 +11,12 @@ interface ConfirmDialogProps {
11
11
  * to be invalid (e.g. an in-use entity) and the dialog only
12
12
  * exists to explain why. */
13
13
  confirmDisabled?: boolean;
14
+ /** Busy from outside: work that outlives the dialog (held in a store a
15
+ * remounted dialog reads) keeps it locked, as its own pending confirm does. */
16
+ loading?: boolean;
14
17
  onConfirm: () => Promise<void> | void;
15
18
  onCancel: () => void;
16
19
  }
17
- declare function ConfirmDialog({ open, title, description, confirmLabel, confirmIcon, variant, confirmDisabled, onConfirm, onCancel, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
20
+ declare function ConfirmDialog({ open, title, description, confirmLabel, confirmIcon, variant, confirmDisabled, loading: busy, onConfirm, onCancel, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
18
21
 
19
22
  export { ConfirmDialog };
@@ -13,16 +13,18 @@ function ConfirmDialog({
13
13
  confirmIcon,
14
14
  variant = "destructive",
15
15
  confirmDisabled = false,
16
+ loading: busy = false,
16
17
  onConfirm,
17
18
  onCancel
18
19
  }) {
19
- const [loading, setLoading] = useState(false);
20
+ const [pending, setPending] = useState(false);
21
+ const loading = busy || pending;
20
22
  const handleConfirm = async () => {
21
- setLoading(true);
23
+ setPending(true);
22
24
  try {
23
25
  await onConfirm();
24
26
  } finally {
25
- setLoading(false);
27
+ setPending(false);
26
28
  }
27
29
  };
28
30
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (o) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/confirm-dialog.tsx"],"names":[],"mappings":";;;;;;;AA8BO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,WAAA;AAAA,EACA,OAAA,GAAU,aAAA;AAAA,EACV,eAAA,GAAkB,KAAA;AAAA,EAClB,SAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAE5C,EAAA,MAAM,gBAAgB,YAAY;AAChC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,EAAU;AAAA,IAClB,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAY,YAAA,EAAc,CAAC,CAAA,KAAM;AAAE,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,OAAA,EAAS,QAAA,EAAS;AAAA,EAAG,CAAA,EAEzE,QAAA,kBAAA,IAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,eAAA,EAAiB,KAAA;AAAA,MACjB,SAAA,EAAU,yCAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,eAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BACpB,GAAA,CAAC,qBAAmB,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EAClC,CAAA;AAAA,wBACA,IAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,QAAA,EACtB,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,QAAA,EAAU,OAAA;AAAA,cACV,OAAA,EAAS,QAAA;AAAA,cACV,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACA,IAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA;AAAA,cACA,UAAU,OAAA,IAAW,eAAA;AAAA,cACrB,OAAA,EAAS,aAAA;AAAA,cAER,QAAA,EAAA;AAAA,gBAAA,OAAA,uBAAW,OAAA,EAAA,EAAQ,SAAA,EAAU,qBAAA,EAAsB,IAAA,EAAM,IAAI,CAAA,GAAK,WAAA;AAAA,gBAClE;AAAA;AAAA;AAAA;AACH,SAAA,EACF;AAAA;AAAA;AAAA,GACF,EACF,CAAA;AAEJ","file":"confirm-dialog.js","sourcesContent":["// Copyright (c) 2026, Invergent SA, developed by Flavius Burca\n// SPDX-License-Identifier: AGPL-3.0-only\n//\nimport { useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { Button } from \"./button\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"./dialog\";\n\ninterface ConfirmDialogProps {\n open: boolean;\n title: string;\n description: React.ReactNode;\n confirmLabel?: string;\n confirmIcon?: React.ReactNode;\n variant?: \"destructive\" | \"default\";\n /** Disables the confirm button. Use when the action is known\n * to be invalid (e.g. an in-use entity) and the dialog only\n * exists to explain why. */\n confirmDisabled?: boolean;\n onConfirm: () => Promise<void> | void;\n onCancel: () => void;\n}\n\nexport function ConfirmDialog({\n open,\n title,\n description,\n confirmLabel = \"Confirm\",\n confirmIcon,\n variant = \"destructive\",\n confirmDisabled = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const [loading, setLoading] = useState(false);\n\n const handleConfirm = async () => {\n setLoading(true);\n try {\n await onConfirm();\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <Dialog open={open} onOpenChange={(o) => { if (!o && !loading) onCancel(); }}>\n {/* Work's confirm: compact, no close button — Cancel and Escape do it. */}\n <DialogContent\n showCloseButton={false}\n className=\"gap-3.5 px-6 pt-6 pb-5 sm:max-w-[430px]\"\n >\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogFooter className=\"pt-1.5\">\n <Button\n variant=\"outline\"\n disabled={loading}\n onClick={onCancel}\n >\n Cancel\n </Button>\n <Button\n variant={variant}\n disabled={loading || confirmDisabled}\n onClick={handleConfirm}\n >\n {loading ? <Loader2 className=\"animate-spin mr-1.5\" size={14} /> : confirmIcon}\n {confirmLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/confirm-dialog.tsx"],"names":[],"mappings":";;;;;;;AAiCO,SAAS,aAAA,CAAc;AAAA,EAC5B,IAAA;AAAA,EACA,KAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,WAAA;AAAA,EACA,OAAA,GAAU,aAAA;AAAA,EACV,eAAA,GAAkB,KAAA;AAAA,EAClB,SAAS,IAAA,GAAO,KAAA;AAAA,EAChB,SAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,UAAU,IAAA,IAAQ,OAAA;AAExB,EAAA,MAAM,gBAAgB,YAAY;AAChC,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACF,MAAA,MAAM,SAAA,EAAU;AAAA,IAClB,CAAA,SAAE;AACA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB;AAAA,EACF,CAAA;AAEA,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAY,YAAA,EAAc,CAAC,CAAA,KAAM;AAAE,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,OAAA,EAAS,QAAA,EAAS;AAAA,EAAG,CAAA,EAEzE,QAAA,kBAAA,IAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,eAAA,EAAiB,KAAA;AAAA,MACjB,SAAA,EAAU,yCAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,eAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BACpB,GAAA,CAAC,qBAAmB,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EAClC,CAAA;AAAA,wBACA,IAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,QAAA,EACtB,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,SAAA;AAAA,cACR,QAAA,EAAU,OAAA;AAAA,cACV,OAAA,EAAS,QAAA;AAAA,cACV,QAAA,EAAA;AAAA;AAAA,WAED;AAAA,0BACA,IAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAA;AAAA,cACA,UAAU,OAAA,IAAW,eAAA;AAAA,cACrB,OAAA,EAAS,aAAA;AAAA,cAER,QAAA,EAAA;AAAA,gBAAA,OAAA,uBAAW,OAAA,EAAA,EAAQ,SAAA,EAAU,qBAAA,EAAsB,IAAA,EAAM,IAAI,CAAA,GAAK,WAAA;AAAA,gBAClE;AAAA;AAAA;AAAA;AACH,SAAA,EACF;AAAA;AAAA;AAAA,GACF,EACF,CAAA;AAEJ","file":"confirm-dialog.js","sourcesContent":["// Copyright (c) 2026, Invergent SA, developed by Flavius Burca\n// SPDX-License-Identifier: AGPL-3.0-only\n//\nimport { useState } from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { Button } from \"./button\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \"./dialog\";\n\ninterface ConfirmDialogProps {\n open: boolean;\n title: string;\n description: React.ReactNode;\n confirmLabel?: string;\n confirmIcon?: React.ReactNode;\n variant?: \"destructive\" | \"default\";\n /** Disables the confirm button. Use when the action is known\n * to be invalid (e.g. an in-use entity) and the dialog only\n * exists to explain why. */\n confirmDisabled?: boolean;\n /** Busy from outside: work that outlives the dialog (held in a store a\n * remounted dialog reads) keeps it locked, as its own pending confirm does. */\n loading?: boolean;\n onConfirm: () => Promise<void> | void;\n onCancel: () => void;\n}\n\nexport function ConfirmDialog({\n open,\n title,\n description,\n confirmLabel = \"Confirm\",\n confirmIcon,\n variant = \"destructive\",\n confirmDisabled = false,\n loading: busy = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const [pending, setPending] = useState(false);\n const loading = busy || pending;\n\n const handleConfirm = async () => {\n setPending(true);\n try {\n await onConfirm();\n } finally {\n setPending(false);\n }\n };\n\n return (\n <Dialog open={open} onOpenChange={(o) => { if (!o && !loading) onCancel(); }}>\n {/* Work's confirm: compact, no close button — Cancel and Escape do it. */}\n <DialogContent\n showCloseButton={false}\n className=\"gap-3.5 px-6 pt-6 pb-5 sm:max-w-[430px]\"\n >\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogFooter className=\"pt-1.5\">\n <Button\n variant=\"outline\"\n disabled={loading}\n onClick={onCancel}\n >\n Cancel\n </Button>\n <Button\n variant={variant}\n disabled={loading || confirmDisabled}\n onClick={handleConfirm}\n >\n {loading ? <Loader2 className=\"animate-spin mr-1.5\" size={14} /> : confirmIcon}\n {confirmLabel}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"]}
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ var chunk6YHDDRIM_cjs = require('./chunk-6YHDDRIM.cjs');
4
+ var lucideReact = require('lucide-react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ function TabStrip({ className, ...props }) {
8
+ return /* @__PURE__ */ jsxRuntime.jsx(
9
+ "div",
10
+ {
11
+ role: "tablist",
12
+ "data-slot": "tab-strip",
13
+ className: chunk6YHDDRIM_cjs.cn("flex min-w-0 items-center gap-0.5 overflow-x-auto", className),
14
+ ...props
15
+ }
16
+ );
17
+ }
18
+ function TabStripTab({
19
+ active = false,
20
+ onSelect,
21
+ onClose,
22
+ closeLabel = "Close tab",
23
+ className,
24
+ children,
25
+ ...props
26
+ }) {
27
+ return /* @__PURE__ */ jsxRuntime.jsxs(
28
+ "div",
29
+ {
30
+ role: "tab",
31
+ tabIndex: 0,
32
+ "aria-selected": active,
33
+ "data-slot": "tab-strip-tab",
34
+ "data-active": active,
35
+ onClick: onSelect,
36
+ onKeyDown: (event) => {
37
+ if (event.target !== event.currentTarget) return;
38
+ if (event.key === "Enter" || event.key === " ") {
39
+ event.preventDefault();
40
+ onSelect();
41
+ }
42
+ },
43
+ className: chunk6YHDDRIM_cjs.cn(
44
+ "flex h-7 min-h-11 max-w-40 shrink-0 cursor-pointer items-center gap-1 rounded-[7px] pl-2.5 text-[12px] transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 pointer-fine:min-h-0",
45
+ onClose ? "pr-1" : "pr-2.5",
46
+ active ? "bg-foreground/[0.08] font-medium text-foreground" : "text-muted-foreground hover:bg-foreground/[0.04] hover:text-foreground",
47
+ className
48
+ ),
49
+ ...props,
50
+ children: [
51
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children }),
52
+ onClose && /* @__PURE__ */ jsxRuntime.jsx(
53
+ "button",
54
+ {
55
+ type: "button",
56
+ "data-slot": "tab-strip-close",
57
+ "aria-label": closeLabel,
58
+ onClick: (event) => {
59
+ event.stopPropagation();
60
+ onClose();
61
+ },
62
+ className: "relative flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-[4px] text-muted-foreground transition-colors outline-none after:absolute after:-inset-1.5 hover:bg-foreground/[0.08] hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/40",
63
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, { className: "size-3" })
64
+ }
65
+ )
66
+ ]
67
+ }
68
+ );
69
+ }
70
+
71
+ exports.TabStrip = TabStrip;
72
+ exports.TabStripTab = TabStripTab;
73
+ //# sourceMappingURL=tab-strip.cjs.map
74
+ //# sourceMappingURL=tab-strip.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tab-strip.tsx"],"names":["jsx","cn","jsxs","XIcon"],"mappings":";;;;;;AAUA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AACtE,EAAA,uBACEA,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,SAAA;AAAA,MACL,WAAA,EAAU,WAAA;AAAA,MACV,SAAA,EAAWC,oBAAA,CAAG,mDAAA,EAAqD,SAAS,CAAA;AAAA,MAC3E,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,WAAA,CAAY;AAAA,EACnB,MAAA,GAAS,KAAA;AAAA,EACT,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA,GAAa,WAAA;AAAA,EACb,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAMG;AACD,EAAA,uBACEC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,KAAA;AAAA,MACL,QAAA,EAAU,CAAA;AAAA,MACV,eAAA,EAAe,MAAA;AAAA,MACf,WAAA,EAAU,eAAA;AAAA,MACV,aAAA,EAAa,MAAA;AAAA,MACb,OAAA,EAAS,QAAA;AAAA,MACT,SAAA,EAAW,CAAC,KAAA,KAAU;AACpB,QAAA,IAAI,KAAA,CAAM,MAAA,KAAW,KAAA,CAAM,aAAA,EAAe;AAC1C,QAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAW,KAAA,CAAM,QAAQ,GAAA,EAAK;AAC9C,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,QAAA,EAAS;AAAA,QACX;AAAA,MACF,CAAA;AAAA,MACA,SAAA,EAAWD,oBAAA;AAAA,QACT,4MAAA;AAAA,QACA,UAAU,MAAA,GAAS,QAAA;AAAA,QACnB,SACI,kDAAA,GACA,wEAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAAD,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAoB,QAAA,EAAS,CAAA;AAAA,QAC5C,OAAA,oBACCA,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,WAAA,EAAU,iBAAA;AAAA,YACV,YAAA,EAAY,UAAA;AAAA,YACZ,OAAA,EAAS,CAAC,KAAA,KAAU;AAElB,cAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,cAAA,OAAA,EAAQ;AAAA,YACV,CAAA;AAAA,YAEA,SAAA,EAAU,8QAAA;AAAA,YAEV,QAAA,kBAAAA,cAAA,CAACG,iBAAA,EAAA,EAAM,SAAA,EAAU,QAAA,EAAS;AAAA;AAAA;AAC5B;AAAA;AAAA,GAEJ;AAEJ","file":"tab-strip.cjs","sourcesContent":["import * as React from \"react\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\n/**\n * A compact strip of tabs that close (a browser's open pages), drawn as the\n * Work view switch draws its segments: muted text, a faint fill on the open\n * one. It switches nothing itself; each tab says what it does.\n */\nfunction TabStrip({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n role=\"tablist\"\n data-slot=\"tab-strip\"\n className={cn(\"flex min-w-0 items-center gap-0.5 overflow-x-auto\", className)}\n {...props}\n />\n )\n}\n\n/**\n * One tab, with an × once `onClose` is given. A `div` with the tab role, not\n * a button: the × is a button, and a button cannot hold another.\n */\nfunction TabStripTab({\n active = false,\n onSelect,\n onClose,\n closeLabel = \"Close tab\",\n className,\n children,\n ...props\n}: Omit<React.ComponentProps<\"div\">, \"onSelect\"> & {\n active?: boolean\n onSelect: () => void\n onClose?: () => void\n /** The ×'s accessible name. */\n closeLabel?: string\n}) {\n return (\n <div\n role=\"tab\"\n tabIndex={0}\n aria-selected={active}\n data-slot=\"tab-strip-tab\"\n data-active={active}\n onClick={onSelect}\n onKeyDown={(event) => {\n if (event.target !== event.currentTarget) return\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault()\n onSelect()\n }\n }}\n className={cn(\n \"flex h-7 min-h-11 max-w-40 shrink-0 cursor-pointer items-center gap-1 rounded-[7px] pl-2.5 text-[12px] transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 pointer-fine:min-h-0\",\n onClose ? \"pr-1\" : \"pr-2.5\",\n active\n ? \"bg-foreground/[0.08] font-medium text-foreground\"\n : \"text-muted-foreground hover:bg-foreground/[0.04] hover:text-foreground\",\n className\n )}\n {...props}\n >\n <span className=\"min-w-0 truncate\">{children}</span>\n {onClose && (\n <button\n type=\"button\"\n data-slot=\"tab-strip-close\"\n aria-label={closeLabel}\n onClick={(event) => {\n // Closing a tab is not opening it.\n event.stopPropagation()\n onClose()\n }}\n // The × is 16px; the overlay gives it a usable hit area.\n className=\"relative flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-[4px] text-muted-foreground transition-colors outline-none after:absolute after:-inset-1.5 hover:bg-foreground/[0.08] hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/40\"\n >\n <XIcon className=\"size-3\" />\n </button>\n )}\n </div>\n )\n}\n\nexport { TabStrip, TabStripTab }\n"]}
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ /**
5
+ * A compact strip of tabs that close (a browser's open pages), drawn as the
6
+ * Work view switch draws its segments: muted text, a faint fill on the open
7
+ * one. It switches nothing itself; each tab says what it does.
8
+ */
9
+ declare function TabStrip({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
10
+ /**
11
+ * One tab, with an × once `onClose` is given. A `div` with the tab role, not
12
+ * a button: the × is a button, and a button cannot hold another.
13
+ */
14
+ declare function TabStripTab({ active, onSelect, onClose, closeLabel, className, children, ...props }: Omit<React.ComponentProps<"div">, "onSelect"> & {
15
+ active?: boolean;
16
+ onSelect: () => void;
17
+ onClose?: () => void;
18
+ /** The ×'s accessible name. */
19
+ closeLabel?: string;
20
+ }): react_jsx_runtime.JSX.Element;
21
+
22
+ export { TabStrip, TabStripTab };
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ /**
5
+ * A compact strip of tabs that close (a browser's open pages), drawn as the
6
+ * Work view switch draws its segments: muted text, a faint fill on the open
7
+ * one. It switches nothing itself; each tab says what it does.
8
+ */
9
+ declare function TabStrip({ className, ...props }: React.ComponentProps<"div">): react_jsx_runtime.JSX.Element;
10
+ /**
11
+ * One tab, with an × once `onClose` is given. A `div` with the tab role, not
12
+ * a button: the × is a button, and a button cannot hold another.
13
+ */
14
+ declare function TabStripTab({ active, onSelect, onClose, closeLabel, className, children, ...props }: Omit<React.ComponentProps<"div">, "onSelect"> & {
15
+ active?: boolean;
16
+ onSelect: () => void;
17
+ onClose?: () => void;
18
+ /** The ×'s accessible name. */
19
+ closeLabel?: string;
20
+ }): react_jsx_runtime.JSX.Element;
21
+
22
+ export { TabStrip, TabStripTab };
@@ -0,0 +1,71 @@
1
+ import { cn } from './chunk-LZGII7SX.js';
2
+ import { XIcon } from 'lucide-react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ function TabStrip({ className, ...props }) {
6
+ return /* @__PURE__ */ jsx(
7
+ "div",
8
+ {
9
+ role: "tablist",
10
+ "data-slot": "tab-strip",
11
+ className: cn("flex min-w-0 items-center gap-0.5 overflow-x-auto", className),
12
+ ...props
13
+ }
14
+ );
15
+ }
16
+ function TabStripTab({
17
+ active = false,
18
+ onSelect,
19
+ onClose,
20
+ closeLabel = "Close tab",
21
+ className,
22
+ children,
23
+ ...props
24
+ }) {
25
+ return /* @__PURE__ */ jsxs(
26
+ "div",
27
+ {
28
+ role: "tab",
29
+ tabIndex: 0,
30
+ "aria-selected": active,
31
+ "data-slot": "tab-strip-tab",
32
+ "data-active": active,
33
+ onClick: onSelect,
34
+ onKeyDown: (event) => {
35
+ if (event.target !== event.currentTarget) return;
36
+ if (event.key === "Enter" || event.key === " ") {
37
+ event.preventDefault();
38
+ onSelect();
39
+ }
40
+ },
41
+ className: cn(
42
+ "flex h-7 min-h-11 max-w-40 shrink-0 cursor-pointer items-center gap-1 rounded-[7px] pl-2.5 text-[12px] transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 pointer-fine:min-h-0",
43
+ onClose ? "pr-1" : "pr-2.5",
44
+ active ? "bg-foreground/[0.08] font-medium text-foreground" : "text-muted-foreground hover:bg-foreground/[0.04] hover:text-foreground",
45
+ className
46
+ ),
47
+ ...props,
48
+ children: [
49
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children }),
50
+ onClose && /* @__PURE__ */ jsx(
51
+ "button",
52
+ {
53
+ type: "button",
54
+ "data-slot": "tab-strip-close",
55
+ "aria-label": closeLabel,
56
+ onClick: (event) => {
57
+ event.stopPropagation();
58
+ onClose();
59
+ },
60
+ className: "relative flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-[4px] text-muted-foreground transition-colors outline-none after:absolute after:-inset-1.5 hover:bg-foreground/[0.08] hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/40",
61
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-3" })
62
+ }
63
+ )
64
+ ]
65
+ }
66
+ );
67
+ }
68
+
69
+ export { TabStrip, TabStripTab };
70
+ //# sourceMappingURL=tab-strip.js.map
71
+ //# sourceMappingURL=tab-strip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tab-strip.tsx"],"names":[],"mappings":";;;;AAUA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AACtE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,SAAA;AAAA,MACL,WAAA,EAAU,WAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,mDAAA,EAAqD,SAAS,CAAA;AAAA,MAC3E,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,WAAA,CAAY;AAAA,EACnB,MAAA,GAAS,KAAA;AAAA,EACT,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA,GAAa,WAAA;AAAA,EACb,SAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAMG;AACD,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,KAAA;AAAA,MACL,QAAA,EAAU,CAAA;AAAA,MACV,eAAA,EAAe,MAAA;AAAA,MACf,WAAA,EAAU,eAAA;AAAA,MACV,aAAA,EAAa,MAAA;AAAA,MACb,OAAA,EAAS,QAAA;AAAA,MACT,SAAA,EAAW,CAAC,KAAA,KAAU;AACpB,QAAA,IAAI,KAAA,CAAM,MAAA,KAAW,KAAA,CAAM,aAAA,EAAe;AAC1C,QAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAW,KAAA,CAAM,QAAQ,GAAA,EAAK;AAC9C,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,QAAA,EAAS;AAAA,QACX;AAAA,MACF,CAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,4MAAA;AAAA,QACA,UAAU,MAAA,GAAS,QAAA;AAAA,QACnB,SACI,kDAAA,GACA,wEAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kBAAA,EAAoB,QAAA,EAAS,CAAA;AAAA,QAC5C,OAAA,oBACC,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,WAAA,EAAU,iBAAA;AAAA,YACV,YAAA,EAAY,UAAA;AAAA,YACZ,OAAA,EAAS,CAAC,KAAA,KAAU;AAElB,cAAA,KAAA,CAAM,eAAA,EAAgB;AACtB,cAAA,OAAA,EAAQ;AAAA,YACV,CAAA;AAAA,YAEA,SAAA,EAAU,8QAAA;AAAA,YAEV,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,SAAA,EAAU,QAAA,EAAS;AAAA;AAAA;AAC5B;AAAA;AAAA,GAEJ;AAEJ","file":"tab-strip.js","sourcesContent":["import * as React from \"react\"\nimport { XIcon } from \"lucide-react\"\n\nimport { cn } from \"./lib/utils\"\n\n/**\n * A compact strip of tabs that close (a browser's open pages), drawn as the\n * Work view switch draws its segments: muted text, a faint fill on the open\n * one. It switches nothing itself; each tab says what it does.\n */\nfunction TabStrip({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n role=\"tablist\"\n data-slot=\"tab-strip\"\n className={cn(\"flex min-w-0 items-center gap-0.5 overflow-x-auto\", className)}\n {...props}\n />\n )\n}\n\n/**\n * One tab, with an × once `onClose` is given. A `div` with the tab role, not\n * a button: the × is a button, and a button cannot hold another.\n */\nfunction TabStripTab({\n active = false,\n onSelect,\n onClose,\n closeLabel = \"Close tab\",\n className,\n children,\n ...props\n}: Omit<React.ComponentProps<\"div\">, \"onSelect\"> & {\n active?: boolean\n onSelect: () => void\n onClose?: () => void\n /** The ×'s accessible name. */\n closeLabel?: string\n}) {\n return (\n <div\n role=\"tab\"\n tabIndex={0}\n aria-selected={active}\n data-slot=\"tab-strip-tab\"\n data-active={active}\n onClick={onSelect}\n onKeyDown={(event) => {\n if (event.target !== event.currentTarget) return\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault()\n onSelect()\n }\n }}\n className={cn(\n \"flex h-7 min-h-11 max-w-40 shrink-0 cursor-pointer items-center gap-1 rounded-[7px] pl-2.5 text-[12px] transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 pointer-fine:min-h-0\",\n onClose ? \"pr-1\" : \"pr-2.5\",\n active\n ? \"bg-foreground/[0.08] font-medium text-foreground\"\n : \"text-muted-foreground hover:bg-foreground/[0.04] hover:text-foreground\",\n className\n )}\n {...props}\n >\n <span className=\"min-w-0 truncate\">{children}</span>\n {onClose && (\n <button\n type=\"button\"\n data-slot=\"tab-strip-close\"\n aria-label={closeLabel}\n onClick={(event) => {\n // Closing a tab is not opening it.\n event.stopPropagation()\n onClose()\n }}\n // The × is 16px; the overlay gives it a usable hit area.\n className=\"relative flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-[4px] text-muted-foreground transition-colors outline-none after:absolute after:-inset-1.5 hover:bg-foreground/[0.08] hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/40\"\n >\n <XIcon className=\"size-3\" />\n </button>\n )}\n </div>\n )\n}\n\nexport { TabStrip, TabStripTab }\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkIVMZANP7_cjs = require('./chunk-IVMZANP7.cjs');
3
+ var chunkILCP5QXL_cjs = require('./chunk-ILCP5QXL.cjs');
4
4
  var chunk6YHDDRIM_cjs = require('./chunk-6YHDDRIM.cjs');
5
5
  var React = require('react');
6
6
  var radixUi = require('radix-ui');
@@ -97,8 +97,10 @@ function ToggleGroupItem({
97
97
  "data-spacing": context.spacing,
98
98
  className: chunk6YHDDRIM_cjs.cn(
99
99
  "shrink-0 focus:z-10 focus-visible:z-10",
100
- chunkIVMZANP7_cjs.toggleVariants({ variant: itemVariant, size: itemSize }),
100
+ chunkILCP5QXL_cjs.toggleVariants({ variant: itemVariant, size: itemSize }),
101
101
  context.spacing === 0 && JOINED_ITEM[itemVariant ?? "default"],
102
+ // A joined segment pads its label; an icon segment stays square.
103
+ itemSize?.startsWith("icon") && "px-0",
102
104
  className
103
105
  ),
104
106
  ...props,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/toggle-group.tsx"],"names":["React","jsx","ToggleGroupPrimitive","cn","toggleVariants"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,IAAM,qBAA2BA,gBAAA,CAAA,aAAA,CAK/B;AAAA,EACA,IAAA,EAAM,SAAA;AAAA,EACN,OAAA,EAAS,SAAA;AAAA,EACT,OAAA,EAAS,CAAA;AAAA,EACT,WAAA,EAAa;AACf,CAAC,CAAA;AAQD,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA,EAAS,6CAAA;AAAA,EACT,OAAA,EAAS;AACX,CAAA;AAEA,IAAM,WAAA,GAAc;AAAA,EAClB,OAAA,EACE,8MAAA;AAAA,EACF,OAAA,EACE;AACJ,CAAA;AAEA,SAAS,WAAA,CAAY;AAAA,EACnB,SAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA,GAAU,CAAA;AAAA,EACV,WAAA,GAAc,YAAA;AAAA,EACd,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAIK;AACH,EAAA,uBACEC,cAAA;AAAA,IAACC,mBAAA,CAAqB,IAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,WAAA,EAAW,IAAA;AAAA,MACX,cAAA,EAAc,OAAA;AAAA,MACd,kBAAA,EAAkB,WAAA;AAAA,MAClB,KAAA,EAAO,EAAE,OAAA,EAAS,OAAA,EAAQ;AAAA,MAC1B,SAAA,EAAWC,oBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAKT,4KAAA;AAAA,QACA,OAAA,KAAY,CAAA,IAAK,YAAA,CAAa,OAAA,IAAW,SAAS,CAAA;AAAA,QAClD;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAAF,cAAA;AAAA,QAAC,kBAAA,CAAmB,QAAA;AAAA,QAAnB;AAAA,UACC,KAAA,EAAO,EAAE,OAAA,EAAS,IAAA,EAAM,SAAS,WAAA,EAAY;AAAA,UAE5C;AAAA;AAAA;AACH;AAAA,GACF;AAEJ;AAEA,SAAS,eAAA,CAAgB;AAAA,EACvB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EACuC;AACrC,EAAA,MAAM,OAAA,GAAgBD,4BAAW,kBAAkB,CAAA;AACnD,EAAA,MAAM,WAAA,GAAc,QAAQ,OAAA,IAAW,OAAA;AACvC,EAAA,MAAM,QAAA,GAAW,QAAQ,IAAA,IAAQ,IAAA;AAEjC,EAAA,uBACEC,cAAA;AAAA,IAACC,mBAAA,CAAqB,IAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,mBAAA;AAAA,MACV,cAAA,EAAc,WAAA;AAAA,MACd,WAAA,EAAW,QAAA;AAAA,MACX,gBAAc,OAAA,CAAQ,OAAA;AAAA,MACtB,SAAA,EAAWC,oBAAA;AAAA,QACT,wCAAA;AAAA,QACAC,iCAAe,EAAE,OAAA,EAAS,WAAA,EAAa,IAAA,EAAM,UAAU,CAAA;AAAA,QACvD,OAAA,CAAQ,OAAA,KAAY,CAAA,IAAK,WAAA,CAAY,eAAe,SAAS,CAAA;AAAA,QAC7D;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAOA,SAAS,UAAA,CAA6B;AAAA,EACpC,KAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA,GAAQ,MAAA;AAAA,EACR;AACF,CAAA,EAMG;AACD,EAAA,uBACEH,cAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,OAAA,EAAQ,SAAA;AAAA,MACR,YAAA,EAAY,KAAA;AAAA,MACZ,KAAA;AAAA,MACA,aAAA,EAAe,CAAC,CAAA,KAAM;AACpB,QAAA,IAAI,CAAA,WAAY,CAAM,CAAA;AAAA,MACxB,CAAA;AAAA,MACA,SAAA;AAAA,MAEC,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,qBACVA,cAAA,CAAC,eAAA,EAAA,EAA2B,KAAA,EAAO,CAAA,CAAE,EAAA,EAClC,QAAA,EAAA,CAAA,CAAE,KAAA,EAAA,EADiB,CAAA,CAAE,EAExB,CACD;AAAA;AAAA,GACH;AAEJ;AAGA,SAAS,iBAAA,CACP,KACA,KAAA,EACqB;AACrB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUD,0BAAY,MAAM;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AACtC,MAAA,OAAO,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,MAAM,KAAK,CAAA,IAAK,MAAM,CAAC,CAAA;AAAA,IAClD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,MAAM,CAAC,CAAA;AAAA,IAChB;AAAA,EACF,CAAC,CAAA;AACD,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAS;AACvB,IAAA,OAAA,CAAQ,CAAC,CAAA;AACT,IAAA,IAAI;AACF,MAAA,YAAA,CAAa,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAC7B,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF,CAAA;AACA,EAAA,OAAO,CAAC,MAAM,MAAM,CAAA;AACtB","file":"toggle-group.cjs","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\nimport { toggleVariants } from \"./toggle\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n>({\n size: \"default\",\n variant: \"default\",\n spacing: 0,\n orientation: \"horizontal\",\n})\n\n// With spacing the items are separate toggles, drawn as `toggle` draws them.\n// Joined (spacing 0) they are one segmented control, as the Work console\n// draws its two: `default` is the Work / Dev switch — a round track with the\n// picked segment an amber pill — and `outline` its view switch (Steps |\n// Stats, Open | Resolved) — a 10px bordered track, the picked segment a\n// faint fill.\nconst JOINED_TRACK = {\n default: \"gap-1 rounded-full bg-foreground/[0.06] p-1\",\n outline: \"gap-0 rounded-[10px] border border-foreground/10 p-0.5\",\n} as const\n\nconst JOINED_ITEM = {\n default:\n \"rounded-full border-transparent bg-transparent px-4 font-semibold text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-amber-400 data-[state=on]:text-stone-950\",\n outline:\n \"rounded-[8px] border-transparent bg-transparent px-3 text-[12.5px] font-normal text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n} as const\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 0,\n orientation = \"horizontal\",\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n // `w-fit` sizes to content and refuses to shrink, so a segmented\n // control wider than a phone dragged the whole page sideways rather\n // than containing itself. Capped at its container, scrolling inside\n // as a last resort — call sites should still shorten their labels.\n \"group/toggle-group no-scrollbar flex w-fit max-w-full flex-row items-center gap-[--spacing(var(--gap))] overflow-x-auto data-vertical:flex-col data-vertical:items-stretch\",\n spacing === 0 && JOINED_TRACK[variant ?? \"default\"],\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n const itemVariant = context.variant || variant\n const itemSize = context.size || size\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={itemVariant}\n data-size={itemSize}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 focus:z-10 focus-visible:z-10\",\n toggleVariants({ variant: itemVariant, size: itemSize }),\n context.spacing === 0 && JOINED_ITEM[itemVariant ?? \"default\"],\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n}\n\n/**\n * A tab's two or three views (Steps | Stats, Members | Recent alerts): the\n * Work view switch. One view is always picked — clicking the picked one\n * again does not clear it.\n */\nfunction ViewSwitch<T extends string>({\n views,\n value,\n onChange,\n label = \"Show\",\n className,\n}: {\n views: readonly { id: T; label: React.ReactNode }[]\n value: T\n onChange: (v: T) => void\n label?: string\n className?: string\n}) {\n return (\n <ToggleGroup\n type=\"single\"\n variant=\"outline\"\n aria-label={label}\n value={value}\n onValueChange={(v) => {\n if (v) onChange(v as T)\n }}\n className={className}\n >\n {views.map((v) => (\n <ToggleGroupItem key={v.id} value={v.id}>\n {v.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroup>\n )\n}\n\n/** The view last chosen under `key`, else the first; storage may be off. */\nfunction useRememberedView<T extends string>(\n key: string,\n views: readonly T[]\n): [T, (v: T) => void] {\n const [view, setView] = React.useState<T>(() => {\n try {\n const saved = localStorage.getItem(key)\n return views.find((v) => v === saved) ?? views[0]\n } catch {\n return views[0]\n }\n })\n const choose = (v: T) => {\n setView(v)\n try {\n localStorage.setItem(key, v)\n } catch {\n // A private window keeps the choice for this visit only.\n }\n }\n return [view, choose]\n}\n\nexport { ToggleGroup, ToggleGroupItem, ViewSwitch, useRememberedView }\n"]}
1
+ {"version":3,"sources":["../src/toggle-group.tsx"],"names":["React","jsx","ToggleGroupPrimitive","cn","toggleVariants"],"mappings":"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","file":"toggle-group.cjs","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\nimport { toggleVariants } from \"./toggle\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n>({\n size: \"default\",\n variant: \"default\",\n spacing: 0,\n orientation: \"horizontal\",\n})\n\n// With spacing the items are separate toggles, drawn as `toggle` draws them.\n// Joined (spacing 0) they are one segmented control, as the Work console\n// draws its two: `default` is the Work / Dev switch — a round track with the\n// picked segment an amber pill — and `outline` its view switch (Steps |\n// Stats, Open | Resolved) — a 10px bordered track, the picked segment a\n// faint fill.\nconst JOINED_TRACK = {\n default: \"gap-1 rounded-full bg-foreground/[0.06] p-1\",\n outline: \"gap-0 rounded-[10px] border border-foreground/10 p-0.5\",\n} as const\n\nconst JOINED_ITEM = {\n default:\n \"rounded-full border-transparent bg-transparent px-4 font-semibold text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-amber-400 data-[state=on]:text-stone-950\",\n outline:\n \"rounded-[8px] border-transparent bg-transparent px-3 text-[12.5px] font-normal text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n} as const\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 0,\n orientation = \"horizontal\",\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n // `w-fit` sizes to content and refuses to shrink, so a segmented\n // control wider than a phone dragged the whole page sideways rather\n // than containing itself. Capped at its container, scrolling inside\n // as a last resort — call sites should still shorten their labels.\n \"group/toggle-group no-scrollbar flex w-fit max-w-full flex-row items-center gap-[--spacing(var(--gap))] overflow-x-auto data-vertical:flex-col data-vertical:items-stretch\",\n spacing === 0 && JOINED_TRACK[variant ?? \"default\"],\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n const itemVariant = context.variant || variant\n const itemSize = context.size || size\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={itemVariant}\n data-size={itemSize}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 focus:z-10 focus-visible:z-10\",\n toggleVariants({ variant: itemVariant, size: itemSize }),\n context.spacing === 0 && JOINED_ITEM[itemVariant ?? \"default\"],\n // A joined segment pads its label; an icon segment stays square.\n itemSize?.startsWith(\"icon\") && \"px-0\",\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n}\n\n/**\n * A tab's two or three views (Steps | Stats, Members | Recent alerts): the\n * Work view switch. One view is always picked — clicking the picked one\n * again does not clear it.\n */\nfunction ViewSwitch<T extends string>({\n views,\n value,\n onChange,\n label = \"Show\",\n className,\n}: {\n views: readonly { id: T; label: React.ReactNode }[]\n value: T\n onChange: (v: T) => void\n label?: string\n className?: string\n}) {\n return (\n <ToggleGroup\n type=\"single\"\n variant=\"outline\"\n aria-label={label}\n value={value}\n onValueChange={(v) => {\n if (v) onChange(v as T)\n }}\n className={className}\n >\n {views.map((v) => (\n <ToggleGroupItem key={v.id} value={v.id}>\n {v.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroup>\n )\n}\n\n/** The view last chosen under `key`, else the first; storage may be off. */\nfunction useRememberedView<T extends string>(\n key: string,\n views: readonly T[]\n): [T, (v: T) => void] {\n const [view, setView] = React.useState<T>(() => {\n try {\n const saved = localStorage.getItem(key)\n return views.find((v) => v === saved) ?? views[0]\n } catch {\n return views[0]\n }\n })\n const choose = (v: T) => {\n setView(v)\n try {\n localStorage.setItem(key, v)\n } catch {\n // A private window keeps the choice for this visit only.\n }\n }\n return [view, choose]\n}\n\nexport { ToggleGroup, ToggleGroupItem, ViewSwitch, useRememberedView }\n"]}
@@ -1,4 +1,4 @@
1
- import { toggleVariants } from './chunk-CPAFEXKR.js';
1
+ import { toggleVariants } from './chunk-WO2SXSNH.js';
2
2
  import { cn } from './chunk-LZGII7SX.js';
3
3
  import * as React from 'react';
4
4
  import { ToggleGroup as ToggleGroup$1 } from 'radix-ui';
@@ -77,6 +77,8 @@ function ToggleGroupItem({
77
77
  "shrink-0 focus:z-10 focus-visible:z-10",
78
78
  toggleVariants({ variant: itemVariant, size: itemSize }),
79
79
  context.spacing === 0 && JOINED_ITEM[itemVariant ?? "default"],
80
+ // A joined segment pads its label; an icon segment stays square.
81
+ itemSize?.startsWith("icon") && "px-0",
80
82
  className
81
83
  ),
82
84
  ...props,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/toggle-group.tsx"],"names":["ToggleGroupPrimitive"],"mappings":"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","file":"toggle-group.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\nimport { toggleVariants } from \"./toggle\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n>({\n size: \"default\",\n variant: \"default\",\n spacing: 0,\n orientation: \"horizontal\",\n})\n\n// With spacing the items are separate toggles, drawn as `toggle` draws them.\n// Joined (spacing 0) they are one segmented control, as the Work console\n// draws its two: `default` is the Work / Dev switch — a round track with the\n// picked segment an amber pill — and `outline` its view switch (Steps |\n// Stats, Open | Resolved) — a 10px bordered track, the picked segment a\n// faint fill.\nconst JOINED_TRACK = {\n default: \"gap-1 rounded-full bg-foreground/[0.06] p-1\",\n outline: \"gap-0 rounded-[10px] border border-foreground/10 p-0.5\",\n} as const\n\nconst JOINED_ITEM = {\n default:\n \"rounded-full border-transparent bg-transparent px-4 font-semibold text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-amber-400 data-[state=on]:text-stone-950\",\n outline:\n \"rounded-[8px] border-transparent bg-transparent px-3 text-[12.5px] font-normal text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n} as const\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 0,\n orientation = \"horizontal\",\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n // `w-fit` sizes to content and refuses to shrink, so a segmented\n // control wider than a phone dragged the whole page sideways rather\n // than containing itself. Capped at its container, scrolling inside\n // as a last resort — call sites should still shorten their labels.\n \"group/toggle-group no-scrollbar flex w-fit max-w-full flex-row items-center gap-[--spacing(var(--gap))] overflow-x-auto data-vertical:flex-col data-vertical:items-stretch\",\n spacing === 0 && JOINED_TRACK[variant ?? \"default\"],\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n const itemVariant = context.variant || variant\n const itemSize = context.size || size\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={itemVariant}\n data-size={itemSize}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 focus:z-10 focus-visible:z-10\",\n toggleVariants({ variant: itemVariant, size: itemSize }),\n context.spacing === 0 && JOINED_ITEM[itemVariant ?? \"default\"],\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n}\n\n/**\n * A tab's two or three views (Steps | Stats, Members | Recent alerts): the\n * Work view switch. One view is always picked — clicking the picked one\n * again does not clear it.\n */\nfunction ViewSwitch<T extends string>({\n views,\n value,\n onChange,\n label = \"Show\",\n className,\n}: {\n views: readonly { id: T; label: React.ReactNode }[]\n value: T\n onChange: (v: T) => void\n label?: string\n className?: string\n}) {\n return (\n <ToggleGroup\n type=\"single\"\n variant=\"outline\"\n aria-label={label}\n value={value}\n onValueChange={(v) => {\n if (v) onChange(v as T)\n }}\n className={className}\n >\n {views.map((v) => (\n <ToggleGroupItem key={v.id} value={v.id}>\n {v.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroup>\n )\n}\n\n/** The view last chosen under `key`, else the first; storage may be off. */\nfunction useRememberedView<T extends string>(\n key: string,\n views: readonly T[]\n): [T, (v: T) => void] {\n const [view, setView] = React.useState<T>(() => {\n try {\n const saved = localStorage.getItem(key)\n return views.find((v) => v === saved) ?? views[0]\n } catch {\n return views[0]\n }\n })\n const choose = (v: T) => {\n setView(v)\n try {\n localStorage.setItem(key, v)\n } catch {\n // A private window keeps the choice for this visit only.\n }\n }\n return [view, choose]\n}\n\nexport { ToggleGroup, ToggleGroupItem, ViewSwitch, useRememberedView }\n"]}
1
+ {"version":3,"sources":["../src/toggle-group.tsx"],"names":["ToggleGroupPrimitive"],"mappings":"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","file":"toggle-group.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { type VariantProps } from \"class-variance-authority\"\nimport { ToggleGroup as ToggleGroupPrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\nimport { toggleVariants } from \"./toggle\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }\n>({\n size: \"default\",\n variant: \"default\",\n spacing: 0,\n orientation: \"horizontal\",\n})\n\n// With spacing the items are separate toggles, drawn as `toggle` draws them.\n// Joined (spacing 0) they are one segmented control, as the Work console\n// draws its two: `default` is the Work / Dev switch — a round track with the\n// picked segment an amber pill — and `outline` its view switch (Steps |\n// Stats, Open | Resolved) — a 10px bordered track, the picked segment a\n// faint fill.\nconst JOINED_TRACK = {\n default: \"gap-1 rounded-full bg-foreground/[0.06] p-1\",\n outline: \"gap-0 rounded-[10px] border border-foreground/10 p-0.5\",\n} as const\n\nconst JOINED_ITEM = {\n default:\n \"rounded-full border-transparent bg-transparent px-4 font-semibold text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-amber-400 data-[state=on]:text-stone-950\",\n outline:\n \"rounded-[8px] border-transparent bg-transparent px-3 text-[12.5px] font-normal text-muted-foreground hover:text-foreground data-[state=on]:border-transparent data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n} as const\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n spacing = 0,\n orientation = \"horizontal\",\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n VariantProps<typeof toggleVariants> & {\n spacing?: number\n orientation?: \"horizontal\" | \"vertical\"\n }) {\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={variant}\n data-size={size}\n data-spacing={spacing}\n data-orientation={orientation}\n style={{ \"--gap\": spacing } as React.CSSProperties}\n className={cn(\n // `w-fit` sizes to content and refuses to shrink, so a segmented\n // control wider than a phone dragged the whole page sideways rather\n // than containing itself. Capped at its container, scrolling inside\n // as a last resort — call sites should still shorten their labels.\n \"group/toggle-group no-scrollbar flex w-fit max-w-full flex-row items-center gap-[--spacing(var(--gap))] overflow-x-auto data-vertical:flex-col data-vertical:items-stretch\",\n spacing === 0 && JOINED_TRACK[variant ?? \"default\"],\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider\n value={{ variant, size, spacing, orientation }}\n >\n {children}\n </ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &\n VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n const itemVariant = context.variant || variant\n const itemSize = context.size || size\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n data-variant={itemVariant}\n data-size={itemSize}\n data-spacing={context.spacing}\n className={cn(\n \"shrink-0 focus:z-10 focus-visible:z-10\",\n toggleVariants({ variant: itemVariant, size: itemSize }),\n context.spacing === 0 && JOINED_ITEM[itemVariant ?? \"default\"],\n // A joined segment pads its label; an icon segment stays square.\n itemSize?.startsWith(\"icon\") && \"px-0\",\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n}\n\n/**\n * A tab's two or three views (Steps | Stats, Members | Recent alerts): the\n * Work view switch. One view is always picked — clicking the picked one\n * again does not clear it.\n */\nfunction ViewSwitch<T extends string>({\n views,\n value,\n onChange,\n label = \"Show\",\n className,\n}: {\n views: readonly { id: T; label: React.ReactNode }[]\n value: T\n onChange: (v: T) => void\n label?: string\n className?: string\n}) {\n return (\n <ToggleGroup\n type=\"single\"\n variant=\"outline\"\n aria-label={label}\n value={value}\n onValueChange={(v) => {\n if (v) onChange(v as T)\n }}\n className={className}\n >\n {views.map((v) => (\n <ToggleGroupItem key={v.id} value={v.id}>\n {v.label}\n </ToggleGroupItem>\n ))}\n </ToggleGroup>\n )\n}\n\n/** The view last chosen under `key`, else the first; storage may be off. */\nfunction useRememberedView<T extends string>(\n key: string,\n views: readonly T[]\n): [T, (v: T) => void] {\n const [view, setView] = React.useState<T>(() => {\n try {\n const saved = localStorage.getItem(key)\n return views.find((v) => v === saved) ?? views[0]\n } catch {\n return views[0]\n }\n })\n const choose = (v: T) => {\n setView(v)\n try {\n localStorage.setItem(key, v)\n } catch {\n // A private window keeps the choice for this visit only.\n }\n }\n return [view, choose]\n}\n\nexport { ToggleGroup, ToggleGroupItem, ViewSwitch, useRememberedView }\n"]}
package/dist/toggle.cjs CHANGED
@@ -1,21 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var chunkIVMZANP7_cjs = require('./chunk-IVMZANP7.cjs');
3
+ var chunkILCP5QXL_cjs = require('./chunk-ILCP5QXL.cjs');
4
4
  require('./chunk-6YHDDRIM.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "FilterPill", {
9
9
  enumerable: true,
10
- get: function () { return chunkIVMZANP7_cjs.FilterPill; }
10
+ get: function () { return chunkILCP5QXL_cjs.FilterPill; }
11
11
  });
12
12
  Object.defineProperty(exports, "Toggle", {
13
13
  enumerable: true,
14
- get: function () { return chunkIVMZANP7_cjs.Toggle; }
14
+ get: function () { return chunkILCP5QXL_cjs.Toggle; }
15
15
  });
16
16
  Object.defineProperty(exports, "toggleVariants", {
17
17
  enumerable: true,
18
- get: function () { return chunkIVMZANP7_cjs.toggleVariants; }
18
+ get: function () { return chunkILCP5QXL_cjs.toggleVariants; }
19
19
  });
20
20
  //# sourceMappingURL=toggle.cjs.map
21
21
  //# sourceMappingURL=toggle.cjs.map
package/dist/toggle.d.cts CHANGED
@@ -6,7 +6,7 @@ import { Toggle as Toggle$1 } from 'radix-ui';
6
6
 
7
7
  declare const toggleVariants: (props?: ({
8
8
  variant?: "default" | "outline" | null | undefined;
9
- size?: "default" | "sm" | "lg" | null | undefined;
9
+ size?: "default" | "sm" | "lg" | "icon" | "icon-xs" | null | undefined;
10
10
  } & class_variance_authority_types.ClassProp) | undefined) => string;
11
11
  declare function Toggle({ className, variant, size, ...props }: React.ComponentProps<typeof Toggle$1.Root> & VariantProps<typeof toggleVariants>): react_jsx_runtime.JSX.Element;
12
12
  /**
package/dist/toggle.d.ts CHANGED
@@ -6,7 +6,7 @@ import { Toggle as Toggle$1 } from 'radix-ui';
6
6
 
7
7
  declare const toggleVariants: (props?: ({
8
8
  variant?: "default" | "outline" | null | undefined;
9
- size?: "default" | "sm" | "lg" | null | undefined;
9
+ size?: "default" | "sm" | "lg" | "icon" | "icon-xs" | null | undefined;
10
10
  } & class_variance_authority_types.ClassProp) | undefined) => string;
11
11
  declare function Toggle({ className, variant, size, ...props }: React.ComponentProps<typeof Toggle$1.Root> & VariantProps<typeof toggleVariants>): react_jsx_runtime.JSX.Element;
12
12
  /**
package/dist/toggle.js CHANGED
@@ -1,4 +1,4 @@
1
- export { FilterPill, Toggle, toggleVariants } from './chunk-CPAFEXKR.js';
1
+ export { FilterPill, Toggle, toggleVariants } from './chunk-WO2SXSNH.js';
2
2
  import './chunk-LZGII7SX.js';
3
3
  //# sourceMappingURL=toggle.js.map
4
4
  //# sourceMappingURL=toggle.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invergent/ui-sdk",
3
- "version": "2.19.1",
3
+ "version": "2.19.3",
4
4
  "description": "Shared theme and UI components for Surogate's web client, chat SDK, desktop and ops console.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "homepage": "https://github.com/invergent-ai/surogates/tree/master/sdk/ui-sdk#readme",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/toggle.tsx"],"names":["TogglePrimitive"],"mappings":";;;;;AAWA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,oVAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,6NAAA;AAAA,QACF,OAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,gDAAA;AAAA,QACT,EAAA,EAAI,+CAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EACuC;AACrC,EAAA,uBACE,GAAA;AAAA,IAACA,QAAA,CAAgB,IAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,UAAA,CAAW;AAAA,EAClB,EAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAQG;AACD,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,SAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MACL,OAAA,EAAS,EAAA;AAAA,MACT,eAAA,EAAiB,MAAM,OAAA,EAAQ;AAAA,MAC/B,WAAW,EAAA,CAAG,GAAA,IAAO,CAAC,EAAA,IAAM,cAAc,SAAS,CAAA;AAAA,MAClD,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-CPAFEXKR.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's pressed-state toggles. `default` is the 9px chip its\n// forms use for a choice that is on or off (Once / Repeating, the days of the\n// week): a faint box, amber-tinted once pressed. `outline` is its filter\n// pill: round, bordered, a neutral fill once on. Muted text brightens on\n// hover. Touch keeps 40px or more, a mouse the compact height.\nconst toggleVariants = cva(\n \"group/toggle inline-flex shrink-0 items-center justify-center gap-1.5 border whitespace-nowrap transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5\",\n {\n variants: {\n variant: {\n default:\n \"rounded-[9px] border-foreground/[0.08] bg-foreground/[0.04] font-medium text-muted-foreground hover:text-foreground data-[state=on]:border-amber-500/40 data-[state=on]:bg-amber-500/[0.12] data-[state=on]:text-foreground\",\n outline:\n \"rounded-full border-foreground/10 text-muted-foreground hover:text-foreground data-[state=on]:border-foreground/30 data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n },\n size: {\n default: \"min-h-10 px-3 text-[13px] pointer-fine:min-h-8\",\n sm: \"min-h-9 px-3 text-[12px] pointer-fine:min-h-7\",\n lg: \"min-h-11 px-4 text-sm pointer-fine:min-h-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Toggle({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\n/**\n * The Work filter pill (a row of them filters a list: \"All channels\",\n * \"Slack 3\"…). An empty filter stays clickable, just quieter.\n */\nfunction FilterPill({\n on,\n onClick,\n dim,\n className,\n ...props\n}: Omit<\n React.ComponentProps<typeof TogglePrimitive.Root>,\n \"pressed\" | \"onPressedChange\" | \"onClick\"\n> & {\n on: boolean\n onClick: () => void\n /** Nothing behind it yet: still clickable, just quieter. */\n dim?: boolean\n}) {\n return (\n <Toggle\n variant=\"outline\"\n size=\"sm\"\n pressed={on}\n onPressedChange={() => onClick()}\n className={cn(dim && !on && \"opacity-55\", className)}\n {...props}\n />\n )\n}\n\nexport { Toggle, FilterPill, toggleVariants }\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/toggle.tsx"],"names":["cva","jsx","TogglePrimitive","cn"],"mappings":";;;;;;;AAWA,IAAM,cAAA,GAAiBA,0BAAA;AAAA,EACrB,oVAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EACE,6NAAA;AAAA,QACF,OAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,gDAAA;AAAA,QACT,EAAA,EAAI,+CAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EACuC;AACrC,EAAA,uBACEC,cAAA;AAAA,IAACC,cAAA,CAAgB,IAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAWC,qBAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,UAAA,CAAW;AAAA,EAClB,EAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAQG;AACD,EAAA,uBACEF,cAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAQ,SAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MACL,OAAA,EAAS,EAAA;AAAA,MACT,eAAA,EAAiB,MAAM,OAAA,EAAQ;AAAA,MAC/B,WAAWE,oBAAA,CAAG,GAAA,IAAO,CAAC,EAAA,IAAM,cAAc,SAAS,CAAA;AAAA,MAClD,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-IVMZANP7.cjs","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Toggle as TogglePrimitive } from \"radix-ui\"\n\nimport { cn } from \"./lib/utils\"\n\n// The Work console's pressed-state toggles. `default` is the 9px chip its\n// forms use for a choice that is on or off (Once / Repeating, the days of the\n// week): a faint box, amber-tinted once pressed. `outline` is its filter\n// pill: round, bordered, a neutral fill once on. Muted text brightens on\n// hover. Touch keeps 40px or more, a mouse the compact height.\nconst toggleVariants = cva(\n \"group/toggle inline-flex shrink-0 items-center justify-center gap-1.5 border whitespace-nowrap transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5\",\n {\n variants: {\n variant: {\n default:\n \"rounded-[9px] border-foreground/[0.08] bg-foreground/[0.04] font-medium text-muted-foreground hover:text-foreground data-[state=on]:border-amber-500/40 data-[state=on]:bg-amber-500/[0.12] data-[state=on]:text-foreground\",\n outline:\n \"rounded-full border-foreground/10 text-muted-foreground hover:text-foreground data-[state=on]:border-foreground/30 data-[state=on]:bg-foreground/[0.08] data-[state=on]:font-medium data-[state=on]:text-foreground\",\n },\n size: {\n default: \"min-h-10 px-3 text-[13px] pointer-fine:min-h-8\",\n sm: \"min-h-9 px-3 text-[12px] pointer-fine:min-h-7\",\n lg: \"min-h-11 px-4 text-sm pointer-fine:min-h-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Toggle({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> &\n VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive.Root\n data-slot=\"toggle\"\n className={cn(toggleVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\n/**\n * The Work filter pill (a row of them filters a list: \"All channels\",\n * \"Slack 3\"…). An empty filter stays clickable, just quieter.\n */\nfunction FilterPill({\n on,\n onClick,\n dim,\n className,\n ...props\n}: Omit<\n React.ComponentProps<typeof TogglePrimitive.Root>,\n \"pressed\" | \"onPressedChange\" | \"onClick\"\n> & {\n on: boolean\n onClick: () => void\n /** Nothing behind it yet: still clickable, just quieter. */\n dim?: boolean\n}) {\n return (\n <Toggle\n variant=\"outline\"\n size=\"sm\"\n pressed={on}\n onPressedChange={() => onClick()}\n className={cn(dim && !on && \"opacity-55\", className)}\n {...props}\n />\n )\n}\n\nexport { Toggle, FilterPill, toggleVariants }\n"]}