@photon-ai/pho-ui 4.6.0 → 4.7.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/dist/chunks/{basic-page-D2PDJklw.js → basic-page-E_on0m1X.js} +638 -638
- package/dist/chunks/basic-page-E_on0m1X.js.map +1 -0
- package/dist/chunks/{button-CgUS0j3D.js → button-C9VqBBIr.js} +9 -9
- package/dist/chunks/button-C9VqBBIr.js.map +1 -0
- package/dist/chunks/{chat-BXjycPi9.js → chat-B0WIgEyM.js} +2 -2
- package/dist/chunks/{chat-BXjycPi9.js.map → chat-B0WIgEyM.js.map} +1 -1
- package/dist/chunks/{code-block-BGgbp-6Q.js → code-block-BuFfh0zH.js} +2 -2
- package/dist/chunks/{code-block-BGgbp-6Q.js.map → code-block-BuFfh0zH.js.map} +1 -1
- package/dist/chunks/{command-BfCCRaoc.js → command-iYvU6Mhf.js} +2 -2
- package/dist/chunks/{command-BfCCRaoc.js.map → command-iYvU6Mhf.js.map} +1 -1
- package/dist/chunks/{dialog-DeM4axJ6.js → dialog-MPvem7yV.js} +2 -2
- package/dist/chunks/{dialog-DeM4axJ6.js.map → dialog-MPvem7yV.js.map} +1 -1
- package/dist/chunks/{error-VvHnteyf.js → error-D5SzZ0ev.js} +2 -2
- package/dist/chunks/{error-VvHnteyf.js.map → error-D5SzZ0ev.js.map} +1 -1
- package/dist/chunks/{filter-bar-BcpeTKCC.js → filter-bar-B-oYYBsU.js} +3 -3
- package/dist/chunks/{filter-bar-BcpeTKCC.js.map → filter-bar-B-oYYBsU.js.map} +1 -1
- package/dist/chunks/{log-list-Didt-MV4.js → log-list-tNuCFGlP.js} +2 -2
- package/dist/chunks/{log-list-Didt-MV4.js.map → log-list-tNuCFGlP.js.map} +1 -1
- package/dist/chunks/{message-CTml-TrB.js → message-Dz2-numf.js} +32 -29
- package/dist/chunks/{message-CTml-TrB.js.map → message-Dz2-numf.js.map} +1 -1
- package/dist/chunks/{sidebar-BmloUwJQ.js → sidebar-BP39w1iA.js} +3 -3
- package/dist/chunks/sidebar-BP39w1iA.js.map +1 -0
- package/dist/chunks/{toast-DUvjSZF7.js → toast-BACxYsv6.js} +2 -2
- package/dist/chunks/{toast-DUvjSZF7.js.map → toast-BACxYsv6.js.map} +1 -1
- package/dist/components/button.js +1 -1
- package/dist/components/chat.js +1 -1
- package/dist/components/code-block.js +1 -1
- package/dist/components/command.js +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/error.js +1 -1
- package/dist/components/filter-bar.js +1 -1
- package/dist/components/log-list.js +1 -1
- package/dist/components/message.js +1 -1
- package/dist/components/toast.js +1 -1
- package/dist/index.js +10 -10
- package/dist/sections/basic-page.js +1 -1
- package/dist/sections/sidebar.js +1 -1
- package/dist/src/components/button/button.d.ts +7 -7
- package/dist/src/components/message/message-status.d.ts +7 -3
- package/dist/src/sections/basic-page/basic-page.d.ts +6 -1
- package/package.json +1 -1
- package/dist/chunks/basic-page-D2PDJklw.js.map +0 -1
- package/dist/chunks/button-CgUS0j3D.js.map +0 -1
- package/dist/chunks/sidebar-BmloUwJQ.js.map +0 -1
|
@@ -10,15 +10,15 @@ import { Fragment as z, jsx as s, jsxs as ee } from "react/jsx-runtime";
|
|
|
10
10
|
import { motion as w, useReducedMotion as oe } from "motion/react";
|
|
11
11
|
var ae = l("group relative inline-flex h-max cursor-pointer items-center justify-center whitespace-nowrap outline-pho-brand transition-[color,background-color,border-color,opacity,box-shadow,outline-color] duration-100 ease-linear focus-visible:outline-2 focus-visible:-outline-offset-2", "disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none"), L = {
|
|
12
12
|
sm: {
|
|
13
|
-
classes: l("gap-1 px-
|
|
13
|
+
classes: l("gap-1.5 px-4 py-1.5 text-base font-medium data-svg-only:p-2", "has-[[data-icon=prefix]]:pl-3 has-[[data-icon=loading]]:pl-3 has-[[data-icon=suffix]]:pr-3"),
|
|
14
14
|
description: "Small — compact rows, tables, and toolbars"
|
|
15
15
|
},
|
|
16
16
|
md: {
|
|
17
|
-
classes: l("gap-1 px-4 py-2 text-base font-medium data-svg-only:p-2.5", "has-[[data-icon=prefix]]:pl-
|
|
17
|
+
classes: l("gap-1.5 px-4.5 py-2 text-base font-medium data-svg-only:p-2.5", "has-[[data-icon=prefix]]:pl-3.5 has-[[data-icon=loading]]:pl-3.5 has-[[data-icon=suffix]]:pr-3.5"),
|
|
18
18
|
description: "Medium — the default"
|
|
19
19
|
},
|
|
20
20
|
lg: {
|
|
21
|
-
classes: l("gap-
|
|
21
|
+
classes: l("gap-2 px-5.5 py-2.5 text-md font-medium data-svg-only:p-3", "has-[[data-icon=prefix]]:pl-4.5 has-[[data-icon=loading]]:pl-4.5 has-[[data-icon=suffix]]:pr-4.5"),
|
|
22
22
|
description: "Large — prominent and marketing actions"
|
|
23
23
|
}
|
|
24
24
|
}, re = {
|
|
@@ -257,9 +257,9 @@ var fe = {
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
}, M = {
|
|
260
|
-
sm: "has-[[data-icon=prefix]]:pl-
|
|
261
|
-
md: "has-[[data-icon=prefix]]:pl-4 has-[[data-icon=loading]]:pl-4 has-[[data-icon=suffix]]:pr-4",
|
|
262
|
-
lg: "has-[[data-icon=prefix]]:pl-5 has-[[data-icon=loading]]:pl-5 has-[[data-icon=suffix]]:pr-5"
|
|
260
|
+
sm: "has-[[data-icon=prefix]]:pl-4 has-[[data-icon=loading]]:pl-4 has-[[data-icon=suffix]]:pr-4",
|
|
261
|
+
md: "has-[[data-icon=prefix]]:pl-4.5 has-[[data-icon=loading]]:pl-4.5 has-[[data-icon=suffix]]:pr-4.5",
|
|
262
|
+
lg: "has-[[data-icon=prefix]]:pl-5.5 has-[[data-icon=loading]]:pl-5.5 has-[[data-icon=suffix]]:pr-5.5"
|
|
263
263
|
};
|
|
264
264
|
function N({ position: e, size: a, children: o }) {
|
|
265
265
|
return /* @__PURE__ */ s(w.span, {
|
|
@@ -302,7 +302,7 @@ function H({ svgOnly: e, loading: a, prefix: o, suffix: r, children: n, iconReve
|
|
|
302
302
|
}) : i ? O(o, "prefix", p) : B(o, "prefix"),
|
|
303
303
|
n != null && n !== !1 && /* @__PURE__ */ s("span", {
|
|
304
304
|
"data-text": !0,
|
|
305
|
-
className: "transition-inherit-all
|
|
305
|
+
className: "transition-inherit-all",
|
|
306
306
|
children: n
|
|
307
307
|
}),
|
|
308
308
|
i ? O(r, "suffix", p) : B(r, "suffix")
|
|
@@ -319,7 +319,7 @@ function W(e, a, o) {
|
|
|
319
319
|
...ce[e],
|
|
320
320
|
transition: ue
|
|
321
321
|
} : {};
|
|
322
|
-
return o.iconReveal && (r.gap = 0, n.gap = e === "lg" ?
|
|
322
|
+
return o.iconReveal && (r.gap = 0, n.gap = e === "lg" ? 6 : 2), {
|
|
323
323
|
initial: !1,
|
|
324
324
|
animate: o.waking && o.sheen ? "wake" : "rest",
|
|
325
325
|
whileHover: a ? void 0 : "hover",
|
|
@@ -469,4 +469,4 @@ export {
|
|
|
469
469
|
F as u
|
|
470
470
|
};
|
|
471
471
|
|
|
472
|
-
//# sourceMappingURL=button-
|
|
472
|
+
//# sourceMappingURL=button-C9VqBBIr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button-C9VqBBIr.js","names":[],"sources":["../../src/components/button/button.tsx"],"sourcesContent":["import {\n isValidElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ButtonHTMLAttributes,\n type ComponentType,\n type FC,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport { SPRING_PRESS } from \"../../motion\";\nimport { cn } from \"../../utils/cn\";\nimport { resolveVariant, type VariantMap } from \"../../utils/resolve-variant\";\nimport { isReactComponent } from \"../../utils/is-react-component\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\nimport { Spinner } from \"../spinner/spinner\";\n\n/**\n * Design notes:\n * - TWO visual axes: `variant` is the surface (filled / outlined / ghost /\n * effect) and `color` is the semantic ink (default / destructive). Dialog\n * confirms use the default `effect`; danger-zone triggers are `ghost` +\n * `destructive`. `effect` is the marketing pill: same-hue 1.5px outer rim\n * plus inset sheen that springs on hover.\n * - `iconReveal` is a separate boolean: on hover, prefix/suffix icons spring\n * in from collapsed — works with any variant, independent of `effect`.\n * - Press scale (Motion `whileTap` → 0.97) is shared by every variant; only\n * `effect` also springs its inset sheen on hover/press, and replays a\n * one-shot sheen glint when it leaves `disabled`/`loading` (wake).\n * - THREE sizes (`sm` / `md` / `lg`, default `md`). No `xs` / `xl`.\n * - `prefix` / `suffix` are generic slots (icon, spinner, count…), not\n * icon-only props. `svgOnly` makes an icon button and *requires* an\n * `aria-label`. `loading` is declarative. Effect’s rim/sheen are\n * box-shadow layers (not layout `border`).\n * - Navigation belongs to `ButtonLink`; an inline text link is an anchor.\n */\n\nconst COMMON_ROOT = cn(\n // Transition colors/shadows in CSS; transform (press scale) is owned by Motion.\n // Inset focus so the ring stays inside a clipping ancestor (a card, a\n // scrollport) and inside the pill itself — never drop the ring.\n \"group relative inline-flex h-max cursor-pointer items-center justify-center whitespace-nowrap outline-pho-brand transition-[color,background-color,border-color,opacity,box-shadow,outline-color] duration-100 ease-linear focus-visible:outline-2 focus-visible:-outline-offset-2\",\n // Disabled (native `disabled` on <button>, `aria-disabled` on links).\n \"disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:pointer-events-none\",\n);\n\n/**\n * Size axis — padding, text size, and icon-only (svgOnly) padding.\n *\n * Icon-side tuck (optical correction): a side that carries an icon sits 4px\n * closer to its edge than the label does to the other — sm 12/16 · md 14/18 ·\n * lg 18/22. An icon's box brings its own whitespace, so equal padding reads\n * as a looser icon side; the tuck is small enough to look equal, not measured\n * to be. Selected structurally via `:has()` on the slot markers (`data-icon`\n * is `prefix`, `suffix`, or `loading` — the spinner is an icon too). The\n * label has no padding of its own: its inset from an icon is the `gap`.\n */\nexport const BUTTON_SIZES = {\n sm: {\n classes: cn(\n \"gap-1.5 px-4 py-1.5 text-base font-medium data-svg-only:p-2\",\n \"has-[[data-icon=prefix]]:pl-3 has-[[data-icon=loading]]:pl-3 has-[[data-icon=suffix]]:pr-3\",\n ),\n description: \"Small — compact rows, tables, and toolbars\",\n },\n md: {\n classes: cn(\n \"gap-1.5 px-4.5 py-2 text-base font-medium data-svg-only:p-2.5\",\n \"has-[[data-icon=prefix]]:pl-3.5 has-[[data-icon=loading]]:pl-3.5 has-[[data-icon=suffix]]:pr-3.5\",\n ),\n description: \"Medium — the default\",\n },\n lg: {\n classes: cn(\n \"gap-2 px-5.5 py-2.5 text-md font-medium data-svg-only:p-3\",\n \"has-[[data-icon=prefix]]:pl-4.5 has-[[data-icon=loading]]:pl-4.5 has-[[data-icon=suffix]]:pr-4.5\",\n ),\n description: \"Large — prominent and marketing actions\",\n },\n} satisfies VariantMap;\n\n/** Shape axis — corner treatment. Pills are the photon.codes default. */\nexport const BUTTON_SHAPES = {\n rounded: {\n classes: \"rounded-full\",\n description: \"Pill — the default; every button on photon.codes\",\n },\n square: {\n classes: \"rounded-base\",\n description: \"Gently rounded corners for dense app chrome\",\n },\n circle: {\n classes: \"rounded-full\",\n description: \"Circular — pair with svgOnly for round icon buttons\",\n },\n} satisfies VariantMap;\n\n/**\n * At `lg`, square buttons add squircle smoothing on top of `rounded-base`\n * (12px) — the same treatment as Input `lg`, so 44px buttons and fields share\n * a corner language. 12/44 ≈ 0.272 — LiftKit's half-step decimal (√φ − 1).\n */\nconst SQUARE_LG_RADIUS = \"squircle\";\n\n/**\n * Optical pad for `effect`: the 1.5px outer rim is a box-shadow (no layout\n * cost), so without this the painted height reads ~3px taller than filled /\n * outlined / ghost. Subtract 1.5px from each side so fill+rim matches siblings.\n */\nconst EFFECT_OPTICAL_PAD: Record<ButtonSize, string> = {\n sm: \"py-[4.5px] data-svg-only:p-[6.5px]\",\n md: \"py-[6.5px] data-svg-only:p-[8.5px]\",\n lg: \"py-[8.5px] data-svg-only:p-[10.5px]\",\n};\n\n/** Surface axis — how the control is drawn. `effect` is the default. */\nexport const BUTTON_VARIANTS = {\n effect: {\n classes: \"\",\n description:\n \"Default — marketing pill with same-hue outer rim and inset sheen\",\n },\n filled: {\n classes: \"\",\n description: \"Solid fill without sheen\",\n },\n outlined: {\n classes: \"\",\n description: \"Hairline ring — supporting action\",\n },\n ghost: {\n classes: \"\",\n description: \"Borderless — quiet / inline action\",\n },\n} satisfies VariantMap;\n\n/** Color axis — semantic ink. `default` is the default. */\nexport const BUTTON_COLORS = {\n default: {\n classes: \"\",\n description: \"Neutral / brand contrast\",\n },\n destructive: {\n classes: \"\",\n description: \"Destructive intent (delete, discard)\",\n },\n} satisfies VariantMap;\n\n/**\n * Surface × color looks. Kept as a matrix so each cell can own its tokens\n * (filled destructive is solid red; ghost destructive is red text only).\n */\nconst BUTTON_LOOKS: Record<\n keyof typeof BUTTON_VARIANTS,\n Record<keyof typeof BUTTON_COLORS, string>\n> = {\n // Icons inherit the label ink (currentColor) — no separate opacity/tint.\n // The rim replicates photon.codes' Framer CTA border: 1.5px in the fill hue\n // at 62% alpha, reading as a soft same-hue edge (the site has NO outer\n // glow — verified against live computed styles). Sheen geometry is CSS\n // vars that Motion springs on hover (see Button). All edges are shadows —\n // never a layout `border` — so height stays paired with other variants.\n effect: {\n default: cn(\n \"squircle overflow-visible bg-pho-brand-solid text-pho-on-brand transition-none\",\n \"hover:bg-pho-brand-solid data-loading:bg-pho-brand-solid\",\n \"[--pho-rim:color-mix(in_oklab,var(--background-color-pho-brand-solid)_62%,transparent)]\",\n \"[--pho-sheen:light-dark(rgba(255,255,255,0.5),rgba(0,0,0,0.12))]\",\n \"shadow-[0_0_0_1.5px_var(--pho-rim),inset_0_0_0_1px_var(--border-color-pho-on-brand),inset_0_var(--pho-sheen-y,0px)_var(--pho-sheen-blur,5px)_var(--pho-sheen-spread,2px)_var(--pho-sheen)]\",\n ),\n destructive: cn(\n \"squircle overflow-visible bg-pho-error-solid text-white outline-pho-error transition-none\",\n \"hover:bg-pho-error-solid data-loading:bg-pho-error-solid\",\n \"[--pho-rim:color-mix(in_oklab,var(--background-color-pho-error-solid)_62%,transparent)]\",\n \"[--pho-sheen:light-dark(rgba(255,255,255,0.45),rgba(0,0,0,0.18))]\",\n \"shadow-[0_0_0_1.5px_var(--pho-rim),inset_0_0_0_1px_oklch(1_0_0/0.2),inset_0_var(--pho-sheen-y,0px)_var(--pho-sheen-blur,5px)_var(--pho-sheen-spread,2px)_var(--pho-sheen)]\",\n ),\n },\n filled: {\n default:\n \"bg-pho-brand-solid text-pho-on-brand hover:bg-pho-brand-solid-hover data-loading:bg-pho-brand-solid-hover\",\n destructive:\n \"bg-pho-error-solid text-white outline-pho-error hover:bg-pho-error-solid-hover data-loading:bg-pho-error-solid-hover\",\n },\n outlined: {\n default:\n // Rest hairline is the card stroke; hover climbs to primary ink so the\n // edge reads as black (white in dark), matching the label's hover lift.\n // The ring spans the full ladder, so ease it in gently — 200ms ease-out\n // approximates the effect variant's soft spring instead of base's\n // 100ms linear snap. Prefer the named `ring-pho-ink` token over an\n // arbitrary value so consumers' Tailwind scanners pick it up reliably.\n \"bg-pho-primary text-pho-secondary ring-1 ring-pho-secondary ring-inset duration-200 ease-out hover:bg-pho-primary-hover hover:text-pho-secondary-hover hover:ring-pho-ink data-loading:bg-pho-primary-hover\",\n destructive:\n \"bg-pho-primary text-pho-error outline-pho-error ring-1 ring-pho-error ring-inset duration-200 ease-out hover:bg-pho-error-primary hover:text-pho-error-hover data-loading:bg-pho-error-primary\",\n },\n ghost: {\n default:\n \"text-pho-secondary hover:bg-pho-ghost-hover hover:text-pho-secondary-hover data-loading:bg-pho-ghost-hover\",\n destructive:\n \"text-pho-error outline-pho-error hover:bg-pho-error-primary hover:text-pho-error-hover data-loading:bg-pho-error-primary\",\n },\n};\n\nexport type ButtonSize = keyof typeof BUTTON_SIZES;\nexport type ButtonShape = keyof typeof BUTTON_SHAPES;\nexport type ButtonVariant = keyof typeof BUTTON_VARIANTS;\nexport type ButtonColor = keyof typeof BUTTON_COLORS;\n\n/** Compose the full class string for a button — exported for reuse/testing. */\nexport function buttonVariants(opts?: {\n variant?: ButtonVariant;\n color?: ButtonColor;\n size?: ButtonSize;\n shape?: ButtonShape;\n className?: string;\n}): string {\n const {\n variant = \"effect\",\n color = \"default\",\n size = \"md\",\n shape: shapeOpt = \"rounded\",\n className,\n } = opts ?? {};\n // Effect pills are always fully rounded — shape is ignored.\n const shape = variant === \"effect\" ? \"rounded\" : shapeOpt;\n const look =\n BUTTON_LOOKS[variant as keyof typeof BUTTON_LOOKS]?.[\n color as keyof (typeof BUTTON_LOOKS)[\"effect\"]\n ] ?? \"\";\n return cn(\n COMMON_ROOT,\n resolveVariant(BUTTON_SHAPES, shape),\n shape === \"square\" && size === \"lg\" && SQUARE_LG_RADIUS,\n resolveVariant(BUTTON_SIZES, size),\n // Outer rim is a 1.5px box-shadow (no layout cost). Shrink padding by the\n // same amount so fill+rim paints at the same visual size as filled /\n // outlined / ghost siblings of the same `size`.\n variant === \"effect\" && EFFECT_OPTICAL_PAD[size],\n look,\n className,\n );\n}\n\n/** An icon/element slot rendered before or after the label. */\ntype Slottable = ReactNode | FC<{ className?: string }>;\n\ninterface ButtonBaseProps {\n /** Surface variant. @default \"effect\" */\n variant?: ButtonVariant;\n /** Semantic color. @default \"default\" */\n color?: ButtonColor;\n /** Size variant. @default \"md\" */\n size?: ButtonSize;\n /** Corner shape. @default \"rounded\" */\n shape?: ButtonShape;\n /** Slot before the label — a component (`Plus`) or element (`<Plus />`). */\n prefix?: Slottable;\n /** Slot after the label. */\n suffix?: Slottable;\n /**\n * Reveal prefix/suffix icons on hover — collapsed and invisible at rest,\n * spring in on hover. Independent of `variant` (including `effect`).\n * Ignored when `svgOnly`. @default false\n */\n iconReveal?: boolean;\n /** Render as an icon-only button. Requires an `aria-label`. */\n svgOnly?: boolean;\n /** Show a spinner and block interaction while staying readable. */\n loading?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\n/**\n * DOM event handlers whose React signatures clash with Motion's gesture\n * props of the same name (Motion re-types these on `motion.*` elements).\n * Excluded from the public API — Button renders through Motion when the\n * sheen or icon reveal is active, so these handlers would be intercepted.\n */\ntype MotionHandlerConflicts =\n | \"onAnimationStart\"\n | \"onAnimationEnd\"\n | \"onAnimationIteration\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onDragEnter\"\n | \"onDragExit\"\n | \"onDragLeave\"\n | \"onDragOver\"\n | \"onDrop\";\n\nexport interface ButtonProps\n extends\n ButtonBaseProps,\n Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof ButtonBaseProps | MotionHandlerConflicts\n > {\n ref?: Ref<HTMLButtonElement>;\n}\n\nexport interface ButtonLinkProps\n extends\n ButtonBaseProps,\n Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof ButtonBaseProps | MotionHandlerConflicts\n > {\n /** Navigate to this URL (rendered via the host's `LinkProvider`). */\n href: string;\n /** Visually and semantically disable the link. */\n disabled?: boolean;\n}\n\nconst SLOT_CLASS =\n // Icons scale with the label: 1.125em tracks the button's font size\n // (16px icon beside 14px text, 18px beside 16px) so small buttons never\n // carry an oversized glyph.\n \"transition-inherit-all pointer-events-none inline-flex shrink-0 items-center [&>svg]:size-[1.125em] [&>svg]:shrink-0\";\n\nfunction Slot({\n position,\n children,\n}: {\n position: \"prefix\" | \"suffix\" | \"loading\";\n children: ReactNode;\n}) {\n return (\n <span data-icon={position} className={SLOT_CLASS}>\n {children}\n </span>\n );\n}\n\nfunction renderSlot(icon: Slottable, position: \"prefix\" | \"suffix\") {\n if (icon == null || icon === false) return null;\n if (isReactComponent(icon)) {\n const Icon = icon;\n return (\n <Slot position={position}>\n <Icon />\n </Slot>\n );\n }\n if (isValidElement(icon)) return <Slot position={position}>{icon}</Slot>;\n return null;\n}\n\nfunction warnMissingLabel(svgOnly: boolean | undefined, label: unknown) {\n if (\n svgOnly &&\n !label &&\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"Button: `svgOnly` buttons require an `aria-label` that names the action.\",\n );\n }\n}\n\n/* ======================== Motion: sheen + icon reveal ======================== */\n\n/** Framer source transition: `spring-physics 200 30 0.1`. */\nconst BUTTON_SPRING = SPRING_PRESS;\n\nconst EFFECT_SHEEN_REST = {\n \"--pho-sheen-y\": \"0px\",\n \"--pho-sheen-blur\": \"5px\",\n \"--pho-sheen-spread\": \"2px\",\n} as const;\n\n/** Per-size sheen hover targets. */\nconst EFFECT_SHEEN_HOVER = {\n sm: {\n \"--pho-sheen-y\": \"-3px\",\n \"--pho-sheen-blur\": \"8px\",\n \"--pho-sheen-spread\": \"2px\",\n },\n md: {\n \"--pho-sheen-y\": \"-3px\",\n \"--pho-sheen-blur\": \"8px\",\n \"--pho-sheen-spread\": \"2px\",\n },\n lg: {\n \"--pho-sheen-y\": \"-6px\",\n \"--pho-sheen-blur\": \"14px\",\n \"--pho-sheen-spread\": \"1px\",\n },\n} as const;\n\n/**\n * Per-size sheen press targets — the inverse gesture of hover: the light\n * drops back below the rest line and tightens while the pill compresses\n * slightly, so hover → press reads as \"lift, then push in\".\n */\nconst EFFECT_SHEEN_PRESS = {\n sm: {\n \"--pho-sheen-y\": \"1.5px\",\n \"--pho-sheen-blur\": \"4px\",\n \"--pho-sheen-spread\": \"1px\",\n },\n md: {\n \"--pho-sheen-y\": \"1.5px\",\n \"--pho-sheen-blur\": \"4px\",\n \"--pho-sheen-spread\": \"1px\",\n },\n lg: {\n \"--pho-sheen-y\": \"3px\",\n \"--pho-sheen-blur\": \"7px\",\n \"--pho-sheen-spread\": \"1px\",\n },\n} as const;\n\n/** Pill compression while pressed — subtle, transform-only; every variant. */\nconst BUTTON_PRESS_SCALE = 0.97;\n\n/**\n * One-shot \"wake\" glint when an effect pill re-enables (disabled / loading →\n * interactive). The keyframes replay the pill's own gesture in reverse: the\n * sheen starts from its pressed-in position (low, tight — the dormant read),\n * springs up past the hover line, and settles at rest. Shadow-only, so the\n * pill never moves or resizes next to its neighbours.\n */\nconst EFFECT_SHEEN_WAKE = {\n sm: {\n \"--pho-sheen-y\": [\"1.5px\", \"-4px\", \"0px\"],\n \"--pho-sheen-blur\": [\"4px\", \"9px\", \"5px\"],\n \"--pho-sheen-spread\": [\"1px\", \"2px\", \"2px\"],\n },\n md: {\n \"--pho-sheen-y\": [\"1.5px\", \"-4px\", \"0px\"],\n \"--pho-sheen-blur\": [\"4px\", \"9px\", \"5px\"],\n \"--pho-sheen-spread\": [\"1px\", \"2px\", \"2px\"],\n },\n lg: {\n \"--pho-sheen-y\": [\"3px\", \"-8px\", \"0px\"],\n \"--pho-sheen-blur\": [\"7px\", \"16px\", \"5px\"],\n \"--pho-sheen-spread\": [\"1px\", \"1px\", \"2px\"],\n },\n} as const;\n\n/**\n * Wake timing: a short delay lets the 100ms opacity fade land first, then a\n * quick rise (feedback) and a relaxed settle. Keyframes need a tween — the\n * shared spring only animates between two values.\n */\nconst WAKE_TRANSITION = {\n duration: 0.6,\n delay: 0.05,\n times: [0, 0.4, 1],\n ease: [\"easeOut\", \"easeInOut\"],\n} as const;\n\n/**\n * Fire the wake glint on the disabled/loading → enabled edge (never on\n * mount), skipped under reduced motion. `data-waking` mirrors the window so\n * tests and styling can observe it.\n */\nfunction useWakeOnEnable(inert: boolean, sheen: boolean) {\n const [waking, setWaking] = useState(false);\n const prevInert = useRef(inert);\n const reduceMotion = useReducedMotion();\n\n useEffect(() => {\n if (prevInert.current && !inert && sheen && !reduceMotion) {\n setWaking(true);\n } else if (inert) {\n setWaking(false);\n }\n prevInert.current = inert;\n }, [inert, sheen, reduceMotion]);\n\n return {\n waking,\n onWakeComplete: (definition: unknown) => {\n if (definition === \"wake\") setWaking(false);\n },\n };\n}\n\n/**\n * Icon reveal sizes — collapsed at rest, full on hover. `lg` matches the\n * Framer 20×21 source; `sm`/`md` scale with the 14px label.\n */\nconst ICON_REVEAL_VARIANTS = {\n sm: {\n rest: { opacity: 0, width: 1, height: 9 },\n hover: { opacity: 1, width: 17, height: 18 },\n },\n md: {\n rest: { opacity: 0, width: 1, height: 9 },\n hover: { opacity: 1, width: 17, height: 18 },\n },\n lg: {\n rest: { opacity: 0, width: 1, height: 10 },\n hover: { opacity: 1, width: 20, height: 21 },\n },\n} as const;\n\n/**\n * When icons are hidden at rest, undo Button's icon-side padding tuck so the\n * pill doesn't look lopsided. Same `:has()` keys as the tuck (later wins).\n */\nconst ICON_REVEAL_PAD_RESTORE: Record<ButtonSize, string> = {\n sm: \"has-[[data-icon=prefix]]:pl-4 has-[[data-icon=loading]]:pl-4 has-[[data-icon=suffix]]:pr-4\",\n md: \"has-[[data-icon=prefix]]:pl-4.5 has-[[data-icon=loading]]:pl-4.5 has-[[data-icon=suffix]]:pr-4.5\",\n lg: \"has-[[data-icon=prefix]]:pl-5.5 has-[[data-icon=loading]]:pl-5.5 has-[[data-icon=suffix]]:pr-5.5\",\n};\n\nfunction RevealSlot({\n position,\n size,\n children,\n}: {\n position: \"prefix\" | \"suffix\";\n size: ButtonSize;\n children: ReactNode;\n}) {\n return (\n <motion.span\n data-icon={position}\n variants={ICON_REVEAL_VARIANTS[size]}\n transition={BUTTON_SPRING}\n style={{\n display: \"inline-flex\",\n flex: \"none\",\n alignItems: \"center\",\n overflow: \"hidden\",\n }}\n className=\"pointer-events-none [&>svg]:block [&>svg]:size-full\"\n >\n {children}\n </motion.span>\n );\n}\n\nfunction wrapRevealIcon(\n icon: Slottable,\n position: \"prefix\" | \"suffix\",\n size: ButtonSize,\n): ReactNode | undefined {\n if (icon == null || icon === false) return undefined;\n if (isReactComponent(icon)) {\n const Icon = icon;\n return (\n <RevealSlot position={position} size={size}>\n <Icon />\n </RevealSlot>\n );\n }\n if (isValidElement(icon)) {\n return (\n <RevealSlot position={position} size={size}>\n {icon}\n </RevealSlot>\n );\n }\n return (\n <RevealSlot position={position} size={size}>\n {icon}\n </RevealSlot>\n );\n}\n\nfunction buttonInner({\n svgOnly,\n loading,\n prefix,\n suffix,\n children,\n iconReveal,\n size,\n}: Pick<\n ButtonBaseProps,\n | \"svgOnly\"\n | \"loading\"\n | \"prefix\"\n | \"suffix\"\n | \"children\"\n | \"iconReveal\"\n | \"size\"\n> & { size: ButtonSize }) {\n if (svgOnly) {\n return loading ? <Spinner /> : children;\n }\n const reveal = Boolean(iconReveal);\n return (\n <>\n {loading ? (\n <Slot position=\"loading\">\n <Spinner />\n </Slot>\n ) : reveal ? (\n wrapRevealIcon(prefix, \"prefix\", size)\n ) : (\n renderSlot(prefix, \"prefix\")\n )}\n {children != null && children !== false && (\n <span data-text className=\"transition-inherit-all\">\n {children}\n </span>\n )}\n {reveal\n ? wrapRevealIcon(suffix, \"suffix\", size)\n : renderSlot(suffix, \"suffix\")}\n </>\n );\n}\n\n/**\n * Root Motion props — press scale on every variant; sheen + icon-reveal gap\n * only when those features are on. Press composes over hover (`whileTap` >\n * `whileHover`): effect sheen inverts while the pill compresses; other\n * variants get the same scale with no sheen change. `waking` plays the\n * one-shot re-enable glint; a real hover mid-glint takes over seamlessly.\n */\nfunction buttonRootMotionProps(\n size: ButtonSize,\n inert: boolean | undefined,\n opts: { sheen: boolean; iconReveal: boolean; waking?: boolean },\n) {\n const rest: Record<string, string | number> = {\n scale: 1,\n ...(opts.sheen ? EFFECT_SHEEN_REST : {}),\n };\n const hover: Record<string, string | number> = opts.sheen\n ? { ...EFFECT_SHEEN_HOVER[size] }\n : {};\n const press: Record<string, string | number> = {\n scale: BUTTON_PRESS_SCALE,\n ...(opts.sheen ? EFFECT_SHEEN_PRESS[size] : {}),\n };\n const wake = opts.sheen\n ? { ...EFFECT_SHEEN_WAKE[size], transition: WAKE_TRANSITION }\n : {};\n if (opts.iconReveal) {\n // Collapse gap at rest so the hidden icon leaves no hole; hover opens it.\n rest.gap = 0;\n hover.gap = size === \"lg\" ? 6 : 2;\n }\n return {\n initial: false as const,\n animate: opts.waking && opts.sheen ? \"wake\" : \"rest\",\n whileHover: inert ? undefined : \"hover\",\n whileTap: inert ? undefined : \"press\",\n variants: { rest, hover, press, wake },\n transition: BUTTON_SPRING,\n };\n}\n\nfunction buttonClassName({\n variant,\n color,\n size,\n shape,\n loading,\n svgOnly,\n className,\n}: {\n variant?: ButtonVariant;\n color?: ButtonColor;\n size?: ButtonSize;\n shape?: ButtonShape;\n loading?: boolean;\n svgOnly?: boolean;\n className?: string;\n}) {\n return cn(\n buttonVariants({ variant, color, size, shape }),\n loading && \"pointer-events-none\",\n svgOnly && \"[&>svg]:size-[1.25em] [&>svg]:shrink-0\",\n className,\n );\n}\n\n/**\n * Button — triggers an action that mutates state (submit, save, delete).\n * For navigation that changes the URL, use {@link ButtonLink}.\n *\n * Default surface is `effect` (same-hue 1.5px outer rim + inset sheen). Use\n * `filled` for a solid fill without those layers. `iconReveal` springs\n * prefix/suffix icons in on hover — independent of variant.\n */\nexport function Button({\n variant = \"effect\",\n color,\n size = \"md\",\n shape,\n prefix,\n suffix,\n iconReveal = false,\n svgOnly,\n loading,\n children,\n className,\n ref,\n ...props\n}: ButtonProps) {\n warnMissingLabel(svgOnly, props[\"aria-label\"]);\n const sheen = variant === \"effect\";\n const reveal = iconReveal && !svgOnly;\n const inert = Boolean(props.disabled || loading);\n const { waking, onWakeComplete } = useWakeOnEnable(inert, sheen);\n const cls = buttonClassName({\n variant,\n color,\n size,\n shape,\n loading,\n svgOnly,\n className: cn(reveal && ICON_REVEAL_PAD_RESTORE[size], className),\n });\n const inner = buttonInner({\n svgOnly,\n loading,\n prefix,\n suffix,\n children,\n iconReveal: reveal,\n size,\n });\n\n return (\n <motion.button\n ref={ref}\n type=\"button\"\n {...buttonRootMotionProps(size, inert, {\n sheen,\n iconReveal: reveal,\n waking,\n })}\n onAnimationComplete={onWakeComplete}\n {...props}\n aria-busy={loading || undefined}\n data-loading={loading ? \"true\" : undefined}\n data-svg-only={svgOnly ? \"true\" : undefined}\n data-waking={waking || undefined}\n className={cls}\n >\n {inner}\n </motion.button>\n );\n}\n\nButton.displayName = \"Button\";\n\n/**\n * ButtonLink — a link styled as a button, for navigation that changes the URL.\n * Shares every visual prop with {@link Button}; renders the host router's link\n * via `LinkProvider`.\n */\nexport function ButtonLink({\n variant = \"effect\",\n color,\n size = \"md\",\n shape,\n prefix,\n suffix,\n iconReveal = false,\n svgOnly,\n loading,\n disabled,\n href,\n children,\n className,\n ...props\n}: ButtonLinkProps) {\n warnMissingLabel(svgOnly, props[\"aria-label\"]);\n const Link = useLinkComponent();\n const sheen = variant === \"effect\";\n const reveal = iconReveal && !svgOnly;\n const cls = buttonClassName({\n variant,\n color,\n size,\n shape,\n loading,\n svgOnly,\n className: cn(reveal && ICON_REVEAL_PAD_RESTORE[size], className),\n });\n const inner = buttonInner({\n svgOnly,\n loading,\n prefix,\n suffix,\n children,\n iconReveal: reveal,\n size,\n });\n // Hooks must run unconditionally — only used when Motion is needed.\n const MotionLink = useMemo(\n // LinkProvider requires `href`; motion.create needs an open prop record —\n // bridge the two through `unknown` (props are supplied at the call site).\n () =>\n motion.create(Link as unknown as ComponentType<Record<string, unknown>>),\n [Link],\n );\n\n const inert = Boolean(disabled || loading);\n const { waking, onWakeComplete } = useWakeOnEnable(inert, sheen);\n const shared = {\n ...props,\n ...(inert ? {} : { href }),\n \"aria-disabled\": inert || undefined,\n \"aria-busy\": loading || undefined,\n \"data-loading\": loading ? (\"true\" as const) : undefined,\n \"data-svg-only\": svgOnly ? (\"true\" as const) : undefined,\n className: cls,\n tabIndex: inert ? -1 : props.tabIndex,\n onClick: inert\n ? (event: ReactMouseEvent<HTMLAnchorElement>) => {\n event.preventDefault();\n }\n : props.onClick,\n };\n\n if (inert) {\n return <span {...shared}>{inner}</span>;\n }\n\n return (\n <MotionLink\n {...buttonRootMotionProps(size, inert, {\n sheen,\n iconReveal: reveal,\n waking,\n })}\n onAnimationComplete={onWakeComplete}\n data-waking={waking || undefined}\n {...shared}\n >\n {inner}\n </MotionLink>\n );\n}\n\nButtonLink.displayName = \"ButtonLink\";\n\n/* ======================= EffectButton (compat alias) ======================= */\n\nexport const EFFECT_BUTTON_SIZES = BUTTON_SIZES;\nexport type EffectButtonSize = ButtonSize;\n\n/** Compose classes for an effect pill — `Button` with `variant=\"effect\"`. */\nexport function effectButtonVariants(opts?: {\n size?: EffectButtonSize;\n fullWidth?: boolean;\n className?: string;\n}): string {\n const { size = \"md\", fullWidth, className } = opts ?? {};\n return buttonVariants({\n variant: \"effect\",\n size,\n className: cn(fullWidth && \"w-full\", className),\n });\n}\n\n/**\n * Legacy EffectButton also reserved `style` (sheen variables lived there) and\n * never exposed the HTML `color` attribute — Button's semantic `color` prop\n * now occupies that name.\n */\ntype MotionConflicts = MotionHandlerConflicts | \"style\" | \"color\";\n\ninterface EffectButtonBaseProps {\n /** Size variant — Button's scale (32 / 36 / 44px). @default \"md\" */\n size?: EffectButtonSize;\n /** Stretch to the container's full width (stacked login / OAuth pills). */\n fullWidth?: boolean;\n /**\n * @deprecated Use `iconReveal` on `Button` instead. Mapped to `iconReveal`\n * when set.\n */\n animated?: boolean;\n /** @see ButtonBaseProps.iconReveal */\n iconReveal?: boolean;\n prefix?: Slottable;\n suffix?: Slottable;\n svgOnly?: boolean;\n loading?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\nexport interface EffectButtonProps\n extends\n EffectButtonBaseProps,\n Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof EffectButtonBaseProps | MotionConflicts\n > {\n ref?: Ref<HTMLButtonElement>;\n}\n\nexport interface EffectButtonLinkProps\n extends\n EffectButtonBaseProps,\n Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof EffectButtonBaseProps | MotionConflicts\n > {\n href: string;\n disabled?: boolean;\n}\n\n/**\n * @deprecated Prefer `<Button variant=\"effect\">`. Thin alias that forwards to\n * Button with the sheen surface (no icon reveal).\n */\nexport function EffectButton({\n size = \"md\",\n fullWidth,\n animated,\n iconReveal,\n className,\n ...props\n}: EffectButtonProps) {\n return (\n <Button\n variant=\"effect\"\n size={size}\n iconReveal={iconReveal ?? animated ?? true}\n className={cn(fullWidth && \"w-full\", className)}\n {...props}\n />\n );\n}\n\nEffectButton.displayName = \"EffectButton\";\n\n/**\n * @deprecated Prefer `<ButtonLink variant=\"effect\">`.\n */\nexport function EffectButtonLink({\n size = \"md\",\n fullWidth,\n animated,\n iconReveal,\n className,\n ...props\n}: EffectButtonLinkProps) {\n return (\n <ButtonLink\n variant=\"effect\"\n size={size}\n iconReveal={iconReveal ?? animated ?? true}\n className={cn(fullWidth && \"w-full\", className)}\n {...props}\n />\n );\n}\n\nEffectButtonLink.displayName = \"EffectButtonLink\";\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { t as x } from "./cn-ChIgwEl3.js";
|
|
3
3
|
import { n as oe } from "./link-provider-DXzDQ08N.js";
|
|
4
4
|
import { FADE_SWAP as K, PRESS_SCALE_ROW as se, SPRING_PRESS as le, TRAVEL_LINEAR as ce } from "../motion.js";
|
|
5
|
-
import { a as z } from "./button-
|
|
5
|
+
import { a as z } from "./button-C9VqBBIr.js";
|
|
6
6
|
import { t as I } from "./createReactComponent-BqCmnqfX.js";
|
|
7
7
|
import { t as de } from "./input-DjvZoF8v.js";
|
|
8
8
|
import { n as B } from "./avatar-BkmGDIqf.js";
|
|
@@ -616,4 +616,4 @@ export {
|
|
|
616
616
|
wt as t
|
|
617
617
|
};
|
|
618
618
|
|
|
619
|
-
//# sourceMappingURL=chat-
|
|
619
|
+
//# sourceMappingURL=chat-B0WIgEyM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-BXjycPi9.js","names":["__iconNode","__iconNode","__iconNode"],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowLeft.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowUp.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconUser.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconUsers.mjs","../../src/components/chat/chat.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.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\": \"M5 12l14 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M5 12l6 6\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M5 12l6 -6\", \"key\": \"svg-2\" }]];\nconst IconArrowLeft = createReactComponent(\"outline\", \"arrow-left\", \"ArrowLeft\", __iconNode);\n\nexport { __iconNode, IconArrowLeft as default };\n//# sourceMappingURL=IconArrowLeft.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.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\": \"M12 5l0 14\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M18 11l-6 -6\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M6 11l6 -6\", \"key\": \"svg-2\" }]];\nconst IconArrowUp = createReactComponent(\"outline\", \"arrow-up\", \"ArrowUp\", __iconNode);\n\nexport { __iconNode, IconArrowUp as default };\n//# sourceMappingURL=IconArrowUp.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.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\": \"M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2\", \"key\": \"svg-1\" }]];\nconst IconUser = createReactComponent(\"outline\", \"user\", \"User\", __iconNode);\n\nexport { __iconNode, IconUser as default };\n//# sourceMappingURL=IconUser.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.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\": \"M5 7a4 4 0 1 0 8 0a4 4 0 1 0 -8 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M3 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M16 3.13a4 4 0 0 1 0 7.75\", \"key\": \"svg-2\" }], [\"path\", { \"d\": \"M21 21v-2a4 4 0 0 0 -3 -3.85\", \"key\": \"svg-3\" }]];\nconst IconUsers = createReactComponent(\"outline\", \"users\", \"Users\", __iconNode);\n\nexport { __iconNode, IconUsers as default };\n//# sourceMappingURL=IconUsers.mjs.map\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ButtonHTMLAttributes,\n type CSSProperties,\n type ComponentProps,\n type ComponentType,\n type FormEvent,\n type KeyboardEvent,\n type PointerEvent,\n type ReactNode,\n type Ref,\n type RefObject,\n} from \"react\";\nimport {\n IconArrowLeft,\n IconArrowUp,\n IconSearch,\n IconUser,\n IconUsers,\n} from \"@tabler/icons-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n BLUR_PX,\n FADE_SWAP,\n PRESS_SCALE_ROW,\n SPRING_PRESS,\n TRAVEL_LINEAR,\n} from \"../../motion\";\nimport { Avatar } from \"../avatar\";\nimport { Button } from \"../button\";\nimport { Input, type InputProps } from \"../input\";\nimport { ScrollArea } from \"../scroll-area\";\nimport { Skeleton } from \"../skeleton\";\nimport { StatusView, type StatusViewProps } from \"../status-view\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/**\n * Chat — an inbox in one card: the conversations down the left, the open\n * thread on the right with its messages scrolling up from the composer.\n * It composes the smaller parts (`Message` rows of `Bubble`s in a\n * `ScrollArea`, an `Input` for search, `Button`s to send and go back) the\n * way `Sidebar` composes a rail: rows that press, one active, links\n * through the host's `LinkProvider`.\n *\n * Two layouts. `default` seats both panes side by side — the divider\n * between them drags so either pane can grow, each down to a min width.\n * `compact` shows one at a time — the list, then the thread with a way\n * back — for a narrow column or a phone. Opening a conversation pushes\n * the thread in from the right; back pops the list in from the left, a\n * short drift on `TRAVEL_LINEAR` with a `FADE_SWAP` fade. `auto` is\n * compact only while the frame is narrower than 42rem (a container\n * query, so it follows the card, not the viewport). Which pane is up is\n * `pane`, controlled or not; opening a conversation moves to the thread,\n * the header's back button returns.\n *\n * Presentational, like every Pho part: the page fetches, formats times,\n * and decides who is who. The thread stays pinned to its newest message\n * while the reader is at the bottom, and keeps its place when earlier\n * pages arrive above.\n */\n\nexport type ChatLayout = \"default\" | \"compact\" | \"auto\";\nexport type ChatPane = \"list\" | \"thread\";\n/** Push is 1 (thread from the right); pop is −1 (list from the left). */\nexport type ChatPaneDirection = 1 | -1;\n\n/** Same chrome as `BasicPage.Card` and `LogList` — one card surface. */\nconst CHAT_SURFACE = \"rounded-base border border-pho-secondary bg-pho-primary\";\n\n// Below this frame width `auto` is compact: the `@2xl` container variant\n// (42rem) in the class strings below. Those variants are spelled out in\n// full on purpose — Tailwind finds utilities by scanning source text, so\n// a variant built from a variable (`${AUTO_WIDE}` before the colon) never\n// reached a consumer's CSS and `auto` stayed single-pane at every width.\n// chat.test.tsx keeps it that way.\n/** `42rem` in px at the 16px root — `frameWidth` is measured in px. */\nconst AUTO_WIDE_PX = 672;\n/**\n * Compact pane travel — a short drift, the same scale as `BAR_RISE_PX`,\n * not a full-width slide.\n */\nconst PANE_TRAVEL_PX = 24;\n/** Outgoing pane drift — same distance as BasicPage `BACK_LABEL_LEAVE_X`. */\nconst PANE_LEAVE_PX = 8;\n\n/** Search (`p-3` + sm Input) is the pane top-bar height; Header matches it. */\nconst TOP_BAR = \"min-h-[61px]\";\n\n/**\n * Wide layouts start the list at 273 — the measured inbox column, not\n * `w-80`. It will not go below `min-w-64` (256); the thread will not go\n * below `min-w-80` (320).\n */\nconst LIST_WIDTH_PX = 273;\nconst LIST_MIN_PX = 256;\nconst THREAD_MIN_PX = 320;\nconst SPLIT_STEP_PX = 16;\n\nfunction clampListWidth(width: number, rootWidth: number) {\n const next = Math.max(LIST_MIN_PX, width);\n if (rootWidth <= 0) return Number.isFinite(next) ? next : LIST_MIN_PX;\n return Math.min(next, Math.max(LIST_MIN_PX, rootWidth - THREAD_MIN_PX));\n}\n\ninterface ChatContextValue {\n layout: ChatLayout;\n pane: ChatPane;\n setPane: (pane: ChatPane) => void;\n /** Latest list ↔ thread step: 1 push, −1 pop. */\n direction: ChatPaneDirection;\n /** One pane at a time — compact, or `auto` once the frame measures narrow. */\n swap: boolean;\n /** True after the first list ↔ thread step — later remounts still push. */\n swapped: boolean;\n listWidth: number;\n frameWidth: number;\n resizeList: (width: number) => void;\n rootRef: RefObject<HTMLDivElement | null>;\n}\n\nconst ChatContext = createContext<ChatContextValue | null>(null);\n\nfunction useChat(part: string): ChatContextValue {\n const ctx = useContext(ChatContext);\n if (ctx == null) {\n throw new Error(`Chat.${part} must be used inside Chat.Root`);\n }\n return ctx;\n}\n\n// React 18 warns that useLayoutEffect does nothing on the server; fall\n// back to useEffect there so SSR'd docs stay quiet.\nconst useIsoLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nfunction paneDirectionFor(pane: ChatPane): ChatPaneDirection {\n return pane === \"thread\" ? 1 : -1;\n}\n\n/**\n * Compact (and `auto` once the frame measures narrower than 42rem) mounts\n * one pane at a time so `AnimatePresence` can push/pop. `frameWidth` 0 is\n * the unmeasured / SSR frame — treat it as wide so both panes render and\n * nothing flashes.\n */\nfunction isPaneSwap(layout: ChatLayout, frameWidth: number) {\n return (\n layout === \"compact\" ||\n (layout === \"auto\" && frameWidth > 0 && frameWidth < AUTO_WIDE_PX)\n );\n}\n\n/**\n * The compact pane swap — incoming travels `PANE_TRAVEL_PX` on\n * `TRAVEL_LINEAR`, fades and breathes `BLUR_PX` on `FADE_SWAP`; outgoing\n * drifts `PANE_LEAVE_PX` the other way. Under reduced motion: opacity\n * only, and instant.\n */\nexport function paneSwapMotion(\n direction: ChatPaneDirection,\n reduceMotion?: boolean | null,\n) {\n if (reduceMotion) {\n return {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: { duration: 0 },\n };\n }\n return {\n initial: {\n x: direction * PANE_TRAVEL_PX,\n opacity: 0,\n filter: `blur(${BLUR_PX}px)`,\n },\n animate: { x: 0, opacity: 1, filter: \"blur(0px)\" },\n exit: {\n x: -direction * PANE_LEAVE_PX,\n opacity: 0,\n filter: `blur(${BLUR_PX}px)`,\n },\n transition: { x: TRAVEL_LINEAR, opacity: FADE_SWAP, filter: FADE_SWAP },\n };\n}\n\nfunction paneSwapVariants(reduceMotion: boolean | null) {\n return {\n enter: (direction: ChatPaneDirection) =>\n paneSwapMotion(direction, reduceMotion).initial,\n rest: (direction: ChatPaneDirection) =>\n paneSwapMotion(direction, reduceMotion).animate,\n leave: (direction: ChatPaneDirection) =>\n paneSwapMotion(direction, reduceMotion).exit,\n };\n}\n\n/**\n * DOM handlers whose React signatures clash with Motion's gesture props.\n * Same omit list as `Button` — swap panes and conversation rows render\n * through `motion.*`.\n */\ntype MotionHandlerConflicts =\n | \"onAnimationStart\"\n | \"onAnimationEnd\"\n | \"onAnimationIteration\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onDragEnter\"\n | \"onDragExit\"\n | \"onDragLeave\"\n | \"onDragOver\"\n | \"onDrop\";\n\ntype SwapPaneProps = {\n show: boolean;\n swapped: boolean;\n direction: ChatPaneDirection;\n reduceMotion: boolean | null;\n children?: ReactNode;\n} & (\n | ({ as: \"aside\" } & Omit<\n ComponentProps<\"aside\">,\n \"children\" | MotionHandlerConflicts\n >)\n | ({ as: \"section\" } & Omit<\n ComponentProps<\"section\">,\n \"children\" | MotionHandlerConflicts\n >)\n);\n\ntype SwapMotionProps = {\n custom: ChatPaneDirection;\n variants: ReturnType<typeof paneSwapVariants>;\n initial: \"enter\";\n animate: \"rest\";\n exit: \"leave\";\n transition: ReturnType<typeof paneSwapMotion>[\"transition\"];\n};\n\n/**\n * The compact face — Root's `AnimatePresence` keys list vs thread. `custom`\n * on that presence feeds this step's push/pop into the exiting face.\n */\nfunction SwapPane({\n as,\n show,\n swapped,\n direction,\n reduceMotion,\n children,\n ...props\n}: SwapPaneProps) {\n const swap = paneSwapMotion(direction, reduceMotion);\n const motionProps: SwapMotionProps = {\n custom: direction,\n variants: paneSwapVariants(reduceMotion),\n initial: \"enter\",\n animate: \"rest\",\n exit: \"leave\",\n transition: swap.transition,\n };\n // Skip the first paint only before any pane change — a Thread that\n // remounts (host `key`) on the way in still pushes.\n return (\n <AnimatePresence\n initial={!swapped && show ? false : undefined}\n mode=\"popLayout\"\n custom={direction}\n >\n {show ? (\n as === \"aside\" ? (\n <motion.aside key=\"list\" {...props} {...motionProps}>\n {children}\n </motion.aside>\n ) : (\n <motion.section key=\"thread\" {...props} {...motionProps}>\n {children}\n </motion.section>\n )\n ) : null}\n </AnimatePresence>\n );\n}\n\n/* --------------------------------- root --------------------------------- */\n\nexport interface ChatRootProps extends ComponentProps<\"div\"> {\n /**\n * `default` shows both panes; `compact` one at a time; `auto` is\n * compact while the frame is narrower than 42rem.\n * @default \"default\"\n */\n layout?: ChatLayout;\n /** The pane that is up in a compact layout. Pair with `onPaneChange`. */\n pane?: ChatPane;\n /** Initial pane when uncontrolled. @default \"list\" */\n defaultPane?: ChatPane;\n /** Called with the next pane — a row opened a thread, back was pressed. */\n onPaneChange?: (pane: ChatPane) => void;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * The card. Give it a height (`h-[32rem]`, or `min-h-0 flex-1` in a\n * column that fills the page); the panes scroll inside it.\n */\nfunction Root({\n layout = \"default\",\n pane: paneProp,\n defaultPane = \"list\",\n onPaneChange,\n className,\n style,\n ref,\n ...props\n}: ChatRootProps) {\n const [uncontrolledPane, setUncontrolledPane] = useState(defaultPane);\n const [listWidth, setListWidth] = useState(LIST_WIDTH_PX);\n const [frameWidth, setFrameWidth] = useState(0);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const controlled = paneProp !== undefined;\n const pane = controlled ? paneProp : uncontrolledPane;\n const [direction, setDirection] = useState<ChatPaneDirection>(() =>\n paneDirectionFor(pane),\n );\n const [swapped, setSwapped] = useState(false);\n const prevPaneRef = useRef(pane);\n // Keep this render's direction aligned with `pane` so a controlled\n // update and a `setPane` call both push/pop on the same frame.\n let renderedDirection = direction;\n let renderedSwapped = swapped;\n if (prevPaneRef.current !== pane) {\n renderedDirection = paneDirectionFor(pane);\n renderedSwapped = true;\n prevPaneRef.current = pane;\n if (renderedDirection !== direction) setDirection(renderedDirection);\n if (!swapped) setSwapped(true);\n }\n const setPane = useCallback(\n (next: ChatPane) => {\n setDirection(paneDirectionFor(next));\n if (!controlled) setUncontrolledPane(next);\n onPaneChange?.(next);\n },\n [controlled, onPaneChange],\n );\n const resizeList = useCallback((width: number) => {\n setListWidth(clampListWidth(width, rootRef.current?.clientWidth ?? 0));\n }, []);\n const swap = isPaneSwap(layout, frameWidth);\n useIsoLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || typeof ResizeObserver === \"undefined\") return;\n const tighten = () => {\n const frame = root.clientWidth;\n setFrameWidth(frame);\n setListWidth((current) => clampListWidth(current, frame));\n };\n tighten();\n const observer = new ResizeObserver(tighten);\n observer.observe(root);\n return () => observer.disconnect();\n }, []);\n const value = useMemo(\n () => ({\n layout,\n pane,\n setPane,\n direction: renderedDirection,\n swap,\n swapped: renderedSwapped,\n listWidth,\n frameWidth,\n resizeList,\n rootRef,\n }),\n [\n layout,\n pane,\n setPane,\n renderedDirection,\n swap,\n renderedSwapped,\n listWidth,\n frameWidth,\n resizeList,\n ],\n );\n return (\n <ChatContext.Provider value={value}>\n <div\n ref={(node) => {\n rootRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) {\n (ref as { current: HTMLDivElement | null }).current = node;\n }\n }}\n data-chat=\"\"\n data-basic-page-card=\"\"\n data-layout={layout}\n data-pane={pane}\n style={\n {\n ...style,\n \"--chat-list-width\": `${listWidth}px`,\n } as CSSProperties\n }\n className={cn(\n CHAT_SURFACE,\n \"@container relative flex min-h-0 min-w-0 overflow-hidden\",\n className,\n )}\n {...props}\n />\n </ChatContext.Provider>\n );\n}\n\n/* --------------------------------- list --------------------------------- */\n\n/** The left pane — search above, conversations below, on the page wash. */\nfunction List({\n className,\n children,\n id: idProp,\n ...props\n}: ComponentProps<\"aside\">) {\n const { layout, pane, direction, swap, swapped } = useChat(\"List\");\n const reduceMotion = useReducedMotion();\n const uid = useId();\n const listId = idProp ?? uid;\n const listClass = cn(\n \"border-pho-secondary bg-pho-page relative z-10 flex min-h-0 shrink-0 flex-col\",\n layout === \"default\" && \"min-w-64 w-[var(--chat-list-width)] border-r\",\n layout === \"compact\" && \"w-full\",\n layout === \"auto\" &&\n cn(\n \"w-full @2xl:min-w-64 @2xl:w-[var(--chat-list-width)] @2xl:border-r\",\n !swap && pane === \"thread\" && \"@max-2xl:hidden\",\n ),\n className,\n );\n const body = (\n <>\n {children}\n {layout !== \"compact\" && <Splitter controlsId={listId} />}\n </>\n );\n const rest = {\n id: listId,\n \"aria-label\": \"Conversations\",\n \"data-chat-list\": \"\",\n className: listClass,\n ...props,\n };\n if (!swap) {\n return <aside {...rest}>{body}</aside>;\n }\n return (\n <SwapPane\n as=\"aside\"\n show={pane === \"list\"}\n swapped={swapped}\n direction={direction}\n reduceMotion={reduceMotion}\n {...rest}\n >\n {body}\n </SwapPane>\n );\n}\n\n/**\n * The drag between the panes — a focusable separator. Hidden in\n * `compact`, and in `auto` while the frame is narrow.\n */\nfunction Splitter({ controlsId }: { controlsId: string }) {\n const { layout, listWidth, frameWidth, resizeList, rootRef } =\n useChat(\"Splitter\");\n const drag = useRef<{ x: number; width: number } | null>(null);\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n event.currentTarget.setPointerCapture?.(event.pointerId);\n drag.current = { x: event.clientX, width: listWidth };\n };\n\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const start = drag.current;\n if (start == null) return;\n const root = rootRef.current;\n const rtl = root != null && getComputedStyle(root).direction === \"rtl\";\n const delta = (event.clientX - start.x) * (rtl ? -1 : 1);\n resizeList(start.width + delta);\n };\n\n const onPointerUp = () => {\n drag.current = null;\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const root = rootRef.current;\n const rtl = root != null && getComputedStyle(root).direction === \"rtl\";\n const shrink = rtl ? \"ArrowRight\" : \"ArrowLeft\";\n const grow = rtl ? \"ArrowLeft\" : \"ArrowRight\";\n const step = event.shiftKey ? SPLIT_STEP_PX * 2 : SPLIT_STEP_PX;\n if (event.key === shrink) {\n event.preventDefault();\n resizeList(listWidth - step);\n } else if (event.key === grow) {\n event.preventDefault();\n resizeList(listWidth + step);\n } else if (event.key === \"Home\") {\n event.preventDefault();\n resizeList(LIST_MIN_PX);\n } else if (event.key === \"End\") {\n event.preventDefault();\n const frame = root?.clientWidth ?? 0;\n if (frame > 0) resizeList(frame - THREAD_MIN_PX);\n }\n };\n\n const valueMax =\n frameWidth > 0\n ? Math.max(LIST_MIN_PX, frameWidth - THREAD_MIN_PX)\n : listWidth;\n\n return (\n <div\n // WAI-ARIA window splitter: a focusable separator with a value. An\n // `hr` can neither take focus nor carry the value attributes.\n // oxlint-disable-next-line jsx-a11y/prefer-tag-over-role\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize conversation list\"\n aria-controls={controlsId}\n aria-valuenow={listWidth}\n aria-valuemin={LIST_MIN_PX}\n aria-valuemax={valueMax}\n aria-valuetext={`${listWidth} pixels`}\n tabIndex={0}\n data-chat-splitter=\"\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n onKeyDown={onKeyDown}\n className={cn(\n \"absolute inset-y-0 -right-3 z-10 w-6 cursor-col-resize touch-none select-none\",\n \"outline-pho-brand focus-visible:outline-2 focus-visible:-outline-offset-2\",\n \"after:absolute after:inset-y-0 after:left-1/2 after:w-px after:-translate-x-1/2 after:bg-transparent\",\n \"[@media(hover:hover)]:hover:after:bg-pho-brand focus-visible:after:bg-pho-brand\",\n layout === \"auto\" && \"@max-2xl:hidden\",\n )}\n />\n );\n}\n\nexport interface ChatSearchProps extends Omit<\n InputProps,\n \"size\" | \"icon\" | \"label\" | \"hint\" | \"labelTrailing\"\n> {}\n\n/** The search row pinned over the conversations — an `sm` `Input`. */\nfunction Search({\n className,\n placeholder = \"Search\",\n ...props\n}: ChatSearchProps) {\n return (\n <div data-chat-search=\"\" className={cn(\"p-3\", TOP_BAR, className)}>\n <Input\n size=\"sm\"\n icon={IconSearch}\n placeholder={placeholder}\n aria-label=\"Search conversations\"\n autoComplete=\"off\"\n spellCheck={false}\n {...props}\n />\n </div>\n );\n}\n\n/**\n * The scrolling part of the list. Put a `ConversationList` in it — or a\n * `ConversationsLoading`, an `Empty` — and anything that belongs after\n * the rows (a load-older button).\n */\nfunction Conversations({\n className,\n children,\n ...props\n}: ComponentProps<\"div\">) {\n return (\n <div\n data-chat-conversations=\"\"\n className={cn(\"flex min-h-0 flex-1 flex-col\", className)}\n {...props}\n >\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content\n // Base UI sets `minWidth: fit-content` on Content; a long\n // title must truncate, not widen the pane.\n style={{ minWidth: 0 }}\n // Same horizontal rail as Sidebar sm (`px-3`): the selected\n // chip sits in the page wash instead of kissing the aside.\n className=\"flex min-h-full flex-col px-3 py-1\"\n >\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </div>\n );\n}\n\n/** The rows. */\nfunction ConversationList({ className, ...props }: ComponentProps<\"ul\">) {\n return (\n <ul\n data-chat-conversation-list=\"\"\n // list-none/m-0/p-0 shield the rows from host prose styles.\n className={cn(\"m-0 flex list-none flex-col gap-0.5 *:m-0\", className)}\n {...props}\n />\n );\n}\n\n/* ------------------------------ conversation ---------------------------- */\n\n/**\n * DOM handlers whose React signatures clash with Motion's gesture props.\n * Same omit list as `Button` — rows render through `motion.*`.\n */\ninterface ConversationBaseProps {\n /** Who — a number, a name, the members of a group. */\n title: ReactNode;\n /** When — the page's relative time (`2d ago`), trailing. */\n time?: ReactNode;\n /** The latest message, one truncated line. */\n preview?: ReactNode;\n /** Replace the default avatar (a person, or people for a `group`). */\n avatar?: ReactNode;\n /** A group conversation — the default avatar shows people. */\n group?: boolean;\n /** The open conversation. */\n active?: boolean;\n className?: string;\n}\n\nexport interface ChatConversationLinkProps\n extends\n ConversationBaseProps,\n Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof ConversationBaseProps | MotionHandlerConflicts\n > {\n /** Destination — rendered through the host's `LinkProvider`. */\n href: string;\n}\n\nexport interface ChatConversationButtonProps\n extends\n ConversationBaseProps,\n Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof ConversationBaseProps | MotionHandlerConflicts\n > {\n href?: undefined;\n}\n\nexport type ChatConversationProps =\n ChatConversationLinkProps | ChatConversationButtonProps;\n\n/** The row at rest, on hover, and while open — one pointer target. */\nconst CONVERSATION_ROW =\n \"outline-pho-brand rounded-base flex w-full cursor-pointer items-center gap-3 px-2 py-2.5 text-left transition-colors focus-visible:outline-2 focus-visible:-outline-offset-1\";\n/**\n * Open row — same chip as `Sidebar.Item` current (`aria-current=page`).\n * Weight lives on the title span, not here: time and preview stay Regular.\n */\nconst CONVERSATION_ROW_ACTIVE =\n \"bg-pho-primary text-pho-primary ring-pho-secondary ring-1 ring-inset *:data-icon:text-pho-primary\";\nconst CONVERSATION_ROW_INACTIVE = \"hover:bg-pho-ghost-hover\";\n\nconst CONVERSATION_PRESS = {\n initial: false as const,\n whileTap: { scale: PRESS_SCALE_ROW },\n transition: SPRING_PRESS,\n};\n\n/**\n * One conversation — a link when `href` is given (through the host's\n * `LinkProvider`), otherwise a button. Opening it in a compact layout\n * brings the thread up.\n */\nfunction Conversation({\n title,\n time,\n preview,\n avatar,\n group,\n active,\n className,\n href,\n onClick,\n ...rest\n}: ChatConversationProps) {\n const { layout, setPane } = useChat(\"Conversation\");\n const Link = useLinkComponent();\n // Same bridge as `Sidebar.Item` — host `LinkProvider` + Motion press.\n const MotionLink = useMemo(\n () =>\n motion.create(Link as unknown as ComponentType<Record<string, unknown>>),\n [Link],\n );\n const rowClass = cn(\n CONVERSATION_ROW,\n active ? CONVERSATION_ROW_ACTIVE : CONVERSATION_ROW_INACTIVE,\n className,\n );\n const open = () => {\n if (layout !== \"default\") setPane(\"thread\");\n };\n const body = (\n <>\n {avatar ?? (\n <Avatar.Root size=\"sm\">\n <Avatar.Fallback>\n {group ? (\n <IconUsers className=\"size-4\" aria-hidden />\n ) : (\n <IconUser className=\"size-4\" aria-hidden />\n )}\n </Avatar.Fallback>\n </Avatar.Root>\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-pho-primary min-w-0 truncate text-base font-medium\">\n {title}\n </span>\n {time != null && (\n <span className=\"text-pho-description shrink-0 text-xs font-normal whitespace-nowrap tabular-nums\">\n {time}\n </span>\n )}\n </span>\n {preview != null && (\n <span className=\"text-pho-description mt-0.5 block min-w-0 truncate text-xs font-normal\">\n {preview}\n </span>\n )}\n </span>\n </>\n );\n\n if (href !== undefined) {\n return (\n <li>\n <MotionLink\n href={href}\n aria-current={active ? \"page\" : undefined}\n {...(rest as AnchorHTMLAttributes<HTMLAnchorElement>)}\n onClick={(event: React.MouseEvent<HTMLAnchorElement>) => {\n (onClick as AnchorHTMLAttributes<HTMLAnchorElement>[\"onClick\"])?.(\n event,\n );\n if (!event.defaultPrevented) open();\n }}\n className={rowClass}\n {...CONVERSATION_PRESS}\n >\n {body}\n </MotionLink>\n </li>\n );\n }\n\n return (\n <li>\n <motion.button\n type=\"button\"\n aria-current={active ? \"true\" : undefined}\n {...(rest as Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n MotionHandlerConflicts\n >)}\n onClick={(event) => {\n (onClick as ButtonHTMLAttributes<HTMLButtonElement>[\"onClick\"])?.(\n event,\n );\n if (!event.defaultPrevented) open();\n }}\n className={rowClass}\n {...CONVERSATION_PRESS}\n >\n {body}\n </motion.button>\n </li>\n );\n}\n\n/* -------------------------------- thread -------------------------------- */\n\n/** The right pane — header, messages, and the docked footer, on the card. */\nfunction Thread({ className, children, ...props }: ComponentProps<\"section\">) {\n const { layout, pane, direction, swap, swapped } = useChat(\"Thread\");\n const reduceMotion = useReducedMotion();\n const threadClass = cn(\n \"bg-pho-primary flex min-h-0 flex-1 flex-col\",\n layout === \"default\" && \"min-w-80\",\n layout === \"compact\" && \"min-w-0\",\n layout === \"auto\" && \"min-w-0 @2xl:min-w-80\",\n !swap && layout === \"auto\" && pane === \"list\" && \"@max-2xl:hidden\",\n className,\n );\n if (!swap) {\n return (\n <section\n aria-label=\"Conversation\"\n data-chat-thread=\"\"\n className={threadClass}\n {...props}\n >\n {children}\n </section>\n );\n }\n return (\n <SwapPane\n as=\"section\"\n show={pane === \"thread\"}\n swapped={swapped}\n direction={direction}\n reduceMotion={reduceMotion}\n aria-label=\"Conversation\"\n data-chat-thread=\"\"\n className={threadClass}\n {...props}\n >\n {children}\n </SwapPane>\n );\n}\n\nexport interface ChatHeaderProps extends ComponentProps<\"header\"> {\n /** The other side's avatar — an `Avatar.Root`. */\n avatar?: ReactNode;\n /** Controls at the trailing edge — a details button, a menu. */\n actions?: ReactNode;\n /** The back button's accessible name. @default \"Back to conversations\" */\n backLabel?: string;\n}\n\n/**\n * Who the thread is with. Children are a `Title` and a `Description`.\n * In a compact layout a back button leads the row; `auto` shows it only\n * while the frame is narrow.\n */\nfunction Header({\n avatar,\n actions,\n backLabel = \"Back to conversations\",\n className,\n children,\n ...props\n}: ChatHeaderProps) {\n const { layout, setPane } = useChat(\"Header\");\n return (\n <header\n data-chat-header=\"\"\n className={cn(\n \"flex shrink-0 items-center gap-3 px-4 py-1.5\",\n TOP_BAR,\n className,\n )}\n {...props}\n >\n {layout !== \"default\" && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n shape=\"circle\"\n svgOnly\n aria-label={backLabel}\n data-chat-back=\"\"\n className={cn(\"-ml-1 shrink-0\", layout === \"auto\" && \"@2xl:hidden\")}\n onClick={() => setPane(\"list\")}\n >\n <IconArrowLeft />\n </Button>\n )}\n {avatar}\n <div className=\"flex min-w-0 flex-1 flex-col\">{children}</div>\n {actions != null && (\n <div className=\"flex shrink-0 items-center gap-1\">{actions}</div>\n )}\n </header>\n );\n}\n\n/** The other side's name. Inline extras (a copy button, a badge) sit after it. */\nfunction Title({ className, children, ...props }: ComponentProps<\"h2\">) {\n return (\n <h2\n data-chat-title=\"\"\n className={cn(\n \"text-pho-primary m-0 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-0.5 overflow-visible text-base font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/** One line under the title — from whom, a status. */\nfunction Description({ className, ...props }: ComponentProps<\"p\">) {\n return (\n <p\n data-chat-description=\"\"\n className={cn(\n \"text-pho-description m-0 min-w-0 truncate text-xs\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/* ------------------------------- messages ------------------------------- */\n\n/** Within this many px of the bottom the pane counts as pinned. */\nconst PIN_SLACK_PX = 40;\n\nexport interface ChatMessagesProps extends ComponentProps<\"div\"> {\n /** Earlier pages exist — a button at the top asks for them. */\n hasEarlier?: boolean;\n /** The earlier page is on its way. */\n loadingEarlier?: boolean;\n /** Ask for the page before the first message shown. */\n onLoadEarlier?: () => void;\n /** The button's label. @default \"Load earlier messages\" */\n earlierLabel?: ReactNode;\n}\n\n/**\n * The messages, oldest to newest, on the thread surface. The pane starts at\n * the bottom and stays there as messages arrive unless the reader has\n * scrolled up; an earlier page keeps what they were reading in place.\n * Children are `Message` rows and `Divider`s.\n */\nfunction Messages({\n hasEarlier = false,\n loadingEarlier = false,\n onLoadEarlier,\n earlierLabel = \"Load earlier messages\",\n className,\n children,\n ...props\n}: ChatMessagesProps) {\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const pinned = useRef(true);\n const anchor = useRef<{ height: number; top: number } | null>(null);\n\n useIsoLayoutEffect(() => {\n const viewport = viewportRef.current;\n const content = contentRef.current;\n if (!viewport || !content) return;\n const settle = () => {\n const kept = anchor.current;\n if (kept) {\n anchor.current = null;\n viewport.scrollTop = viewport.scrollHeight - kept.height + kept.top;\n return;\n }\n if (pinned.current) viewport.scrollTop = viewport.scrollHeight;\n };\n settle();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(settle);\n observer.observe(content);\n observer.observe(viewport);\n return () => observer.disconnect();\n }, []);\n\n const onScroll = () => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n pinned.current =\n viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <\n PIN_SLACK_PX;\n };\n\n const loadEarlier = () => {\n const viewport = viewportRef.current;\n if (viewport) {\n anchor.current = {\n height: viewport.scrollHeight,\n top: viewport.scrollTop,\n };\n }\n pinned.current = false;\n onLoadEarlier?.();\n };\n\n return (\n <div\n data-chat-messages=\"\"\n className={cn(\n // Bubbles' focus and selected rings offset against the thread.\n \"flex min-h-0 flex-1 flex-col [--pho-bubble-backdrop:var(--background-color-pho-primary)]\",\n className,\n )}\n {...props}\n >\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport ref={viewportRef} onScroll={onScroll}>\n <ScrollArea.Content\n ref={contentRef}\n style={{ minWidth: 0 }}\n className=\"flex min-h-full flex-col gap-1 p-4\"\n >\n {hasEarlier && (\n <div className=\"flex justify-center\">\n <Button\n variant=\"outlined\"\n size=\"sm\"\n loading={loadingEarlier}\n onClick={loadEarlier}\n >\n {earlierLabel}\n </Button>\n </div>\n )}\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </div>\n );\n}\n\n/** A centered caption in the thread — the day, \"Unread\". */\nfunction Divider({ className, children, ...props }: ComponentProps<\"div\">) {\n return (\n <div\n data-chat-divider=\"\"\n className={cn(\"text-pho-description py-1 text-center text-xs\", className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\n/* -------------------------------- footer -------------------------------- */\n\n/** The docked bar under the messages — usually a `Composer`. */\nfunction Footer({ className, ...props }: ComponentProps<\"footer\">) {\n return (\n <footer\n data-chat-footer=\"\"\n className={cn(\"shrink-0 px-4 py-3\", className)}\n {...props}\n />\n );\n}\n\n/** The draft box grows with the text up to this, then scrolls. */\nconst COMPOSER_MAX_HEIGHT_PX = 200;\n\nexport interface ChatComposerProps extends Omit<\n ComponentProps<\"form\">,\n \"onSubmit\" | \"prefix\" | \"children\"\n> {\n /** The draft. */\n value: string;\n onValueChange: (value: string) => void;\n /** Enter, or the send button. Not called while `sending` or with nothing to send. */\n onSend: () => void;\n placeholder?: string;\n /** The send is in flight — the button spins, the box waits. */\n sending?: boolean;\n disabled?: boolean;\n /**\n * There is something to send besides text (an attachment). By default\n * the send button wakes when the draft has a non-blank character.\n */\n canSend?: boolean;\n /** Controls at the start of the bottom row — an add-attachment button. */\n prefix?: ReactNode;\n /** A quiet line between `prefix` and the send button — a count, a size. */\n meta?: ReactNode;\n /** The send button's accessible name. @default \"Send\" */\n sendLabel?: string;\n /** Above the text — attachment thumbnails. */\n children?: ReactNode;\n /** The `<textarea>`. */\n textareaRef?: Ref<HTMLTextAreaElement>;\n}\n\n/**\n * The message box: text that grows with the draft, Enter to send and\n * Shift+Enter for a new line, one round send button. Attachments are the\n * page's: put their thumbnails in `children`, the button that adds them\n * in `prefix`, and flip `canSend` when they alone should send.\n */\nfunction Composer({\n value,\n onValueChange,\n onSend,\n placeholder = \"Message\",\n sending = false,\n disabled = false,\n canSend,\n prefix,\n meta,\n sendLabel = \"Send\",\n children,\n textareaRef,\n className,\n ...props\n}: ChatComposerProps) {\n const innerRef = useRef<HTMLTextAreaElement | null>(null);\n const ready = !sending && !disabled && (canSend ?? value.trim().length > 0);\n\n useIsoLayoutEffect(() => {\n const element = innerRef.current;\n if (!element) return;\n element.style.height = \"0px\";\n element.style.height = `${Math.min(element.scrollHeight, COMPOSER_MAX_HEIGHT_PX)}px`;\n }, [value]);\n\n const submit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (ready) onSend();\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (\n event.key === \"Enter\" &&\n !event.shiftKey &&\n !event.nativeEvent.isComposing\n ) {\n event.preventDefault();\n if (ready) onSend();\n }\n };\n\n return (\n <form\n aria-label=\"Message composer\"\n data-chat-composer=\"\"\n onSubmit={submit}\n className={cn(\n // The field surface, as `Input`: hairline at rest, brand ring while\n // anything inside has focus.\n \"rounded-base bg-pho-primary ring-pho-primary focus-within:ring-pho-brand ring-1 transition-shadow duration-100 ease-linear ring-inset focus-within:ring-2\",\n disabled && \"opacity-50\",\n className,\n )}\n {...props}\n >\n {children}\n <textarea\n ref={(node) => {\n innerRef.current = node;\n if (typeof textareaRef === \"function\") textareaRef(node);\n else if (textareaRef) {\n (textareaRef as { current: HTMLTextAreaElement | null }).current =\n node;\n }\n }}\n value={value}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={onKeyDown}\n rows={1}\n placeholder={placeholder}\n aria-label=\"Message\"\n disabled={disabled}\n // In flight the box holds its text but stays focusable — `disabled`\n // would drop focus mid-send; `ready` already blocks a second send.\n readOnly={sending}\n className=\"text-pho-primary placeholder:text-pho-placeholder m-0 block w-full resize-none bg-transparent px-4 pt-3 pb-1 text-base outline-none disabled:cursor-not-allowed\"\n />\n <div className=\"flex items-center gap-2 px-2 pb-2\">\n {prefix}\n <p className=\"text-pho-description m-0 min-w-0 flex-1 truncate text-xs\">\n {meta}\n </p>\n <Button\n type=\"submit\"\n size=\"sm\"\n shape=\"circle\"\n svgOnly\n aria-label={sendLabel}\n disabled={!ready}\n loading={sending}\n >\n <IconArrowUp />\n </Button>\n </div>\n </form>\n );\n}\n\n/* --------------------------------- states ------------------------------- */\n\nexport interface ChatEmptyProps extends StatusViewProps {}\n\n/**\n * The standing-in view for either pane — no conversations, no thread\n * chosen, nothing said yet. `StatusView` at card size, centered in\n * whatever room the pane has.\n */\nfunction Empty({ className, size = \"sm\", ...props }: ChatEmptyProps) {\n return (\n <div\n data-chat-empty=\"\"\n className={cn(\n \"flex flex-1 flex-col items-center justify-center px-6 py-8\",\n className,\n )}\n >\n <StatusView size={size} {...props} />\n </div>\n );\n}\n\n/** Bones in the shape of conversation rows — avatar, who, when, preview. */\nfunction ConversationsLoading({ rows = 5 }: { rows?: number }) {\n return (\n <div\n aria-hidden\n data-chat-conversations-loading=\"\"\n className=\"flex flex-col gap-0.5\"\n >\n {Array.from({ length: rows }, (_, row) => (\n <div key={row} className=\"flex items-center gap-3 px-2 py-2.5\">\n <Skeleton className=\"size-8 shrink-0 rounded-full\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <Skeleton className=\"h-3.5 w-32\" />\n <Skeleton className=\"h-2.5 w-8\" />\n </div>\n <Skeleton className=\"mt-2 h-2.5 w-44\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\n/** Bones in a thread's shape — theirs left, ours right. */\nfunction MessagesLoading() {\n return (\n <div\n aria-hidden\n data-chat-messages-loading=\"\"\n className=\"flex flex-col gap-3\"\n >\n <Skeleton className=\"rounded-base h-10 w-1/2 self-start\" />\n <Skeleton className=\"rounded-base h-10 w-2/5 self-end\" />\n <Skeleton className=\"rounded-base h-16 w-3/5 self-start\" />\n </div>\n );\n}\n\n/**\n * The composed inbox. Assemble the two panes and fill them:\n *\n * ```tsx\n * <Chat.Root layout=\"auto\" className=\"h-[32rem]\">\n * <Chat.List>\n * <Chat.Search value={query} onChange={…} />\n * <Chat.Conversations>\n * <Chat.ConversationList>\n * <Chat.Conversation title=\"+1 (315) 997-8332\" time=\"2d ago\" preview=\"…\" active />\n * </Chat.ConversationList>\n * </Chat.Conversations>\n * </Chat.List>\n * <Chat.Thread>\n * <Chat.Header avatar={<Avatar.Root size=\"md\">…</Avatar.Root>}>\n * <Chat.Title>+1 (315) 997-8332</Chat.Title>\n * <Chat.Description>From …</Chat.Description>\n * </Chat.Header>\n * <Chat.Messages>\n * <Chat.Divider>September 12</Chat.Divider>\n * <Message.Root>…</Message.Root>\n * </Chat.Messages>\n * <Chat.Footer>\n * <Chat.Composer value={draft} onValueChange={setDraft} onSend={send} />\n * </Chat.Footer>\n * </Chat.Thread>\n * </Chat.Root>\n * ```\n */\nexport const Chat = {\n Root,\n List,\n Search,\n Conversations,\n ConversationList,\n Conversation,\n Thread,\n Header,\n Title,\n Description,\n Messages,\n Divider,\n Footer,\n Composer,\n Empty,\n ConversationsLoading,\n MessagesLoading,\n};\n"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chat-B0WIgEyM.js","names":["__iconNode","__iconNode","__iconNode"],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowLeft.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowUp.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconUser.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconUsers.mjs","../../src/components/chat/chat.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.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\": \"M5 12l14 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M5 12l6 6\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M5 12l6 -6\", \"key\": \"svg-2\" }]];\nconst IconArrowLeft = createReactComponent(\"outline\", \"arrow-left\", \"ArrowLeft\", __iconNode);\n\nexport { __iconNode, IconArrowLeft as default };\n//# sourceMappingURL=IconArrowLeft.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.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\": \"M12 5l0 14\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M18 11l-6 -6\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M6 11l6 -6\", \"key\": \"svg-2\" }]];\nconst IconArrowUp = createReactComponent(\"outline\", \"arrow-up\", \"ArrowUp\", __iconNode);\n\nexport { __iconNode, IconArrowUp as default };\n//# sourceMappingURL=IconArrowUp.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.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\": \"M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2\", \"key\": \"svg-1\" }]];\nconst IconUser = createReactComponent(\"outline\", \"user\", \"User\", __iconNode);\n\nexport { __iconNode, IconUser as default };\n//# sourceMappingURL=IconUser.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.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\": \"M5 7a4 4 0 1 0 8 0a4 4 0 1 0 -8 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M3 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M16 3.13a4 4 0 0 1 0 7.75\", \"key\": \"svg-2\" }], [\"path\", { \"d\": \"M21 21v-2a4 4 0 0 0 -3 -3.85\", \"key\": \"svg-3\" }]];\nconst IconUsers = createReactComponent(\"outline\", \"users\", \"Users\", __iconNode);\n\nexport { __iconNode, IconUsers as default };\n//# sourceMappingURL=IconUsers.mjs.map\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ButtonHTMLAttributes,\n type CSSProperties,\n type ComponentProps,\n type ComponentType,\n type FormEvent,\n type KeyboardEvent,\n type PointerEvent,\n type ReactNode,\n type Ref,\n type RefObject,\n} from \"react\";\nimport {\n IconArrowLeft,\n IconArrowUp,\n IconSearch,\n IconUser,\n IconUsers,\n} from \"@tabler/icons-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport {\n BLUR_PX,\n FADE_SWAP,\n PRESS_SCALE_ROW,\n SPRING_PRESS,\n TRAVEL_LINEAR,\n} from \"../../motion\";\nimport { Avatar } from \"../avatar\";\nimport { Button } from \"../button\";\nimport { Input, type InputProps } from \"../input\";\nimport { ScrollArea } from \"../scroll-area\";\nimport { Skeleton } from \"../skeleton\";\nimport { StatusView, type StatusViewProps } from \"../status-view\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/**\n * Chat — an inbox in one card: the conversations down the left, the open\n * thread on the right with its messages scrolling up from the composer.\n * It composes the smaller parts (`Message` rows of `Bubble`s in a\n * `ScrollArea`, an `Input` for search, `Button`s to send and go back) the\n * way `Sidebar` composes a rail: rows that press, one active, links\n * through the host's `LinkProvider`.\n *\n * Two layouts. `default` seats both panes side by side — the divider\n * between them drags so either pane can grow, each down to a min width.\n * `compact` shows one at a time — the list, then the thread with a way\n * back — for a narrow column or a phone. Opening a conversation pushes\n * the thread in from the right; back pops the list in from the left, a\n * short drift on `TRAVEL_LINEAR` with a `FADE_SWAP` fade. `auto` is\n * compact only while the frame is narrower than 42rem (a container\n * query, so it follows the card, not the viewport). Which pane is up is\n * `pane`, controlled or not; opening a conversation moves to the thread,\n * the header's back button returns.\n *\n * Presentational, like every Pho part: the page fetches, formats times,\n * and decides who is who. The thread stays pinned to its newest message\n * while the reader is at the bottom, and keeps its place when earlier\n * pages arrive above.\n */\n\nexport type ChatLayout = \"default\" | \"compact\" | \"auto\";\nexport type ChatPane = \"list\" | \"thread\";\n/** Push is 1 (thread from the right); pop is −1 (list from the left). */\nexport type ChatPaneDirection = 1 | -1;\n\n/** Same chrome as `BasicPage.Card` and `LogList` — one card surface. */\nconst CHAT_SURFACE = \"rounded-base border border-pho-secondary bg-pho-primary\";\n\n// Below this frame width `auto` is compact: the `@2xl` container variant\n// (42rem) in the class strings below. Those variants are spelled out in\n// full on purpose — Tailwind finds utilities by scanning source text, so\n// a variant built from a variable (`${AUTO_WIDE}` before the colon) never\n// reached a consumer's CSS and `auto` stayed single-pane at every width.\n// chat.test.tsx keeps it that way.\n/** `42rem` in px at the 16px root — `frameWidth` is measured in px. */\nconst AUTO_WIDE_PX = 672;\n/**\n * Compact pane travel — a short drift, the same scale as `BAR_RISE_PX`,\n * not a full-width slide.\n */\nconst PANE_TRAVEL_PX = 24;\n/** Outgoing pane drift — same distance as BasicPage `BACK_LABEL_LEAVE_X`. */\nconst PANE_LEAVE_PX = 8;\n\n/** Search (`p-3` + sm Input) is the pane top-bar height; Header matches it. */\nconst TOP_BAR = \"min-h-[61px]\";\n\n/**\n * Wide layouts start the list at 273 — the measured inbox column, not\n * `w-80`. It will not go below `min-w-64` (256); the thread will not go\n * below `min-w-80` (320).\n */\nconst LIST_WIDTH_PX = 273;\nconst LIST_MIN_PX = 256;\nconst THREAD_MIN_PX = 320;\nconst SPLIT_STEP_PX = 16;\n\nfunction clampListWidth(width: number, rootWidth: number) {\n const next = Math.max(LIST_MIN_PX, width);\n if (rootWidth <= 0) return Number.isFinite(next) ? next : LIST_MIN_PX;\n return Math.min(next, Math.max(LIST_MIN_PX, rootWidth - THREAD_MIN_PX));\n}\n\ninterface ChatContextValue {\n layout: ChatLayout;\n pane: ChatPane;\n setPane: (pane: ChatPane) => void;\n /** Latest list ↔ thread step: 1 push, −1 pop. */\n direction: ChatPaneDirection;\n /** One pane at a time — compact, or `auto` once the frame measures narrow. */\n swap: boolean;\n /** True after the first list ↔ thread step — later remounts still push. */\n swapped: boolean;\n listWidth: number;\n frameWidth: number;\n resizeList: (width: number) => void;\n rootRef: RefObject<HTMLDivElement | null>;\n}\n\nconst ChatContext = createContext<ChatContextValue | null>(null);\n\nfunction useChat(part: string): ChatContextValue {\n const ctx = useContext(ChatContext);\n if (ctx == null) {\n throw new Error(`Chat.${part} must be used inside Chat.Root`);\n }\n return ctx;\n}\n\n// React 18 warns that useLayoutEffect does nothing on the server; fall\n// back to useEffect there so SSR'd docs stay quiet.\nconst useIsoLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nfunction paneDirectionFor(pane: ChatPane): ChatPaneDirection {\n return pane === \"thread\" ? 1 : -1;\n}\n\n/**\n * Compact (and `auto` once the frame measures narrower than 42rem) mounts\n * one pane at a time so `AnimatePresence` can push/pop. `frameWidth` 0 is\n * the unmeasured / SSR frame — treat it as wide so both panes render and\n * nothing flashes.\n */\nfunction isPaneSwap(layout: ChatLayout, frameWidth: number) {\n return (\n layout === \"compact\" ||\n (layout === \"auto\" && frameWidth > 0 && frameWidth < AUTO_WIDE_PX)\n );\n}\n\n/**\n * The compact pane swap — incoming travels `PANE_TRAVEL_PX` on\n * `TRAVEL_LINEAR`, fades and breathes `BLUR_PX` on `FADE_SWAP`; outgoing\n * drifts `PANE_LEAVE_PX` the other way. Under reduced motion: opacity\n * only, and instant.\n */\nexport function paneSwapMotion(\n direction: ChatPaneDirection,\n reduceMotion?: boolean | null,\n) {\n if (reduceMotion) {\n return {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: { duration: 0 },\n };\n }\n return {\n initial: {\n x: direction * PANE_TRAVEL_PX,\n opacity: 0,\n filter: `blur(${BLUR_PX}px)`,\n },\n animate: { x: 0, opacity: 1, filter: \"blur(0px)\" },\n exit: {\n x: -direction * PANE_LEAVE_PX,\n opacity: 0,\n filter: `blur(${BLUR_PX}px)`,\n },\n transition: { x: TRAVEL_LINEAR, opacity: FADE_SWAP, filter: FADE_SWAP },\n };\n}\n\nfunction paneSwapVariants(reduceMotion: boolean | null) {\n return {\n enter: (direction: ChatPaneDirection) =>\n paneSwapMotion(direction, reduceMotion).initial,\n rest: (direction: ChatPaneDirection) =>\n paneSwapMotion(direction, reduceMotion).animate,\n leave: (direction: ChatPaneDirection) =>\n paneSwapMotion(direction, reduceMotion).exit,\n };\n}\n\n/**\n * DOM handlers whose React signatures clash with Motion's gesture props.\n * Same omit list as `Button` — swap panes and conversation rows render\n * through `motion.*`.\n */\ntype MotionHandlerConflicts =\n | \"onAnimationStart\"\n | \"onAnimationEnd\"\n | \"onAnimationIteration\"\n | \"onDrag\"\n | \"onDragStart\"\n | \"onDragEnd\"\n | \"onDragEnter\"\n | \"onDragExit\"\n | \"onDragLeave\"\n | \"onDragOver\"\n | \"onDrop\";\n\ntype SwapPaneProps = {\n show: boolean;\n swapped: boolean;\n direction: ChatPaneDirection;\n reduceMotion: boolean | null;\n children?: ReactNode;\n} & (\n | ({ as: \"aside\" } & Omit<\n ComponentProps<\"aside\">,\n \"children\" | MotionHandlerConflicts\n >)\n | ({ as: \"section\" } & Omit<\n ComponentProps<\"section\">,\n \"children\" | MotionHandlerConflicts\n >)\n);\n\ntype SwapMotionProps = {\n custom: ChatPaneDirection;\n variants: ReturnType<typeof paneSwapVariants>;\n initial: \"enter\";\n animate: \"rest\";\n exit: \"leave\";\n transition: ReturnType<typeof paneSwapMotion>[\"transition\"];\n};\n\n/**\n * The compact face — Root's `AnimatePresence` keys list vs thread. `custom`\n * on that presence feeds this step's push/pop into the exiting face.\n */\nfunction SwapPane({\n as,\n show,\n swapped,\n direction,\n reduceMotion,\n children,\n ...props\n}: SwapPaneProps) {\n const swap = paneSwapMotion(direction, reduceMotion);\n const motionProps: SwapMotionProps = {\n custom: direction,\n variants: paneSwapVariants(reduceMotion),\n initial: \"enter\",\n animate: \"rest\",\n exit: \"leave\",\n transition: swap.transition,\n };\n // Skip the first paint only before any pane change — a Thread that\n // remounts (host `key`) on the way in still pushes.\n return (\n <AnimatePresence\n initial={!swapped && show ? false : undefined}\n mode=\"popLayout\"\n custom={direction}\n >\n {show ? (\n as === \"aside\" ? (\n <motion.aside key=\"list\" {...props} {...motionProps}>\n {children}\n </motion.aside>\n ) : (\n <motion.section key=\"thread\" {...props} {...motionProps}>\n {children}\n </motion.section>\n )\n ) : null}\n </AnimatePresence>\n );\n}\n\n/* --------------------------------- root --------------------------------- */\n\nexport interface ChatRootProps extends ComponentProps<\"div\"> {\n /**\n * `default` shows both panes; `compact` one at a time; `auto` is\n * compact while the frame is narrower than 42rem.\n * @default \"default\"\n */\n layout?: ChatLayout;\n /** The pane that is up in a compact layout. Pair with `onPaneChange`. */\n pane?: ChatPane;\n /** Initial pane when uncontrolled. @default \"list\" */\n defaultPane?: ChatPane;\n /** Called with the next pane — a row opened a thread, back was pressed. */\n onPaneChange?: (pane: ChatPane) => void;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * The card. Give it a height (`h-[32rem]`, or `min-h-0 flex-1` in a\n * column that fills the page); the panes scroll inside it.\n */\nfunction Root({\n layout = \"default\",\n pane: paneProp,\n defaultPane = \"list\",\n onPaneChange,\n className,\n style,\n ref,\n ...props\n}: ChatRootProps) {\n const [uncontrolledPane, setUncontrolledPane] = useState(defaultPane);\n const [listWidth, setListWidth] = useState(LIST_WIDTH_PX);\n const [frameWidth, setFrameWidth] = useState(0);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const controlled = paneProp !== undefined;\n const pane = controlled ? paneProp : uncontrolledPane;\n const [direction, setDirection] = useState<ChatPaneDirection>(() =>\n paneDirectionFor(pane),\n );\n const [swapped, setSwapped] = useState(false);\n const prevPaneRef = useRef(pane);\n // Keep this render's direction aligned with `pane` so a controlled\n // update and a `setPane` call both push/pop on the same frame.\n let renderedDirection = direction;\n let renderedSwapped = swapped;\n if (prevPaneRef.current !== pane) {\n renderedDirection = paneDirectionFor(pane);\n renderedSwapped = true;\n prevPaneRef.current = pane;\n if (renderedDirection !== direction) setDirection(renderedDirection);\n if (!swapped) setSwapped(true);\n }\n const setPane = useCallback(\n (next: ChatPane) => {\n setDirection(paneDirectionFor(next));\n if (!controlled) setUncontrolledPane(next);\n onPaneChange?.(next);\n },\n [controlled, onPaneChange],\n );\n const resizeList = useCallback((width: number) => {\n setListWidth(clampListWidth(width, rootRef.current?.clientWidth ?? 0));\n }, []);\n const swap = isPaneSwap(layout, frameWidth);\n useIsoLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || typeof ResizeObserver === \"undefined\") return;\n const tighten = () => {\n const frame = root.clientWidth;\n setFrameWidth(frame);\n setListWidth((current) => clampListWidth(current, frame));\n };\n tighten();\n const observer = new ResizeObserver(tighten);\n observer.observe(root);\n return () => observer.disconnect();\n }, []);\n const value = useMemo(\n () => ({\n layout,\n pane,\n setPane,\n direction: renderedDirection,\n swap,\n swapped: renderedSwapped,\n listWidth,\n frameWidth,\n resizeList,\n rootRef,\n }),\n [\n layout,\n pane,\n setPane,\n renderedDirection,\n swap,\n renderedSwapped,\n listWidth,\n frameWidth,\n resizeList,\n ],\n );\n return (\n <ChatContext.Provider value={value}>\n <div\n ref={(node) => {\n rootRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) {\n (ref as { current: HTMLDivElement | null }).current = node;\n }\n }}\n data-chat=\"\"\n data-basic-page-card=\"\"\n data-layout={layout}\n data-pane={pane}\n style={\n {\n ...style,\n \"--chat-list-width\": `${listWidth}px`,\n } as CSSProperties\n }\n className={cn(\n CHAT_SURFACE,\n \"@container relative flex min-h-0 min-w-0 overflow-hidden\",\n className,\n )}\n {...props}\n />\n </ChatContext.Provider>\n );\n}\n\n/* --------------------------------- list --------------------------------- */\n\n/** The left pane — search above, conversations below, on the page wash. */\nfunction List({\n className,\n children,\n id: idProp,\n ...props\n}: ComponentProps<\"aside\">) {\n const { layout, pane, direction, swap, swapped } = useChat(\"List\");\n const reduceMotion = useReducedMotion();\n const uid = useId();\n const listId = idProp ?? uid;\n const listClass = cn(\n \"border-pho-secondary bg-pho-page relative z-10 flex min-h-0 shrink-0 flex-col\",\n layout === \"default\" && \"min-w-64 w-[var(--chat-list-width)] border-r\",\n layout === \"compact\" && \"w-full\",\n layout === \"auto\" &&\n cn(\n \"w-full @2xl:min-w-64 @2xl:w-[var(--chat-list-width)] @2xl:border-r\",\n !swap && pane === \"thread\" && \"@max-2xl:hidden\",\n ),\n className,\n );\n const body = (\n <>\n {children}\n {layout !== \"compact\" && <Splitter controlsId={listId} />}\n </>\n );\n const rest = {\n id: listId,\n \"aria-label\": \"Conversations\",\n \"data-chat-list\": \"\",\n className: listClass,\n ...props,\n };\n if (!swap) {\n return <aside {...rest}>{body}</aside>;\n }\n return (\n <SwapPane\n as=\"aside\"\n show={pane === \"list\"}\n swapped={swapped}\n direction={direction}\n reduceMotion={reduceMotion}\n {...rest}\n >\n {body}\n </SwapPane>\n );\n}\n\n/**\n * The drag between the panes — a focusable separator. Hidden in\n * `compact`, and in `auto` while the frame is narrow.\n */\nfunction Splitter({ controlsId }: { controlsId: string }) {\n const { layout, listWidth, frameWidth, resizeList, rootRef } =\n useChat(\"Splitter\");\n const drag = useRef<{ x: number; width: number } | null>(null);\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n if (event.button !== 0) return;\n event.currentTarget.setPointerCapture?.(event.pointerId);\n drag.current = { x: event.clientX, width: listWidth };\n };\n\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const start = drag.current;\n if (start == null) return;\n const root = rootRef.current;\n const rtl = root != null && getComputedStyle(root).direction === \"rtl\";\n const delta = (event.clientX - start.x) * (rtl ? -1 : 1);\n resizeList(start.width + delta);\n };\n\n const onPointerUp = () => {\n drag.current = null;\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const root = rootRef.current;\n const rtl = root != null && getComputedStyle(root).direction === \"rtl\";\n const shrink = rtl ? \"ArrowRight\" : \"ArrowLeft\";\n const grow = rtl ? \"ArrowLeft\" : \"ArrowRight\";\n const step = event.shiftKey ? SPLIT_STEP_PX * 2 : SPLIT_STEP_PX;\n if (event.key === shrink) {\n event.preventDefault();\n resizeList(listWidth - step);\n } else if (event.key === grow) {\n event.preventDefault();\n resizeList(listWidth + step);\n } else if (event.key === \"Home\") {\n event.preventDefault();\n resizeList(LIST_MIN_PX);\n } else if (event.key === \"End\") {\n event.preventDefault();\n const frame = root?.clientWidth ?? 0;\n if (frame > 0) resizeList(frame - THREAD_MIN_PX);\n }\n };\n\n const valueMax =\n frameWidth > 0\n ? Math.max(LIST_MIN_PX, frameWidth - THREAD_MIN_PX)\n : listWidth;\n\n return (\n <div\n // WAI-ARIA window splitter: a focusable separator with a value. An\n // `hr` can neither take focus nor carry the value attributes.\n // oxlint-disable-next-line jsx-a11y/prefer-tag-over-role\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize conversation list\"\n aria-controls={controlsId}\n aria-valuenow={listWidth}\n aria-valuemin={LIST_MIN_PX}\n aria-valuemax={valueMax}\n aria-valuetext={`${listWidth} pixels`}\n tabIndex={0}\n data-chat-splitter=\"\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n onKeyDown={onKeyDown}\n className={cn(\n \"absolute inset-y-0 -right-3 z-10 w-6 cursor-col-resize touch-none select-none\",\n \"outline-pho-brand focus-visible:outline-2 focus-visible:-outline-offset-2\",\n \"after:absolute after:inset-y-0 after:left-1/2 after:w-px after:-translate-x-1/2 after:bg-transparent\",\n \"[@media(hover:hover)]:hover:after:bg-pho-brand focus-visible:after:bg-pho-brand\",\n layout === \"auto\" && \"@max-2xl:hidden\",\n )}\n />\n );\n}\n\nexport interface ChatSearchProps extends Omit<\n InputProps,\n \"size\" | \"icon\" | \"label\" | \"hint\" | \"labelTrailing\"\n> {}\n\n/** The search row pinned over the conversations — an `sm` `Input`. */\nfunction Search({\n className,\n placeholder = \"Search\",\n ...props\n}: ChatSearchProps) {\n return (\n <div data-chat-search=\"\" className={cn(\"p-3\", TOP_BAR, className)}>\n <Input\n size=\"sm\"\n icon={IconSearch}\n placeholder={placeholder}\n aria-label=\"Search conversations\"\n autoComplete=\"off\"\n spellCheck={false}\n {...props}\n />\n </div>\n );\n}\n\n/**\n * The scrolling part of the list. Put a `ConversationList` in it — or a\n * `ConversationsLoading`, an `Empty` — and anything that belongs after\n * the rows (a load-older button).\n */\nfunction Conversations({\n className,\n children,\n ...props\n}: ComponentProps<\"div\">) {\n return (\n <div\n data-chat-conversations=\"\"\n className={cn(\"flex min-h-0 flex-1 flex-col\", className)}\n {...props}\n >\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content\n // Base UI sets `minWidth: fit-content` on Content; a long\n // title must truncate, not widen the pane.\n style={{ minWidth: 0 }}\n // Same horizontal rail as Sidebar sm (`px-3`): the selected\n // chip sits in the page wash instead of kissing the aside.\n className=\"flex min-h-full flex-col px-3 py-1\"\n >\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </div>\n );\n}\n\n/** The rows. */\nfunction ConversationList({ className, ...props }: ComponentProps<\"ul\">) {\n return (\n <ul\n data-chat-conversation-list=\"\"\n // list-none/m-0/p-0 shield the rows from host prose styles.\n className={cn(\"m-0 flex list-none flex-col gap-0.5 *:m-0\", className)}\n {...props}\n />\n );\n}\n\n/* ------------------------------ conversation ---------------------------- */\n\n/**\n * DOM handlers whose React signatures clash with Motion's gesture props.\n * Same omit list as `Button` — rows render through `motion.*`.\n */\ninterface ConversationBaseProps {\n /** Who — a number, a name, the members of a group. */\n title: ReactNode;\n /** When — the page's relative time (`2d ago`), trailing. */\n time?: ReactNode;\n /** The latest message, one truncated line. */\n preview?: ReactNode;\n /** Replace the default avatar (a person, or people for a `group`). */\n avatar?: ReactNode;\n /** A group conversation — the default avatar shows people. */\n group?: boolean;\n /** The open conversation. */\n active?: boolean;\n className?: string;\n}\n\nexport interface ChatConversationLinkProps\n extends\n ConversationBaseProps,\n Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n keyof ConversationBaseProps | MotionHandlerConflicts\n > {\n /** Destination — rendered through the host's `LinkProvider`. */\n href: string;\n}\n\nexport interface ChatConversationButtonProps\n extends\n ConversationBaseProps,\n Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n keyof ConversationBaseProps | MotionHandlerConflicts\n > {\n href?: undefined;\n}\n\nexport type ChatConversationProps =\n ChatConversationLinkProps | ChatConversationButtonProps;\n\n/** The row at rest, on hover, and while open — one pointer target. */\nconst CONVERSATION_ROW =\n \"outline-pho-brand rounded-base flex w-full cursor-pointer items-center gap-3 px-2 py-2.5 text-left transition-colors focus-visible:outline-2 focus-visible:-outline-offset-1\";\n/**\n * Open row — same chip as `Sidebar.Item` current (`aria-current=page`).\n * Weight lives on the title span, not here: time and preview stay Regular.\n */\nconst CONVERSATION_ROW_ACTIVE =\n \"bg-pho-primary text-pho-primary ring-pho-secondary ring-1 ring-inset *:data-icon:text-pho-primary\";\nconst CONVERSATION_ROW_INACTIVE = \"hover:bg-pho-ghost-hover\";\n\nconst CONVERSATION_PRESS = {\n initial: false as const,\n whileTap: { scale: PRESS_SCALE_ROW },\n transition: SPRING_PRESS,\n};\n\n/**\n * One conversation — a link when `href` is given (through the host's\n * `LinkProvider`), otherwise a button. Opening it in a compact layout\n * brings the thread up.\n */\nfunction Conversation({\n title,\n time,\n preview,\n avatar,\n group,\n active,\n className,\n href,\n onClick,\n ...rest\n}: ChatConversationProps) {\n const { layout, setPane } = useChat(\"Conversation\");\n const Link = useLinkComponent();\n // Same bridge as `Sidebar.Item` — host `LinkProvider` + Motion press.\n const MotionLink = useMemo(\n () =>\n motion.create(Link as unknown as ComponentType<Record<string, unknown>>),\n [Link],\n );\n const rowClass = cn(\n CONVERSATION_ROW,\n active ? CONVERSATION_ROW_ACTIVE : CONVERSATION_ROW_INACTIVE,\n className,\n );\n const open = () => {\n if (layout !== \"default\") setPane(\"thread\");\n };\n const body = (\n <>\n {avatar ?? (\n <Avatar.Root size=\"sm\">\n <Avatar.Fallback>\n {group ? (\n <IconUsers className=\"size-4\" aria-hidden />\n ) : (\n <IconUser className=\"size-4\" aria-hidden />\n )}\n </Avatar.Fallback>\n </Avatar.Root>\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-pho-primary min-w-0 truncate text-base font-medium\">\n {title}\n </span>\n {time != null && (\n <span className=\"text-pho-description shrink-0 text-xs font-normal whitespace-nowrap tabular-nums\">\n {time}\n </span>\n )}\n </span>\n {preview != null && (\n <span className=\"text-pho-description mt-0.5 block min-w-0 truncate text-xs font-normal\">\n {preview}\n </span>\n )}\n </span>\n </>\n );\n\n if (href !== undefined) {\n return (\n <li>\n <MotionLink\n href={href}\n aria-current={active ? \"page\" : undefined}\n {...(rest as AnchorHTMLAttributes<HTMLAnchorElement>)}\n onClick={(event: React.MouseEvent<HTMLAnchorElement>) => {\n (onClick as AnchorHTMLAttributes<HTMLAnchorElement>[\"onClick\"])?.(\n event,\n );\n if (!event.defaultPrevented) open();\n }}\n className={rowClass}\n {...CONVERSATION_PRESS}\n >\n {body}\n </MotionLink>\n </li>\n );\n }\n\n return (\n <li>\n <motion.button\n type=\"button\"\n aria-current={active ? \"true\" : undefined}\n {...(rest as Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n MotionHandlerConflicts\n >)}\n onClick={(event) => {\n (onClick as ButtonHTMLAttributes<HTMLButtonElement>[\"onClick\"])?.(\n event,\n );\n if (!event.defaultPrevented) open();\n }}\n className={rowClass}\n {...CONVERSATION_PRESS}\n >\n {body}\n </motion.button>\n </li>\n );\n}\n\n/* -------------------------------- thread -------------------------------- */\n\n/** The right pane — header, messages, and the docked footer, on the card. */\nfunction Thread({ className, children, ...props }: ComponentProps<\"section\">) {\n const { layout, pane, direction, swap, swapped } = useChat(\"Thread\");\n const reduceMotion = useReducedMotion();\n const threadClass = cn(\n \"bg-pho-primary flex min-h-0 flex-1 flex-col\",\n layout === \"default\" && \"min-w-80\",\n layout === \"compact\" && \"min-w-0\",\n layout === \"auto\" && \"min-w-0 @2xl:min-w-80\",\n !swap && layout === \"auto\" && pane === \"list\" && \"@max-2xl:hidden\",\n className,\n );\n if (!swap) {\n return (\n <section\n aria-label=\"Conversation\"\n data-chat-thread=\"\"\n className={threadClass}\n {...props}\n >\n {children}\n </section>\n );\n }\n return (\n <SwapPane\n as=\"section\"\n show={pane === \"thread\"}\n swapped={swapped}\n direction={direction}\n reduceMotion={reduceMotion}\n aria-label=\"Conversation\"\n data-chat-thread=\"\"\n className={threadClass}\n {...props}\n >\n {children}\n </SwapPane>\n );\n}\n\nexport interface ChatHeaderProps extends ComponentProps<\"header\"> {\n /** The other side's avatar — an `Avatar.Root`. */\n avatar?: ReactNode;\n /** Controls at the trailing edge — a details button, a menu. */\n actions?: ReactNode;\n /** The back button's accessible name. @default \"Back to conversations\" */\n backLabel?: string;\n}\n\n/**\n * Who the thread is with. Children are a `Title` and a `Description`.\n * In a compact layout a back button leads the row; `auto` shows it only\n * while the frame is narrow.\n */\nfunction Header({\n avatar,\n actions,\n backLabel = \"Back to conversations\",\n className,\n children,\n ...props\n}: ChatHeaderProps) {\n const { layout, setPane } = useChat(\"Header\");\n return (\n <header\n data-chat-header=\"\"\n className={cn(\n \"flex shrink-0 items-center gap-3 px-4 py-1.5\",\n TOP_BAR,\n className,\n )}\n {...props}\n >\n {layout !== \"default\" && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n shape=\"circle\"\n svgOnly\n aria-label={backLabel}\n data-chat-back=\"\"\n className={cn(\"-ml-1 shrink-0\", layout === \"auto\" && \"@2xl:hidden\")}\n onClick={() => setPane(\"list\")}\n >\n <IconArrowLeft />\n </Button>\n )}\n {avatar}\n <div className=\"flex min-w-0 flex-1 flex-col\">{children}</div>\n {actions != null && (\n <div className=\"flex shrink-0 items-center gap-1\">{actions}</div>\n )}\n </header>\n );\n}\n\n/** The other side's name. Inline extras (a copy button, a badge) sit after it. */\nfunction Title({ className, children, ...props }: ComponentProps<\"h2\">) {\n return (\n <h2\n data-chat-title=\"\"\n className={cn(\n \"text-pho-primary m-0 flex min-w-0 flex-wrap items-center gap-x-2 gap-y-0.5 overflow-visible text-base font-medium\",\n className,\n )}\n {...props}\n >\n {children}\n </h2>\n );\n}\n\n/** One line under the title — from whom, a status. */\nfunction Description({ className, ...props }: ComponentProps<\"p\">) {\n return (\n <p\n data-chat-description=\"\"\n className={cn(\n \"text-pho-description m-0 min-w-0 truncate text-xs\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/* ------------------------------- messages ------------------------------- */\n\n/** Within this many px of the bottom the pane counts as pinned. */\nconst PIN_SLACK_PX = 40;\n\nexport interface ChatMessagesProps extends ComponentProps<\"div\"> {\n /** Earlier pages exist — a button at the top asks for them. */\n hasEarlier?: boolean;\n /** The earlier page is on its way. */\n loadingEarlier?: boolean;\n /** Ask for the page before the first message shown. */\n onLoadEarlier?: () => void;\n /** The button's label. @default \"Load earlier messages\" */\n earlierLabel?: ReactNode;\n}\n\n/**\n * The messages, oldest to newest, on the thread surface. The pane starts at\n * the bottom and stays there as messages arrive unless the reader has\n * scrolled up; an earlier page keeps what they were reading in place.\n * Children are `Message` rows and `Divider`s.\n */\nfunction Messages({\n hasEarlier = false,\n loadingEarlier = false,\n onLoadEarlier,\n earlierLabel = \"Load earlier messages\",\n className,\n children,\n ...props\n}: ChatMessagesProps) {\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const pinned = useRef(true);\n const anchor = useRef<{ height: number; top: number } | null>(null);\n\n useIsoLayoutEffect(() => {\n const viewport = viewportRef.current;\n const content = contentRef.current;\n if (!viewport || !content) return;\n const settle = () => {\n const kept = anchor.current;\n if (kept) {\n anchor.current = null;\n viewport.scrollTop = viewport.scrollHeight - kept.height + kept.top;\n return;\n }\n if (pinned.current) viewport.scrollTop = viewport.scrollHeight;\n };\n settle();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(settle);\n observer.observe(content);\n observer.observe(viewport);\n return () => observer.disconnect();\n }, []);\n\n const onScroll = () => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n pinned.current =\n viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight <\n PIN_SLACK_PX;\n };\n\n const loadEarlier = () => {\n const viewport = viewportRef.current;\n if (viewport) {\n anchor.current = {\n height: viewport.scrollHeight,\n top: viewport.scrollTop,\n };\n }\n pinned.current = false;\n onLoadEarlier?.();\n };\n\n return (\n <div\n data-chat-messages=\"\"\n className={cn(\n // Bubbles' focus and selected rings offset against the thread.\n \"flex min-h-0 flex-1 flex-col [--pho-bubble-backdrop:var(--background-color-pho-primary)]\",\n className,\n )}\n {...props}\n >\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport ref={viewportRef} onScroll={onScroll}>\n <ScrollArea.Content\n ref={contentRef}\n style={{ minWidth: 0 }}\n className=\"flex min-h-full flex-col gap-1 p-4\"\n >\n {hasEarlier && (\n <div className=\"flex justify-center\">\n <Button\n variant=\"outlined\"\n size=\"sm\"\n loading={loadingEarlier}\n onClick={loadEarlier}\n >\n {earlierLabel}\n </Button>\n </div>\n )}\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </div>\n );\n}\n\n/** A centered caption in the thread — the day, \"Unread\". */\nfunction Divider({ className, children, ...props }: ComponentProps<\"div\">) {\n return (\n <div\n data-chat-divider=\"\"\n className={cn(\"text-pho-description py-1 text-center text-xs\", className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\n/* -------------------------------- footer -------------------------------- */\n\n/** The docked bar under the messages — usually a `Composer`. */\nfunction Footer({ className, ...props }: ComponentProps<\"footer\">) {\n return (\n <footer\n data-chat-footer=\"\"\n className={cn(\"shrink-0 px-4 py-3\", className)}\n {...props}\n />\n );\n}\n\n/** The draft box grows with the text up to this, then scrolls. */\nconst COMPOSER_MAX_HEIGHT_PX = 200;\n\nexport interface ChatComposerProps extends Omit<\n ComponentProps<\"form\">,\n \"onSubmit\" | \"prefix\" | \"children\"\n> {\n /** The draft. */\n value: string;\n onValueChange: (value: string) => void;\n /** Enter, or the send button. Not called while `sending` or with nothing to send. */\n onSend: () => void;\n placeholder?: string;\n /** The send is in flight — the button spins, the box waits. */\n sending?: boolean;\n disabled?: boolean;\n /**\n * There is something to send besides text (an attachment). By default\n * the send button wakes when the draft has a non-blank character.\n */\n canSend?: boolean;\n /** Controls at the start of the bottom row — an add-attachment button. */\n prefix?: ReactNode;\n /** A quiet line between `prefix` and the send button — a count, a size. */\n meta?: ReactNode;\n /** The send button's accessible name. @default \"Send\" */\n sendLabel?: string;\n /** Above the text — attachment thumbnails. */\n children?: ReactNode;\n /** The `<textarea>`. */\n textareaRef?: Ref<HTMLTextAreaElement>;\n}\n\n/**\n * The message box: text that grows with the draft, Enter to send and\n * Shift+Enter for a new line, one round send button. Attachments are the\n * page's: put their thumbnails in `children`, the button that adds them\n * in `prefix`, and flip `canSend` when they alone should send.\n */\nfunction Composer({\n value,\n onValueChange,\n onSend,\n placeholder = \"Message\",\n sending = false,\n disabled = false,\n canSend,\n prefix,\n meta,\n sendLabel = \"Send\",\n children,\n textareaRef,\n className,\n ...props\n}: ChatComposerProps) {\n const innerRef = useRef<HTMLTextAreaElement | null>(null);\n const ready = !sending && !disabled && (canSend ?? value.trim().length > 0);\n\n useIsoLayoutEffect(() => {\n const element = innerRef.current;\n if (!element) return;\n element.style.height = \"0px\";\n element.style.height = `${Math.min(element.scrollHeight, COMPOSER_MAX_HEIGHT_PX)}px`;\n }, [value]);\n\n const submit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (ready) onSend();\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (\n event.key === \"Enter\" &&\n !event.shiftKey &&\n !event.nativeEvent.isComposing\n ) {\n event.preventDefault();\n if (ready) onSend();\n }\n };\n\n return (\n <form\n aria-label=\"Message composer\"\n data-chat-composer=\"\"\n onSubmit={submit}\n className={cn(\n // The field surface, as `Input`: hairline at rest, brand ring while\n // anything inside has focus.\n \"rounded-base bg-pho-primary ring-pho-primary focus-within:ring-pho-brand ring-1 transition-shadow duration-100 ease-linear ring-inset focus-within:ring-2\",\n disabled && \"opacity-50\",\n className,\n )}\n {...props}\n >\n {children}\n <textarea\n ref={(node) => {\n innerRef.current = node;\n if (typeof textareaRef === \"function\") textareaRef(node);\n else if (textareaRef) {\n (textareaRef as { current: HTMLTextAreaElement | null }).current =\n node;\n }\n }}\n value={value}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={onKeyDown}\n rows={1}\n placeholder={placeholder}\n aria-label=\"Message\"\n disabled={disabled}\n // In flight the box holds its text but stays focusable — `disabled`\n // would drop focus mid-send; `ready` already blocks a second send.\n readOnly={sending}\n className=\"text-pho-primary placeholder:text-pho-placeholder m-0 block w-full resize-none bg-transparent px-4 pt-3 pb-1 text-base outline-none disabled:cursor-not-allowed\"\n />\n <div className=\"flex items-center gap-2 px-2 pb-2\">\n {prefix}\n <p className=\"text-pho-description m-0 min-w-0 flex-1 truncate text-xs\">\n {meta}\n </p>\n <Button\n type=\"submit\"\n size=\"sm\"\n shape=\"circle\"\n svgOnly\n aria-label={sendLabel}\n disabled={!ready}\n loading={sending}\n >\n <IconArrowUp />\n </Button>\n </div>\n </form>\n );\n}\n\n/* --------------------------------- states ------------------------------- */\n\nexport interface ChatEmptyProps extends StatusViewProps {}\n\n/**\n * The standing-in view for either pane — no conversations, no thread\n * chosen, nothing said yet. `StatusView` at card size, centered in\n * whatever room the pane has.\n */\nfunction Empty({ className, size = \"sm\", ...props }: ChatEmptyProps) {\n return (\n <div\n data-chat-empty=\"\"\n className={cn(\n \"flex flex-1 flex-col items-center justify-center px-6 py-8\",\n className,\n )}\n >\n <StatusView size={size} {...props} />\n </div>\n );\n}\n\n/** Bones in the shape of conversation rows — avatar, who, when, preview. */\nfunction ConversationsLoading({ rows = 5 }: { rows?: number }) {\n return (\n <div\n aria-hidden\n data-chat-conversations-loading=\"\"\n className=\"flex flex-col gap-0.5\"\n >\n {Array.from({ length: rows }, (_, row) => (\n <div key={row} className=\"flex items-center gap-3 px-2 py-2.5\">\n <Skeleton className=\"size-8 shrink-0 rounded-full\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <Skeleton className=\"h-3.5 w-32\" />\n <Skeleton className=\"h-2.5 w-8\" />\n </div>\n <Skeleton className=\"mt-2 h-2.5 w-44\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\n/** Bones in a thread's shape — theirs left, ours right. */\nfunction MessagesLoading() {\n return (\n <div\n aria-hidden\n data-chat-messages-loading=\"\"\n className=\"flex flex-col gap-3\"\n >\n <Skeleton className=\"rounded-base h-10 w-1/2 self-start\" />\n <Skeleton className=\"rounded-base h-10 w-2/5 self-end\" />\n <Skeleton className=\"rounded-base h-16 w-3/5 self-start\" />\n </div>\n );\n}\n\n/**\n * The composed inbox. Assemble the two panes and fill them:\n *\n * ```tsx\n * <Chat.Root layout=\"auto\" className=\"h-[32rem]\">\n * <Chat.List>\n * <Chat.Search value={query} onChange={…} />\n * <Chat.Conversations>\n * <Chat.ConversationList>\n * <Chat.Conversation title=\"+1 (315) 997-8332\" time=\"2d ago\" preview=\"…\" active />\n * </Chat.ConversationList>\n * </Chat.Conversations>\n * </Chat.List>\n * <Chat.Thread>\n * <Chat.Header avatar={<Avatar.Root size=\"md\">…</Avatar.Root>}>\n * <Chat.Title>+1 (315) 997-8332</Chat.Title>\n * <Chat.Description>From …</Chat.Description>\n * </Chat.Header>\n * <Chat.Messages>\n * <Chat.Divider>September 12</Chat.Divider>\n * <Message.Root>…</Message.Root>\n * </Chat.Messages>\n * <Chat.Footer>\n * <Chat.Composer value={draft} onValueChange={setDraft} onSend={send} />\n * </Chat.Footer>\n * </Chat.Thread>\n * </Chat.Root>\n * ```\n */\nexport const Chat = {\n Root,\n List,\n Search,\n Conversations,\n ConversationList,\n Conversation,\n Thread,\n Header,\n Title,\n Description,\n Messages,\n Divider,\n Footer,\n Composer,\n Empty,\n ConversationsLoading,\n MessagesLoading,\n};\n"],"x_google_ignoreList":[0,1,2,3],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { t as v } from "./cn-ChIgwEl3.js";
|
|
3
|
-
import { a as V } from "./button-
|
|
3
|
+
import { a as V } from "./button-C9VqBBIr.js";
|
|
4
4
|
import { t as Y } from "./createReactComponent-BqCmnqfX.js";
|
|
5
5
|
import { n as q, t as G } from "./IconArrowsMinimize-BfPUGuCB.js";
|
|
6
6
|
import { t as Q } from "./IconChevronDown-CZilB71T.js";
|
|
@@ -194,4 +194,4 @@ export {
|
|
|
194
194
|
pe as t
|
|
195
195
|
};
|
|
196
196
|
|
|
197
|
-
//# sourceMappingURL=code-block-
|
|
197
|
+
//# sourceMappingURL=code-block-BuFfh0zH.js.map
|