@hanzo/ui 8.29.22 → 8.29.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/chat/Composer.cjs +181 -99
  2. package/dist/chat/Composer.d.ts +110 -81
  3. package/dist/chat/Composer.d.ts.map +1 -1
  4. package/dist/chat/Composer.js +183 -101
  5. package/dist/chat/Composer.js.map +1 -1
  6. package/dist/chat/Dial.cjs +96 -0
  7. package/dist/chat/Dial.d.ts +7 -0
  8. package/dist/chat/Dial.d.ts.map +1 -0
  9. package/dist/chat/Dial.js +94 -0
  10. package/dist/chat/Dial.js.map +1 -0
  11. package/dist/chat/Dictation.cjs +142 -0
  12. package/dist/chat/Dictation.d.ts +13 -0
  13. package/dist/chat/Dictation.d.ts.map +1 -0
  14. package/dist/chat/Dictation.js +140 -0
  15. package/dist/chat/Dictation.js.map +1 -0
  16. package/dist/chat/Families.cjs +41 -0
  17. package/dist/chat/Families.d.ts +3 -0
  18. package/dist/chat/Families.d.ts.map +1 -0
  19. package/dist/chat/Families.js +39 -0
  20. package/dist/chat/Families.js.map +1 -0
  21. package/dist/chat/Mention.cjs +25 -0
  22. package/dist/chat/Mention.d.ts +16 -0
  23. package/dist/chat/Mention.d.ts.map +1 -0
  24. package/dist/chat/Mention.js +22 -0
  25. package/dist/chat/Mention.js.map +1 -0
  26. package/dist/chat/Palette.cjs +22 -0
  27. package/dist/chat/Palette.d.ts +21 -0
  28. package/dist/chat/Palette.d.ts.map +1 -0
  29. package/dist/chat/Palette.js +20 -0
  30. package/dist/chat/Palette.js.map +1 -0
  31. package/dist/chat/Plus.cjs +76 -0
  32. package/dist/chat/Plus.d.ts +49 -0
  33. package/dist/chat/Plus.d.ts.map +1 -0
  34. package/dist/chat/Plus.js +74 -0
  35. package/dist/chat/Plus.js.map +1 -0
  36. package/dist/chat/Tune.cjs +55 -0
  37. package/dist/chat/Tune.d.ts +49 -0
  38. package/dist/chat/Tune.d.ts.map +1 -0
  39. package/dist/chat/Tune.js +51 -0
  40. package/dist/chat/Tune.js.map +1 -0
  41. package/dist/chat/index.cjs +25 -4
  42. package/dist/chat/index.d.ts +11 -3
  43. package/dist/chat/index.d.ts.map +1 -1
  44. package/dist/chat/index.js +10 -2
  45. package/dist/chat/index.js.map +1 -1
  46. package/dist/chat/languages.cjs +17 -0
  47. package/dist/chat/languages.d.ts +11 -0
  48. package/dist/chat/languages.d.ts.map +1 -0
  49. package/dist/chat/languages.js +15 -0
  50. package/dist/chat/languages.js.map +1 -0
  51. package/dist/chat/pure.cjs +7 -1
  52. package/dist/chat/pure.d.ts +3 -1
  53. package/dist/chat/pure.d.ts.map +1 -1
  54. package/dist/chat/pure.js +4 -0
  55. package/dist/chat/pure.js.map +1 -1
  56. package/dist/chat/ring.cjs +9 -0
  57. package/dist/chat/ring.d.ts +11 -0
  58. package/dist/chat/ring.d.ts.map +1 -0
  59. package/dist/chat/ring.js +7 -0
  60. package/dist/chat/ring.js.map +1 -0
  61. package/dist/chat/send.cjs +3 -2
  62. package/dist/chat/send.d.ts +4 -1
  63. package/dist/chat/send.d.ts.map +1 -1
  64. package/dist/chat/send.js +3 -2
  65. package/dist/chat/send.js.map +1 -1
  66. package/dist/chat/ways.cjs +19 -0
  67. package/dist/chat/ways.d.ts +11 -0
  68. package/dist/chat/ways.d.ts.map +1 -0
  69. package/dist/chat/ways.js +17 -0
  70. package/dist/chat/ways.js.map +1 -0
  71. package/dist/gallery.cjs +4 -1
  72. package/dist/gallery.d.ts.map +1 -1
  73. package/dist/gallery.html +41 -15
  74. package/dist/gallery.js +5 -2
  75. package/dist/gallery.js.map +1 -1
  76. package/dist/models/ModelPicker.cjs +3 -3
  77. package/dist/models/ModelPicker.d.ts +6 -1
  78. package/dist/models/ModelPicker.d.ts.map +1 -1
  79. package/dist/models/ModelPicker.js +3 -3
  80. package/dist/models/ModelPicker.js.map +1 -1
  81. package/dist/models/ModelPickerMenu.cjs +19 -13
  82. package/dist/models/ModelPickerMenu.d.ts +4 -0
  83. package/dist/models/ModelPickerMenu.d.ts.map +1 -1
  84. package/dist/models/ModelPickerMenu.js +19 -13
  85. package/dist/models/ModelPickerMenu.js.map +1 -1
  86. package/dist/models/catalog.cjs +7 -0
  87. package/dist/models/catalog.d.ts +2 -0
  88. package/dist/models/catalog.d.ts.map +1 -1
  89. package/dist/models/catalog.js +6 -0
  90. package/dist/models/catalog.js.map +1 -1
  91. package/dist/models/index.cjs +2 -1
  92. package/dist/models/index.d.ts +1 -1
  93. package/dist/models/index.d.ts.map +1 -1
  94. package/dist/models/index.js +1 -1
  95. package/dist/models/index.js.map +1 -1
  96. package/dist/product/BranchSelect.cjs +1 -1
  97. package/dist/product/BranchSelect.js +1 -1
  98. package/dist/product/BranchSelect.js.map +1 -1
  99. package/dist/product/ChipSelect.cjs +60 -11
  100. package/dist/product/ChipSelect.d.ts +13 -2
  101. package/dist/product/ChipSelect.d.ts.map +1 -1
  102. package/dist/product/ChipSelect.js +61 -12
  103. package/dist/product/ChipSelect.js.map +1 -1
  104. package/dist/product/RepoSelect.cjs +11 -5
  105. package/dist/product/RepoSelect.d.ts +6 -2
  106. package/dist/product/RepoSelect.d.ts.map +1 -1
  107. package/dist/product/RepoSelect.js +13 -7
  108. package/dist/product/RepoSelect.js.map +1 -1
  109. package/dist/product/chipSelect.logic.d.ts +4 -1
  110. package/dist/product/chipSelect.logic.d.ts.map +1 -1
  111. package/dist/product/chipSelect.logic.js.map +1 -1
  112. package/dist/product/index.cjs +3 -3
  113. package/dist/product/index.d.ts +1 -1
  114. package/dist/product/index.d.ts.map +1 -1
  115. package/dist/product/index.js +3 -3
  116. package/dist/product/index.js.map +1 -1
  117. package/dist/styles.css +37 -11
  118. package/package.json +8 -2
