@ai-matrx/design-system 0.49.59 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -12,6 +12,11 @@
12
12
  - **The drill answer's coverage and Pareto lines are labels, not sentences** (lane DRILL-LIVE-FIXES, interface text is layout, 2026-09-30). Coverage reads `$100.00 of $400.00 (25%)` (was "This slice is $100.00 of the $400.00 the whole window holds (25%)."), with "This slice's share of the whole window" in its tooltip; a Pareto line that never reaches its share reads `All 5 shown make 20% of Cost` (the groups past the limit are already the table's own "N more" row). Proof: `drill-usage-adoptions.test.tsx`, `drill-pareto-and-row-actions.test.tsx`. Consumer action: none.
13
13
  - **The drill chart's value axis says the number the Measure printed, never the raw value** (localhost walk of `/administration/usage`, 2026-09-30). When a Measure's format converts its unit (the usage explorer stores dollars and prints points at 20,000 a dollar) and the printed tick is too long for the axis, the tick used to compact the RAW value, so a 9,000,000-point day read `450` under "Cost (points) by day". `drillChartAxisNumber` now compacts the number the format printed (`9.0M`), keeping a one-character currency sign (`$1.2k`). Proof: `drill-chart-axis.test.ts`. Consumer action: none.
14
14
 
15
+ ## 0.50.0
16
+
17
+ - **The organization picker: favorites, a highlighted active row, coloured marks** (owner, 2026-10-01). Every row carries its own star (`favoriteOrganizationIds` + `onToggleFavorite(id, favorite)`); favorites are drawn first, then the person's own, then the rest; the star is a sibling button and never selects. The "Keep it at the top" switch and the "Working in …" / "No organization selected" line are gone — the active row is the answer (tinted, bold, ringed, checked). New `OrganizationMark` (logo, or the 2–3 letter abbreviation on a colour tile seeded by `organizationColor(id)`) replaces `OrganizationAbbreviation`. Proof: `organization-picker.test.tsx`.
18
+ **Consumer action (breaking):** replace `defaultOrganizationId` / `onSetDefault` with `favoriteOrganizationIds` / `onToggleFavorite`; drop `hideStatus`; import `OrganizationMark` instead of `OrganizationAbbreviation`. Dashboard and Workflow Studio are adapted in the same commit (their single stored favorite maps onto the star).
19
+
15
20
  ## 0.49.59
16
21
 
