@hanzo/ui 8.27.45 → 8.27.46

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.
@@ -23,6 +23,9 @@ const slot_1 = require("./slot.cjs");
23
23
  const DEFAULT_OFFSET = 4;
24
24
  const DEFAULT_SIDE = 'bottom';
25
25
  const Publish = /* @__PURE__ */ (0, react_1.createContext)(null);
26
+ /** Whether the panel this one opened from is solid. A list opened inside a solid
27
+ * panel stands on the same ground, so the pair reads as one surface. */
28
+ const Solid = /* @__PURE__ */ (0, react_1.createContext)(false);
26
29
  function Popover({ offset = DEFAULT_OFFSET, placement, ...props }) {
27
30
  const [placed, setPlaced] = (0, react_1.useState)({});
28
31
  const publish = (0, react_1.useCallback)((p) => setPlaced((prev) => ({ ...prev, ...p })), []);
@@ -34,10 +37,12 @@ const PopoverAnchor = gui_1.Popover.Anchor;
34
37
  exports.PopoverAnchor = PopoverAnchor;
35
38
  const PopoverClose = gui_1.Popover.Close;
36
39
  exports.PopoverClose = PopoverClose;
37
- const PopoverContent = ({ sideOffset = DEFAULT_OFFSET, align, ...props }) => {
40
+ const PopoverContent = ({ sideOffset = DEFAULT_OFFSET, align, solid, ...props }) => {
38
41
  const themeName = (0, portal_theme_1.useThemeName)();
39
42
  const publish = (0, react_1.useContext)(Publish);
43
+ const inherited = (0, react_1.useContext)(Solid);
44
+ const opaque = solid ?? inherited;
40
45
  (0, react_1.useEffect)(() => publish?.({ offset: sideOffset, align }), [publish, sideOffset, align]);
41
- return ((0, jsx_runtime_1.jsx)(portal_theme_1.PortalTheme, { name: themeName, children: (0, jsx_runtime_1.jsx)(gui_1.Popover.Content, { ...(0, slot_1.slot)('popover-content'), bg: "$panel", borderWidth: 1, borderColor: "$borderColor", rounded: "$4", p: "$4", width: 288, ...props }) }));
46
+ return ((0, jsx_runtime_1.jsx)(Solid.Provider, { value: opaque, children: (0, jsx_runtime_1.jsx)(portal_theme_1.PortalTheme, { name: themeName, children: (0, jsx_runtime_1.jsx)(gui_1.Popover.Content, { ...(0, slot_1.slot)('popover-content'), ...(opaque ? { 'data-material': 'solid' } : null), bg: opaque ? 'var(--popover)' : '$panel', borderWidth: 1, borderColor: "$borderColor", rounded: "$4", p: "$4", width: 288, ...props }) }) }));
42
47
  };
43
48
  exports.PopoverContent = PopoverContent;
@@ -23,7 +23,14 @@ declare const PopoverClose: typeof GuiPopover.Close;
23
23
  export type PopoverContentProps = ComponentProps<typeof GuiPopover.Content> & {
24
24
  sideOffset?: number;
25
25
  align?: Align;
26
+ /**
27
+ * Stand on the opaque `--popover` ground instead of glass. For a panel over
28
+ * something that moves, such as a menu over a streaming transcript, where the
29
+ * text behind would read through the frost. It keeps the rung's shadow and
30
+ * lit edge, and any popover opened from inside it is solid too.
31
+ */
32
+ solid?: boolean;
26
33
  };
27
- declare const PopoverContent: ({ sideOffset, align, ...props }: PopoverContentProps) => import("react").JSX.Element;
34
+ declare const PopoverContent: ({ sideOffset, align, solid, ...props }: PopoverContentProps) => import("react").JSX.Element;
28
35
  export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverClose };
29
36
  //# sourceMappingURL=popover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/popover.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,OAAO,CAAA;AAEd,OAAO,EAAS,KAAK,KAAK,EAAE,MAAM,SAAS,CAAA;AAM3C,YAAY,EAAE,KAAK,EAAE,CAAA;AAOrB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAElG,iBAAS,OAAO,CAAC,EAAE,MAAuB,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BAY9E;AAED,QAAA,MAAM,cAAc,EAAE,OAAO,UAAU,CAAC,OAA4B,CAAA;AACpE,QAAA,MAAM,aAAa,EAAE,OAAO,UAAU,CAAC,MAA0B,CAAA;AACjE,QAAA,MAAM,YAAY,EAAE,OAAO,UAAU,CAAC,KAAwB,CAAA;AAE9D,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAED,QAAA,MAAM,cAAc,oCAAsD,mBAAmB,gCAkB5F,CAAA;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/popover.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,OAAO,CAAA;AAEd,OAAO,EAAS,KAAK,KAAK,EAAE,MAAM,SAAS,CAAA;AAM3C,YAAY,EAAE,KAAK,EAAE,CAAA;AAWrB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAElG,iBAAS,OAAO,CAAC,EAAE,MAAuB,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BAY9E;AAED,QAAA,MAAM,cAAc,EAAE,OAAO,UAAU,CAAC,OAA4B,CAAA;AACpE,QAAA,MAAM,aAAa,EAAE,OAAO,UAAU,CAAC,MAA0B,CAAA;AACjE,QAAA,MAAM,YAAY,EAAE,OAAO,UAAU,CAAC,KAAwB,CAAA;AAE9D,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,UAAU,CAAC,OAAO,CAAC,GAAG;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,CAAA;IACb;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,QAAA,MAAM,cAAc,2CAA6D,mBAAmB,gCAuBnG,CAAA;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA"}
@@ -19,6 +19,9 @@ import { slot } from './slot.js';
19
19
  const DEFAULT_OFFSET = 4;
20
20
  const DEFAULT_SIDE = 'bottom';
21
21
  const Publish = /* @__PURE__ */ createContext(null);
22
+ /** Whether the panel this one opened from is solid. A list opened inside a solid
23
+ * panel stands on the same ground, so the pair reads as one surface. */
24
+ const Solid = /* @__PURE__ */ createContext(false);
22
25
  function Popover({ offset = DEFAULT_OFFSET, placement, ...props }) {
23
26
  const [placed, setPlaced] = useState({});
24
27
  const publish = useCallback((p) => setPlaced((prev) => ({ ...prev, ...p })), []);
@@ -27,11 +30,13 @@ function Popover({ offset = DEFAULT_OFFSET, placement, ...props }) {
27
30
  const PopoverTrigger = GuiPopover.Trigger;
28
31
  const PopoverAnchor = GuiPopover.Anchor;
29
32
  const PopoverClose = GuiPopover.Close;
30
- const PopoverContent = ({ sideOffset = DEFAULT_OFFSET, align, ...props }) => {
33
+ const PopoverContent = ({ sideOffset = DEFAULT_OFFSET, align, solid, ...props }) => {
31
34
  const themeName = useThemeName();
32
35
  const publish = useContext(Publish);
36
+ const inherited = useContext(Solid);
37
+ const opaque = solid ?? inherited;
33
38
  useEffect(() => publish?.({ offset: sideOffset, align }), [publish, sideOffset, align]);
34
- return (_jsx(PortalTheme, { name: themeName, children: _jsx(GuiPopover.Content, { ...slot('popover-content'), bg: "$panel", borderWidth: 1, borderColor: "$borderColor", rounded: "$4", p: "$4", width: 288, ...props }) }));
39
+ return (_jsx(Solid.Provider, { value: opaque, children: _jsx(PortalTheme, { name: themeName, children: _jsx(GuiPopover.Content, { ...slot('popover-content'), ...(opaque ? { 'data-material': 'solid' } : null), bg: opaque ? 'var(--popover)' : '$panel', borderWidth: 1, borderColor: "$borderColor", rounded: "$4", p: "$4", width: 288, ...props }) }) }));
35
40
  };
36
41
  export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverClose };
37
42
  //# sourceMappingURL=popover.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../../src/backends/gui/popover.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;GAUG;AACH,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EACL,aAAa,EACb,WAAW,EACX,UAAU,EACV,SAAS,EACT,QAAQ,GAET,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC3E,OAAO,EAAE,KAAK,EAAc,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,MAAM,cAAc,GAAG,CAAC,CAAA;AACxB,MAAM,YAAY,GAAG,QAAQ,CAAA;AAO7B,MAAM,OAAO,GAAG,eAAe,CAAC,aAAa,CAA+B,IAAI,CAAC,CAAA;AAIjF,SAAS,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,SAAS,EAAE,GAAG,KAAK,EAAgB;IAC7E,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAA;IAChD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACxF,OAAO,CACL,KAAC,OAAO,CAAC,QAAQ,IAAC,KAAK,EAAE,OAAO,YAC9B,KAAC,UAAU,IACT,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,MAAM,EAC/B,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,YAAY,EAAE,MAAM,CAAC,KAAK,CAAqB,KACzE,KAAK,GACT,GACe,CACpB,CAAA;AACH,CAAC;AAED,MAAM,cAAc,GAA8B,UAAU,CAAC,OAAO,CAAA;AACpE,MAAM,aAAa,GAA6B,UAAU,CAAC,MAAM,CAAA;AACjE,MAAM,YAAY,GAA4B,UAAU,CAAC,KAAK,CAAA;AAO9D,MAAM,cAAc,GAAG,CAAC,EAAE,UAAU,GAAG,cAAc,EAAE,KAAK,EAAE,GAAG,KAAK,EAAuB,EAAE,EAAE;IAC/F,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IACnC,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAA;IACvF,OAAO,CACL,KAAC,WAAW,IAAC,IAAI,EAAE,SAAS,YAC1B,KAAC,UAAU,CAAC,OAAO,OACb,IAAI,CAAC,iBAAiB,CAAC,EAC3B,EAAE,EAAC,QAAQ,EACX,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,cAAc,EAC1B,OAAO,EAAC,IAAI,EACZ,CAAC,EAAC,IAAI,EACN,KAAK,EAAE,GAAG,KACN,KAAK,GACT,GACU,CACf,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"popover.js","sourceRoot":"","sources":["../../../src/backends/gui/popover.tsx"],"names":[],"mappings":"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"}
@@ -63,7 +63,7 @@ const words_1 = require("./words.cjs");
63
63
  * in exactly that direction: `Parts` reads `type` before it reads anything else.
64
64
  */
65
65
  const draw = (said) => typeof said === 'string' || said == null ? ((0, ink_1.ink)((0, words_1.words)(said))) : ((0, jsx_runtime_1.jsx)(Parts_1.Parts, { parts: said }));
66
- function Chat({ messages, streaming = false, send: onSend, stop: onStop, body, empty, composer, onFiles, ...thread }) {
66
+ function Chat({ messages, streaming = false, send: onSend, stop: onStop, body, empty, center = false, composer, onFiles, ...thread }) {
67
67
  const [draft, setDraft] = (0, react_1.useState)('');
68
68
  // The ONE window-level drop, off the shared primitive. Enabled only when a
69
69
  // host passed `onFiles` — a surface that cannot route a file leaves the
@@ -80,6 +80,11 @@ function Chat({ messages, streaming = false, send: onSend, stop: onStop, body, e
80
80
  onSend(text);
81
81
  }, [draft, onSend]);
82
82
  const last = messages.length - 1;
83
+ const opening = messages.length === 0 && Boolean(empty);
84
+ // The spacers hold their places in the child list whether or not they draw,
85
+ // so the composer keeps its position and its field keeps focus when the
86
+ // first turn arrives.
87
+ const centred = center && opening;
83
88
  // No `minHeight: 0` on the frame: rnw's View base and gui's stack base both
84
89
  // set it already, measured on the rendered element — and gui publishes no
85
90
  // such prop, so writing it type-errors rather than silently doing nothing,
@@ -90,7 +95,7 @@ function Chat({ messages, streaming = false, send: onSend, stop: onStop, body, e
90
95
  // from the composer lands on a `display: contents` wrapper or on the page,
91
96
  // and then reports a component that is fine as broken, or one that is broken
92
97
  // as fine.
93
- return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { flex: 1, width: "100%", ...(0, slot_1.slot)('chat'), children: [messages.length === 0 && empty ? (empty) : ((0, jsx_runtime_1.jsx)(Thread_1.Thread, { flex: 1, ...thread, children: messages.map((turn, i) => ((0, jsx_runtime_1.jsx)(Message_1.Message, { role: turn.role, busy: streaming && i === last && turn.role === 'assistant', children: body ? body(turn) : draw(turn.content) }, turn.id))) })), (0, jsx_runtime_1.jsx)(Composer_1.Composer, { value: draft, onChange: setDraft, onSend: send, busy: streaming, ...(onStop ? { onStop } : {}), ...composer }), dropping ? ((0, jsx_runtime_1.jsx)("div", { "aria-hidden": true, style: {
98
+ return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { flex: 1, width: "100%", ...(0, slot_1.slot)('chat'), children: [centred ? (0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('chat-space'), flex: 1 }) : null, opening ? (empty) : ((0, jsx_runtime_1.jsx)(Thread_1.Thread, { flex: 1, ...thread, children: messages.map((turn, i) => ((0, jsx_runtime_1.jsx)(Message_1.Message, { role: turn.role, busy: streaming && i === last && turn.role === 'assistant', children: body ? body(turn) : draw(turn.content) }, turn.id))) })), (0, jsx_runtime_1.jsx)(Composer_1.Composer, { value: draft, onChange: setDraft, onSend: send, busy: streaming, ...(onStop ? { onStop } : {}), ...composer }), centred ? (0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('chat-space'), flex: 1 }) : null, dropping ? ((0, jsx_runtime_1.jsx)("div", { "aria-hidden": true, style: {
94
99
  position: 'fixed',
95
100
  inset: 0,
96
101
  zIndex: 50,
@@ -58,6 +58,19 @@ export interface ChatProps extends Omit<ThreadProps, 'children' | 'ref'> {
58
58
  body?: (turn: Turn) => ReactNode;
59
59
  /** Shown instead of the thread while nothing has been said. */
60
60
  empty?: ReactNode;
61
+ /**
62
+ * While nothing has been said, `empty` and the composer sit together in the
63
+ * middle of the height, the free space split evenly above and below them.
64
+ * Once a turn exists the thread takes the height and the composer docks under
65
+ * it.
66
+ *
67
+ * The space is two spacers around the pair, not margins on it. With a `head`
68
+ * or `foot` the composer is a shell around its frame, and a margin passed in
69
+ * `composer` lands on the frame inside that shell, where it moves nothing.
70
+ * The spacers shrink to nothing when the pair is taller than the window, so
71
+ * the heading is never pushed above the top.
72
+ */
73
+ center?: boolean;
61
74
  /** The composer's own props — placeholder, hint, the send control, the field. */
62
75
  composer?: Partial<ComposerProps>;
63
76
  /**
@@ -72,5 +85,5 @@ export interface ChatProps extends Omit<ThreadProps, 'children' | 'ref'> {
72
85
  */
73
86
  onFiles?: (files: File[]) => void;
74
87
  }
75
- export declare function Chat({ messages, streaming, send: onSend, stop: onStop, body, empty, composer, onFiles, ...thread }: ChatProps): import("react").JSX.Element;
88
+ export declare function Chat({ messages, streaming, send: onSend, stop: onStop, body, empty, center, composer, onFiles, ...thread }: ChatProps): import("react").JSX.Element;
76
89
  //# sourceMappingURL=Chat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../src/chat/Chat.tsx"],"names":[],"mappings":"AAoCA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7D,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAW,KAAK,IAAI,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,SAAS,CAAA;AAE1C;;;;;;;GAOG;AACH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,IAAI,CAAA;IACV;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,IAAI,CAAA;CACf;AAED,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,KAAK,CAAC;IACtE,sCAAsC;IACtC,QAAQ,EAAE,IAAI,EAAE,CAAA;IAChB,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;;;;;OAUG;IACH,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAA;IACjB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAA;IAChC,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IACjC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAA;CAClC;AAyBD,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,SAAiB,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,OAAO,EACP,GAAG,MAAM,EACV,EAAE,SAAS,+BA6EX"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../src/chat/Chat.tsx"],"names":[],"mappings":"AAoCA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7D,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAW,KAAK,IAAI,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,SAAS,CAAA;AAE1C;;;;;;;GAOG;AACH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,IAAI,CAAA;IACV;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,IAAI,CAAA;CACf;AAED,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,KAAK,CAAC;IACtE,sCAAsC;IACtC,QAAQ,EAAE,IAAI,EAAE,CAAA;IAChB,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;;;;;OAUG;IACH,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,IAAI,CAAA;IACjB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAA;IAChC,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IACjC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAA;CAClC;AAyBD,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,SAAiB,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EACJ,KAAK,EACL,MAAc,EACd,QAAQ,EACR,OAAO,EACP,GAAG,MAAM,EACV,EAAE,SAAS,+BAoFX"}
package/dist/chat/Chat.js CHANGED
@@ -60,7 +60,7 @@ import { words } from './words.js';
60
60
  * in exactly that direction: `Parts` reads `type` before it reads anything else.
61
61
  */
62
62
  const draw = (said) => typeof said === 'string' || said == null ? (ink(words(said))) : (_jsx(Parts, { parts: said }));
63
- export function Chat({ messages, streaming = false, send: onSend, stop: onStop, body, empty, composer, onFiles, ...thread }) {
63
+ export function Chat({ messages, streaming = false, send: onSend, stop: onStop, body, empty, center = false, composer, onFiles, ...thread }) {
64
64
  const [draft, setDraft] = useState('');
65
65
  // The ONE window-level drop, off the shared primitive. Enabled only when a
66
66
  // host passed `onFiles` — a surface that cannot route a file leaves the
@@ -77,6 +77,11 @@ export function Chat({ messages, streaming = false, send: onSend, stop: onStop,
77
77
  onSend(text);
78
78
  }, [draft, onSend]);
79
79
  const last = messages.length - 1;
80
+ const opening = messages.length === 0 && Boolean(empty);
81
+ // The spacers hold their places in the child list whether or not they draw,
82
+ // so the composer keeps its position and its field keeps focus when the
83
+ // first turn arrives.
84
+ const centred = center && opening;
80
85
  // No `minHeight: 0` on the frame: rnw's View base and gui's stack base both
81
86
  // set it already, measured on the rendered element — and gui publishes no
82
87
  // such prop, so writing it type-errors rather than silently doing nothing,
@@ -87,7 +92,7 @@ export function Chat({ messages, streaming = false, send: onSend, stop: onStop,
87
92
  // from the composer lands on a `display: contents` wrapper or on the page,
88
93
  // and then reports a component that is fine as broken, or one that is broken
89
94
  // as fine.
90
- return (_jsxs(YStack, { flex: 1, width: "100%", ...slot('chat'), children: [messages.length === 0 && empty ? (empty) : (_jsx(Thread, { flex: 1, ...thread, children: messages.map((turn, i) => (_jsx(Message, { role: turn.role, busy: streaming && i === last && turn.role === 'assistant', children: body ? body(turn) : draw(turn.content) }, turn.id))) })), _jsx(Composer, { value: draft, onChange: setDraft, onSend: send, busy: streaming, ...(onStop ? { onStop } : {}), ...composer }), dropping ? (_jsx("div", { "aria-hidden": true, style: {
95
+ return (_jsxs(YStack, { flex: 1, width: "100%", ...slot('chat'), children: [centred ? _jsx(YStack, { ...slot('chat-space'), flex: 1 }) : null, opening ? (empty) : (_jsx(Thread, { flex: 1, ...thread, children: messages.map((turn, i) => (_jsx(Message, { role: turn.role, busy: streaming && i === last && turn.role === 'assistant', children: body ? body(turn) : draw(turn.content) }, turn.id))) })), _jsx(Composer, { value: draft, onChange: setDraft, onSend: send, busy: streaming, ...(onStop ? { onStop } : {}), ...composer }), centred ? _jsx(YStack, { ...slot('chat-space'), flex: 1 }) : null, dropping ? (_jsx("div", { "aria-hidden": true, style: {
91
96
  position: 'fixed',
92
97
  inset: 0,
93
98
  zIndex: 50,
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.js","sourceRoot":"","sources":["../../src/chat/Chat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Chat.js","sourceRoot":"","sources":["../../src/chat/Chat.tsx"],"names":[],"mappings":"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"}
package/dist/gallery.html CHANGED
@@ -1,4 +1,4 @@
1
- <!doctype html><html lang="en" class="t_dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>@hanzo/ui 8.27.45</title><style>/* @hanzo/ui — generated by scripts/gen-css.mjs. Do not edit. */
1
+ <!doctype html><html lang="en" class="t_dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>@hanzo/ui 8.27.46</title><style>/* @hanzo/ui — generated by scripts/gen-css.mjs. Do not edit. */
2
2
  :root { --hanzo-ui-styles: 1; }
3
3
  /* Hanzo Design System — the entry point. Import THIS one file.
4
4
  *
@@ -1585,6 +1585,20 @@
1585
1585
  }
1586
1586
  }
1587
1587
 
1588
+ /* ── Solid — the one way out of the material ─────────────────────────────────
1589
+ A panel over something that moves (a menu over a streaming transcript) reads
1590
+ the motion through 72% frost. `<PopoverContent solid>` marks itself, and every
1591
+ popover opened from inside it, with `data-material="solid"`: the ground is
1592
+ design's opaque `--popover` and nothing behind is blurred into it. The rung's
1593
+ shadow, lit edge and prism lip stay, so it is the same surface at the same
1594
+ height with a solid fill. Declared after the material so the later rule wins
1595
+ between two !important declarations of equal weight. */
1596
+ [data-material="solid"] {
1597
+ background-color: var(--popover, #0f0f0f) !important;
1598
+ -webkit-backdrop-filter: none;
1599
+ backdrop-filter: none;
1600
+ }
1601
+
1588
1602
  /* ── Depth — three rungs, and the lit edge is the load-bearing half ──────────
1589
1603
  A cast shadow is how a light page shows lift. On a near-black canvas it is
1590
1604
  nearly free of information: black on near-black moves no pixels, so a raised
package/dist/glass.css CHANGED
@@ -115,6 +115,20 @@
115
115
  }
116
116
  }
117
117
 
118
+ /* ── Solid — the one way out of the material ─────────────────────────────────
119
+ A panel over something that moves (a menu over a streaming transcript) reads
120
+ the motion through 72% frost. `<PopoverContent solid>` marks itself, and every
121
+ popover opened from inside it, with `data-material="solid"`: the ground is
122
+ design's opaque `--popover` and nothing behind is blurred into it. The rung's
123
+ shadow, lit edge and prism lip stay, so it is the same surface at the same
124
+ height with a solid fill. Declared after the material so the later rule wins
125
+ between two !important declarations of equal weight. */
126
+ [data-material="solid"] {
127
+ background-color: var(--popover, #0f0f0f) !important;
128
+ -webkit-backdrop-filter: none;
129
+ backdrop-filter: none;
130
+ }
131
+
118
132
  /* ── Depth — three rungs, and the lit edge is the load-bearing half ──────────
119
133
  A cast shadow is how a light page shows lift. On a near-black canvas it is
120
134
  nearly free of information: black on near-black moves no pixels, so a raised
package/dist/styles.css CHANGED
@@ -1585,6 +1585,20 @@
1585
1585
  }
1586
1586
  }
1587
1587
 
1588
+ /* ── Solid — the one way out of the material ─────────────────────────────────
1589
+ A panel over something that moves (a menu over a streaming transcript) reads
1590
+ the motion through 72% frost. `<PopoverContent solid>` marks itself, and every
1591
+ popover opened from inside it, with `data-material="solid"`: the ground is
1592
+ design's opaque `--popover` and nothing behind is blurred into it. The rung's
1593
+ shadow, lit edge and prism lip stay, so it is the same surface at the same
1594
+ height with a solid fill. Declared after the material so the later rule wins
1595
+ between two !important declarations of equal weight. */
1596
+ [data-material="solid"] {
1597
+ background-color: var(--popover, #0f0f0f) !important;
1598
+ -webkit-backdrop-filter: none;
1599
+ backdrop-filter: none;
1600
+ }
1601
+
1588
1602
  /* ── Depth — three rungs, and the lit edge is the load-bearing half ──────────
1589
1603
  A cast shadow is how a light page shows lift. On a near-black canvas it is
1590
1604
  nearly free of information: black on near-black moves no pixels, so a raised
package/dist/theme.css CHANGED
@@ -1583,6 +1583,20 @@
1583
1583
  }
1584
1584
  }
1585
1585
 
1586
+ /* ── Solid — the one way out of the material ─────────────────────────────────
1587
+ A panel over something that moves (a menu over a streaming transcript) reads
1588
+ the motion through 72% frost. `<PopoverContent solid>` marks itself, and every
1589
+ popover opened from inside it, with `data-material="solid"`: the ground is
1590
+ design's opaque `--popover` and nothing behind is blurred into it. The rung's
1591
+ shadow, lit edge and prism lip stay, so it is the same surface at the same
1592
+ height with a solid fill. Declared after the material so the later rule wins
1593
+ between two !important declarations of equal weight. */
1594
+ [data-material="solid"] {
1595
+ background-color: var(--popover, #0f0f0f) !important;
1596
+ -webkit-backdrop-filter: none;
1597
+ backdrop-filter: none;
1598
+ }
1599
+
1586
1600
  /* ── Depth — three rungs, and the lit edge is the load-bearing half ──────────
1587
1601
  A cast shadow is how a light page shows lift. On a near-black canvas it is
1588
1602
  nearly free of information: black on near-black moves no pixels, so a raised
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/ui",
3
- "version": "8.27.45",
3
+ "version": "8.27.46",
4
4
  "type": "module",
5
5
  "description": "Hanzo UI — the one canonical Hanzo component library, on @hanzo/gui + @hanzo/design. ONE substrate: every component renders through @hanzo/gui primitives, so the same import works on web, native (expo) and desktop (Tauri). Self-contained (theme.css), presentational, host-agnostic, clean-room.",
6
6
  "exports": {