@@ -1,131 +1,213 @@
1
1
  'use client';"use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.ASK = void 0;
4
+ exports.ROUND = exports.measure = exports.GAP = exports.MEASURE = exports.ASK = void 0;
5
+ exports.useUpload = useUpload;
5
6
  exports.Composer = Composer;
6
- exports.ComposerTool = ComposerTool;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  /**
9
- * Composer — the one chat input for every Hanzo surface.
9
+ * Composer — the one composer every Hanzo surface draws: Chat, Dev, Studio, a
10
+ * room, a reply, a run being steered. A surface hands it slots and defaults and
11
+ * nothing else; the field, the keys, the controls and their look are here once.
10
12
  *
11
- * Presentational and controlled: it owns no draft, no transport and no model
12
- * state. `children` is the toolbar slot, which is where a surface puts its
13
- * `ModelPicker`, attachment control or mode chips — that keeps the shell the
14
- * same everywhere while the affordances stay per-surface.
13
+ * ┌ pills ───────────────────────────────┐ where a run goes, which repository
14
+ * │ the field │
15
+ * │ + carried… children ✦ 🎙 ⬆ │ + menu, what the draft carries,
16
+ * └──────────────────────────────────────┘ commands, dictation, send / stop
17
+ * chips… model effort mode
15
18
  *
16
- * The send control is the same button in both states: it submits, and while a
17
- * turn is in flight it stops. Two buttons in one place was the thing every
18
- * surface got subtly different.
19
+ * Above the frame: the surface's `head`, the `/` or `@` list, and the `note`.
20
+ * Under it, one row: the surface's chips, then the model, the effort and the mode.
19
21
  *
20
- * Escape and ArrowUp are not bound. Dismissal belongs to whatever the composer
21
- * floats inside, and history recall needs a turn store this has no view of.
22
+ * THE PERSON'S SETTING (@hanzo/appearance `useComposing`, Settings →
23
+ * Appearance) decides which key sends and whether the chips, the model
24
+ * selector and the mode are drawn, everywhere at once. An axis they left on
25
+ * Auto takes the surface's `defaults`, and the model selector is off until
26
+ * they turn it on.
22
27
  *
23
- * Growth is `Textarea`'s and follows the content, so a wrapped paragraph raises
24
- * the field. `rows` is the floor, `maxHeight` the ceiling.
28
+ * Its paint is @hanzo/design's: `$` tokens and `--primary`, sized through
29
+ * `--density` (the round controls are @hanzo/composer's `Control`), so text
30
+ * size, density and accent change it with the rest of the product.
31
+ *
32
+ * Its own words are the reader's language (@hanzo/i18n `t`). A host's words —
33
+ * its placeholder, a shelf's rows, a chip's label — are drawn as given.
25
34
  */
26
35
  const gui_1 = require("@hanzo/gui");
36
+ const appearance_1 = require("@hanzo/appearance");
37
+ const composer_1 = require("@hanzo/composer");
38
+ const i18n_1 = require("@hanzo/i18n");
39
+ const react_1 = require("@hanzo/i18n/react");
27
40
  const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
41
+ const voice_1 = require("@hanzo/voice");
42
+ const react_2 = require("react");
28
43
  const gui_2 = require("../backends/gui/index.cjs");
29
44
  const slot_1 = require("../backends/gui/slot.cjs");
45
+ const Dial_1 = require("./Dial.cjs");
46
+ const Dictation_1 = require("./Dictation.cjs");
47
+ const Mention_1 = require("./Mention.cjs");
48
+ const Palette_1 = require("./Palette.cjs");
49
+ const Plus_1 = require("./Plus.cjs");
30
50
  const send_1 = require("./send.cjs");
31
- const PAD = 8;
32
- const MIN_ROWS = 1;
33
- /** How tall the field may grow before it scrolls, px. Uncapped, a long paste
34
- * pushes the thread off screen; narrower frames pass their own. */
35
- const CEILING = 200;
36
- /** Floor for the field, px. `Textarea` defaults to 64, which is three lines of
37
- * chrome before anything is typed. 44 is the touch-target floor. */
38
- const FLOOR = 44;
51
+ const ring_1 = require("./ring.cjs");
52
+ const Tune_1 = require("./Tune.cjs");
39
53
  /**
40
- * The one-line frame: 40px outside, so the field inside is 38 — a 20px line
41
- * with 9px above and below it. The frame is the target, not the glyph, which
42
- * is why the send control can be a 28px mark inside a row a thumb already hits.
54
+ * The resting placeholder. It addresses the person rather than the mechanism,
55
+ * and as one constant it never re-announces when the model changes.
43
56
  */