17
22
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/dist/index.cjs CHANGED
@@ -172,7 +172,7 @@ __export(src_exports, {
172
172
  MOTION_SHEET: () => MOTION_SHEET,
173
173
  MOTION_SPIN: () => MOTION_SPIN,
174
174
  NATIVE_TITLE_OPT_OUT_ATTR: () => NATIVE_TITLE_OPT_OUT_ATTR,
175
- OrganizationAbbreviation: () => OrganizationAbbreviation,
175
+ OrganizationMark: () => OrganizationMark,
176
176
  OrganizationPicker: () => OrganizationPicker,
177
177
  OverflowToolbar: () => OverflowToolbar,
178
178
  POPPER_OFFSET: () => POPPER_OFFSET,
@@ -260,6 +260,7 @@ __export(src_exports, {
260
260
  isInsideFloatingLayer: () => isInsideFloatingLayer,
261
261
  isModalLayerOpen: () => isModalLayerOpen,
262
262
  keepFloatingLayersInside: () => keepFloatingLayersInside,
263
+ organizationColor: () => organizationColor,
263
264
  registerModalLayer: () => registerModalLayer,
264
265
  scoreAccentBgClasses: () => scoreAccentBgClasses,
265
266
  scoreRingColorClasses: () => scoreRingColorClasses,
@@ -3925,7 +3926,7 @@ var SheetTitle = React29.forwardRef(({ className, ...props }, ref) => /* @__PURE
3925
3926
  SheetTitle.displayName = SheetPrimitive.Title.displayName;
3926
3927
 
3927
3928
  // src/organization-picker.tsx
3928
- var React31 = __toESM(require("react"), 1);
3929
+ var React30 = __toESM(require("react"), 1);
3929
3930
 
3930
3931
  // src/skeleton.tsx
3931
3932
  var import_jsx_runtime38 = require("react/jsx-runtime");
@@ -3944,47 +3945,8 @@ function Skeleton({ className, animated = true, ...props }) {
3944
3945
  );
3945
3946
  }
3946
3947
 
3947
- // src/switch.tsx
3948
- var SwitchPrimitives = __toESM(require("@radix-ui/react-switch"), 1);
3949
- var React30 = __toESM(require("react"), 1);
3950
- var import_jsx_runtime39 = require("react/jsx-runtime");
3951
- var SWITCH_SIZES = {
3952
- sm: {
3953
- root: "h-4 w-9 border-border data-[state=unchecked]:bg-input",
3954
- thumb: "h-4 w-4 border border-primary data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
3955
- },
3956
- md: {
3957
- root: "h-5 w-9 border-transparent data-[state=unchecked]:bg-input",
3958
- thumb: "h-4 w-4 data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
3959
- }
3960
- };
3961
- var Switch = React30.forwardRef(({ className, size = "md", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3962
- SwitchPrimitives.Root,
3963
- {
3964
- ref,
3965
- "data-slot": "switch",
3966
- className: cn(
3967
- "peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary",
3968
- SWITCH_SIZES[size].root,
3969
- className
3970
- ),
3971
- ...props,
3972
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3973
- SwitchPrimitives.Thumb,
3974
- {
3975
- "data-slot": "switch-thumb",
3976
- className: cn(
3977
- "pointer-events-none block rounded-full bg-background shadow-lg ring-0 transition-transform",
3978
- SWITCH_SIZES[size].thumb
3979
- )
3980
- }
3981
- )
3982
- }
3983
- ));
3984
- Switch.displayName = SwitchPrimitives.Root.displayName;
3985
-
3986
3948
  // src/organization-picker.tsx
3987
- var import_jsx_runtime40 = require("react/jsx-runtime");
3949
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3988
3950
  var SEARCH_APPEARS_ABOVE = 8;
3989
3951
  function matchesQuery(org, query) {
3990
3952
  const q = query.trim().toLowerCase();
@@ -3993,45 +3955,71 @@ function matchesQuery(org, query) {
3993
3955
  const abbreviation = org.abbreviation?.trim().toLowerCase();
3994
3956
  return !!abbreviation && abbreviation.includes(q);
3995
3957
  }
3996
- function OrganizationAbbreviation({
3997
- abbreviation,
3958
+ var ORGANIZATION_HUES = [217, 262, 330, 12, 32, 152, 189, 290];
3959
+ function organizationColor(seed) {
3960
+ let hash = 0;
3961
+ for (let index = 0; index < seed.length; index += 1) {
3962
+ hash = hash * 31 + seed.charCodeAt(index) >>> 0;
3963
+ }
3964
+ const hue = ORGANIZATION_HUES[hash % ORGANIZATION_HUES.length];
3965
+ return { background: `hsl(${hue} 62% 46%)`, color: "#fff" };
3966
+ }
3967
+ function OrganizationMark({
3968
+ id,
3998
3969
  name,
3970
+ abbreviation,
3971
+ logoUrl,
3972
+ size = 20,
3999
3973
  className
4000
3974
  }) {
4001
- const mark = abbreviation && abbreviation.trim() || name.trim().slice(0, 1) || "?";
4002
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
3975
+ const box = { width: size, height: size };
3976
+ if (logoUrl) {
3977
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3978
+ "span",
3979
+ {
3980
+ style: box,
3981
+ className: cn("relative inline-flex shrink-0 overflow-hidden rounded-md bg-muted", className),
3982
+ "data-slot": "organization-mark",
3983
+ children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("img", { src: logoUrl, alt: name, className: "h-full w-full object-cover" })
3984
+ }
3985
+ );
3986
+ }
3987
+ const letters = (abbreviation && abbreviation.trim() || name.trim().slice(0, 1) || "?").slice(0, 3).toUpperCase();
3988
+ const fontSize = Math.round(size * (letters.length >= 3 ? 0.36 : 0.44));
3989
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4003
3990
  "span",
4004
3991
  {
3992
+ style: { ...box, ...organizationColor(id || name), fontSize },
4005
3993
  className: cn(
4006
- "inline-flex shrink-0 items-center justify-center font-bold uppercase tracking-wide",
3994
+ "inline-flex shrink-0 items-center justify-center rounded-md font-bold leading-none tracking-tight",
4007
3995
  className
4008
3996
  ),
4009
- "aria-label": `Organization abbreviation ${mark}`,
4010
- title: mark,
4011
- children: mark
3997
+ "aria-label": `Organization abbreviation ${letters}`,
3998
+ title: letters,
3999
+ "data-slot": "organization-mark",
4000
+ children: letters
4012
4001
  }
4013
4002
  );
4014
4003
  }
4015
4004
  function OrganizationPicker({
4016
4005
  organizations,
4017
4006
  activeOrganizationId,
4018
- defaultOrganizationId = null,
4007
+ favoriteOrganizationIds = [],
4019
4008
  loading = false,
4020
4009
  loadFailed = false,
4021
4010
  onSelect,
4022
- onSetDefault,
4011
+ onToggleFavorite,
4023
4012
  hideHeading = false,
4024
4013
  itemClassName,
4025
- hideStatus = false,
4026
4014
  foldedLabel = "More",
4027
4015
  className
4028
4016
  }) {
4029
- const [query, setQuery] = React31.useState("");
4030
- const [showFixtures, setShowFixtures] = React31.useState(false);
4031
- const [showFolded, setShowFolded] = React31.useState(false);
4032
- const active = organizations.find((o) => o.id === activeOrganizationId) ?? null;
4033
- const isDefault = (id) => !!defaultOrganizationId && id === defaultOrganizationId;
4034
- const rank = (org) => org.id === defaultOrganizationId ? 0 : org.isOwn ? 1 : 2;
4017
+ const [query, setQuery] = React30.useState("");
4018
+ const [showFixtures, setShowFixtures] = React30.useState(false);
4019
+ const [showFolded, setShowFolded] = React30.useState(false);
4020
+ const favorites = new Set(favoriteOrganizationIds);
4021
+ const isFavorite = (id) => favorites.has(id);
4022
+ const rank = (org) => isFavorite(org.id) ? 0 : org.isOwn ? 1 : 2;
4035
4023
  const ordered = [...organizations].sort((a, b) => rank(a) - rank(b));
4036
4024
  const matching = ordered.filter((org) => matchesQuery(org, query));
4037
4025
  const listed = matching.filter((org) => !org.isTestFixture && !org.folded);
@@ -4042,66 +4030,83 @@ function OrganizationPicker({
4042
4030
  const sharesItsName = (org) => organizations.filter((other) => other.name.trim() === org.name.trim()).length > 1;
4043
4031
  const renderRow = (org) => {
4044
4032
  const isActive = org.id === activeOrganizationId;
4045
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("li", { role: "none", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4046
- "button",
4047
- {
4048
- type: "button",
4049
- role: "option",
4050
- "aria-selected": isActive,
4051
- "aria-pressed": isActive,
4052
- onClick: (event) => {
4053
- event.stopPropagation();
4054
- onSelect(org);
4055
- },
4056
- className: cn(
4057
- "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-accent",
4058
- isActive && "bg-primary/10 font-medium text-primary",
4059
- itemClassName
4060
- ),
4061
- children: [
4062
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4063
- OrganizationAbbreviation,
4064
- {
4065
- abbreviation: org.abbreviation,
4066
- name: org.name,
4067
- className: cn(
4068
- "h-5 min-w-8 rounded border border-border bg-muted px-1 text-[9px]",
4069
- isActive ? "text-primary" : "text-muted-foreground"
4070
- )
4071
- }
4033
+ const favorite = isFavorite(org.id);
4034
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("li", { role: "none", className: "group/org relative flex items-center", children: [
4035
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
4036
+ "button",
4037
+ {
4038
+ type: "button",
4039
+ role: "option",
4040
+ "aria-selected": isActive,
4041
+ "aria-pressed": isActive,
4042
+ onClick: (event) => {
4043
+ event.stopPropagation();
4044
+ onSelect(org);
4045
+ },
4046
+ className: cn(
4047
+ "flex w-full min-w-0 items-center gap-2.5 rounded-md py-1.5 pl-2 pr-8 text-left text-sm text-foreground transition-colors hover:bg-accent",
4048
+ isActive && "bg-primary/10 font-semibold text-primary ring-1 ring-inset ring-primary/30 hover:bg-primary/15",
4049
+ itemClassName
4072
4050
  ),
4073
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col", children: [
4074
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "truncate", children: org.name }),
4075
- sharesItsName(org) && org.distinguisher ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "truncate text-[10px] font-normal text-muted-foreground", children: org.distinguisher }) : null
4076
- ] }),
4077
- org.detail ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4078
- "span",
4079
- {
4080
- className: "shrink-0 text-xs font-normal text-muted-foreground",
4081
- "data-slot": "organization-picker-detail",
4082
- children: org.detail
4083
- }
4084
- ) : null,
4085
- isDefault(org.id) && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4051
+ "data-active": isActive ? "" : void 0,
4052
+ children: [
4053
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(OrganizationMark, { id: org.id, name: org.name, abbreviation: org.abbreviation, size: 20 }),
4054
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col", children: [
4055
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "truncate", children: org.name }),
4056
+ sharesItsName(org) && org.distinguisher ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "truncate text-[10px] font-normal text-muted-foreground", children: org.distinguisher }) : null
4057
+ ] }),
4058
+ org.detail ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4059
+ "span",
4060
+ {
4061
+ className: "shrink-0 text-xs font-normal text-muted-foreground",
4062
+ "data-slot": "organization-picker-detail",
4063
+ children: org.detail
4064
+ }
4065
+ ) : null,
4066
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LucideCheckIcon, { className: "h-[15px] w-[15px] shrink-0 text-primary" })
4067
+ ]
4068
+ }
4069
+ ),
4070
+ onToggleFavorite ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4071
+ "button",
4072
+ {
4073
+ type: "button",
4074
+ "aria-pressed": favorite,
4075
+ "aria-label": favorite ? `Remove ${org.name} from favorites` : `Add ${org.name} to favorites`,
4076
+ title: favorite ? "Remove from favorites" : "Add to favorites",
4077
+ onClick: (event) => {
4078
+ event.stopPropagation();
4079
+ onToggleFavorite(org.id, !favorite);
4080
+ },
4081
+ className: cn(
4082
+ "absolute right-1 flex h-6 w-6 items-center justify-center rounded-md text-muted-foreground transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100",
4083
+ favorite ? "opacity-100" : "opacity-0 group-hover/org:opacity-100"
4084
+ ),
4085
+ "data-slot": "organization-picker-favorite",
4086
+ children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4086
4087
  StarIcon,
4087
4088
  {
4088
- className: "h-[13px] w-[13px] shrink-0 fill-warning text-warning",
4089
- "aria-hidden": false,
4090
- "aria-label": "Default organization",
4091
- role: "img"
4089
+ className: cn("h-[14px] w-[14px]", favorite && "fill-warning text-warning")
4092
4090
  }
4093
- ),
4094
- isActive && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(LucideCheckIcon, { className: "h-[15px] w-[15px] shrink-0 text-primary" })
4095
- ]
4096
- }
4097
- ) }, org.id);
4091
+ )
4092
+ }
4093
+ ) : favorite ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4094
+ StarIcon,
4095
+ {
4096
+ className: "absolute right-2 h-[13px] w-[13px] fill-warning text-warning",
4097
+ "aria-hidden": false,
4098
+ "aria-label": "Favorite",
4099
+ role: "img"
4100
+ }
4101
+ ) : null
4102
+ ] }, org.id);
4098
4103
  };
4099
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cn("flex flex-col", className), "data-slot": "organization-picker", children: [
4100
- !hideHeading && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Organization" }),
4101
- loading ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "space-y-1 px-1 py-1", "aria-busy": "true", "aria-label": "Loading organizations", children: [
4102
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Skeleton, { className: "h-7 rounded-md" }),
4103
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Skeleton, { className: "h-7 rounded-md" })
4104
- ] }) : loadFailed ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4104
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("flex flex-col", className), "data-slot": "organization-picker", children: [
4105
+ !hideHeading && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Organization" }),
4106
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "space-y-1 px-1 py-1", "aria-busy": "true", "aria-label": "Loading organizations", children: [
4107
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-7 rounded-md" }),
4108
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-7 rounded-md" })
4109
+ ] }) : loadFailed ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4105
4110
  ErrorBox,
4106
4111
  {
4107
4112
  className: "px-2 py-2 text-xs text-destructive",
@@ -4109,13 +4114,8 @@ function OrganizationPicker({
4109
4114
  origin: "design-system/OrganizationPicker",
4110
4115
  children: "Could not load organizations."
4111
4116
  }
4112
- ) : organizations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "px-2 py-2 text-xs text-muted-foreground", children: "Your account is not a member of any organization. Ask an administrator to add you to one." }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
4113
- hideStatus ? null : active ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("p", { className: "px-2 pb-1 text-[11px] text-muted-foreground", "data-slot": "organization-picker-status", children: [
4114
- "Working in",
4115
- " ",
4116
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "font-medium text-foreground", children: active.name })
4117
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "px-2 pb-1 text-[11px] text-muted-foreground", "data-slot": "organization-picker-status", children: "No organization selected \u2014 pick one below." }),
4118
- searchable && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "px-2 pb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4117
+ ) : organizations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "px-2 py-2 text-xs text-muted-foreground", children: "Your account is not a member of any organization. Ask an administrator to add you to one." }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
4118
+ searchable && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "px-2 pb-1.5", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4119
4119
  Input,
4120
4120
  {
4121
4121
  type: "search",
@@ -4129,7 +4129,7 @@ function OrganizationPicker({
4129
4129
  "data-slot": "organization-picker-search"
4130
4130
  }
4131
4131
  ) }),
4132
- listed.length === 0 && folded.length === 0 && fixtures.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4132
+ listed.length === 0 && folded.length === 0 && fixtures.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
4133
4133
  "p",
4134
4134
  {
4135
4135
  className: "px-2 py-2 text-xs text-muted-foreground",
@@ -4151,16 +4151,16 @@ function OrganizationPicker({
4151
4151
  clicking. So: count the matches, say where they are, and carry
4152
4152
  the click that reveals them — the same shape as the honest
4153
4153
  empty-filter twin one line down. (TAILS-3) */
4154
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4154
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4155
4155
  "p",
4156
4156
  {
4157
4157
  className: "px-2 py-2 text-xs text-muted-foreground",
4158
4158
  "data-slot": "organization-picker-only-fixtures",
4159
- children: query.trim() ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
4159
+ children: query.trim() ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
4160
4160
  fixtures.length === 1 ? `1 match for \u201C${query.trim()}\u201D is in your test organizations` : `All ${fixtures.length} matches for \u201C${query.trim()}\u201D are in your test organizations`,
4161
- showFixtures ? ", listed below." : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
4161
+ showFixtures ? ", listed below." : /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
4162
4162
  " \u2014 ",
4163
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4163
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4164
4164
  "button",
4165
4165
  {
4166
4166
  type: "button",
@@ -4178,8 +4178,8 @@ function OrganizationPicker({
4178
4178
  ] }) : `Every organization you belong to is a test organization \u2014 all ${fixtures.length} are below.`
4179
4179
  }
4180
4180
  )
4181
- ) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "max-h-72 overflow-y-auto", role: "listbox", "aria-label": "Organizations", children: listed.map(renderRow) }),
4182
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4181
+ ) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "max-h-72 overflow-y-auto", role: "listbox", "aria-label": "Organizations", children: listed.map(renderRow) }),
4182
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4183
4183
  ArchivedDisclosure,
