@reforma/components 0.2.1 → 0.3.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.
Files changed (58) hide show
  1. package/dist/Button/Button.module.css +1 -1
  2. package/dist/Composer/RichField.d.ts +6 -2
  3. package/dist/Composer/RichField.d.ts.map +1 -1
  4. package/dist/Composer/RichField.js +107 -37
  5. package/dist/Composer/RichField.js.map +1 -1
  6. package/dist/Composer/context.d.ts +6 -2
  7. package/dist/Composer/context.d.ts.map +1 -1
  8. package/dist/Composer/context.js +158 -130
  9. package/dist/Composer/context.js.map +1 -1
  10. package/dist/Composer/index.d.ts +1 -1
  11. package/dist/Composer/index.d.ts.map +1 -1
  12. package/dist/Composer/parts.d.ts +18 -17
  13. package/dist/Composer/parts.d.ts.map +1 -1
  14. package/dist/Composer/parts.js +283 -187
  15. package/dist/Composer/parts.js.map +1 -1
  16. package/dist/Composer/reforma/Composer.module.css +1 -0
  17. package/dist/Composer/reforma/Composer.module.css.js +60 -0
  18. package/dist/Composer/reforma/Composer.module.css.js.map +1 -0
  19. package/dist/Composer/reforma/index.d.ts +4 -0
  20. package/dist/Composer/reforma/index.d.ts.map +1 -0
  21. package/dist/Composer/reforma/index.js +6 -0
  22. package/dist/Composer/reforma/index.js.map +1 -0
  23. package/dist/Composer/types.d.ts +6 -0
  24. package/dist/Composer/types.d.ts.map +1 -1
  25. package/dist/List/Menu.d.ts.map +1 -1
  26. package/dist/List/Menu.js +98 -84
  27. package/dist/List/Menu.js.map +1 -1
  28. package/dist/chat/Chip/Chip.js +9 -9
  29. package/dist/chat/Chip/Chip.module.css.js +8 -8
  30. package/dist/chat/Chip/helpers/cursorLines.d.ts +1 -0
  31. package/dist/chat/Chip/helpers/cursorLines.d.ts.map +1 -1
  32. package/dist/chat/Chip/helpers/cursorLines.js +27 -21
  33. package/dist/chat/Chip/helpers/cursorLines.js.map +1 -1
  34. package/dist/chat/Chip/index.d.ts +1 -1
  35. package/dist/chat/Chip/index.d.ts.map +1 -1
  36. package/dist/chat/Chip/index.js +9 -8
  37. package/dist/chat/Message/segments/MessagePhaseSection.module.css +1 -1
  38. package/dist/chat/Message/streamdown/options.d.ts +2 -0
  39. package/dist/chat/Message/streamdown/options.d.ts.map +1 -1
  40. package/dist/chat/Message/streamdown/options.js +13 -12
  41. package/dist/chat/Message/streamdown/options.js.map +1 -1
  42. package/dist/chat/Message/turn/MessageUserBubble.d.ts.map +1 -1
  43. package/dist/chat/Message/turn/MessageUserBubble.js +57 -54
  44. package/dist/chat/Message/turn/MessageUserBubble.js.map +1 -1
  45. package/dist/chat/Tool/mountTool.d.ts.map +1 -1
  46. package/dist/chat/Tool/remove-file/RemoveFileTool.d.ts +1 -1
  47. package/dist/chat/Tool/remove-file/RemoveFileTool.d.ts.map +1 -1
  48. package/dist/chat/Tool/remove-file/RemoveFileTool.js +82 -38
  49. package/dist/chat/Tool/remove-file/RemoveFileTool.js.map +1 -1
  50. package/dist/chat/Tool/remove-file/RemoveFileTool.module.css +1 -0
  51. package/dist/chat/Tool/remove-file/RemoveFileTool.module.css.js +8 -0
  52. package/dist/chat/Tool/remove-file/RemoveFileTool.module.css.js.map +1 -0
  53. package/dist/chat/index.js +110 -109
  54. package/dist/index.js +417 -416
  55. package/package.json +3 -1
  56. package/dist/Composer/Composer.module.css +0 -1
  57. package/dist/Composer/Composer.module.css.js +0 -26
  58. package/dist/Composer/Composer.module.css.js.map +0 -1