44
- const LINE = 40;
45
- const LINE_FIELD = LINE - 2;
46
- const LINE_PAD = (LINE_FIELD - 20) / 2;
47
- /** The inline send mark: a glyph in the field's own row, never a filled slab. */
48
- const MARK = 28;
57
+ exports.ASK = (0, i18n_1.phrase)('Ask anything');
58
+ /** The reading measure: @hanzo/design's prose width, which Width (appearance) retunes. */
59
+ exports.MEASURE = 'var(--container-prose, 48rem)';
60
+ /** The space between turns, px: one rhythm for every thread. */
61
+ exports.GAP = 20;
62
+ /** The composer's width under a thread: the measure less its 0.75rem gutters, centred, so its edges are the text's. */
63
+ exports.measure = { width: 'calc(100% - 1.5rem)', maxW: `calc(${exports.MEASURE} - 1.5rem)`, mx: 'auto' };
64
+ /** The round controls' box, px, and a phone's, a finger's width: `+`, the effort, the mic, its chevron and send all take it, so they share one centreline. */
65
+ exports.ROUND = 36;
66
+ const TAP = 44;
67
+ /** The frame's corner, px: 12 on a laptop, 22 on a phone. */
68
+ const CORNER = 12;
69
+ const CORNER_PHONE = 22;
70
+ /** How tall the field grows before it scrolls, px. */
71
+ const CEILING = 200;
72
+ /** The ink on a filled round: the accent's own foreground. */
73
+ const ON = 'var(--primary-foreground)';
74
+ /** A round control with no ground of its own until it is pointed at. */
75
+ const QUIET = { bg: 'transparent', color: 'var(--foreground)', hoverStyle: { bg: '$hover' } };
76
+ /** Ctrl+U (⌘U) uploads, while a composer with an upload is on the page. */
77
+ function useUpload(upload) {
78
+ const now = (0, react_2.useRef)(upload);
79
+ now.current = upload;
80
+ (0, react_2.useEffect)(() => {
81
+ if (!upload)
82
+ return;
83
+ const key = (e) => {
84
+ if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && e.key.toLowerCase() === 'u') {
85
+ e.preventDefault();
86
+ now.current?.();
87
+ }
88
+ };
89
+ window.addEventListener('keydown', key);
90
+ return () => window.removeEventListener('keydown', key);
91
+ }, [Boolean(upload)]); // eslint-disable-line react-hooks/exhaustive-deps
92
+ }
93
+ /** The modifier state off a keydown, web or native. */
94
+ const modsOf = (e) => ({
95
+ shiftKey: e.shiftKey ?? e.nativeEvent?.shiftKey,
96
+ altKey: e.altKey ?? e.nativeEvent?.altKey,
97
+ metaKey: e.metaKey ?? e.nativeEvent?.metaKey,
98
+ ctrlKey: e.ctrlKey ?? e.nativeEvent?.ctrlKey,
99
+ isComposing: e.isComposing ?? e.nativeEvent?.isComposing,
100
+ // Safari's only honest IME signal on this keydown.
101
+ keyCode: e.keyCode ?? e.nativeEvent?.keyCode,
102
+ });
49
103
  /**
50
- * The resting placeholder.
51
- *
52
- * "Ask anything", not "Send a message" and not "Message <model>". It addresses
53
- * the person rather than describing the mechanism, and being one constant string
54
- * it never has to be recomputed or re-announced when the model or endpoint
55
- * changes — which is what a model-named placeholder forces a surface to do.
104
+ * How far the software keyboard covers the page, px: the layout viewport less the
105
+ * visual one. A phone keyboard that does not shrink the layout leaves a fixed
106
+ * composer under it; this is how far to lift it. Zero where the layout follows the
107
+ * keyboard (the browser resized it) and wherever there is no keyboard.
56
108
  */