4184
4184
  {
4185
4185
  count: folded.length,
@@ -4187,10 +4187,10 @@ function OrganizationPicker({
4187
4187
  onOpenChange: setShowFolded,
4188
4188
  label: foldedLabel,
4189
4189
  className: "mt-0.5",
4190
- children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("ul", { className: "max-h-72 overflow-y-auto", role: "listbox", "aria-label": foldedLabel, children: folded.map(renderRow) })
4190
+ children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "max-h-72 overflow-y-auto", role: "listbox", "aria-label": foldedLabel, children: folded.map(renderRow) })
4191
4191
  }
4192
4192
  ),
4193
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4193
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4194
4194
  ArchivedDisclosure,
4195
4195
  {
4196
4196
  count: fixtures.length,
@@ -4198,7 +4198,7 @@ function OrganizationPicker({
4198
4198
  onOpenChange: setShowFixtures,
4199
4199
  label: "Test organizations",
4200
4200
  className: "mt-0.5",
4201
- children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4201
+ children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4202
4202
  "ul",
4203
4203
  {
4204
4204
  className: "max-h-72 overflow-y-auto",
@@ -4208,50 +4208,49 @@ function OrganizationPicker({
4208
4208
  }
4209
4209
  )
4210
4210
  }
4211
- ),
4212
- onSetDefault && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
4213
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "my-1 border-t border-border" }),
4214
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4215
- DefaultOrganizationSwitch,
4216
- {
4217
- active,
4218
- checked: !!active && isDefault(active.id),
4219
- onChange: (on) => onSetDefault(on && active ? active.id : null)
4220
- }
4221
- )
4222
- ] })
4211
+ )
4223
4212
  ] })
