@photon-ai/pho-ui 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as o } from "./cn-DTiB6ek_.js";
2
+ import { t as a } from "./cn-DTiB6ek_.js";
3
3
  import { n as d } from "./link-provider-9TFNyDqO.js";
4
4
  import { s as f } from "./close-button-B8gF5UNk.js";
5
5
  import { t as p } from "./createReactComponent-BqCmnqfX.js";
@@ -12,93 +12,105 @@ var g = [["path", {
12
12
  }]], y = p("outline", "chevron-left", "ChevronLeft", g), N = [["path", {
13
13
  d: "M9 6l6 6l-6 6",
14
14
  key: "svg-0"
15
- }]], b = p("outline", "chevron-right", "ChevronRight", N), w = "divide-y divide-pho-secondary rounded-base border border-pho-secondary bg-pho-primary", C = "flex flex-col gap-3 rounded-base border border-pho-secondary bg-pho-page p-5", m = "flex min-h-[4.25rem] flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6";
16
- function A({ className: e, ...t }) {
15
+ }]], b = p("outline", "chevron-right", "ChevronRight", N), _ = "divide-y divide-pho-secondary rounded-base border border-pho-secondary bg-pho-primary", A = "flex flex-col gap-3 rounded-base border border-pho-secondary bg-pho-page p-5", m = "flex min-h-[4.25rem] flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6", C = "flex flex-col gap-3 px-5 py-4", I = "-mx-5 -mb-4 flex items-center rounded-b-[calc(0.75rem-1px)] bg-pho-secondary py-1 pr-3 pl-5", w = "-mx-2 -mt-1.5 flex items-center rounded-sm bg-pho-secondary px-2 py-0.5";
16
+ function E({ className: e, ...t }) {
17
17
  return /* @__PURE__ */ r("div", {
18
- className: o("relative mx-auto w-full max-w-[44.5rem] px-5 py-12", e),
18
+ className: a("relative mx-auto w-full max-w-[44.5rem] px-5 py-12", e),
19
19
  ...t
20
20
  });
21
21
  }