57
- exports.ASK = 'Ask anything';
58
- function Composer({ value, onChange, onSend, onStop, busy = false, disabled = false, placeholder = exports.ASK, rows = MIN_ROWS, maxHeight = CEILING, children, hint, label, field, send, head, foot, inline = false, ...props }) {
59
- const sendable = (0, send_1.ready)(value, busy, disabled);
60
- const keyed = (e) => {
61
- const key = e.key ?? e.nativeEvent?.key ?? '';
62
- const mods = {
63
- shiftKey: e.shiftKey ?? e.nativeEvent?.shiftKey,
64
- altKey: e.altKey ?? e.nativeEvent?.altKey,
65
- metaKey: e.metaKey ?? e.nativeEvent?.metaKey,
66
- ctrlKey: e.ctrlKey ?? e.nativeEvent?.ctrlKey,
67
- isComposing: e.isComposing ?? e.nativeEvent?.isComposing,
68
- // Safari's only honest IME signal on this keydown. Dropping it here would
69
- // put the mid-candidate submit straight back, whatever `sends` checks.
70
- keyCode: e.keyCode ?? e.nativeEvent?.keyCode,
109
+ function useLift() {
110
+ const [lift, setLift] = (0, react_2.useState)(0);
111
+ (0, react_2.useEffect)(() => {
112
+ const vv = typeof window === 'undefined' ? null : window.visualViewport;
113
+ if (!vv)
114
+ return;
115
+ const read = () => {
116
+ const covered = Math.round(window.innerHeight - vv.height - vv.offsetTop);
117
+ // A bar of the browser's own coming and going is not a keyboard.
118
+ setLift(covered > 100 ? covered : 0);
71
119
  };
72
- if (!(0, send_1.sends)(key, mods))
120
+ read();
121
+ vv.addEventListener('resize', read);
122
+ vv.addEventListener('scroll', read);
123
+ return () => {
124
+ vv.removeEventListener('resize', read);
125
+ vv.removeEventListener('scroll', read);
126
+ };
127
+ }, []);
128
+ return lift;
129
+ }
130
+ function Composer({ value, onChange, onSend, onStop, busy = false, disabled = false, ready: readyProp, placeholder, label, rows = 1, maxHeight = CEILING, field, hint, children, head, pills, carried, plus, slash, at, commands, chips, mind, effort, limits, onUpgrade, mode, voice, language = null, onLanguage, talk, starters, note, column = false, framed = false, narrow: narrowProp, defaults, ...props }) {
131
+ const { t } = (0, react_1.useI18n)();
132
+ const media = (0, gui_1.useMedia)();
133
+ const narrow = narrowProp ?? !media.sm;
134
+ const hit = narrow ? TAP : exports.ROUND;
135
+ const lift = useLift();
136
+ const chosen = (0, appearance_1.useComposing)();
137
+ const rule = chosen.send ?? defaults?.send ?? 'enter';
138
+ const showChips = chosen.chips ?? defaults?.chips ?? true;
139
+ const showModel = chosen.model ?? defaults?.model ?? false;
140
+ const showMode = chosen.mode ?? defaults?.mode ?? true;
141
+ const lit = readyProp ?? (0, send_1.ready)(value);
142
+ const live = busy ? Boolean(onStop) : lit && !disabled;
143
+ useUpload(plus?.upload);
144
+ // `/` and `@`: the shelf the caret's word opens, filtered by what follows it.
145
+ const [index, setIndex] = (0, react_2.useState)(0);
146
+ const [closed, setClosed] = (0, react_2.useState)(null);
147
+ const typed = (0, Mention_1.trigger)(value);
148
+ const shelf = typed ? (typed.char === '/' ? slash : at) : undefined;
149
+ const listed = shelf && typed && closed !== value ? shelf.rows.filter((r) => r.label.toLowerCase().includes(typed.query)).slice(0, 8) : null;
150
+ const row = Math.min(index, Math.max(0, (listed?.length ?? 1) - 1));
151
+ (0, react_2.useEffect)(() => setIndex(0), [typed?.char, typed?.query]);
152
+ const pick = (id) => {
153
+ if (!typed || !shelf)
73
154
  return;
74
- e.preventDefault?.();
75
- if (sendable)
155
+ onChange(value.slice(0, typed.at).trimEnd() + (typed.at > 0 ? ' ' : ''));
156
+ shelf.pick(id);
157
+ };
158
+ const [palette, setPalette] = (0, react_2.useState)(false);
159
+ const submit = () => {
160
+ if (listed?.length)
161
+ return pick(listed[row].id);
162
+ if (live && !busy)
76
163
  onSend();
77
164
  };
78
- const input = ((0, jsx_runtime_1.jsx)(gui_2.Textarea, { ...(0, slot_1.slot)('composer-field'), rows: rows, placeholder: placeholder, disabled: disabled, borderWidth: 0, ...(inline
79
- ? {
80
- flex: 1,
81
- minW: 0,
82
- minH: LINE_FIELD,
83
- px: 0,
84
- pt: LINE_PAD,
85
- pb: LINE_PAD,
86
- bg: 'transparent',
165
+ const keyed = (e) => {
166
+ const key = e?.key ?? e?.nativeEvent?.key ?? '';
167
+ const mods = modsOf(e ?? {});
168
+ if (listed) {
169
+ if (key === 'ArrowDown') {
170
+ e.preventDefault?.();
171
+ return setIndex((i) => Math.min(i + 1, listed.length - 1));
172
+ }
173
+ if (key === 'ArrowUp') {
174
+ e.preventDefault?.();
175
+ return setIndex((i) => Math.max(0, i - 1));
87
176
  }
88
- : { minH: FLOOR }), maxH: maxHeight, "aria-label": label ?? placeholder, ...field,
89
- // After `field`: spread over, a caller's `onKeyDown` would replace the
90
- // Enter rule and the IME guard. Theirs runs first and can claim the key.
177
+ if (key === 'Escape') {
178
+ e.preventDefault?.();
179
+ return setClosed(value);
180
+ }
181
+ }
182
+ if (commands?.length && (mods.metaKey || mods.ctrlKey) && key.toLowerCase() === 'k') {
183
+ e.preventDefault?.();
184
+ return setPalette(true);
185
+ }
186
+ if (!(0, send_1.sends)(key, mods, rule))
187
+ return;
188
+ e.preventDefault?.();
189
+ submit();
190
+ };
191
+ const input = ((0, jsx_runtime_1.jsx)(gui_2.Textarea, { ...(0, slot_1.slot)('composer-field'), rows: rows, placeholder: placeholder ?? t(exports.ASK), disabled: disabled, borderWidth: 0, fontSize: 16, lineHeight: 24, px: 8, pt: 2, pb: 0, minH: 26, maxH: maxHeight, bg: "transparent", "aria-label": label ?? placeholder ?? t(exports.ASK), ...field,
192
+ // After `field`: a caller's `onKeyDown` runs first and can claim the key,
193
+ // but cannot replace the send rule and the IME guard.
91
194
  value: value, onChangeText: onChange, onKeyDown: (e) => {
92
195
  field?.onKeyDown?.(e);
93
196
  if (!e?.defaultPrevented)
94
197
  keyed(e);
95
198
  } }));
96
- const said = hint ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$soft", children: hint })) : null;
97
- const frame = inline ? ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('composer'), "data-variant": "inline", width: "100%", items: "center", rounded: "$3", borderWidth: 1, borderColor: "$rim", bg: "$hover", paddingInlineStart: "$3", paddingInlineEnd: "$1.5", gap: "$1.5", ...props, children: [input, children, said, send ?? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('composer-send'), ...(0, slot_1.tip)(busy ? 'Stop' : 'Send'), role: "button", tabIndex: busy ? (onStop ? 0 : -1) : sendable ? 0 : -1, "aria-label": busy ? 'Stop' : 'Send', "aria-disabled": busy ? !onStop : !sendable, width: MARK, height: MARK, shrink: 0, rounded: "$2", items: "center", justify: "center", cursor: (busy ? onStop : sendable) ? 'pointer' : 'default', opacity: (busy ? onStop : sendable) ? 1 : 0.6, hoverStyle: { bg: '$raised' }, onPress: () => (busy ? onStop?.() : sendable ? onSend() : undefined), onKeyDown: (e) => {
98
- if (e?.key !== 'Enter' && e?.key !== ' ')
99
- return;
100
- e.preventDefault?.();
101
- if (busy)
102
- onStop?.();
103
- else if (sendable)
104
- onSend();
105
- }, children: busy ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Square, { size: 12, color: "$soft" }) : (0, jsx_runtime_1.jsx)(lucide_icons_2_1.CornerDownLeft, { size: 14, color: "$soft" }) }))] })) : ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('composer'), width: "100%", rounded: "$5", borderWidth: 1, borderColor: "$borderColor", bg: "$background", p: PAD, gap: PAD, ...props, children: [input, (0, jsx_runtime_1.jsxs)(gui_1.XStack, { items: "center", gap: PAD, children: [children, (0, jsx_runtime_1.jsx)(gui_1.XStack, { flex: 1 }), said, send ?? ((0, jsx_runtime_1.jsx)(gui_2.Button, { ...(0, slot_1.slot)('composer-send'), size: "sm", disabled: busy ? !onStop : !sendable, onPress: busy ? onStop : onSend, "aria-label": busy ? 'Stop' : 'Send',
106
- // A circle, and the room's one primary control. The height is the
107
- // size's; `aspectRatio` takes the width from it, so no second number
108
- // is written down. `--primary` is the accent a reader picks, and at
109
- // rest it is the ink pair Send already paints in both themes.
110
- px: 0, aspectRatio: 1, rounded: 'var(--radius-full, 9999px)', bg: "var(--primary)", borderWidth: 0, hoverStyle: { bg: 'var(--primary)', opacity: 0.9 }, pressStyle: { bg: 'var(--primary)', opacity: 0.85 }, children: busy ? ((0, jsx_runtime_1.jsx)(lucide_icons_2_1.Square, { size: 14, color: 'var(--primary-foreground)' })) : ((0, jsx_runtime_1.jsx)(lucide_icons_2_1.ArrowUp, { size: 16, color: 'var(--primary-foreground)' })) }))] })] }));
111
- // With nothing above or below it the composer IS the frame, exactly as it
112
- // was before either existed — no wrapper, so every caller's tree is unchanged.
113
- if (!head && !foot)
114
- return frame;
115
- return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('composer-shell'), width: "100%", gap: "$2.5", children: [head ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('composer-head'), items: "center", gap: "$1.5", flexWrap: "wrap", children: head })) : null, frame, foot ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('composer-foot'), items: "center", gap: "$2", px: "$1.5", mt: -4, children: foot })) : null] }));
116
- }
117
- /**
118
- * ComposerTool — one quiet control in a composer's `foot` or `head`: attach,
119
- * voice, a mode, the model. 24px tall, muted until pointed at, and a real
120
- * button to the keyboard. Its name is `label` whether or not it shows words,
121
- * because an icon-only control is the whole navigation for someone who cannot
122
- * see the icon.
123
- */
124
- function ComposerTool({ label, icon, text, caret = false, onPress, disabled = false, ...rest }) {
125
- return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('composer-tool'), ...(0, slot_1.tip)(label), role: "button", tabIndex: disabled ? -1 : 0, "aria-label": label, "aria-disabled": disabled || undefined, "aria-haspopup": caret ? 'menu' : undefined, height: 24, px: text ? '$1.5' : '$1', gap: "$1", items: "center", rounded: "$2", shrink: 0, cursor: disabled ? 'default' : 'pointer', opacity: disabled ? 0.5 : 1, hoverStyle: disabled ? undefined : { bg: '$hover' }, focusVisibleStyle: { outlineColor: '$outlineColor', outlineWidth: 2, outlineStyle: 'solid' }, hitSlop: { top: 10, bottom: 10, left: 2, right: 2 }, onPress: disabled ? undefined : onPress, onKeyDown: (e) => {
126
- if (disabled || (e?.key !== 'Enter' && e?.key !== ' '))
199
+ const round = ((0, jsx_runtime_1.jsx)(composer_1.Control, { type: "button", size: hit, fill: true, rounded: 999, ...(0, slot_1.slot)('composer-send'), "aria-label": t(busy ? 'Stop' : 'Send'), "aria-disabled": !live || undefined, opacity: live ? 1 : 0.4, focusVisibleStyle: ring_1.RING, onClick: () => {
200
+ if (!live)
127
201
  return;
128
- e.preventDefault?.();
129
- onPress?.();
130
- }, ...rest, children: [icon ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { "aria-hidden": true, items: "center", children: icon })) : null, text ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$2", color: "$quiet", numberOfLines: 1, children: text })) : null, caret ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.ChevronDown, { size: 12, color: "$soft", "aria-hidden": true }) : null] }));
202
+ if (busy)
203
+ onStop?.();
204
+ else
205
+ onSend();
206
+ }, children: busy ? (0, jsx_runtime_1.jsx)(lucide_icons_2_1.Square, { size: 13, color: ON, fill: ON }) : (0, jsx_runtime_1.jsx)(lucide_icons_2_1.ArrowUp, { size: 16, strokeWidth: 2.5, color: ON }) }));
207
+ const mention = listed && shelf && typed ? (0, jsx_runtime_1.jsx)(Mention_1.Mention, { shelf: shelf, rows: listed, index: row, onPick: pick, skills: typed.char === '/' }) : null;
208
+ const above = starters || head || note || mention ? ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('composer-head'), gap: "$1.5", children: [starters, head, mention, note ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { ...(0, slot_1.slot)('composer-note'), fontSize: 12, color: "$soft", text: "center", self: "center", children: note })) : null] })) : null;
209
+ const shown = showChips && chips?.length ? chips : null;
210
+ const tuned = (showModel && mind) || (showMode && mode);
211
+ const under = shown || tuned ? ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('composer-foot'), items: "center", gap: 6, flexWrap: "wrap", rowGap: 4, width: "100%", children: [shown ? (0, jsx_runtime_1.jsx)(Tune_1.Chips, { chips: shown }) : null, tuned ? (0, jsx_runtime_1.jsx)(Tune_1.Tune, { mind: showModel ? mind : null, mode: showMode ? mode : null, onUpgrade: onUpgrade, limits: limits }) : null] })) : null;
212
+ return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('composer-shell'), ...(column ? exports.measure : { width: '100%' }), gap: 6, ...(lift ? { mb: lift } : null), ...props, children: [above, (0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('composer'), width: "100%", rounded: CORNER, borderWidth: 1, borderColor: "$borderColor", bg: "$edge", p: 8, pt: pills ? 8 : 12, gap: 6, "$max-sm": { rounded: CORNER_PHONE }, ...(framed ? { boxShadow: 'var(--shadow-sheet-1)' } : null), children: [pills ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { ...(0, slot_1.slot)('composer-pills'), items: "center", gap: 4, flexWrap: "wrap", rowGap: 4, px: 2, children: pills })) : null, input, (0, jsx_runtime_1.jsxs)(gui_1.XStack, { items: "center", gap: 4, children: [(0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('composer-start'), items: "center", gap: 4, flex: 1, minW: 0, flexWrap: "wrap", children: [plus ? (0, jsx_runtime_1.jsx)(Plus_1.Plus, { ...plus, size: hit, disabled: disabled || plus.disabled }) : null, (carried ?? []).map((c) => ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('composer-carried'), items: "center", gap: 6, paddingInlineStart: 8, paddingInlineEnd: 4, height: 28, rounded: 8, bg: "$hover", maxW: 180, children: [c.icon ? (0, jsx_runtime_1.jsx)(gui_1.XStack, { "aria-hidden": true, children: c.icon }) : null, (0, jsx_runtime_1.jsx)(gui_1.SizableText, { fontSize: 13, color: "$ink", numberOfLines: 1, shrink: 1, children: c.label }), (0, jsx_runtime_1.jsx)(gui_1.XStack, { render: "button", "aria-label": t('Remove {name}', { name: c.label }), onPress: c.onRemove, width: 20, height: 20, rounded: 6, items: "center", justify: "center", hoverStyle: { bg: '$raised' }, cursor: "pointer", children: (0, jsx_runtime_1.jsx)(lucide_icons_2_1.X, { size: 12, color: "$hint" }) })] }, c.id))), children] }), (0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('composer-end'), items: "center", gap: 4, shrink: 0, children: [hint ? ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: hint })) : null, effort ? (0, jsx_runtime_1.jsx)(Dial_1.Dial, { effort: effort, size: hit, disabled: disabled }) : null, commands?.length ? (0, jsx_runtime_1.jsx)(Palette_1.Palette, { commands: commands, open: palette, onOpenChange: setPalette, size: hit, disabled: disabled }) : null, voice ? (0, jsx_runtime_1.jsx)(Dictation_1.Dictation, { voice: voice, disabled: disabled, size: hit, language: language, ...(onLanguage ? { onLanguage } : {}) }) : null, !busy && !lit && talk ? ((0, jsx_runtime_1.jsx)(composer_1.Control, { asChild: true, size: hit, fill: narrow, rounded: 999, ...(narrow ? null : QUIET), focusVisibleStyle: ring_1.RING, children: (0, jsx_runtime_1.jsx)(voice_1.Voice, { voice: talk, disabled: disabled, "data-slot": "composer-talk", says: { idle: t('Voice mode'), listening: t('In conversation — click to hang up'), speaking: t('Hanzo is speaking — talk to interrupt') }, children: () => (0, jsx_runtime_1.jsx)(lucide_icons_2_1.AudioLines, { size: 16, color: narrow ? ON : 'var(--foreground)' }) }) })) : (round)] })] })] }), under] }));
131
213
  }