4224
4213
  ] });
4225
4214
  }
4226
- function DefaultOrganizationSwitch({
4227
- active,
4228
- checked,
4229
- onChange
4230
- }) {
4231
- const disabled = !active;
4232
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4233
- "div",
4234
- {
4235
- className: "flex items-center justify-between gap-3 rounded-md px-2 py-1.5",
4236
- "data-slot": "organization-picker-default",
4237
- children: [
4238
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "min-w-0", children: [
4239
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "text-xs font-medium text-foreground", children: "Keep it at the top" }),
4240
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "truncate text-[11px] text-muted-foreground", children: disabled ? "Select an organization first" : checked ? `${active.name} is first in this list on every device` : "Star it so it is first in this list on every device" })
4241
- ] }),
4242
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4243
- Switch,
4244
- {
4245
- checked,
4246
- disabled,
4247
- onCheckedChange: onChange,
4248
- "aria-label": "Keep this organization at the top of the list"
4249
- }
4215
+
4216
+ // src/switch.tsx
4217
+ var SwitchPrimitives = __toESM(require("@radix-ui/react-switch"), 1);
4218
+ var React31 = __toESM(require("react"), 1);
4219
+ var import_jsx_runtime40 = require("react/jsx-runtime");
4220
+ var SWITCH_SIZES = {
4221
+ sm: {
4222
+ root: "h-4 w-9 border-border data-[state=unchecked]:bg-input",
4223
+ thumb: "h-4 w-4 border border-primary data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
4224
+ },
4225
+ md: {
4226
+ root: "h-5 w-9 border-transparent data-[state=unchecked]:bg-input",
4227
+ thumb: "h-4 w-4 data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
4228
+ }
4229
+ };
4230
+ var Switch = React31.forwardRef(({ className, size = "md", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4231
+ SwitchPrimitives.Root,
4232
+ {
4233
+ ref,
4234
+ "data-slot": "switch",
4235
+ className: cn(
4236
+ "peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary",
4237
+ SWITCH_SIZES[size].root,
4238
+ className
4239
+ ),
4240
+ ...props,
4241
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4242
+ SwitchPrimitives.Thumb,
4243
+ {
4244
+ "data-slot": "switch-thumb",
4245
+ className: cn(
4246
+ "pointer-events-none block rounded-full bg-background shadow-lg ring-0 transition-transform",
4247
+ SWITCH_SIZES[size].thumb
4250
4248
  )
4251
- ]
4252
- }
4253
- );
4254
- }
4249
+ }
4250
+ )
4251
+ }
4252
+ ));
4253
+ Switch.displayName = SwitchPrimitives.Root.displayName;
4255
4254
 
4256
4255
  // src/tabbed-bottom-sheet.tsx
4257
4256
  var import_react4 = require("react");