22
- function _(e) {
22
+ function L(e) {
23
23
  return e.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
24
24
  }
25
- function R(e) {
25
+ function P(e) {
26
26
  if (!(typeof e != "string" && typeof e != "number"))
27
- return _(String(e)) || void 0;
27
+ return L(String(e)) || void 0;
28
28
  }
29
29
  function c(e, t) {
30
30
  if (e !== "")
31
- return e ?? R(t);
31
+ return e ?? P(t);
32
32
  }
33
- function k({ id: e, className: t, children: n, ...i }) {
33
+ function R({ id: e, className: t, children: n, ...o }) {
34
34
  return /* @__PURE__ */ r("h1", {
35
35
  id: c(e, n),
36
- className: o("text-display-base text-pho-primary scroll-mt-12 px-5 font-medium", t),
37
- ...i,
36
+ className: a("text-display-base text-pho-primary scroll-mt-12 px-5 font-medium", t),
37
+ ...o,
38
38
  children: n
39
39
  });
40
40
  }
41
- function L({ className: e, ...t }) {
41
+ function S({ className: e, ...t }) {
42
42
  return /* @__PURE__ */ r("div", {
43
- className: o("mt-6 flex flex-col gap-10", "*:flex *:flex-col *:gap-3", e),
43
+ className: a("mt-6 flex flex-col gap-10", "*:flex *:flex-col *:gap-3", e),
44
44
  ...t
45
45
  });
46
46
  }
47
- function E({ className: e, ...t }) {
47
+ function k({ className: e, ...t }) {
48
48
  return /* @__PURE__ */ r("div", {
49
- className: o("flex flex-col gap-0.5", e),
49
+ className: a("flex flex-col gap-0.5", e),
50
50
  ...t
51
51
  });
52
52
  }
53
- function I({ id: e, className: t, children: n, ...i }) {
53
+ function B({ id: e, className: t, children: n, ...o }) {
54
54
  return /* @__PURE__ */ r("h2", {
55
55
  id: c(e, n),
56
- className: o("text-display-xs text-pho-primary scroll-mt-12 px-5 font-medium", t),
57
- ...i,
56
+ className: a("text-display-xs text-pho-primary scroll-mt-12 px-5 font-medium", t),
57
+ ...o,
58
58
  children: n
59
59
  });
60
60
  }
61
- function S({ className: e, ...t }) {
61
+ function D({ className: e, ...t }) {
62
62
  return /* @__PURE__ */ r("p", {
63
- className: o("text-display-xs text-pho-description px-5 font-normal", e),
63
+ className: a("text-display-xs text-pho-description px-5 font-normal", e),
64
64
  ...t
65
65
  });
66
66
  }
67
- function B({ className: e, ...t }) {
67
+ function G({ className: e, ...t }) {
68
68
  return /* @__PURE__ */ r("p", {
69
- className: o("text-pho-description px-5 text-xs font-normal", e),
69
+ className: a("text-pho-description px-5 text-xs font-normal", e),
70
70
  ...t
71
71
  });
72
72
  }
73
- function P({ className: e, ...t }) {
73
+ function T({ className: e, ...t }) {
74
74
  return /* @__PURE__ */ r("div", {
75
- className: o(w, e),
75
+ className: a(_, e),
76
76
  ...t
77
77
  });
78
78
  }
79
- function D({ className: e, ...t }) {
79
+ function M({ className: e, ...t }) {
80
+ return /* @__PURE__ */ r("div", {
81
+ className: a(C, e),
82
+ ...t
83
+ });
84
+ }
85
+ function H({ divided: e = !1, className: t, ...n }) {
86
+ return /* @__PURE__ */ r("div", {
87
+ className: a(e ? w : I, t),
88
+ ...n
89
+ });
90
+ }
91
+ function j({ className: e, ...t }) {
80
92
  return /* @__PURE__ */ r("div", {
81
- className: o(C, e),
93
+ className: a(A, e),
82
94
  ...t
83
95
  });
84
96
  }
85
- function G({ id: e, className: t, children: n, ...i }) {
97
+ function z({ id: e, className: t, children: n, ...o }) {
86
98
  return /* @__PURE__ */ r("h2", {
87
99
  id: c(e, n),
88
- className: o("text-display-xs text-pho-primary scroll-mt-12 font-medium", t),
89
- ...i,
100
+ className: a("text-display-xs text-pho-primary scroll-mt-12 font-medium", t),
101
+ ...o,
90
102
  children: n
91
103
  });
92
104
  }
93
- function H({ className: e, ...t }) {
105
+ function F({ className: e, ...t }) {
94
106
  return /* @__PURE__ */ r("p", {
95
- className: o("text-display-xs text-pho-description font-normal", e),
107
+ className: a("text-display-xs text-pho-description font-normal", e),
96
108
  ...t
97
109
  });
98
110
  }
99
- function T({ label: e, description: t, htmlFor: n, className: i, children: a, ...l }) {
111
+ function V({ label: e, description: t, htmlFor: n, className: o, children: i, ...l }) {
100
112
  return /* @__PURE__ */ s("div", {
101
- className: o(m, i),
113
+ className: a(m, o),
102
114
  ...l,
103
115
  children: [/* @__PURE__ */ s("div", {
104
116
  className: "min-w-0",
@@ -115,37 +127,37 @@ function T({ label: e, description: t, htmlFor: n, className: i, children: a, ..
115
127
  }) : null]
116
128
  }), /* @__PURE__ */ r("div", {
117
129
  className: "flex w-full min-w-0 items-center gap-2 sm:w-auto",
118
- children: a
130
+ children: i
119
131
  })]
120
132
  });
121
133
  }
122
- function j({ className: e, ...t }) {
134
+ function O({ className: e, ...t }) {
123
135
  return /* @__PURE__ */ r("p", {
124
- className: o("text-pho-description truncate text-base", e),
136
+ className: a("text-pho-description truncate text-base", e),
125
137
  ...t
126
138
  });
127
139
  }
128
- function z({ className: e, ...t }) {
140
+ function $({ className: e, ...t }) {
129
141
  return /* @__PURE__ */ r("p", {
130
142
  role: "alert",
131
- className: o("text-pho-error px-5 pb-3 text-xs", e),
143
+ className: a("text-pho-error px-5 pb-3 text-xs", e),
132
144
  ...t
133
145
  });
134
146
  }
135
- var F = {
147
+ var K = {
136
148
  type: "spring",
137
149
  stiffness: 640,
138
150
  damping: 50
139
- }, M = {
151
+ }, U = {
140
152
  duration: 0.18,
141
153
  ease: "easeOut"
142
154
  };
143
- function O({ show: e, className: t, ...n }) {
144
- const i = v(), a = /* @__PURE__ */ r("div", {
145
- className: o("flex items-center justify-between gap-6 px-5 py-4", t),
155
+ function W({ show: e, className: t, ...n }) {
156
+ const o = v(), i = /* @__PURE__ */ r("div", {
157
+ className: a("flex items-center justify-between gap-6 px-5 py-4", t),
146
158
  ...n
147
159
  });
148
- return e === void 0 ? a : /* @__PURE__ */ r(x, {
160
+ return e === void 0 ? i : /* @__PURE__ */ r(x, {
149
161
  initial: !1,
150
162
  children: e ? /* @__PURE__ */ r(h.div, {
151
163
  className: "overflow-hidden",
@@ -161,32 +173,32 @@ function O({ show: e, className: t, ...n }) {
161
173
  height: 0,
162
174
  opacity: 0
163
175
  },
164
- transition: i ? { duration: 0 } : {
165
- height: F,
166
- opacity: M
176
+ transition: o ? { duration: 0 } : {
177
+ height: K,
178
+ opacity: U
167
179
  },
168
- children: a
180
+ children: i
169
181
  }) : null
170
182
  });
171
183
  }
172
- function V({ href: e, className: t, children: n = "Back", ...i }) {
184
+ function q({ href: e, className: t, children: n = "Back", ...o }) {
173
185
  return /* @__PURE__ */ r(f, {
174
186
  variant: "ghost",
175
187
  size: "sm",
176
188
  href: e,
177
189
  prefix: /* @__PURE__ */ r(y, {}),
178
- className: o("absolute top-2 left-[10.25px]", t),
179
- ...i,
190
+ className: a("absolute top-2 left-[10.25px]", t),
191
+ ...o,
180
192
  children: n
181
193
  });
182
194
  }
183
- function $({ label: e, description: t, leading: n, href: i, className: a, children: l, ...u }) {
195
+ function J({ label: e, description: t, leading: n, href: o, className: i, children: l, ...u }) {
184
196
  return /* @__PURE__ */ s(d(), {
185
- href: i,
197
+ href: o,
186
198
  ...u,
187
- className: o(m, "group outline-pho-brand hover:bg-pho-primary-hover cursor-pointer transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2", "first:rounded-t-[calc(var(--radius-base)-1px)] last:rounded-b-[calc(var(--radius-base)-1px)]", a),
199
+ className: a(m, "group outline-pho-brand hover:bg-pho-primary-hover cursor-pointer transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2", "first:rounded-t-[calc(var(--radius-base)-1px)] last:rounded-b-[calc(var(--radius-base)-1px)]", i),
188
200
  children: [/* @__PURE__ */ s("div", {
189
- className: o("flex min-w-0 items-center", n != null && "gap-3"),
201
+ className: a("flex min-w-0 items-center", n != null && "gap-3"),
190
202
  children: [n, /* @__PURE__ */ s("div", {
191
203
  className: "min-w-0",
192
204
  children: [/* @__PURE__ */ r("div", {
@@ -209,30 +221,35 @@ function $({ label: e, description: t, leading: n, href: i, className: a, childr
209
221
  })]
210
222
  });
211
223
  }
212
- var Y = {
213
- Root: A,
214
- Back: V,
215
- Title: k,
216
- Stack: L,
217
- Header: E,
218
- SectionTitle: I,
219
- Description: S,
220
- SectionFooter: B,
221
- Card: P,
222
- Callout: D,
223
- CalloutTitle: G,
224
- CalloutDescription: H,
225
- Row: T,
226
- RowLink: $,
227
- Value: j,
228
- Alert: z,
229
- Footer: O
224
+ var ne = {
225
+ Root: E,
226
+ Back: q,
227
+ Title: R,
228
+ Stack: S,
229
+ Header: k,
230
+ SectionTitle: B,
231
+ Description: D,
232
+ SectionFooter: G,
233
+ Card: T,
234
+ Item: M,
235
+ ItemPanel: H,
236
+ Callout: j,
237
+ CalloutTitle: z,
238
+ CalloutDescription: F,
239
+ Row: V,
240
+ RowLink: J,
241
+ Value: O,
242
+ Alert: $,
243
+ Footer: W
230
244
  };
231
245
  export {
232
- Y as i,
233
- w as n,
234
- m as r,
235
- C as t
246
+ w as a,
247
+ I as i,
248
+ _ as n,
249
+ m as o,
250
+ C as r,
251
+ ne as s,
252
+ A as t
236
253
  };
237
254
 
238
- //# sourceMappingURL=basic-page-C50WUzYV.js.map
255
+ //# sourceMappingURL=basic-page-4_GZOvRr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basic-page-4_GZOvRr.js","names":["__iconNode"],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs","../../src/sections/basic-page/basic-page.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M15 6l-6 6l6 6\", \"key\": \"svg-0\" }]];\nconst IconChevronLeft = createReactComponent(\"outline\", \"chevron-left\", \"ChevronLeft\", __iconNode);\n\nexport { __iconNode, IconChevronLeft as default };\n//# sourceMappingURL=IconChevronLeft.mjs.map\n","/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M9 6l6 6l-6 6\", \"key\": \"svg-0\" }]];\nconst IconChevronRight = createReactComponent(\"outline\", \"chevron-right\", \"ChevronRight\", __iconNode);\n\nexport { __iconNode, IconChevronRight as default };\n//# sourceMappingURL=IconChevronRight.mjs.map\n","import {\n type AnchorHTMLAttributes,\n type ComponentProps,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { IconChevronLeft, IconChevronRight } from \"@tabler/icons-react\";\nimport { ButtonLink, type ButtonLinkProps } from \"../../components/button\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/**\n * BasicPage — Pho's standard content page: a page title, section titles, and\n * bordered cards of label/control rows. Settings, billing, members — any\n * single-column management surface.\n *\n * Spacing: wrap the page in `Root` (a 42rem column with `px-5` gutters,\n * vertical padding). `Stack` separates blocks (`gap-10`). Inside a block,\n * children share `gap-3`. Wrap a section title + description in `Header`\n * (`gap-0.5`) so that pair stays tight — don't put them as loose siblings.\n * Parts already carry `px-5`.\n *\n * Navigation: pages may drill into subpages. `RowLink` is a whole-row link\n * (trailing chevron) and `Back` returns to the parent — both render through\n * the host's `LinkProvider`; the URL itself stays the router's job. `Back`\n * floats in `Root`'s top padding, so `Title` never moves between pages that\n * have a back link and pages that don't.\n */\n\n/* ------------------------------- class map ------------------------------- */\n\n/** Bordered card that stacks rows with hairline dividers. */\nexport const BASIC_PAGE_CARD =\n \"divide-y divide-pho-secondary rounded-base border border-pho-secondary bg-pho-primary\";\n\n/**\n * Standalone callout surface — featured block (invite form, notice, etc.).\n * Don't wrap in `Card`; this is the outer chrome.\n */\nexport const BASIC_PAGE_CALLOUT =\n \"flex flex-col gap-3 rounded-base border border-pho-secondary bg-pho-page p-5\";\n\n/**\n * One row — label (+ optional description) left, control right.\n * `min-h-[4.25rem]` (68px) keeps avatar/control rows from collapsing shorter\n * than a comfortable touch target.\n */\nexport const BASIC_PAGE_ROW =\n \"flex min-h-[4.25rem] flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6\";\n\n/**\n * One card row that can host subviews. Same padding rhythm as a plain row —\n * an optional trailing `ItemPanel` breaks out of it on its own.\n */\nexport const BASIC_PAGE_ITEM = \"flex flex-col gap-3 px-5 py-4\";\n\n/**\n * Secondary strip closing an `Item` that is last in its card. Negative\n * margins escape the item's `px-5 pb-4` so the gray sheet runs edge-to-edge\n * and owns the row's bottom padding. The body above stays square and the\n * sheet's top is flush against it; only the bottom rounds, nesting into the\n * card's 12px corner (11px inside the 1px border). Content lands back on the\n * item's left gutter.\n */\nexport const BASIC_PAGE_ITEM_PANEL =\n \"-mx-5 -mb-4 flex items-center rounded-b-[calc(0.75rem-1px)] bg-pho-secondary py-1 pr-3 pl-5\";\n\n/**\n * Mid-list variant — the full-bleed sheet only reads well against the card's\n * bottom corner, so when later rows follow, the panel becomes an inset chip\n * instead: fully rounded at the small-control radius, overhanging the text\n * gutter by 8px per side (content stays aligned with the body above), and\n * leaving the row's own bottom padding and the card's hairline divider alone.\n * `-mt-1.5` collapses the item's `gap-3` (12px) to an effective `gap-1.5` (6px).\n */\nexport const BASIC_PAGE_ITEM_PANEL_DIVIDED =\n \"-mx-2 -mt-1.5 flex items-center rounded-sm bg-pho-secondary px-2 py-0.5\";\n\n/* --------------------------------- parts --------------------------------- */\n\n/**\n * Page chrome — centered column at the standard content width. Hosts\n * `Title` + `Stack` (and any route-level siblings). Prefer this over\n * ad-hoc `max-w-*` wrappers in the app shell.\n *\n * `44.5rem` = the 42rem (`2xl`) content column plus the two `px-5` gutters,\n * so wide viewports render exactly as before while narrow ones keep a 20px\n * breathing edge instead of running content into the viewport.\n *\n * `relative` anchors `Back`, which floats in the top padding — the reserved\n * zone that keeps `Title` at the same position on every page.\n */\nfunction Root({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return (\n <div\n className={cn(\n \"relative mx-auto w-full max-w-[44.5rem] px-5 py-12\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Slug for hash targets — \"Danger zone\" → `danger-zone`. Empty / non-string\n * children yield no id; pass an explicit `id` to override or `id=\"\"` to opt out.\n */\nfunction slugifyHeading(value: string): string {\n return value\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction headingIdFromChildren(children: ReactNode): string | undefined {\n if (typeof children !== \"string\" && typeof children !== \"number\") {\n return undefined;\n }\n const slug = slugifyHeading(String(children));\n return slug || undefined;\n}\n\n/** Resolve `id`: explicit wins; `\"\"` opts out; else slug from plain-text children. */\nfunction resolveHeadingId(\n id: string | undefined,\n children: ReactNode,\n): string | undefined {\n if (id === \"\") return undefined;\n if (id != null) return id;\n return headingIdFromChildren(children);\n}\n\n/**\n * Page title — largest heading on the surface. Plain-text children get a slug\n * `id` for hash targets (`#profile`); the heading itself is not a link.\n */\nfunction Title({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h1\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h1\n id={headingId}\n className={cn(\n \"text-display-base text-pho-primary scroll-mt-12 px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h1>\n );\n}\n\n/**\n * Vertical stack under the page title. Blocks (forms / sections) use `gap-10`;\n * each block lays out its children with `gap-3`.\n */\nfunction Stack({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return (\n <div\n className={cn(\n \"mt-6 flex flex-col gap-10\",\n \"*:flex *:flex-col *:gap-3\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Title + optional description pair. Keeps that couple tight (`gap-0.5`) so\n * the block's `gap-3` only applies between this header and the card.\n */\nfunction Header({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(\"flex flex-col gap-0.5\", className)} {...props} />;\n}\n\n/**\n * Section heading — same padding as the page title, smaller type. Hashable via\n * slug `id` (not a link).\n */\nfunction SectionTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary scroll-mt-12 px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/**\n * Supporting copy under a section title. Same display step as the title;\n * color + normal weight keep it secondary. Always wrap with `Header`.\n */\nfunction Description({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description px-5 font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Optional caption below a section's `Card` (outside the card). One step\n * smaller than `Description` (`text-xs`). Not the card-internal dirty-state\n * `Footer`.\n */\nfunction SectionFooter({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\"text-pho-description px-5 text-xs font-normal\", className)}\n {...props}\n />\n );\n}\n\n/** Bordered card that stacks rows with hairline dividers. */\nfunction Card({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(BASIC_PAGE_CARD, className)} {...props} />;\n}\n\n/**\n * One card row that can host subviews. Padding matches a plain row, so use it\n * for any row that may grow an `ItemPanel` — primary content goes straight in\n * as children; the panel, when present, is the last child.\n *\n * ```tsx\n * <BasicPage.Card>\n * <BasicPage.Item>\n * …name, meta, actions…\n * <BasicPage.ItemPanel divided>…secret / expanded content…</BasicPage.ItemPanel>\n * </BasicPage.Item>\n * …later siblings (pass `divided` on the panel above)…\n * </BasicPage.Card>\n * ```\n */\nfunction Item({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(BASIC_PAGE_ITEM, className)} {...props} />;\n}\n\nexport interface BasicPageItemPanelProps extends ComponentProps<\"div\"> {\n /**\n * Set when later card rows follow this item. The panel then renders as an\n * inset rounded chip (keeping the card's own divider) instead of the\n * full-bleed bottom sheet, which only reads well against the card's corner.\n * @default false\n */\n divided?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Secondary strip at the end of an `Item`. When the item closes the card,\n * it's a gray sheet flush under the body, full-bleed and owning the row's\n * bottom padding, rounding only into the card's bottom corner. Pass `divided`\n * when later card rows follow — the panel becomes an inset rounded chip and\n * the card's hairline divider stays in charge. Content is already a centered\n * flex row either way.\n */\nfunction ItemPanel({\n divided = false,\n className,\n ...props\n}: BasicPageItemPanelProps) {\n return (\n <div\n className={cn(\n divided ? BASIC_PAGE_ITEM_PANEL_DIVIDED : BASIC_PAGE_ITEM_PANEL,\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Standalone callout. Pair with `CalloutTitle` / `CalloutDescription` (and\n * optional actions) for a featured block — e.g. an invite form. Do not wrap\n * in `Card`; this is already the outer surface.\n */\nfunction Callout({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(BASIC_PAGE_CALLOUT, className)} {...props} />;\n}\n\n/** Callout heading — same type as `SectionTitle`. Hashable via slug `id`. */\nfunction CalloutTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary scroll-mt-12 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/** Supporting copy under a callout title. */\nfunction CalloutDescription({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface BasicPageRowProps extends Omit<\n ComponentProps<\"div\">,\n \"title\"\n> {\n /** Left-side field name. */\n label: string;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Associates the label with a control id. When omitted, the label is not a `<label>`. */\n htmlFor?: string;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * One row: label (+ optional description) left, control right.\n * Pass `htmlFor` when the row wraps a labelled input; omit it for display/\n * action rows (avatar, danger-zone delete).\n */\nfunction Row({\n label,\n description,\n htmlFor,\n className,\n children,\n ...props\n}: BasicPageRowProps) {\n return (\n <div className={cn(BASIC_PAGE_ROW, className)} {...props}>\n <div className=\"min-w-0\">\n {htmlFor ? (\n <label\n htmlFor={htmlFor}\n className=\"text-pho-primary block text-base font-normal\"\n >\n {label}\n </label>\n ) : (\n <p className=\"text-pho-primary text-base font-normal\">{label}</p>\n )}\n {description ? (\n <p className=\"text-pho-description mt-0.5 text-xs\">{description}</p>\n ) : null}\n </div>\n <div className=\"flex w-full min-w-0 items-center gap-2 sm:w-auto\">\n {children}\n </div>\n </div>\n );\n}\n\n/** Read-only value on the right side of a row (email, etc.). */\nfunction Value({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\"text-pho-description truncate text-base\", className)}\n {...props}\n />\n );\n}\n\n/**\n * Inline error under a row (still inside the card). Matches card horizontal\n * padding so hosts don't re-apply `px-5`.\n */\nfunction Alert({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n role=\"alert\"\n className={cn(\"text-pho-error px-5 pb-3 text-xs\", className)}\n {...props}\n />\n );\n}\n\n/**\n * Height spring for the `Footer` reveal — quick and essentially critically\n * damped (an overshooting edge would show clipped content). Same feel as the\n * onboarding / invite card's height-follow spring.\n */\nconst REVEAL_HEIGHT_SPRING = {\n type: \"spring\",\n stiffness: 640,\n damping: 50,\n} as const;\n\n/**\n * Content fade layered over the height reveal, so the bar doesn't pop while\n * the card grows — mirrors the onboarding step-content fade.\n */\nconst REVEAL_FADE = { duration: 0.18, ease: \"easeOut\" } as const;\n\nexport interface BasicPageFooterProps extends ComponentProps<\"div\"> {\n /**\n * Animated presence for dirty-state bars: the card glides open/closed on a\n * height spring while the content fades. Omit for a static, always-visible\n * footer (no animation). No reveal plays on first mount — only on flips.\n */\n show?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Trailing bar inside a card — typically a save status + submit button that\n * appears after the form is dirty. Same horizontal/vertical padding as a row.\n * Pass `show` (instead of conditional rendering) to animate the bar in and\n * out following the onboarding card's motion language.\n */\nfunction Footer({ show, className, ...props }: BasicPageFooterProps) {\n const reduceMotion = useReducedMotion();\n const bar = (\n <div\n className={cn(\n \"flex items-center justify-between gap-6 px-5 py-4\",\n className,\n )}\n {...props}\n />\n );\n\n if (show === undefined) return bar;\n\n return (\n <AnimatePresence initial={false}>\n {show ? (\n <motion.div\n className=\"overflow-hidden\"\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : { height: REVEAL_HEIGHT_SPRING, opacity: REVEAL_FADE }\n }\n >\n {bar}\n </motion.div>\n ) : null}\n </AnimatePresence>\n );\n}\n\n/* ------------------------------- navigation ------------------------------ */\n\nexport interface BasicPageBackProps extends Omit<\n ButtonLinkProps,\n \"variant\" | \"size\" | \"shape\" | \"prefix\" | \"suffix\" | \"svgOnly\" | \"href\"\n> {\n /** Parent destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Label — name the parent page. @default \"Back\" */\n children?: ReactNode;\n}\n\n/**\n * Back link for a subpage — a small ghost `ButtonLink`; place inside `Root`,\n * before `Title`. It floats in `Root`'s reserved top padding (vertically\n * centered in the 48px zone) instead of taking layout space, so `Title` sits\n * at exactly the same position whether or not a page has one.\n *\n * The offsets align the *label* glyph with the title glyph. Title text sits\n * 40px in (`px-5` root gutter + `px-5` title pad); inside a `sm` ghost button\n * the label sits 29.75px in (8px icon-side pad + 15.75px chevron, 1.125em at\n * the 14px `text-base`, + 4px gap + 2px label-span `px-0.5`) — so `left` is\n * the 10.25px difference. `top-2` centers the 32px button in the 48px\n * reserved zone. The chevron and the ghost hover pill hang in the padding —\n * the usual optical alignment for borderless controls.\n */\nfunction Back({\n href,\n className,\n children = \"Back\",\n ...props\n}: BasicPageBackProps) {\n return (\n <ButtonLink\n variant=\"ghost\"\n size=\"sm\"\n href={href}\n prefix={<IconChevronLeft />}\n className={cn(\"absolute top-2 left-[10.25px]\", className)}\n {...props}\n >\n {children}\n </ButtonLink>\n );\n}\n\nexport interface BasicPageRowLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"href\" | \"title\"\n> {\n /** Left-side field name — plain text, or compose with a trailing badge. */\n label: ReactNode;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Optional media left of the label (e.g. project avatar). */\n leading?: ReactNode;\n /** Subpage destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Optional trailing value before the chevron (compose with `Value`). */\n children?: ReactNode;\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A row that navigates — the whole row is one link into a subpage, with a\n * trailing chevron cue. Same geometry as `Row`; hover lifts the row, and\n * first/last rows follow the card's corner radius.\n */\nfunction RowLink({\n label,\n description,\n leading,\n href,\n className,\n children,\n ...props\n}: BasicPageRowLinkProps) {\n const Link = useLinkComponent();\n return (\n <Link\n href={href}\n {...props}\n className={cn(\n BASIC_PAGE_ROW,\n \"group outline-pho-brand hover:bg-pho-primary-hover cursor-pointer transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2\",\n // Hover wash follows the card's rounding (minus the 1px border).\n \"first:rounded-t-[calc(var(--radius-base)-1px)] last:rounded-b-[calc(var(--radius-base)-1px)]\",\n className,\n )}\n >\n <div\n className={cn(\"flex min-w-0 items-center\", leading != null && \"gap-3\")}\n >\n {leading}\n <div className=\"min-w-0\">\n <div className=\"flex min-w-0 items-center gap-1\">\n {typeof label === \"string\" || typeof label === \"number\" ? (\n <p className=\"text-pho-primary truncate text-base font-medium\">\n {label}\n </p>\n ) : (\n label\n )}\n </div>\n {description ? (\n <div className=\"text-pho-description text-xs\">{description}</div>\n ) : null}\n </div>\n </div>\n <div className=\"flex w-full min-w-0 items-center gap-2 sm:w-auto\">\n {children}\n <IconChevronRight\n aria-hidden\n className=\"text-pho-secondary group-hover:text-pho-secondary-hover size-4 shrink-0 transition-colors\"\n />\n </div>\n </Link>\n );\n}\n\n/* -------------------------------- assembly ------------------------------- */\n\n/**\n * Basic page layout. One stack, one gap rhythm — only title scale differs:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Title>Profile</BasicPage.Title>\n * <BasicPage.Stack>\n * <form>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Name\" htmlFor=\"first-name\">\n * <Input id=\"first-name\" size=\"sm\" />\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </form>\n * <form>\n * <BasicPage.Header>\n * <BasicPage.SectionTitle>Agent profile</BasicPage.SectionTitle>\n * <BasicPage.Description>…</BasicPage.Description>\n * </BasicPage.Header>\n * <BasicPage.Card>…</BasicPage.Card>\n * </form>\n * <div>\n * <BasicPage.SectionTitle>Danger zone</BasicPage.SectionTitle>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Delete account\" description=\"…\">\n * <Button color=\"destructive\" size=\"sm\">Delete</Button>\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </div>\n * <BasicPage.Callout>\n * <BasicPage.Header>\n * <BasicPage.CalloutTitle>Invitations</BasicPage.CalloutTitle>\n * <BasicPage.CalloutDescription>…</BasicPage.CalloutDescription>\n * </BasicPage.Header>\n * …invite form…\n * </BasicPage.Callout>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n *\n * Subpage — `Back` above the title, `RowLink` rows to drill in:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Back href=\"/settings\">Settings</BasicPage.Back>\n * <BasicPage.Title>Billing</BasicPage.Title>\n * <BasicPage.Stack>\n * <div>\n * <BasicPage.Card>\n * <BasicPage.RowLink label=\"Invoices\" href=\"/settings/invoices\">\n * <BasicPage.Value>12 documents</BasicPage.Value>\n * </BasicPage.RowLink>\n * </BasicPage.Card>\n * </div>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n */\nexport const BasicPage = {\n Root,\n Back,\n Title,\n Stack,\n Header,\n SectionTitle,\n Description,\n SectionFooter,\n Card,\n Item,\n ItemPanel,\n Callout,\n CalloutTitle,\n CalloutDescription,\n Row,\n RowLink,\n Value,\n Alert,\n Footer,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { t } from "./cn-DTiB6ek_.js";
3
+ import "react";
4
+ import { jsx as s, jsxs as n } from "react/jsx-runtime";
5
+ var p = "mx-auto flex w-fit max-w-lg min-w-0 flex-col items-start justify-center text-left", m = "flex flex-col", x = {
6
+ sm: {
7
+ description: "Small — states inside cards and panels",
8
+ classes: {
9
+ root: "px-5 py-8",
10
+ icon: "mb-1.5 *:size-6",
11
+ copy: "gap-0",
12
+ title: "text-base",
13
+ description: "text-base",
14
+ actions: "mt-5"
15
+ }
16
+ },
17
+ base: {
18
+ description: "Base — the default; full pages and large regions",
19
+ classes: {
20
+ root: "px-5 py-12",
21
+ icon: "mb-4 *:size-10",
22
+ copy: "gap-1",
23
+ title: "text-display-sm",
24
+ description: "text-display-xs",
25
+ actions: "mt-5"
26
+ }
27
+ }
28
+ };
29
+ function f({ icon: a, title: o, description: i, actions: l, size: c = "base", className: r, ...d }) {
30
+ const e = x[c].classes;
31
+ return /* @__PURE__ */ n("div", {
32
+ className: t(p, e.root, r),
33
+ ...d,
34
+ children: [
35
+ a != null && /* @__PURE__ */ s("div", {
36
+ "aria-hidden": !0,
37
+ className: t("text-pho-secondary", e.icon),
38
+ children: a
39
+ }),
40
+ /* @__PURE__ */ n("div", {
41
+ className: t(m, e.copy),
42
+ children: [/* @__PURE__ */ s("div", {
43
+ className: t("text-pho-secondary font-display font-medium text-balance", e.title),
44
+ children: o
45
+ }), i != null && /* @__PURE__ */ s("div", {
46
+ className: t("text-pho-description font-normal", e.description),
47
+ children: i
48
+ })]
49
+ }),
50
+ l != null && /* @__PURE__ */ s("div", {
51
+ className: t("flex flex-wrap items-center justify-start gap-2", e.actions),
52
+ children: l
53
+ })
54
+ ]
55
+ });
56
+ }
57
+ f.displayName = "StatusView";
58
+ export {
59
+ f as i,
60
+ m as n,
61
+ x as r,
62
+ p as t
63
+ };
64
+
65
+ //# sourceMappingURL=status-view-CcbctPqR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-view-CcbctPqR.js","names":[],"sources":["../../src/components/status-view/status-view.tsx"],"sourcesContent":["import { type ComponentProps, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/**\n * Hugs its content (`w-fit`) and centers itself in the host (`mx-auto`); text\n * stays start-aligned so the icon / title / description share one left edge.\n * `max-w-lg` only caps long prose at Dialog width before it wraps.\n */\nexport const STATUS_VIEW =\n \"mx-auto flex w-fit max-w-lg min-w-0 flex-col items-start justify-center text-left\";\n\n/** Title + description group — flex column; gap comes from the size axis. */\nexport const STATUS_VIEW_COPY = \"flex flex-col\";\n\n/**\n * Size axis — retunes every slot. Title + description share Dialog's\n * `font-display` ladder: `base` matches Dialog (`gap-1`); `sm` steps one rung\n * down (`gap-0`) for cards and panels.\n */\nexport const STATUS_VIEW_SIZES = {\n sm: {\n description: \"Small — states inside cards and panels\",\n classes: {\n root: \"px-5 py-8\",\n icon: \"mb-1.5 *:size-6\",\n copy: \"gap-0\",\n title: \"text-base\",\n description: \"text-base\",\n actions: \"mt-5\",\n },\n },\n base: {\n description: \"Base — the default; full pages and large regions\",\n classes: {\n root: \"px-5 py-12\",\n icon: \"mb-4 *:size-10\",\n copy: \"gap-1\",\n title: \"text-display-sm\",\n description: \"text-display-xs\",\n actions: \"mt-5\",\n },\n },\n} satisfies Record<\n string,\n { description: string; classes: Record<string, string> }\n>;\n\nexport type StatusViewSize = keyof typeof STATUS_VIEW_SIZES;\n\ninterface StatusViewBaseProps {\n /** Decorative glyph above the title, usually a Tabler icon. Sized by the view (`*:size-*`), inked `text-pho-secondary`. */\n icon?: ReactNode;\n /** One short line naming the state (\"No API keys yet\", \"Page not found\"). */\n title: ReactNode;\n /** Supporting prose — what it means or what to do next. */\n description?: ReactNode;\n /** Optional action row (buttons / links). Empty states usually omit it. */\n actions?: ReactNode;\n /** Size variant. @default \"base\" */\n size?: StatusViewSize;\n}\n\nexport interface StatusViewProps\n extends\n StatusViewBaseProps,\n Omit<ComponentProps<\"div\">, keyof StatusViewBaseProps | \"children\"> {}\n\n/**\n * StatusView — the standing-in view for a region with nothing to show or\n * nothing that worked: icon over title over description, with an optional\n * action row. The block shrink-wraps and centers itself while its text stays\n * left-aligned; the host owns the footprint (a card body, or a `min-h-screen`\n * flex-centered page). Use `size=\"sm\"` inside cards, the default `base` for\n * whole pages.\n *\n * Empty and error states share this one component — they differ only in what\n * you pass:\n *\n * - **Empty** — usually no `icon` and no `actions`; the create affordance\n * lives elsewhere on the page.\n * - **Error** — pass a warning `icon`, `role=\"alert\"` so it announces, and\n * `actions` offering a way out (retry, reload, a route back).\n */\nexport function StatusView({\n icon,\n title,\n description,\n actions,\n size = \"base\",\n className,\n ...props\n}: StatusViewProps) {\n const slot = STATUS_VIEW_SIZES[size].classes;\n return (\n <div className={cn(STATUS_VIEW, slot.root, className)} {...props}>\n {icon != null && (\n <div aria-hidden className={cn(\"text-pho-secondary\", slot.icon)}>\n {icon}\n </div>\n )}\n <div className={cn(STATUS_VIEW_COPY, slot.copy)}>\n <div\n className={cn(\n \"text-pho-secondary font-display font-medium text-balance\",\n slot.title,\n )}\n >\n {title}\n </div>\n {description != null && (\n <div\n className={cn(\"text-pho-description font-normal\", slot.description)}\n >\n {description}\n </div>\n )}\n </div>\n {actions != null && (\n <div\n className={cn(\n \"flex flex-wrap items-center justify-start gap-2\",\n slot.actions,\n )}\n >\n {actions}\n </div>\n )}\n </div>\n );\n}\n\nStatusView.displayName = \"StatusView\";\n"],"mappings":";;;;AAQA,IAAa,IACX,qFAGW,IAAmB,iBAOnB,IAAoB;AAAA,EAC/B,IAAI;AAAA,IACF,aAAa;AAAA,IACb,SAAS;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,aAAa;AAAA,IACb,SAAS;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAyCA,SAAgB,EAAW,EACzB,MAAA,GACA,OAAA,GACA,aAAA,GACA,SAAA,GACA,MAAA,IAAO,QACP,WAAA,GACA,GAAG,EAAA,GACe;AAClB,QAAM,IAAO,EAAkB,CAAA,EAAM;AACrC,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAW,EAAG,GAAa,EAAK,MAAM,CAAS;AAAA,IAAG,GAAI;AAAA,cAA3D;AAAA,MACG,KAAQ,QACP,gBAAA,EAAC,OAAD;AAAA,QAAK,eAAA;AAAA,QAAY,WAAW,EAAG,sBAAsB,EAAK,IAAI;AAAA,kBAC3D;AAAA,MACE,CAAA;AAAA,MAEP,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAW,EAAG,GAAkB,EAAK,IAAI;AAAA,kBAA9C,CACE,gBAAA,EAAC,OAAD;AAAA,UACE,WAAW,EACT,4DACA,EAAK,KACP;AAAA,oBAEC;AAAA,QACE,CAAA,GACJ,KAAe,QACd,gBAAA,EAAC,OAAD;AAAA,UACE,WAAW,EAAG,oCAAoC,EAAK,WAAW;AAAA,oBAEjE;AAAA,QACE,CAAA,CAEJ;AAAA;MACJ,KAAW,QACV,gBAAA,EAAC,OAAD;AAAA,QACE,WAAW,EACT,mDACA,EAAK,OACP;AAAA,kBAEC;AAAA,MACE,CAAA;AAAA,IAEJ;AAAA;AAET;AAEA,EAAW,cAAc"}
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { i as s, n as t, r as T, t as a } from "../chunks/status-view-CcbctPqR.js";
3
+ export {
4
+ a as STATUS_VIEW,
5
+ t as STATUS_VIEW_COPY,
6
+ T as STATUS_VIEW_SIZES,
7
+ s as StatusView
8
+ };
package/dist/index.js CHANGED
@@ -1,53 +1,61 @@
1
1
  "use client";
2
2
  import { t as s } from "./chunks/cn-DTiB6ek_.js";
3
- import { n as o, r, t as n } from "./chunks/link-provider-9TFNyDqO.js";
4
- import { t as i } from "./chunks/resolve-variant-CcD8iG5l.js";
5
- import { n as _, r as m, t as A } from "./chunks/use-press-pulse-8iorQPsh.js";
3
+ import { n as o, r as E, t as _ } from "./chunks/link-provider-9TFNyDqO.js";
4
+ import { t as S } from "./chunks/resolve-variant-CcD8iG5l.js";
5
+ import { n as I, r as T, t as i } from "./chunks/use-press-pulse-8iorQPsh.js";
6
6
  import "./utils.js";
7
- import { a as B, c as R, d as e, f as O, i as f, l as p, n as C, o as u, r as D, s as N, t as P, u as L } from "./chunks/close-button-B8gF5UNk.js";
8
- import { a as l, c as U, i as V, n as d, o as G, r as g, s as k, t as F } from "./chunks/sidebar-DGpEKxOn.js";
9
- import { i as b, n as v, r as H, t as Z } from "./chunks/basic-page-C50WUzYV.js";
10
- import { t as W } from "./chunks/input-CxS7ndpb.js";
11
- import { t as j } from "./chunks/input-group-D6dlma8k.js";
12
- import { n as w, t as y } from "./chunks/card-9cGnv-VD.js";
13
- import { n as J, t as K } from "./chunks/dialog-Ba0UUE5g.js";
7
+ import { a as B, c as e, d as R, f as C, i as O, l as f, n as p, o as P, r as u, s as D, t as N, u as L } from "./chunks/close-button-B8gF5UNk.js";
8
+ import { a as U, c, i as G, n as l, o as M, r as d, s as g, t as k } from "./chunks/sidebar-DGpEKxOn.js";
9
+ import { a as F, i as Z, n as b, o as v, r as H, s as w, t as x } from "./chunks/basic-page-4_GZOvRr.js";
10
+ import { t as h } from "./chunks/input-CxS7ndpb.js";
11
+ import { t as q } from "./chunks/input-group-D6dlma8k.js";
12
+ import { n as z, t as J } from "./chunks/card-9cGnv-VD.js";
13
+ import { n as Q, t as X } from "./chunks/dialog-Ba0UUE5g.js";
14
+ import { i as aa, n as sa, r as ta, t as oa } from "./chunks/status-view-CcbctPqR.js";
14
15
  export {
15
- Z as BASIC_PAGE_CALLOUT,
16
- v as BASIC_PAGE_CARD,
17
- H as BASIC_PAGE_ROW,
18
- C as BUTTON_COLORS,
19
- D as BUTTON_SHAPES,
20
- f as BUTTON_SIZES,
16
+ x as BASIC_PAGE_CALLOUT,
17
+ b as BASIC_PAGE_CARD,
18
+ H as BASIC_PAGE_ITEM,
19
+ Z as BASIC_PAGE_ITEM_PANEL,
20
+ F as BASIC_PAGE_ITEM_PANEL_DIVIDED,
21
+ v as BASIC_PAGE_ROW,
22
+ p as BUTTON_COLORS,
23
+ u as BUTTON_SHAPES,
24
+ O as BUTTON_SIZES,
21
25
  B as BUTTON_VARIANTS,
22
- b as BasicPage,
23
- u as Button,
24
- N as ButtonLink,
25
- y as CARD_SURFACE,
26
- A as CONTROL_PRESS_SCALE,
27
- _ as CONTROL_PRESS_SPRING,
28
- w as Card,
29
- P as CloseButton,
30
- K as Dialog,
31
- R as EFFECT_BUTTON_SIZES,
32
- p as EffectButton,
26
+ w as BasicPage,
27
+ P as Button,
28
+ D as ButtonLink,
29
+ J as CARD_SURFACE,
30
+ i as CONTROL_PRESS_SCALE,
31
+ I as CONTROL_PRESS_SPRING,
32
+ z as Card,
33
+ N as CloseButton,
34
+ X as Dialog,
35
+ e as EFFECT_BUTTON_SIZES,
36
+ f as EffectButton,
33
37
  L as EffectButtonLink,
34
- W as Input,
35
- j as InputGroup,
36
- n as LinkProvider,
37
- F as SIDEBAR_HEADER_INSET,
38
- d as SIDEBAR_ITEM,
39
- g as SIDEBAR_ITEM_ACTIVE,
40
- V as SIDEBAR_ITEM_INACTIVE,
41
- l as SIDEBAR_ROOT,
42
- G as SIDEBAR_ROOT_BASE,
43
- k as SIDEBAR_ROOT_INSET,
44
- U as Sidebar,
45
- e as buttonVariants,
38
+ h as Input,
39
+ q as InputGroup,
40
+ _ as LinkProvider,
41
+ k as SIDEBAR_HEADER_INSET,
42
+ l as SIDEBAR_ITEM,
43
+ d as SIDEBAR_ITEM_ACTIVE,
44
+ G as SIDEBAR_ITEM_INACTIVE,
45
+ U as SIDEBAR_ROOT,
46
+ M as SIDEBAR_ROOT_BASE,
47
+ g as SIDEBAR_ROOT_INSET,
48
+ oa as STATUS_VIEW,
49
+ sa as STATUS_VIEW_COPY,
50
+ ta as STATUS_VIEW_SIZES,
51
+ c as Sidebar,
52
+ aa as StatusView,
53
+ R as buttonVariants,
46
54
  s as cn,
47
- O as effectButtonVariants,
48
- r as isReactComponent,
49
- i as resolveVariant,
50
- J as useDialogPending,
55
+ C as effectButtonVariants,
56
+ E as isReactComponent,
57
+ S as resolveVariant,
58
+ Q as useDialogPending,
51
59
  o as useLinkComponent,
52
- m as usePressPulse
60
+ T as usePressPulse
53
61
  };
@@ -1,8 +1,11 @@
1
1
  "use client";
2
- import { i as a, n as s, r as _, t as C } from "../chunks/basic-page-C50WUzYV.js";
2
+ import { a as _, i as E, n as I, o as a, r as s, s as P, t as C } from "../chunks/basic-page-4_GZOvRr.js";
3
3
  export {
4
4
  C as BASIC_PAGE_CALLOUT,
5
- s as BASIC_PAGE_CARD,
6
- _ as BASIC_PAGE_ROW,
7
- a as BasicPage
5
+ I as BASIC_PAGE_CARD,
6
+ s as BASIC_PAGE_ITEM,
7
+ E as BASIC_PAGE_ITEM_PANEL,
8
+ _ as BASIC_PAGE_ITEM_PANEL_DIVIDED,
9
+ a as BASIC_PAGE_ROW,
10
+ P as BasicPage
8
11
  };
@@ -0,0 +1 @@
1
+ export { StatusView, STATUS_VIEW, STATUS_VIEW_COPY, STATUS_VIEW_SIZES, type StatusViewProps, type StatusViewSize, } from './status-view';
@@ -0,0 +1,74 @@
1
+ import { ComponentProps, ReactNode } from 'react';
2
+ /**
3
+ * Hugs its content (`w-fit`) and centers itself in the host (`mx-auto`); text
4
+ * stays start-aligned so the icon / title / description share one left edge.
5
+ * `max-w-lg` only caps long prose at Dialog width before it wraps.
6
+ */
7
+ export declare const STATUS_VIEW = "mx-auto flex w-fit max-w-lg min-w-0 flex-col items-start justify-center text-left";
8
+ /** Title + description group — flex column; gap comes from the size axis. */
9
+ export declare const STATUS_VIEW_COPY = "flex flex-col";
10
+ /**
11
+ * Size axis — retunes every slot. Title + description share Dialog's
12
+ * `font-display` ladder: `base` matches Dialog (`gap-1`); `sm` steps one rung
13
+ * down (`gap-0`) for cards and panels.
14
+ */
15
+ export declare const STATUS_VIEW_SIZES: {
16
+ sm: {
17
+ description: string;
18
+ classes: {
19
+ root: string;
20
+ icon: string;
21
+ copy: string;
22
+ title: string;
23
+ description: string;
24
+ actions: string;
25
+ };
26
+ };
27
+ base: {
28
+ description: string;
29
+ classes: {
30
+ root: string;
31
+ icon: string;
32
+ copy: string;
33
+ title: string;
34
+ description: string;
35
+ actions: string;
36
+ };
37
+ };
38
+ };
39
+ export type StatusViewSize = keyof typeof STATUS_VIEW_SIZES;
40
+ interface StatusViewBaseProps {
41
+ /** Decorative glyph above the title, usually a Tabler icon. Sized by the view (`*:size-*`), inked `text-pho-secondary`. */
42
+ icon?: ReactNode;
43
+ /** One short line naming the state ("No API keys yet", "Page not found"). */
44
+ title: ReactNode;
45
+ /** Supporting prose — what it means or what to do next. */
46
+ description?: ReactNode;
47
+ /** Optional action row (buttons / links). Empty states usually omit it. */
48
+ actions?: ReactNode;
49
+ /** Size variant. @default "base" */
50
+ size?: StatusViewSize;
51
+ }
52
+ export interface StatusViewProps extends StatusViewBaseProps, Omit<ComponentProps<"div">, keyof StatusViewBaseProps | "children"> {
53
+ }
54
+ /**
55
+ * StatusView — the standing-in view for a region with nothing to show or
56
+ * nothing that worked: icon over title over description, with an optional
57
+ * action row. The block shrink-wraps and centers itself while its text stays
58
+ * left-aligned; the host owns the footprint (a card body, or a `min-h-screen`
59
+ * flex-centered page). Use `size="sm"` inside cards, the default `base` for
60
+ * whole pages.
61
+ *
62
+ * Empty and error states share this one component — they differ only in what
63
+ * you pass:
64
+ *
65
+ * - **Empty** — usually no `icon` and no `actions`; the create affordance
66
+ * lives elsewhere on the page.
67
+ * - **Error** — pass a warning `icon`, `role="alert"` so it announces, and
68
+ * `actions` offering a way out (retry, reload, a route back).
69
+ */
70
+ export declare function StatusView({ icon, title, description, actions, size, className, ...props }: StatusViewProps): import("react").JSX.Element;
71
+ export declare namespace StatusView {
72
+ var displayName: string;
73
+ }
74
+ export {};
@@ -11,5 +11,6 @@ export * from './components/input';
11
11
  export * from './components/input-group';
12
12
  export * from './components/card';
13
13
  export * from './components/dialog';
14
+ export * from './components/status-view';
14
15
  export * from './sections/sidebar';
15
16
  export * from './sections/basic-page';
@@ -30,6 +30,29 @@ export declare const BASIC_PAGE_CALLOUT = "flex flex-col gap-3 rounded-base bord
30
30
  * than a comfortable touch target.
31
31
  */
32
32
  export declare const BASIC_PAGE_ROW = "flex min-h-[4.25rem] flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6";
33
+ /**
34
+ * One card row that can host subviews. Same padding rhythm as a plain row —
35
+ * an optional trailing `ItemPanel` breaks out of it on its own.
36
+ */
37
+ export declare const BASIC_PAGE_ITEM = "flex flex-col gap-3 px-5 py-4";
38
+ /**
39
+ * Secondary strip closing an `Item` that is last in its card. Negative
40
+ * margins escape the item's `px-5 pb-4` so the gray sheet runs edge-to-edge
41
+ * and owns the row's bottom padding. The body above stays square and the
42
+ * sheet's top is flush against it; only the bottom rounds, nesting into the
43
+ * card's 12px corner (11px inside the 1px border). Content lands back on the
44
+ * item's left gutter.
45
+ */
46
+ export declare const BASIC_PAGE_ITEM_PANEL = "-mx-5 -mb-4 flex items-center rounded-b-[calc(0.75rem-1px)] bg-pho-secondary py-1 pr-3 pl-5";
47
+ /**
48
+ * Mid-list variant — the full-bleed sheet only reads well against the card's
49
+ * bottom corner, so when later rows follow, the panel becomes an inset chip
50
+ * instead: fully rounded at the small-control radius, overhanging the text
51
+ * gutter by 8px per side (content stays aligned with the body above), and
52
+ * leaving the row's own bottom padding and the card's hairline divider alone.
53
+ * `-mt-1.5` collapses the item's `gap-3` (12px) to an effective `gap-1.5` (6px).
54
+ */
55
+ export declare const BASIC_PAGE_ITEM_PANEL_DIVIDED = "-mx-2 -mt-1.5 flex items-center rounded-sm bg-pho-secondary px-2 py-0.5";
33
56
  /**
34
57
  * Page chrome — centered column at the standard content width. Hosts
35
58
  * `Title` + `Stack` (and any route-level siblings). Prefer this over
@@ -92,6 +115,43 @@ declare function SectionFooter({ className, ...props }: ComponentProps<"p"> & {
92
115
  declare function Card({ className, ...props }: ComponentProps<"div"> & {
93
116
  ref?: Ref<HTMLDivElement>;
94
117
  }): import("react").JSX.Element;
118
+ /**
119
+ * One card row that can host subviews. Padding matches a plain row, so use it
120
+ * for any row that may grow an `ItemPanel` — primary content goes straight in
121
+ * as children; the panel, when present, is the last child.
122
+ *
123
+ * ```tsx
124
+ * <BasicPage.Card>
125
+ * <BasicPage.Item>
126
+ * …name, meta, actions…
127
+ * <BasicPage.ItemPanel divided>…secret / expanded content…</BasicPage.ItemPanel>
128
+ * </BasicPage.Item>
129
+ * …later siblings (pass `divided` on the panel above)…
130
+ * </BasicPage.Card>
131
+ * ```
132
+ */
133
+ declare function Item({ className, ...props }: ComponentProps<"div"> & {
134
+ ref?: Ref<HTMLDivElement>;
135
+ }): import("react").JSX.Element;
136
+ export interface BasicPageItemPanelProps extends ComponentProps<"div"> {
137
+ /**
138
+ * Set when later card rows follow this item. The panel then renders as an
139
+ * inset rounded chip (keeping the card's own divider) instead of the
140
+ * full-bleed bottom sheet, which only reads well against the card's corner.
141
+ * @default false
142
+ */
143
+ divided?: boolean;
144
+ ref?: Ref<HTMLDivElement>;
145
+ }
146
+ /**
147
+ * Secondary strip at the end of an `Item`. When the item closes the card,
148
+ * it's a gray sheet flush under the body, full-bleed and owning the row's
149
+ * bottom padding, rounding only into the card's bottom corner. Pass `divided`
150
+ * when later card rows follow — the panel becomes an inset rounded chip and
151
+ * the card's hairline divider stays in charge. Content is already a centered
152
+ * flex row either way.
153
+ */
154
+ declare function ItemPanel({ divided, className, ...props }: BasicPageItemPanelProps): import("react").JSX.Element;
95
155
  /**
96
156
  * Standalone callout. Pair with `CalloutTitle` / `CalloutDescription` (and
97
157
  * optional actions) for a featured block — e.g. an invite form. Do not wrap
@@ -258,6 +318,8 @@ export declare const BasicPage: {
258
318
  Description: typeof Description;
259
319
  SectionFooter: typeof SectionFooter;
260
320
  Card: typeof Card;
321
+ Item: typeof Item;
322
+ ItemPanel: typeof ItemPanel;
261
323
  Callout: typeof Callout;
262
324
  CalloutTitle: typeof CalloutTitle;
263
325
  CalloutDescription: typeof CalloutDescription;
@@ -1 +1 @@
1
- export { BasicPage, BASIC_PAGE_CARD, BASIC_PAGE_CALLOUT, BASIC_PAGE_ROW, type BasicPageRowProps, type BasicPageRowLinkProps, type BasicPageBackProps, type BasicPageFooterProps, } from './basic-page';
1
+ export { BasicPage, BASIC_PAGE_CARD, BASIC_PAGE_CALLOUT, BASIC_PAGE_ROW, BASIC_PAGE_ITEM, BASIC_PAGE_ITEM_PANEL, BASIC_PAGE_ITEM_PANEL_DIVIDED, type BasicPageRowProps, type BasicPageRowLinkProps, type BasicPageBackProps, type BasicPageFooterProps, type BasicPageItemPanelProps, } from './basic-page';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@photon-ai/pho-ui",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Pho Design System — Photon's React component library, built on Base UI",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -201,6 +201,10 @@
201
201
  "types": "./dist/src/components/spinner/index.d.ts",
202
202
  "import": "./dist/components/spinner.js"
203
203
  },
204
+ "./components/status-view": {
205
+ "types": "./dist/src/components/status-view/index.d.ts",
206
+ "import": "./dist/components/status-view.js"
207
+ },
204
208
  "./components/notification": {
205
209
  "types": "./dist/src/components/notification/index.d.ts",
206
210
  "import": "./dist/components/notification.js"
@@ -1 +0,0 @@
1
- {"version":3,"file":"basic-page-C50WUzYV.js","names":["__iconNode"],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs","../../src/sections/basic-page/basic-page.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M15 6l-6 6l6 6\", \"key\": \"svg-0\" }]];\nconst IconChevronLeft = createReactComponent(\"outline\", \"chevron-left\", \"ChevronLeft\", __iconNode);\n\nexport { __iconNode, IconChevronLeft as default };\n//# sourceMappingURL=IconChevronLeft.mjs.map\n","/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M9 6l6 6l-6 6\", \"key\": \"svg-0\" }]];\nconst IconChevronRight = createReactComponent(\"outline\", \"chevron-right\", \"ChevronRight\", __iconNode);\n\nexport { __iconNode, IconChevronRight as default };\n//# sourceMappingURL=IconChevronRight.mjs.map\n","import {\n type AnchorHTMLAttributes,\n type ComponentProps,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { IconChevronLeft, IconChevronRight } from \"@tabler/icons-react\";\nimport { ButtonLink, type ButtonLinkProps } from \"../../components/button\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/**\n * BasicPage — Pho's standard content page: a page title, section titles, and\n * bordered cards of label/control rows. Settings, billing, members — any\n * single-column management surface.\n *\n * Spacing: wrap the page in `Root` (a 42rem column with `px-5` gutters,\n * vertical padding). `Stack` separates blocks (`gap-10`). Inside a block,\n * children share `gap-3`. Wrap a section title + description in `Header`\n * (`gap-0.5`) so that pair stays tight — don't put them as loose siblings.\n * Parts already carry `px-5`.\n *\n * Navigation: pages may drill into subpages. `RowLink` is a whole-row link\n * (trailing chevron) and `Back` returns to the parent — both render through\n * the host's `LinkProvider`; the URL itself stays the router's job. `Back`\n * floats in `Root`'s top padding, so `Title` never moves between pages that\n * have a back link and pages that don't.\n */\n\n/* ------------------------------- class map ------------------------------- */\n\n/** Bordered card that stacks rows with hairline dividers. */\nexport const BASIC_PAGE_CARD =\n \"divide-y divide-pho-secondary rounded-base border border-pho-secondary bg-pho-primary\";\n\n/**\n * Standalone callout surface — featured block (invite form, notice, etc.).\n * Don't wrap in `Card`; this is the outer chrome.\n */\nexport const BASIC_PAGE_CALLOUT =\n \"flex flex-col gap-3 rounded-base border border-pho-secondary bg-pho-page p-5\";\n\n/**\n * One row — label (+ optional description) left, control right.\n * `min-h-[4.25rem]` (68px) keeps avatar/control rows from collapsing shorter\n * than a comfortable touch target.\n */\nexport const BASIC_PAGE_ROW =\n \"flex min-h-[4.25rem] flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6\";\n\n/* --------------------------------- parts --------------------------------- */\n\n/**\n * Page chrome — centered column at the standard content width. Hosts\n * `Title` + `Stack` (and any route-level siblings). Prefer this over\n * ad-hoc `max-w-*` wrappers in the app shell.\n *\n * `44.5rem` = the 42rem (`2xl`) content column plus the two `px-5` gutters,\n * so wide viewports render exactly as before while narrow ones keep a 20px\n * breathing edge instead of running content into the viewport.\n *\n * `relative` anchors `Back`, which floats in the top padding — the reserved\n * zone that keeps `Title` at the same position on every page.\n */\nfunction Root({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return (\n <div\n className={cn(\n \"relative mx-auto w-full max-w-[44.5rem] px-5 py-12\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Slug for hash targets — \"Danger zone\" → `danger-zone`. Empty / non-string\n * children yield no id; pass an explicit `id` to override or `id=\"\"` to opt out.\n */\nfunction slugifyHeading(value: string): string {\n return value\n .normalize(\"NFKD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nfunction headingIdFromChildren(children: ReactNode): string | undefined {\n if (typeof children !== \"string\" && typeof children !== \"number\") {\n return undefined;\n }\n const slug = slugifyHeading(String(children));\n return slug || undefined;\n}\n\n/** Resolve `id`: explicit wins; `\"\"` opts out; else slug from plain-text children. */\nfunction resolveHeadingId(\n id: string | undefined,\n children: ReactNode,\n): string | undefined {\n if (id === \"\") return undefined;\n if (id != null) return id;\n return headingIdFromChildren(children);\n}\n\n/**\n * Page title — largest heading on the surface. Plain-text children get a slug\n * `id` for hash targets (`#profile`); the heading itself is not a link.\n */\nfunction Title({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h1\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h1\n id={headingId}\n className={cn(\n \"text-display-base text-pho-primary scroll-mt-12 px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h1>\n );\n}\n\n/**\n * Vertical stack under the page title. Blocks (forms / sections) use `gap-10`;\n * each block lays out its children with `gap-3`.\n */\nfunction Stack({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return (\n <div\n className={cn(\n \"mt-6 flex flex-col gap-10\",\n \"*:flex *:flex-col *:gap-3\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Title + optional description pair. Keeps that couple tight (`gap-0.5`) so\n * the block's `gap-3` only applies between this header and the card.\n */\nfunction Header({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(\"flex flex-col gap-0.5\", className)} {...props} />;\n}\n\n/**\n * Section heading — same padding as the page title, smaller type. Hashable via\n * slug `id` (not a link).\n */\nfunction SectionTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary scroll-mt-12 px-5 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/**\n * Supporting copy under a section title. Same display step as the title;\n * color + normal weight keep it secondary. Always wrap with `Header`.\n */\nfunction Description({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description px-5 font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Optional caption below a section's `Card` (outside the card). One step\n * smaller than `Description` (`text-xs`). Not the card-internal dirty-state\n * `Footer`.\n */\nfunction SectionFooter({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\"text-pho-description px-5 text-xs font-normal\", className)}\n {...props}\n />\n );\n}\n\n/** Bordered card that stacks rows with hairline dividers. */\nfunction Card({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(BASIC_PAGE_CARD, className)} {...props} />;\n}\n\n/**\n * Standalone callout. Pair with `CalloutTitle` / `CalloutDescription` (and\n * optional actions) for a featured block — e.g. an invite form. Do not wrap\n * in `Card`; this is already the outer surface.\n */\nfunction Callout({\n className,\n ...props\n}: ComponentProps<\"div\"> & { ref?: Ref<HTMLDivElement> }) {\n return <div className={cn(BASIC_PAGE_CALLOUT, className)} {...props} />;\n}\n\n/** Callout heading — same type as `SectionTitle`. Hashable via slug `id`. */\nfunction CalloutTitle({\n id,\n className,\n children,\n ...props\n}: ComponentProps<\"h2\"> & { ref?: Ref<HTMLHeadingElement> }) {\n const headingId = resolveHeadingId(id, children);\n return (\n <h2\n id={headingId}\n className={cn(\n \"text-display-xs text-pho-primary scroll-mt-12 font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/** Supporting copy under a callout title. */\nfunction CalloutDescription({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\n \"text-display-xs text-pho-description font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport interface BasicPageRowProps extends Omit<\n ComponentProps<\"div\">,\n \"title\"\n> {\n /** Left-side field name. */\n label: string;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Associates the label with a control id. When omitted, the label is not a `<label>`. */\n htmlFor?: string;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * One row: label (+ optional description) left, control right.\n * Pass `htmlFor` when the row wraps a labelled input; omit it for display/\n * action rows (avatar, danger-zone delete).\n */\nfunction Row({\n label,\n description,\n htmlFor,\n className,\n children,\n ...props\n}: BasicPageRowProps) {\n return (\n <div className={cn(BASIC_PAGE_ROW, className)} {...props}>\n <div className=\"min-w-0\">\n {htmlFor ? (\n <label\n htmlFor={htmlFor}\n className=\"text-pho-primary block text-base font-normal\"\n >\n {label}\n </label>\n ) : (\n <p className=\"text-pho-primary text-base font-normal\">{label}</p>\n )}\n {description ? (\n <p className=\"text-pho-description mt-0.5 text-xs\">{description}</p>\n ) : null}\n </div>\n <div className=\"flex w-full min-w-0 items-center gap-2 sm:w-auto\">\n {children}\n </div>\n </div>\n );\n}\n\n/** Read-only value on the right side of a row (email, etc.). */\nfunction Value({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n className={cn(\"text-pho-description truncate text-base\", className)}\n {...props}\n />\n );\n}\n\n/**\n * Inline error under a row (still inside the card). Matches card horizontal\n * padding so hosts don't re-apply `px-5`.\n */\nfunction Alert({\n className,\n ...props\n}: ComponentProps<\"p\"> & { ref?: Ref<HTMLParagraphElement> }) {\n return (\n <p\n role=\"alert\"\n className={cn(\"text-pho-error px-5 pb-3 text-xs\", className)}\n {...props}\n />\n );\n}\n\n/**\n * Height spring for the `Footer` reveal — quick and essentially critically\n * damped (an overshooting edge would show clipped content). Same feel as the\n * onboarding / invite card's height-follow spring.\n */\nconst REVEAL_HEIGHT_SPRING = {\n type: \"spring\",\n stiffness: 640,\n damping: 50,\n} as const;\n\n/**\n * Content fade layered over the height reveal, so the bar doesn't pop while\n * the card grows — mirrors the onboarding step-content fade.\n */\nconst REVEAL_FADE = { duration: 0.18, ease: \"easeOut\" } as const;\n\nexport interface BasicPageFooterProps extends ComponentProps<\"div\"> {\n /**\n * Animated presence for dirty-state bars: the card glides open/closed on a\n * height spring while the content fades. Omit for a static, always-visible\n * footer (no animation). No reveal plays on first mount — only on flips.\n */\n show?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * Trailing bar inside a card — typically a save status + submit button that\n * appears after the form is dirty. Same horizontal/vertical padding as a row.\n * Pass `show` (instead of conditional rendering) to animate the bar in and\n * out following the onboarding card's motion language.\n */\nfunction Footer({ show, className, ...props }: BasicPageFooterProps) {\n const reduceMotion = useReducedMotion();\n const bar = (\n <div\n className={cn(\n \"flex items-center justify-between gap-6 px-5 py-4\",\n className,\n )}\n {...props}\n />\n );\n\n if (show === undefined) return bar;\n\n return (\n <AnimatePresence initial={false}>\n {show ? (\n <motion.div\n className=\"overflow-hidden\"\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={\n reduceMotion\n ? { duration: 0 }\n : { height: REVEAL_HEIGHT_SPRING, opacity: REVEAL_FADE }\n }\n >\n {bar}\n </motion.div>\n ) : null}\n </AnimatePresence>\n );\n}\n\n/* ------------------------------- navigation ------------------------------ */\n\nexport interface BasicPageBackProps extends Omit<\n ButtonLinkProps,\n \"variant\" | \"size\" | \"shape\" | \"prefix\" | \"suffix\" | \"svgOnly\" | \"href\"\n> {\n /** Parent destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Label — name the parent page. @default \"Back\" */\n children?: ReactNode;\n}\n\n/**\n * Back link for a subpage — a small ghost `ButtonLink`; place inside `Root`,\n * before `Title`. It floats in `Root`'s reserved top padding (vertically\n * centered in the 48px zone) instead of taking layout space, so `Title` sits\n * at exactly the same position whether or not a page has one.\n *\n * The offsets align the *label* glyph with the title glyph. Title text sits\n * 40px in (`px-5` root gutter + `px-5` title pad); inside a `sm` ghost button\n * the label sits 29.75px in (8px icon-side pad + 15.75px chevron, 1.125em at\n * the 14px `text-base`, + 4px gap + 2px label-span `px-0.5`) — so `left` is\n * the 10.25px difference. `top-2` centers the 32px button in the 48px\n * reserved zone. The chevron and the ghost hover pill hang in the padding —\n * the usual optical alignment for borderless controls.\n */\nfunction Back({\n href,\n className,\n children = \"Back\",\n ...props\n}: BasicPageBackProps) {\n return (\n <ButtonLink\n variant=\"ghost\"\n size=\"sm\"\n href={href}\n prefix={<IconChevronLeft />}\n className={cn(\"absolute top-2 left-[10.25px]\", className)}\n {...props}\n >\n {children}\n </ButtonLink>\n );\n}\n\nexport interface BasicPageRowLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"href\" | \"title\"\n> {\n /** Left-side field name — plain text, or compose with a trailing badge. */\n label: ReactNode;\n /** Optional helper under the label. */\n description?: ReactNode;\n /** Optional media left of the label (e.g. project avatar). */\n leading?: ReactNode;\n /** Subpage destination — rendered through the host's `LinkProvider`. */\n href: string;\n /** Optional trailing value before the chevron (compose with `Value`). */\n children?: ReactNode;\n ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * A row that navigates — the whole row is one link into a subpage, with a\n * trailing chevron cue. Same geometry as `Row`; hover lifts the row, and\n * first/last rows follow the card's corner radius.\n */\nfunction RowLink({\n label,\n description,\n leading,\n href,\n className,\n children,\n ...props\n}: BasicPageRowLinkProps) {\n const Link = useLinkComponent();\n return (\n <Link\n href={href}\n {...props}\n className={cn(\n BASIC_PAGE_ROW,\n \"group outline-pho-brand hover:bg-pho-primary-hover cursor-pointer transition-colors focus-visible:outline-2 focus-visible:-outline-offset-2\",\n // Hover wash follows the card's rounding (minus the 1px border).\n \"first:rounded-t-[calc(var(--radius-base)-1px)] last:rounded-b-[calc(var(--radius-base)-1px)]\",\n className,\n )}\n >\n <div\n className={cn(\"flex min-w-0 items-center\", leading != null && \"gap-3\")}\n >\n {leading}\n <div className=\"min-w-0\">\n <div className=\"flex min-w-0 items-center gap-1\">\n {typeof label === \"string\" || typeof label === \"number\" ? (\n <p className=\"text-pho-primary truncate text-base font-medium\">\n {label}\n </p>\n ) : (\n label\n )}\n </div>\n {description ? (\n <div className=\"text-pho-description text-xs\">{description}</div>\n ) : null}\n </div>\n </div>\n <div className=\"flex w-full min-w-0 items-center gap-2 sm:w-auto\">\n {children}\n <IconChevronRight\n aria-hidden\n className=\"text-pho-secondary group-hover:text-pho-secondary-hover size-4 shrink-0 transition-colors\"\n />\n </div>\n </Link>\n );\n}\n\n/* -------------------------------- assembly ------------------------------- */\n\n/**\n * Basic page layout. One stack, one gap rhythm — only title scale differs:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Title>Profile</BasicPage.Title>\n * <BasicPage.Stack>\n * <form>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Name\" htmlFor=\"first-name\">\n * <Input id=\"first-name\" size=\"sm\" />\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </form>\n * <form>\n * <BasicPage.Header>\n * <BasicPage.SectionTitle>Agent profile</BasicPage.SectionTitle>\n * <BasicPage.Description>…</BasicPage.Description>\n * </BasicPage.Header>\n * <BasicPage.Card>…</BasicPage.Card>\n * </form>\n * <div>\n * <BasicPage.SectionTitle>Danger zone</BasicPage.SectionTitle>\n * <BasicPage.Card>\n * <BasicPage.Row label=\"Delete account\" description=\"…\">\n * <Button color=\"destructive\" size=\"sm\">Delete</Button>\n * </BasicPage.Row>\n * </BasicPage.Card>\n * </div>\n * <BasicPage.Callout>\n * <BasicPage.Header>\n * <BasicPage.CalloutTitle>Invitations</BasicPage.CalloutTitle>\n * <BasicPage.CalloutDescription>…</BasicPage.CalloutDescription>\n * </BasicPage.Header>\n * …invite form…\n * </BasicPage.Callout>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n *\n * Subpage — `Back` above the title, `RowLink` rows to drill in:\n *\n * ```tsx\n * <BasicPage.Root>\n * <BasicPage.Back href=\"/settings\">Settings</BasicPage.Back>\n * <BasicPage.Title>Billing</BasicPage.Title>\n * <BasicPage.Stack>\n * <div>\n * <BasicPage.Card>\n * <BasicPage.RowLink label=\"Invoices\" href=\"/settings/invoices\">\n * <BasicPage.Value>12 documents</BasicPage.Value>\n * </BasicPage.RowLink>\n * </BasicPage.Card>\n * </div>\n * </BasicPage.Stack>\n * </BasicPage.Root>\n * ```\n */\nexport const BasicPage = {\n Root,\n Back,\n Title,\n Stack,\n Header,\n SectionTitle,\n Description,\n SectionFooter,\n Card,\n Callout,\n CalloutTitle,\n CalloutDescription,\n Row,\n RowLink,\n Value,\n Alert,\n Footer,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}