@@ -1,109 +1,138 @@
1
1
  /**
2
- * Composer — the one chat input for every Hanzo surface.
2
+ * Composer — the one composer every Hanzo surface draws: Chat, Dev, Studio, a
3
+ * room, a reply, a run being steered. A surface hands it slots and defaults and
4
+ * nothing else; the field, the keys, the controls and their look are here once.
3
5
  *
4
- * Presentational and controlled: it owns no draft, no transport and no model
5
- * state. `children` is the toolbar slot, which is where a surface puts its
6
- * `ModelPicker`, attachment control or mode chips — that keeps the shell the
7
- * same everywhere while the affordances stay per-surface.
6
+ * ┌ pills ───────────────────────────────┐ where a run goes, which repository
7
+ * │ the field │
8
+ * │ + carried… children ✦ 🎙 ⬆ │ + menu, what the draft carries,
9
+ * └──────────────────────────────────────┘ commands, dictation, send / stop
10
+ * chips… model effort mode
8
11
  *
9
- * The send control is the same button in both states: it submits, and while a
10
- * turn is in flight it stops. Two buttons in one place was the thing every
11
- * surface got subtly different.
12
+ * Above the frame: the surface's `head`, the `/` or `@` list, and the `note`.
13
+ * Under it, one row: the surface's chips, then the model, the effort and the mode.
12
14
  *
13
- * Escape and ArrowUp are not bound. Dismissal belongs to whatever the composer
14
- * floats inside, and history recall needs a turn store this has no view of.
15
+ * THE PERSON'S SETTING (@hanzo/appearance `useComposing`, Settings →
16
+ * Appearance) decides which key sends and whether the chips, the model
17
+ * selector and the mode are drawn, everywhere at once. An axis they left on
18
+ * Auto takes the surface's `defaults`, and the model selector is off until
19
+ * they turn it on.
15
20
  *
16
- * Growth is `Textarea`'s and follows the content, so a wrapped paragraph raises
17
- * the field. `rows` is the floor, `maxHeight` the ceiling.
21
+ * Its paint is @hanzo/design's: `$` tokens and `--primary`, sized through
22
+ * `--density` (the round controls are @hanzo/composer's `Control`), so text
23
+ * size, density and accent change it with the rest of the product.
24
+ *
25
+ * Its own words are the reader's language (@hanzo/i18n `t`). A host's words —
26
+ * its placeholder, a shelf's rows, a chip's label — are drawn as given.
18
27
  */