@@ -1,70 +1,91 @@
1
- import { coerceUploadMimeType as z, MAX_CHAT_ATTACHMENT_BYTES_PER_FILE as y, MAX_CHAT_ATTACHMENT_BYTES_TOTAL as x, COMPOSER_PASTE_AS_FILE_MIN_CHARS as $ } from "@reforma/constants";
2
- import { revokeObjectURL as A, formatFileSize as F, createObjectURL as X } from "@reforma/lib";
3
- import { useRef as f, useState as Y, useLayoutEffect as W, useEffect as q, useCallback as R, use as G, createContext as J } from "react";
4
- import { useFileDrag as K } from "../hooks/useFileDrag.js";
5
- import { toast as T } from "../Toast/Toast.js";
6
- import { jsxs as Q, jsx as V } from "react/jsx-runtime";
7
- const M = /* @__PURE__ */ J(null);
8
- function it() {
9
- const o = G(M);
10
- if (!o)
1
+ import { coerceUploadMimeType as x, MAX_CHAT_ATTACHMENT_BYTES_PER_FILE as S, MAX_CHAT_ATTACHMENT_BYTES_TOTAL as O, COMPOSER_PASTE_AS_FILE_MIN_CHARS as Z } from "@reforma/constants";
2
+ import { revokeObjectURL as C, formatFileSize as P, createObjectURL as ee } from "@reforma/lib";
3
+ import { useState as k, useCallback as y, useRef as f, useLayoutEffect as B, useEffect as te, use as re, createContext as ne } from "react";
4
+ import { useFileDrag as oe } from "../hooks/useFileDrag.js";
5
+ import { Show as se } from "../Show/Show.js";
6
+ import { jsxs as D, jsx as H } from "react/jsx-runtime";
7
+ const L = /* @__PURE__ */ ne(null);
8
+ function fe() {
9
+ const s = re(L);
10
+ if (!s)
11
11
  throw new Error("Composer pieces must render inside ComposerProvider");
12
- return o;
13
- }
14
- function Z(o) {
15
- let s = 0;
16
- for (const c of o)
17
- typeof c.size == "number" && Number.isFinite(c.size) && (s += c.size);
18
12
  return s;
19
13
  }
20
- function tt(o) {
21
- return o.length === 0 ? !0 : o.every((s) => s.uploadStatus === "ready" && !!s.url);
14
+ function ae(s) {
15
+ let a = 0;
16
+ for (const i of s)
17
+ typeof i.size == "number" && Number.isFinite(i.size) && (a += i.size);
18
+ return a;
19
+ }
20
+ function ie(s) {
21
+ return s.length === 0 ? !0 : s.every((a) => a.uploadStatus === "ready" && !!a.url);
22
22
  }
23
- function v(o, s, c) {
23
+ function E(s, a, i) {
24
24
  return {
25
- ...o,
26
- attachments: o.attachments.map((m) => m.clientId === s ? {
25
+ ...s,
26
+ attachments: s.attachments.map((m) => m.clientId === a ? {
27
27
  ...m,
28
- ...c
28
+ ...i
29
29
  } : m)
30
30
  };
31
31
  }
32
- function ct({
33
- value: o,
34
- onChange: s,
35
- onSubmit: c,
36
- uploadFile: m,
37
- busy: E = !1,
38
- placeholder: b = "What should it do?",
39
- autoFocus: O = !0,
40
- submitHotkey: C = "mod+enter",
41
- rows: h = 3,
42
- children: P
32
+ function he({
33
+ classNames: s = {},
34
+ onError: a,
35
+ value: i,
36
+ onChange: m,
37
+ onSubmit: U,
38
+ uploadFile: _,
39
+ busy: z = !1,
40
+ placeholder: I = "What should it do?",
41
+ autoFocus: N = !0,
42
+ submitHotkey: j = "mod+enter",
43
+ rows: A = 3,
44
+ children: $
43
45
  }) {
44
- const S = f(null), _ = f(null), i = f(o), l = f(/* @__PURE__ */ new Map()), [B, D] = Y(!1);
45
- W(() => {
46
- i.current = o;
47
- }, [o]), q(() => {
48
- const t = l.current;
46
+ const [v, R] = k(null), h = y((e) => {
47
+ a ? a(e) : R(e);
48
+ }, [a]), w = f(null), F = f(null), c = f(i), M = f(m), d = f(/* @__PURE__ */ new Map()), [X, Y] = k(!1);
49
+ B(() => {
50
+ c.current = i;
51
+ }, [i]), B(() => {
52
+ M.current = m;
53
+ }, [m]);
54
+ const l = y((e) => {
55
+ c.current = e, M.current(e);
56
+ }, []);
57
+ te(() => {
58
+ const e = d.current;
49
59
  return () => {
50
- for (const n of i.current.attachments)
51
- A(n.preview);
52
- t.clear();
60
+ for (const n of c.current.attachments)
61
+ C(n.preview);
62
+ e.clear();
53
63
  };
54
64
  }, []);
55
- const w = !!o.prompt.trim() && tt(o.attachments) && !E, g = R(async (t, n) => {
56
- const r = await m(n), a = i.current;
57
- if (!a.attachments.some((u) => u.clientId === t)) {
58
- l.current.delete(t);
65
+ const b = !!i.prompt.trim() && ie(i.attachments) && !z, T = y(async (e, n) => {
66
+ let r;
67
+ try {
68
+ r = await _(n);
69
+ } catch (u) {
70
+ r = {
71
+ ok: !1,
72
+ message: u instanceof Error ? u.message : void 0
73
+ };
74
+ }
75
+ if (d.current.get(e) !== n)
76
+ return;
77
+ const o = c.current;
78
+ if (!o.attachments.some((u) => u.clientId === e)) {
79
+ d.current.delete(e);
59
80
  return;
60
81
  }
61
82
  if (r.ok) {
62
- const u = a.attachments.find((d) => d.clientId === t)?.preview;
63
- A(u), l.current.delete(t), s(v(a, t, {
83
+ const u = o.attachments.find((p) => p.clientId === e)?.preview;
84
+ C(u), d.current.delete(e), l(E(o, e, {
64
85
  id: r.data.id,
65
86
  url: r.data.url,
66
87
  filename: r.data.name ?? n.name,
67
- mediaType: r.data.mimeType ?? z(n.name, n.type),
88
+ mediaType: r.data.mimeType ?? x(n.name, n.type),
68
89
  size: r.data.size ?? n.size,
69
90
  uploadStatus: "ready",
70
91
  uploadError: void 0,
@@ -72,134 +93,141 @@ function ct({
72
93
  }));
73
94
  return;
74
95
  }
75
- s(v(a, t, {
96
+ l(E(o, e, {
76
97
  uploadStatus: "error",
77
98
  uploadError: r.message ?? "Upload failed"
78
99
  }));
79
- }, [s, m]), p = R((t) => {
80
- const n = [...t], r = [];
81
- let a = 0;
82
- const u = Z(i.current.attachments);
83
- for (const e of n) {
84
- if (e.size > y) {
85
- T.warning({
100
+ }, [l, _]), g = y((e) => {
101
+ R(null);
102
+ const n = [...e], r = [];
103
+ let o = 0;
104
+ const u = ae(c.current.attachments);
105
+ for (const t of n) {
106
+ if (t.size > S) {
107
+ h({
86
108
  title: "Attachment too large",
87
- message: `${e.name} is over the ${F(y, {
109
+ message: `${t.name} is over the ${P(S, {
88
110
  round: "up"
89
111
  })} per-file limit.`
90
112
  });
91
113
  continue;
92
114
  }
93
- if (u + a + e.size > x) {
94
- T.warning({
115
+ if (u + o + t.size > O) {
116
+ h({
95
117
  title: "Attachments too large",
96
- message: `Adding ${e.name} would exceed the ${F(x, {
118
+ message: `Adding ${t.name} would exceed the ${P(O, {
97
119
  round: "up"
98
120
  })} combined limit.`
99
121
  });
100
122
  continue;
101
123
  }
102
- r.push(e), a += e.size;
124
+ r.push(t), o += t.size;
103
125
  }
104
126
  if (r.length === 0)
105
127
  return;
106
- const d = r.map((e) => ({
128
+ const p = r.map((t) => ({
107
129
  clientId: crypto.randomUUID(),
108
- filename: e.name,
109
- mediaType: z(e.name, e.type),
110
- size: e.size,
111
- lastModified: e.lastModified,
130
+ filename: t.name,
131
+ mediaType: x(t.name, t.type),
132
+ size: t.size,
133
+ lastModified: t.lastModified,
112
134
  uploadStatus: "uploading",
113
- preview: X(e) ?? void 0
135
+ preview: ee(t) ?? void 0
114
136
  }));
115
- for (let e = 0; e < r.length; e++)
116
- l.current.set(d[e].clientId, r[e]);
117
- const N = {
118
- ...i.current,
119
- attachments: [...i.current.attachments, ...d]
137
+ for (let t = 0; t < r.length; t++)
138
+ d.current.set(p[t].clientId, r[t]);
139
+ const Q = {
140
+ ...c.current,
141
+ attachments: [...c.current.attachments, ...p]
120
142
  };
121
- s(N);
122
- for (let e = 0; e < r.length; e++)
123
- g(d[e].clientId, r[e]);
124
- }, [s, g]), H = K({
125
- onFileDragOver: D,
126
- onFilesDropped: (t) => p(t)
127
- }), I = (t) => {
128
- const n = i.current, r = n.attachments.find((a) => a.clientId === t);
129
- A(r?.preview), l.current.delete(t), s({
143
+ l(Q);
144
+ for (let t = 0; t < r.length; t++)
145
+ T(p[t].clientId, r[t]);
146
+ }, [l, T, h]), V = oe({
147
+ onFileDragOver: Y,
148
+ onFilesDropped: (e) => g(e)
149
+ }), W = (e) => {
150
+ const n = c.current, r = n.attachments.find((o) => o.clientId === e);
151
+ C(r?.preview), d.current.delete(e), l({
130
152
  ...n,
131
- attachments: n.attachments.filter((a) => a.clientId !== t)
153
+ attachments: n.attachments.filter((o) => o.clientId !== e)
132
154
  });
133
- }, L = (t) => {
134
- const n = i.current, r = n.attachments.find((u) => u.clientId === t), a = l.current.get(t);
155
+ }, q = (e) => {
156
+ const n = c.current, r = n.attachments.find((u) => u.clientId === e), o = d.current.get(e);
135
157
  if (!(!r || r.uploadStatus !== "error")) {
136
- if (!a) {
137
- T.warning({
158
+ if (!o) {
159
+ h({
138
160
  title: "Could not retry",
139
161
  message: "Remove the file and attach it again."
140
162
  });
141
163
  return;
142
164
  }
143
- s(v(n, t, {
165
+ l(E(n, e, {
144
166
  uploadStatus: "uploading",
145
167
  uploadError: void 0
146
- })), g(t, a);
168
+ })), T(e, o);
147
169
  }
148
- }, U = () => {
149
- w && c();
150
- }, k = (t) => {
151
- if (t.length < $)
170
+ }, G = () => {
171
+ b && U();
172
+ }, J = (e) => {
173
+ if (e.length < Z)
152
174
  return !1;
153
- const n = new File([t], "paste.txt", {
175
+ const n = new File([e], "paste.txt", {
154
176
  type: "text/plain"
155
177
  });
156
- return n.size > y ? !1 : (p([n]), !0);
157
- }, j = {
158
- value: o,
159
- setPrompt: (t) => s({
160
- ...i.current,
161
- prompt: t
178
+ return n.size > S ? !1 : (g([n]), !0);
179
+ }, K = {
180
+ classNames: s,
181
+ value: i,
182
+ setPrompt: (e) => l({
183
+ ...c.current,
184
+ prompt: e
162
185
  }),
163
- setPlanMode: (t) => s({
164
- ...i.current,
165
- planMode: t
186
+ setPlanMode: (e) => l({
187
+ ...c.current,
188
+ planMode: e
166
189
  }),
167
- addFiles: p,
168
- removeAttachment: I,
169
- retryAttachment: L,
170
- submit: U,
171
- canSubmit: w,
172
- busy: E,
173
- placeholder: b,
174
- autoFocus: O,
175
- submitOnEnter: C === "enter",
176
- rows: h,
177
- minHeight: h ? h * 22 : 20,
178
- pasteTextAsFile: k,
179
- openFilePicker: () => S.current?.click(),
180
- focus: () => _.current?.focus(),
181
- focusRef: _,
182
- fileDragOver: B,
183
- drag: H
190
+ addFiles: g,
191
+ removeAttachment: W,
192
+ retryAttachment: q,
193
+ submit: G,
194
+ canSubmit: b,
195
+ busy: z,
196
+ placeholder: I,
197
+ autoFocus: N,
198
+ submitOnEnter: j === "enter",
199
+ rows: A,
200
+ minHeight: A ? A * 22 : 20,
201
+ pasteTextAsFile: J,
202
+ openFilePicker: () => w.current?.click(),
203
+ focus: () => F.current?.focus(),
204
+ focusRef: F,
205
+ fileDragOver: X,
206
+ drag: V
184
207
  };
185
- return /* @__PURE__ */ Q(M, {
186
- value: j,
187
- children: [P, /* @__PURE__ */ V("input", {
188
- ref: S,
208
+ return /* @__PURE__ */ D(L, {
209
+ value: K,
210
+ children: [$, /* @__PURE__ */ H(se, {
211
+ when: v && !a,
212
+ children: /* @__PURE__ */ D("p", {
213
+ role: "alert",
214
+ className: s.notice,
215
+ children: [v?.title, ": ", v?.message]
216
+ })
217
+ }), /* @__PURE__ */ H("input", {
218
+ ref: w,
189
219
  type: "file",
190
220
  multiple: !0,
191
221
  tabIndex: -1,
192
- style: {
193
- display: "none"
194
- },
195
- onChange: (t) => {
196
- t.target.files?.length && p(t.target.files), t.target.value = "";
222
+ hidden: !0,
223
+ onChange: (e) => {
224
+ e.target.files?.length && g(e.target.files), e.target.value = "";
197
225
  }
198
226
  })]
199
227
  });
200
228
  }
201
229
  export {
202
- ct as ComposerProvider,
203
- it as useComposer
230
+ he as ComposerProvider,
231
+ fe as useComposer
204
232
  };
205
233
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sources":["../../src/Composer/context.tsx"],"sourcesContent":["'use client';\n\nimport {\n coerceUploadMimeType,\n COMPOSER_PASTE_AS_FILE_MIN_CHARS,\n MAX_CHAT_ATTACHMENT_BYTES_PER_FILE,\n MAX_CHAT_ATTACHMENT_BYTES_TOTAL,\n} from '@reforma/constants';\nimport { createObjectURL, formatFileSize, revokeObjectURL } from '@reforma/lib';\nimport {\n createContext,\n use,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\n\nimport { useFileDrag } from '../hooks/useFileDrag';\nimport { toast } from '../Toast';\n\nimport type {\n ComposerAttachment,\n ComposerUploadResult,\n ComposerValue,\n} from './types';\n\nexport type ComposerFieldHandle = {\n focus: () => void;\n};\n\nexport type ComposerContextValue = {\n value: ComposerValue;\n setPrompt: (prompt: string) => void;\n setPlanMode: (planMode: boolean) => void;\n addFiles: (files: FileList | readonly File[]) => void;\n removeAttachment: (clientId: string) => void;\n retryAttachment: (clientId: string) => void;\n submit: () => void;\n canSubmit: boolean;\n busy: boolean;\n placeholder: string;\n autoFocus: boolean;\n submitOnEnter: boolean;\n rows: number;\n minHeight: number;\n pasteTextAsFile: (text: string) => boolean;\n openFilePicker: () => void;\n focus: () => void;\n focusRef: RefObject<ComposerFieldHandle | null>;\n fileDragOver: boolean;\n drag: ReturnType<typeof useFileDrag>;\n};\n\nconst ComposerContext = createContext<ComposerContextValue | null>(null);\n\nexport function useComposer(): ComposerContextValue {\n const context = use(ComposerContext);\n\n if (!context) {\n throw new Error('Composer pieces must render inside ComposerProvider');\n }\n\n return context;\n}\n\nfunction sumAttachmentBytes(items: readonly ComposerAttachment[]): number {\n let sum = 0;\n\n for (const item of items) {\n if (typeof item.size === 'number' && Number.isFinite(item.size)) {\n sum += item.size;\n }\n }\n\n return sum;\n}\n\nfunction attachmentsReady(items: readonly ComposerAttachment[]): boolean {\n if (items.length === 0) {\n return true;\n }\n\n return items.every(item => item.uploadStatus === 'ready' && Boolean(item.url));\n}\n\nfunction patchAttachment(\n value: ComposerValue,\n clientId: string,\n patch: Partial<ComposerAttachment>\n): ComposerValue {\n return {\n ...value,\n attachments: value.attachments.map(item => (\n item.clientId === clientId ? { ...item, ...patch } : item\n )),\n };\n}\n\nexport type ComposerProviderProps = {\n value: ComposerValue;\n onChange: (value: ComposerValue) => void;\n onSubmit: () => void;\n uploadFile: (file: File) => Promise<ComposerUploadResult>;\n busy?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n submitHotkey?: 'enter' | 'mod+enter';\n /** Fixed min rows for the field (create project uses 3). */\n rows?: number;\n children: ReactNode;\n};\n\nexport function ComposerProvider({\n value,\n onChange,\n onSubmit,\n uploadFile,\n busy = false,\n placeholder = 'What should it do?',\n autoFocus = true,\n submitHotkey = 'mod+enter',\n rows = 3,\n children,\n}: ComposerProviderProps) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const focusRef = useRef<ComposerFieldHandle | null>(null);\n const valueRef = useRef(value);\n const pendingFilesRef = useRef(new Map<string, File>());\n const [fileDragOver, setFileDragOver] = useState(false);\n\n useLayoutEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n useEffect(() => {\n const pending = pendingFilesRef.current;\n\n return () => {\n for (const item of valueRef.current.attachments) {\n revokeObjectURL(item.preview);\n }\n\n pending.clear();\n };\n }, []);\n\n const canSubmit = Boolean(value.prompt.trim())\n && attachmentsReady(value.attachments)\n && !busy;\n\n const uploadOne = useCallback(async(clientId: string, file: File) => {\n const result = await uploadFile(file);\n const current = valueRef.current;\n\n if (!current.attachments.some(item => item.clientId === clientId)) {\n pendingFilesRef.current.delete(clientId);\n\n return;\n }\n\n if (result.ok) {\n const preview = current.attachments.find(item => item.clientId === clientId)?.preview;\n revokeObjectURL(preview);\n pendingFilesRef.current.delete(clientId);\n onChange(patchAttachment(current, clientId, {\n id: result.data.id,\n url: result.data.url,\n filename: result.data.name ?? file.name,\n mediaType: result.data.mimeType ?? coerceUploadMimeType(file.name, file.type),\n size: result.data.size ?? file.size,\n uploadStatus: 'ready',\n uploadError: undefined,\n preview: undefined,\n }));\n\n return;\n }\n\n onChange(patchAttachment(current, clientId, {\n uploadStatus: 'error',\n uploadError: result.message ?? 'Upload failed',\n }));\n }, [onChange, uploadFile]);\n\n const addFiles = useCallback((files: FileList | readonly File[]) => {\n const list = [...files];\n const accepted: File[] = [];\n let batchBytes = 0;\n const used = sumAttachmentBytes(valueRef.current.attachments);\n\n for (const file of list) {\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n toast.warning({\n title: 'Attachment too large',\n message: `${ file.name } is over the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_PER_FILE, { round: 'up' }) } per-file limit.`,\n });\n continue;\n }\n\n if (used + batchBytes + file.size > MAX_CHAT_ATTACHMENT_BYTES_TOTAL) {\n toast.warning({\n title: 'Attachments too large',\n message: `Adding ${ file.name } would exceed the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_TOTAL, { round: 'up' }) } combined limit.`,\n });\n continue;\n }\n\n accepted.push(file);\n batchBytes += file.size;\n }\n\n if (accepted.length === 0) {\n return;\n }\n\n const nextItems: ComposerAttachment[] = accepted.map(file => ({\n clientId: crypto.randomUUID(),\n filename: file.name,\n mediaType: coerceUploadMimeType(file.name, file.type),\n size: file.size,\n lastModified: file.lastModified,\n uploadStatus: 'uploading',\n preview: createObjectURL(file) ?? undefined,\n }));\n\n for (let i = 0; i < accepted.length; i++) {\n pendingFilesRef.current.set(nextItems[i]!.clientId, accepted[i]!);\n }\n\n const next: ComposerValue = {\n ...valueRef.current,\n attachments: [...valueRef.current.attachments, ...nextItems],\n };\n onChange(next);\n\n for (let i = 0; i < accepted.length; i++) {\n void uploadOne(nextItems[i]!.clientId, accepted[i]!);\n }\n }, [onChange, uploadOne]);\n\n const drag = useFileDrag({\n onFileDragOver: setFileDragOver,\n onFilesDropped: files => addFiles(files),\n });\n\n const removeAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n revokeObjectURL(item?.preview);\n pendingFilesRef.current.delete(clientId);\n onChange({\n ...current,\n attachments: current.attachments.filter(entry => entry.clientId !== clientId),\n });\n };\n\n const retryAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n const file = pendingFilesRef.current.get(clientId);\n\n if (!item || item.uploadStatus !== 'error') {\n return;\n }\n\n if (!file) {\n toast.warning({\n title: 'Could not retry',\n message: 'Remove the file and attach it again.',\n });\n\n return;\n }\n\n onChange(patchAttachment(current, clientId, {\n uploadStatus: 'uploading',\n uploadError: undefined,\n }));\n void uploadOne(clientId, file);\n };\n\n const submit = () => {\n if (!canSubmit) {\n return;\n }\n\n onSubmit();\n };\n\n const pasteTextAsFile = (text: string) => {\n if (text.length < COMPOSER_PASTE_AS_FILE_MIN_CHARS) {\n return false;\n }\n\n const file = new File([text], 'paste.txt', { type: 'text/plain' });\n\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n return false;\n }\n\n addFiles([file]);\n\n return true;\n };\n\n const api: ComposerContextValue = {\n value,\n setPrompt: (prompt) => onChange({ ...valueRef.current, prompt }),\n setPlanMode: (planMode) => onChange({ ...valueRef.current, planMode }),\n addFiles,\n removeAttachment,\n retryAttachment,\n submit,\n canSubmit,\n busy,\n placeholder,\n autoFocus,\n submitOnEnter: submitHotkey === 'enter',\n rows,\n minHeight: rows ? rows * 22 : 20,\n pasteTextAsFile,\n openFilePicker: () => fileInputRef.current?.click(),\n focus: () => focusRef.current?.focus(),\n focusRef,\n fileDragOver,\n drag,\n };\n\n return (\n <ComposerContext value={ api }>\n { children }\n <input\n ref={ fileInputRef }\n type=\"file\"\n multiple\n tabIndex={ -1 }\n style={ { display: 'none' } }\n onChange={ (event) => {\n if (event.target.files?.length) {\n addFiles(event.target.files);\n }\n\n event.target.value = '';\n } }\n />\n </ComposerContext>\n );\n}\n"],"names":["ComposerContext","useComposer","context","use","sumAttachmentBytes","items","sum","item","attachmentsReady","patchAttachment","value","clientId","patch","ComposerProvider","onChange","onSubmit","uploadFile","busy","placeholder","autoFocus","submitHotkey","rows","children","fileInputRef","useRef","focusRef","valueRef","pendingFilesRef","fileDragOver","setFileDragOver","useState","useLayoutEffect","useEffect","pending","revokeObjectURL","canSubmit","uploadOne","useCallback","file","result","current","preview","coerceUploadMimeType","addFiles","files","list","accepted","batchBytes","used","MAX_CHAT_ATTACHMENT_BYTES_PER_FILE","toast","formatFileSize","MAX_CHAT_ATTACHMENT_BYTES_TOTAL","nextItems","createObjectURL","i","next","drag","useFileDrag","removeAttachment","entry","retryAttachment","submit","pasteTextAsFile","text","COMPOSER_PASTE_AS_FILE_MIN_CHARS","api","prompt","planMode","_jsx","event"],"mappings":"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"}
1
+ {"version":3,"file":"context.js","sources":["../../src/Composer/context.tsx"],"sourcesContent":["'use client';\n\nimport {\n coerceUploadMimeType,\n COMPOSER_PASTE_AS_FILE_MIN_CHARS,\n MAX_CHAT_ATTACHMENT_BYTES_PER_FILE,\n MAX_CHAT_ATTACHMENT_BYTES_TOTAL,\n} from '@reforma/constants';\nimport { createObjectURL, formatFileSize, revokeObjectURL } from '@reforma/lib';\nimport {\n createContext,\n use,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\n\nimport { useFileDrag } from '../hooks/useFileDrag';\nimport { Show } from '../Show';\n\nimport type {\n ComposerAttachment,\n ComposerClassNames,\n ComposerNotice,\n ComposerUploadResult,\n ComposerValue,\n} from './types';\n\nexport type ComposerFieldHandle = {\n focus: () => void;\n};\n\nexport type ComposerContextValue = {\n classNames: ComposerClassNames;\n value: ComposerValue;\n setPrompt: (prompt: string) => void;\n setPlanMode: (planMode: boolean) => void;\n addFiles: (files: FileList | readonly File[]) => void;\n removeAttachment: (clientId: string) => void;\n retryAttachment: (clientId: string) => void;\n submit: () => void;\n canSubmit: boolean;\n busy: boolean;\n placeholder: string;\n autoFocus: boolean;\n submitOnEnter: boolean;\n rows: number;\n minHeight: number;\n pasteTextAsFile: (text: string) => boolean;\n openFilePicker: () => void;\n focus: () => void;\n focusRef: RefObject<ComposerFieldHandle | null>;\n fileDragOver: boolean;\n drag: ReturnType<typeof useFileDrag>;\n};\n\nconst ComposerContext = createContext<ComposerContextValue | null>(null);\n\nexport function useComposer(): ComposerContextValue {\n const context = use(ComposerContext);\n\n if (!context) {\n throw new Error('Composer pieces must render inside ComposerProvider');\n }\n\n return context;\n}\n\nfunction sumAttachmentBytes(items: readonly ComposerAttachment[]): number {\n let sum = 0;\n\n for (const item of items) {\n if (typeof item.size === 'number' && Number.isFinite(item.size)) {\n sum += item.size;\n }\n }\n\n return sum;\n}\n\nfunction attachmentsReady(items: readonly ComposerAttachment[]): boolean {\n if (items.length === 0) {\n return true;\n }\n\n return items.every(item => item.uploadStatus === 'ready' && Boolean(item.url));\n}\n\nfunction patchAttachment(\n value: ComposerValue,\n clientId: string,\n patch: Partial<ComposerAttachment>\n): ComposerValue {\n return {\n ...value,\n attachments: value.attachments.map(item => (\n item.clientId === clientId ? { ...item, ...patch } : item\n )),\n };\n}\n\nexport type ComposerProviderProps = {\n classNames?: ComposerClassNames;\n /** Report validation errors in the host UI. Defaults to an inline alert. */\n onError?: (notice: ComposerNotice) => void;\n value: ComposerValue;\n onChange: (value: ComposerValue) => void;\n onSubmit: () => void;\n uploadFile: (file: File) => Promise<ComposerUploadResult>;\n busy?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n submitHotkey?: 'enter' | 'mod+enter';\n /** Fixed min rows for the field (create project uses 3). */\n rows?: number;\n children: ReactNode;\n};\n\nexport function ComposerProvider({\n classNames = {},\n onError,\n value,\n onChange,\n onSubmit,\n uploadFile,\n busy = false,\n placeholder = 'What should it do?',\n autoFocus = true,\n submitHotkey = 'mod+enter',\n rows = 3,\n children,\n}: ComposerProviderProps) {\n const [notice, setNotice] = useState<ComposerNotice | null>(null);\n const reportError = useCallback((next: ComposerNotice) => {\n if (onError) {\n onError(next);\n }\n else {\n setNotice(next);\n }\n }, [onError]);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const focusRef = useRef<ComposerFieldHandle | null>(null);\n const valueRef = useRef(value);\n const onChangeRef = useRef(onChange);\n const pendingFilesRef = useRef(new Map<string, File>());\n const [fileDragOver, setFileDragOver] = useState(false);\n\n useLayoutEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n useLayoutEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n const changeValue = useCallback((next: ComposerValue) => {\n valueRef.current = next;\n onChangeRef.current(next);\n }, []);\n\n useEffect(() => {\n const pending = pendingFilesRef.current;\n\n return () => {\n for (const item of valueRef.current.attachments) {\n revokeObjectURL(item.preview);\n }\n\n pending.clear();\n };\n }, []);\n\n const canSubmit = Boolean(value.prompt.trim())\n && attachmentsReady(value.attachments)\n && !busy;\n\n const uploadOne = useCallback(async(clientId: string, file: File) => {\n let result: ComposerUploadResult;\n try {\n result = await uploadFile(file);\n }\n catch (error) {\n result = { ok: false, message: error instanceof Error ? error.message : undefined };\n }\n\n if (pendingFilesRef.current.get(clientId) !== file) {\n return;\n }\n const current = valueRef.current;\n\n if (!current.attachments.some(item => item.clientId === clientId)) {\n pendingFilesRef.current.delete(clientId);\n\n return;\n }\n\n if (result.ok) {\n const preview = current.attachments.find(item => item.clientId === clientId)?.preview;\n revokeObjectURL(preview);\n pendingFilesRef.current.delete(clientId);\n changeValue(patchAttachment(current, clientId, {\n id: result.data.id,\n url: result.data.url,\n filename: result.data.name ?? file.name,\n mediaType: result.data.mimeType ?? coerceUploadMimeType(file.name, file.type),\n size: result.data.size ?? file.size,\n uploadStatus: 'ready',\n uploadError: undefined,\n preview: undefined,\n }));\n\n return;\n }\n\n changeValue(patchAttachment(current, clientId, {\n uploadStatus: 'error',\n uploadError: result.message ?? 'Upload failed',\n }));\n }, [changeValue, uploadFile]);\n\n const addFiles = useCallback((files: FileList | readonly File[]) => {\n setNotice(null);\n const list = [...files];\n const accepted: File[] = [];\n let batchBytes = 0;\n const used = sumAttachmentBytes(valueRef.current.attachments);\n\n for (const file of list) {\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n reportError({\n title: 'Attachment too large',\n message: `${ file.name } is over the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_PER_FILE, { round: 'up' }) } per-file limit.`,\n });\n continue;\n }\n\n if (used + batchBytes + file.size > MAX_CHAT_ATTACHMENT_BYTES_TOTAL) {\n reportError({\n title: 'Attachments too large',\n message: `Adding ${ file.name } would exceed the ${ formatFileSize(MAX_CHAT_ATTACHMENT_BYTES_TOTAL, { round: 'up' }) } combined limit.`,\n });\n continue;\n }\n\n accepted.push(file);\n batchBytes += file.size;\n }\n\n if (accepted.length === 0) {\n return;\n }\n\n const nextItems: ComposerAttachment[] = accepted.map(file => ({\n clientId: crypto.randomUUID(),\n filename: file.name,\n mediaType: coerceUploadMimeType(file.name, file.type),\n size: file.size,\n lastModified: file.lastModified,\n uploadStatus: 'uploading',\n preview: createObjectURL(file) ?? undefined,\n }));\n\n for (let i = 0; i < accepted.length; i++) {\n pendingFilesRef.current.set(nextItems[i]!.clientId, accepted[i]!);\n }\n\n const next: ComposerValue = {\n ...valueRef.current,\n attachments: [...valueRef.current.attachments, ...nextItems],\n };\n changeValue(next);\n\n for (let i = 0; i < accepted.length; i++) {\n void uploadOne(nextItems[i]!.clientId, accepted[i]!);\n }\n }, [changeValue, uploadOne, reportError]);\n\n const drag = useFileDrag({\n onFileDragOver: setFileDragOver,\n onFilesDropped: files => addFiles(files),\n });\n\n const removeAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n revokeObjectURL(item?.preview);\n pendingFilesRef.current.delete(clientId);\n changeValue({\n ...current,\n attachments: current.attachments.filter(entry => entry.clientId !== clientId),\n });\n };\n\n const retryAttachment = (clientId: string) => {\n const current = valueRef.current;\n const item = current.attachments.find(entry => entry.clientId === clientId);\n const file = pendingFilesRef.current.get(clientId);\n\n if (!item || item.uploadStatus !== 'error') {\n return;\n }\n\n if (!file) {\n reportError({\n title: 'Could not retry',\n message: 'Remove the file and attach it again.',\n });\n\n return;\n }\n\n changeValue(patchAttachment(current, clientId, {\n uploadStatus: 'uploading',\n uploadError: undefined,\n }));\n void uploadOne(clientId, file);\n };\n\n const submit = () => {\n if (!canSubmit) {\n return;\n }\n\n onSubmit();\n };\n\n const pasteTextAsFile = (text: string) => {\n if (text.length < COMPOSER_PASTE_AS_FILE_MIN_CHARS) {\n return false;\n }\n\n const file = new File([text], 'paste.txt', { type: 'text/plain' });\n\n if (file.size > MAX_CHAT_ATTACHMENT_BYTES_PER_FILE) {\n return false;\n }\n\n addFiles([file]);\n\n return true;\n };\n\n const api: ComposerContextValue = {\n classNames,\n value,\n setPrompt: (prompt) => changeValue({ ...valueRef.current, prompt }),\n setPlanMode: (planMode) => changeValue({ ...valueRef.current, planMode }),\n addFiles,\n removeAttachment,\n retryAttachment,\n submit,\n canSubmit,\n busy,\n placeholder,\n autoFocus,\n submitOnEnter: submitHotkey === 'enter',\n rows,\n minHeight: rows ? rows * 22 : 20,\n pasteTextAsFile,\n openFilePicker: () => fileInputRef.current?.click(),\n focus: () => focusRef.current?.focus(),\n focusRef,\n fileDragOver,\n drag,\n };\n\n return (\n <ComposerContext value={ api }>\n { children }\n <Show when={ notice && !onError }>\n <p role=\"alert\" className={ classNames.notice }>\n { notice?.title }: { notice?.message }\n </p>\n </Show>\n <input\n ref={ fileInputRef }\n type=\"file\"\n multiple\n tabIndex={ -1 }\n hidden\n onChange={ (event) => {\n if (event.target.files?.length) {\n addFiles(event.target.files);\n }\n\n event.target.value = '';\n } }\n />\n </ComposerContext>\n );\n}\n"],"names":["ComposerContext","useComposer","context","use","sumAttachmentBytes","items","sum","item","attachmentsReady","patchAttachment","value","clientId","patch","ComposerProvider","classNames","onError","onChange","onSubmit","uploadFile","busy","placeholder","autoFocus","submitHotkey","rows","children","notice","setNotice","useState","reportError","useCallback","next","fileInputRef","useRef","focusRef","valueRef","onChangeRef","pendingFilesRef","fileDragOver","setFileDragOver","useLayoutEffect","changeValue","useEffect","pending","revokeObjectURL","canSubmit","uploadOne","file","result","error","current","preview","coerceUploadMimeType","addFiles","files","list","accepted","batchBytes","used","MAX_CHAT_ATTACHMENT_BYTES_PER_FILE","formatFileSize","MAX_CHAT_ATTACHMENT_BYTES_TOTAL","nextItems","createObjectURL","i","drag","useFileDrag","removeAttachment","entry","retryAttachment","submit","pasteTextAsFile","text","COMPOSER_PASTE_AS_FILE_MIN_CHARS","api","prompt","planMode","_jsx","Show","event"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { ComposerProvider, useComposer, type ComposerContextValue, type ComposerFieldHandle, type ComposerProviderProps, } from './context';
2
2
  export { ComposerAttachments, ComposerFileButton, ComposerFrame, ComposerPlan, ComposerSubmit, ComposerSurface, ComposerTextarea, ComposerToolbar, ComposerTools, } from './parts';
3
3
  export { ComposerRichField } from './RichField';
4
- export type { ComposerAttachment, ComposerUploadErr, ComposerUploadOk, ComposerUploadResult, ComposerValue, } from './types';
4
+ export type { ComposerAttachment, ComposerClassNames, ComposerNotice, ComposerUploadErr, ComposerUploadOk, ComposerUploadResult, ComposerValue, } from './types';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EACH,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EACR,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GAChB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,WAAW,EACX,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,GAC7B,MAAM,WAAW,CAAC;AACnB,OAAO,EACH,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EACR,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,GAChB,MAAM,SAAS,CAAC"}
@@ -1,22 +1,23 @@
1
- import { type ReactNode } from 'react';
2
- export declare function ComposerFrame({ className, children, }: {
3
- className?: string;
4
- children: ReactNode;
1
+ import { type ButtonHTMLAttributes, type HTMLAttributes, type TextareaHTMLAttributes } from 'react';
2
+ import type { ComposerClassNames } from './types';
3
+ type ContainerProps = HTMLAttributes<HTMLDivElement>;
4
+ type ActionProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' | 'disabled' | 'type'>;
5
+ export declare function ComposerFrame({ className, classNames: slots, children, onDragEnter, onDragLeave, onDragOver, onDrop, onPaste, ...props }: ContainerProps & {
6
+ classNames?: Pick<ComposerClassNames, 'shell' | 'dropOverlay' | 'dropLabel'>;
5
7
  }): import("react").JSX.Element;
6
- /** Relative row that pins the tools and the submit button to the field. */
7
- export declare function ComposerSurface({ children }: {
8
- children: ReactNode;
8
+ export declare function ComposerSurface({ className, children, onPointerDown, ...props }: ContainerProps): import("react").JSX.Element;
9
+ export declare function ComposerTools({ className, ...props }: ContainerProps): import("react").JSX.Element;
10
+ export declare function ComposerToolbar({ className, children, ...props }: ContainerProps): import("react").JSX.Element;
11
+ export declare function ComposerAttachments({ className, classNames: slots, ...props }: ContainerProps & {
12
+ classNames?: Pick<ComposerClassNames, 'attachment' | 'attachmentPreview' | 'attachmentName' | 'attachmentStatus' | 'attachmentRetry' | 'attachmentRemove'>;
9
13
  }): import("react").JSX.Element;
10
- /** Left cluster: file button, plan, whatever else you drop in. */
11
- export declare function ComposerTools({ children }: {
12
- children: ReactNode;
14
+ export declare function ComposerFileButton({ className, children, ...props }: ActionProps): import("react").JSX.Element;
15
+ export declare function ComposerPlan({ className, children, classNames: slots, ...props }: ActionProps & {
16
+ classNames?: Pick<ComposerClassNames, 'planIcon' | 'planLabel'>;
13
17
  }): import("react").JSX.Element;
14
- export declare function ComposerToolbar({ children }: {
15
- children?: ReactNode;
18
+ export declare function ComposerTextarea({ className, classNames: slots, style, onKeyDown, onPaste, ...props }: Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'defaultValue' | 'onChange' | 'ref'> & {
19
+ classNames?: Pick<ComposerClassNames, 'textareaWrap'>;
16
20
  }): import("react").JSX.Element;
17
- export declare function ComposerAttachments(): import("react").JSX.Element;
18
- export declare function ComposerFileButton(): import("react").JSX.Element;
19
- export declare function ComposerPlan(): import("react").JSX.Element;
20
- export declare function ComposerTextarea(): import("react").JSX.Element;
21
- export declare function ComposerSubmit(): import("react").JSX.Element;
21
+ export declare function ComposerSubmit({ className, children, ...props }: ActionProps): import("react").JSX.Element;
22
+ export {};
22
23
  //# sourceMappingURL=parts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/Composer/parts.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAW3D,wBAAgB,aAAa,CAAC,EAC1B,SAAS,EACT,QAAQ,GACX,EAAE;IACC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACvB,+BAkBA;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAkBpE;AAED,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAMlE;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAQrE;AAED,wBAAgB,mBAAmB,gCA8BlC;AAED,wBAAgB,kBAAkB,gCAiBjC;AAED,wBAAgB,YAAY,gCAsC3B;AAED,wBAAgB,gBAAgB,gCAsD/B;AAED,wBAAgB,cAAc,gCAmB7B"}
1
+ {"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/Composer/parts.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,KAAK,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAMpG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,KAAK,cAAc,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;AACrD,KAAK,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC;AAElG,wBAAgB,aAAa,CAAC,EAC1B,SAAS,EACT,UAAU,EAAE,KAAK,EACjB,QAAQ,EACR,WAAW,EACX,WAAW,EACX,UAAU,EACV,MAAM,EACN,OAAO,EACP,GAAG,KAAK,EACX,EAAE,cAAc,GAAG;IAAE,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,OAAO,GAAG,aAAa,GAAG,WAAW,CAAC,CAAA;CAAE,+BA4CnG;AAED,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAqB/F;AAED,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAIpE;AAED,wBAAgB,eAAe,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAUhF;AAED,wBAAgB,mBAAmB,CAAC,EAChC,SAAS,EACT,UAAU,EAAE,KAAK,EACjB,GAAG,KAAK,EACX,EAAE,cAAc,GAAG;IAChB,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAChC,YAAY,GAAG,mBAAmB,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,kBAAkB,CAAC,CAAC;CAC5H,+BAoDA;AAED,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BAgBhF;AAED,wBAAgB,YAAY,CAAC,EACzB,SAAS,EACT,QAAQ,EACR,UAAU,EAAE,KAAK,EACjB,GAAG,KAAK,EACX,EAAE,WAAW,GAAG;IAAE,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,WAAW,CAAC,CAAA;CAAE,+BA2BnF;AAED,wBAAgB,gBAAgB,CAAC,EAC7B,SAAS,EACT,UAAU,EAAE,KAAK,EACjB,KAAK,EACL,SAAS,EACT,OAAO,EACP,GAAG,KAAK,EACX,EAAE,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,KAAK,CAAC,GAAG;IAClG,UAAU,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;CACzD,+BAuCA;AAED,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BAkB5E"}