19
- import { XStack, YStack } from '@hanzo/gui';
20
- import type { ComponentProps, ReactNode } from 'react';
28
+ import { YStack } from '@hanzo/gui';
29
+ import { type Composing } from '@hanzo/appearance';
30
+ import { type Machine } from '@hanzo/voice';
31
+ import { type ComponentProps, type ReactNode } from 'react';
21
32
  import { Textarea } from '../backends/gui/index.js';
33
+ import type { PauseSource } from '../models/catalog.js';
34
+ import { type Command } from './Palette.js';
35
+ import { type PlusProps, type Shelf } from './Plus.js';
36
+ import { type Chip, type Mind, type Modes } from './Tune.js';
22
37
  /** `onChange` is dropped: here it carries the draft, not a DOM change event. */
23
38
  type Stack = Omit<ComponentProps<typeof YStack>, 'children' | 'onChange'>;
24
39
  type FieldProps = Omit<ComponentProps<typeof Textarea>, 'value' | 'onChangeText'>;
25
40
  /**
26
- * The resting placeholder.
27
- *
28
- * "Ask anything", not "Send a message" and not "Message <model>". It addresses
29
- * the person rather than describing the mechanism, and being one constant string
30
- * it never has to be recomputed or re-announced when the model or endpoint
31
- * changes — which is what a model-named placeholder forces a surface to do.
41
+ * The resting placeholder. It addresses the person rather than the mechanism,
42
+ * and as one constant it never re-announces when the model changes.
32
43
  */
33
- export declare const ASK = "Ask anything";
44
+ export declare const ASK: string;
45
+ /** The reading measure: @hanzo/design's prose width, which Width (appearance) retunes. */
46
+ export declare const MEASURE = "var(--container-prose, 48rem)";
47
+ /** The space between turns, px: one rhythm for every thread. */
48
+ export declare const GAP = 20;
49
+ /** The composer's width under a thread: the measure less its 0.75rem gutters, centred, so its edges are the text's. */
50
+ export declare const measure: {
51
+ readonly width: 'calc(100% - 1.5rem)';
52
+ readonly maxW: "calc(var(--container-prose, 48rem) - 1.5rem)";
53
+ readonly mx: 'auto';
54
+ };
55
+ /** The round controls' box, px, and a phone's, a finger's width: `+`, the effort, the mic, its chevron and send all take it, so they share one centreline. */
56
+ export declare const ROUND = 36;
57
+ /** One thing the draft carries, after `+`: a file, a skill that is on. */
58
+ export interface Carried {
59
+ id: string;
60
+ label: string;
61
+ icon?: ReactNode;
62
+ onRemove: () => void;
63
+ }
34
64
  export interface ComposerProps extends Stack {
35
65
  value: string;
36
66
  onChange: (value: string) => void;
37
- /** Called when the draft is submitted. Clearing `value` is the host's job. */
67
+ /** The draft is submitted. Clearing `value` is the host's job. */
38
68
  onSend: () => void;
39
- /** Called instead of `onSend` while `busy`. Omit to disable stopping. */
69
+ /** Called instead of `onSend` while `busy`. Absent, busy only disables send. */
40
70
  onStop?: () => void;
41
- /** A turn is in flight: the send control becomes stop. */
71
+ /** A turn is in flight: send becomes stop. */
42
72
  busy?: boolean;
43
73
  disabled?: boolean;
74
+ /** Whether send is lit. Default: the draft has words. */
75
+ ready?: boolean;
44
76
  placeholder?: string;
77
+ /** The field's accessible name, independent of the placeholder. */
78
+ label?: string;
45
79
  /** Row floor for the field. It grows with the draft from here. */
46
80
  rows?: number;
47
- /** Ceiling for that growth, px. Past it the field scrolls instead. */
81
+ /** Ceiling for that growth, px. Past it the field scrolls. */
48
82
  maxHeight?: number;
49
- /** Toolbar slot, rendered at the start of the footer row. */
50
- children?: ReactNode;
51
- /** Hint shown at the end of the footer row. */
52
- hint?: string;
53
- /**
54
- * The accessible name of the field, independent of `placeholder`.
55
- *
56
- * A placeholder that rotates renames the control on every tick and gets the
57
- * field re-announced mid-sentence. The name is stable; the placeholder is
58
- * decoration.
59
- */
60
- label?: string;
61
- /** The field's own props — a ref, a testid, focus handlers, a paste handler. */
83
+ /** The field's own props — a ref, a testid, a paste handler. */
62
84
  field?: FieldProps;
63
- /** Replaces the send control. `children` is the START of the footer row, so a
64
- * second commit mode has nowhere else to go. */
65
- send?: ReactNode;
66
- /**
67
- * Drawn ABOVE the frame — the row of context a draft is sent with (where it
68
- * runs, which repository, which branch). Outside the frame on purpose: it
69
- * says what the draft is about, and the field says what it is.
70
- */
85
+ /** A word at the end of the tool row, before the controls: a status. */
86
+ hint?: string;
87
+ /** The tool row's start, after `+` and what the draft carries. */
88
+ children?: ReactNode;
89
+ /** Above the frame, at its width: what the draft is sent with, a banner. */
71
90
  head?: ReactNode;
72
- /**
73
- * Drawn UNDER the frame — attach, voice, mode at its start and the model at
74
- * its end, as the host arranges them. Unlike `children`, which lives inside
75
- * the frame beside the send control.
76
- */
77
- foot?: ReactNode;
78
- /**
79
- * One line: the field and the send control share a single row inside the
80
- * frame, and the send control is a glyph at the field's end — Enter's own
81
- * mark while idle, Stop while busy. `children` and `hint` join that row
82
- * before it. Unset, the frame is the stacked field-over-toolbar it has
83
- * always been.
84
- */
85
- inline?: boolean;
86
- }
87
- export declare function Composer({ value, onChange, onSend, onStop, busy, disabled, placeholder, rows, maxHeight, children, hint, label, field, send, head, foot, inline, ...props }: ComposerProps): import("react").JSX.Element;
88
- type Row = Omit<ComponentProps<typeof XStack>, 'children'>;
89
- export interface ComposerToolProps extends Row {
90
- /** The control's name — what a screen reader says and the tooltip shows. */
91
- label: string;
92
- icon?: ReactNode;
93
- /** Words drawn after the icon — a mode, a model. Absent, the tool is icon-only. */
94
- text?: string;
95
- /** A trailing caret: this opens a menu. */
96
- caret?: boolean;
97
- onPress?: () => void;
98
- disabled?: boolean;
91
+ /** The frame's first row: the surface's pills — where a run goes, which repository, which branch. */
92
+ pills?: ReactNode;
93
+ /** What the draft carries, as chips after `+`. */
94
+ carried?: readonly Carried[];
95
+ /** The `+` menu. Absent, there is none. */
96
+ plus?: PlusProps;
97
+ /** `/` lists these (the skills) above the frame. */
98
+ slash?: Shelf;
99
+ /** `@` lists these (the plugins) above the frame. */
100
+ at?: Shelf;
101
+ /** The commands ✦ and ⌘K open. */
102
+ commands?: readonly Command[];
103
+ /** Under the frame, at the row's start. Hidden where the person hid chips. */
104
+ chips?: readonly Chip[];
105
+ /** The model, drawn where the person turned the model selector on. Null where the next send names none (steering a run). */
106
+ mind?: Mind | null;
107
+ /** The effort, one in force. Null where the next send takes none (steering a run). */
108
+ effort?: Modes | null;
109
+ limits?: PauseSource | null;
110
+ /** A model the plan does not grant was chosen: the way to the plan that does. */
111
+ onUpgrade?: (model: string) => void;
112
+ /** The mode, as the pill at the row's end. */
113
+ mode?: Modes | null;
114
+ /** Dictation into the draft (@hanzo/voice `useVoice` + `useDictation`). */
115
+ voice?: Machine;
116
+ /** The language dictation listens in, null for Auto, and how to change it. */
117
+ language?: string | null;
118
+ onLanguage?: (id: string | null) => void;
119
+ /** A spoken conversation (@hanzo/voice `useTalk`): the round button while the draft is empty. */
120
+ talk?: Machine;
121
+ /** Above the frame, nearest it: the person's suggestions, at every width. */
122
+ starters?: ReactNode;
123
+ /** Centred just above the frame: what every message is sent under. */
124
+ note?: ReactNode;
125
+ /** At the reading column's width (`measure`), centred: the composer under a thread, so its edges are the text's. Absent, the width of what holds it. */
126
+ column?: boolean;
127
+ /** Drawn on a pane: the frame floats as a pane of its own. */
128
+ framed?: boolean;
129
+ /** A phone: suggestions go above the frame and every target is 44px. Absent, the viewport decides. */
130
+ narrow?: boolean;
131
+ /** This surface's answer where the person left an axis on Auto. */
132
+ defaults?: Composing;
99
133
  }
100
- /**
101
- * ComposerTool — one quiet control in a composer's `foot` or `head`: attach,
102
- * voice, a mode, the model. 24px tall, muted until pointed at, and a real
103
- * button to the keyboard. Its name is `label` whether or not it shows words,
104
- * because an icon-only control is the whole navigation for someone who cannot
105
- * see the icon.
106
- */
107
- export declare function ComposerTool({ label, icon, text, caret, onPress, disabled, ...rest }: ComposerToolProps): import("react").JSX.Element;
134
+ /** Ctrl+U (⌘U) uploads, while a composer with an upload is on the page. */
135
+ export declare function useUpload(upload: (() => void) | undefined): void;
136
+ export declare function Composer({ value, onChange, onSend, onStop, busy, disabled, ready: readyProp, placeholder, label, rows, maxHeight, field, hint, children, head, pills, carried, plus, slash, at, commands, chips, mind, effort, limits, onUpgrade, mode, voice, language, onLanguage, talk, starters, note, column, framed, narrow: narrowProp, defaults, ...props }: ComposerProps): import("react").JSX.Element;
108
137
  export {};
109
138
  //# sourceMappingURL=Composer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../src/chat/Composer.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAe,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtD,OAAO,EAAU,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAIlD,gFAAgF;AAChF,KAAK,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,CAAA;AACzE,KAAK,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,CAAA;AAyBjF;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG,iBAAiB,CAAA;AAEjC,MAAM,WAAW,aAAc,SAAQ,KAAK;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,gFAAgF;IAChF,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB;qDACiD;IACjD,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAM,EACN,IAAY,EACZ,QAAgB,EAChB,WAAiB,EACjB,IAAe,EACf,SAAmB,EACnB,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAc,EACd,GAAG,KAAK,EACT,EAAE,aAAa,+BA2Kf;AAED,KAAK,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC,CAAA;AAE1D,MAAM,WAAW,iBAAkB,SAAQ,GAAG;IAC5C,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,KAAa,EACb,OAAO,EACP,QAAgB,EAChB,GAAG,IAAI,EACR,EAAE,iBAAiB,+BA0CnB"}
1
+ {"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../src/chat/Composer.tsx"],"names":[],"mappings":"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"}