@jrapps/my_tickets_chat_ui 0.2.2 → 0.2.3

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.
@@ -186,7 +186,7 @@ var import_react2 = require("react");
186
186
  if (typeof document !== "undefined" && !document.getElementById("jrapps-style-ebcf221d")) {
187
187
  const s = document.createElement("style");
188
188
  s.id = "jrapps-style-ebcf221d";
189
- s.textContent = ".cw-footer {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 10px 12px;\n background-color: var(--cw-background);\n border-top: 1px solid var(--cw-border);\n flex-shrink: 0;\n}\n\n.cw-footer__input {\n flex: 1;\n resize: none;\n border: 1px solid var(--cw-input-border);\n border-radius: var(--cw-button-radius);\n background-color: var(--cw-input-background);\n font-family: var(--cw-font-family);\n font-size: var(--cw-font-size);\n color: inherit;\n padding: 8px 12px;\n line-height: 1.5;\n min-height: 38px;\n max-height: 120px;\n overflow-y: auto;\n transition: border-color 0.15s ease;\n}\n\n.cw-footer__input:focus {\n outline: none;\n border-color: var(--cw-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--cw-primary) 20%, transparent);\n}\n\n.cw-footer__input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.cw-footer__attach-btn,\n.cw-footer__send-btn {\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n transition: background-color 0.15s ease, color 0.15s ease;\n color: var(--cw-primary);\n margin-bottom: 1px;\n}\n\n.cw-footer__attach-btn:hover,\n.cw-footer__send-btn:not(.cw-footer__send-btn--disabled):hover {\n background-color: color-mix(in srgb, var(--cw-primary) 10%, transparent);\n}\n\n.cw-footer__attach-btn:focus-visible,\n.cw-footer__send-btn:focus-visible {\n outline: 2px solid var(--cw-primary);\n outline-offset: 2px;\n}\n\n.cw-footer__attach-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.cw-footer__send-btn--disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.cw-footer__file-input {\n display: none;\n}\n";
189
+ s.textContent = ".cw-footer {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n background-color: var(--cw-background);\n border-top: 1px solid var(--cw-border);\n flex-shrink: 0;\n}\n\n.cw-footer__controls {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n}\n\n/* \u2500\u2500\u2500 Staged file chips \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n.cw-footer__file-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.cw-footer__file-chip {\n display: flex;\n align-items: center;\n gap: 4px;\n background-color: color-mix(in srgb, var(--cw-primary) 12%, transparent);\n border: 1px solid color-mix(in srgb, var(--cw-primary) 30%, transparent);\n border-radius: 999px;\n padding: 3px 8px 3px 10px;\n font-size: 12px;\n color: var(--cw-primary);\n max-width: 200px;\n}\n\n.cw-footer__file-chip-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.cw-footer__file-chip-remove {\n background: none;\n border: none;\n cursor: pointer;\n padding: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: inherit;\n border-radius: 50%;\n flex-shrink: 0;\n opacity: 0.7;\n transition: opacity 0.15s ease, background-color 0.15s ease;\n}\n\n.cw-footer__file-chip-remove:hover {\n opacity: 1;\n background-color: color-mix(in srgb, var(--cw-primary) 15%, transparent);\n}\n\n.cw-footer__file-chip-remove:focus-visible {\n outline: 2px solid var(--cw-primary);\n outline-offset: 1px;\n}\n\n.cw-footer__input {\n flex: 1;\n resize: none;\n border: 1px solid var(--cw-input-border);\n border-radius: var(--cw-button-radius);\n background-color: var(--cw-input-background);\n font-family: var(--cw-font-family);\n font-size: var(--cw-font-size);\n color: inherit;\n padding: 8px 12px;\n line-height: 1.5;\n min-height: 38px;\n max-height: 120px;\n overflow-y: auto;\n transition: border-color 0.15s ease;\n}\n\n.cw-footer__input:focus {\n outline: none;\n border-color: var(--cw-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--cw-primary) 20%, transparent);\n}\n\n.cw-footer__input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.cw-footer__attach-btn,\n.cw-footer__send-btn {\n background: none;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n transition: background-color 0.15s ease, color 0.15s ease;\n color: var(--cw-primary);\n margin-bottom: 1px;\n}\n\n.cw-footer__attach-btn:hover,\n.cw-footer__send-btn:not(.cw-footer__send-btn--disabled):hover {\n background-color: color-mix(in srgb, var(--cw-primary) 10%, transparent);\n}\n\n.cw-footer__attach-btn:focus-visible,\n.cw-footer__send-btn:focus-visible {\n outline: 2px solid var(--cw-primary);\n outline-offset: 2px;\n}\n\n.cw-footer__attach-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.cw-footer__send-btn--disabled {\n opacity: 0.35;\n cursor: not-allowed;\n}\n\n.cw-footer__file-input {\n display: none;\n}\n";
190
190
  document.head.appendChild(s);
191
191
  }
192
192
 
@@ -194,34 +194,33 @@ if (typeof document !== "undefined" && !document.getElementById("jrapps-style-eb
194
194
  var import_jsx_runtime2 = require("react/jsx-runtime");
195
195
  var Footer = ({ onSend, onAttachment, disabled }) => {
196
196
  const [text, setText] = (0, import_react2.useState)("");
197
+ const [stagedFiles, setStagedFiles] = (0, import_react2.useState)([]);
197
198
  const fileInputRef = (0, import_react2.useRef)(null);
198
199
  const textareaRef = (0, import_react2.useRef)(null);
199
- const isEmpty = text.trim().length === 0;
200
- const handleKeyDown = (0, import_react2.useCallback)(
201
- (e) => {
202
- if (e.key === "Enter" && !e.shiftKey) {
203
- e.preventDefault();
204
- if (!isEmpty && !disabled) {
205
- onSend(text.trim());
206
- setText("");
207
- if (textareaRef.current) {
208
- textareaRef.current.style.height = "auto";
209
- }
210
- }
211
- }
212
- },
213
- [isEmpty, disabled, onSend, text]
214
- );
200
+ const isEmpty = text.trim().length === 0 && stagedFiles.length === 0;
215
201
  const handleSend = (0, import_react2.useCallback)(() => {
216
202
  if (!isEmpty && !disabled) {
217
- onSend(text.trim());
218
- setText("");
203
+ if (text.trim().length > 0) {
204
+ onSend(text.trim());
205
+ setText("");
206
+ }
207
+ stagedFiles.forEach((file) => onAttachment(file));
208
+ setStagedFiles([]);
219
209
  if (textareaRef.current) {
220
210
  textareaRef.current.style.height = "auto";
221
211
  textareaRef.current.focus();
222
212
  }
223
213
  }
224
- }, [isEmpty, disabled, onSend, text]);
214
+ }, [isEmpty, disabled, onSend, text, stagedFiles, onAttachment]);
215
+ const handleKeyDown = (0, import_react2.useCallback)(
216
+ (e) => {
217
+ if (e.key === "Enter" && !e.shiftKey) {
218
+ e.preventDefault();
219
+ handleSend();
220
+ }
221
+ },
222
+ [handleSend]
223
+ );
225
224
  const handleChange = (0, import_react2.useCallback)(
226
225
  (e) => {
227
226
  setText(e.target.value);
@@ -238,90 +237,109 @@ var Footer = ({ onSend, onAttachment, disabled }) => {
238
237
  const handleFileChange = (0, import_react2.useCallback)(
239
238
  (e) => {
240
239
  var _a;
241
- const file = (_a = e.target.files) == null ? void 0 : _a[0];
242
- if (file) {
243
- onAttachment(file);
240
+ const files = Array.from((_a = e.target.files) != null ? _a : []);
241
+ if (files.length > 0) {
242
+ setStagedFiles((prev) => [...prev, ...files]);
244
243
  }
245
244
  if (fileInputRef.current) {
246
245
  fileInputRef.current.value = "";
247
246
  }
248
247
  },
249
- [onAttachment]
248
+ []
250
249
  );
250
+ const handleRemoveStagedFile = (0, import_react2.useCallback)((index) => {
251
+ setStagedFiles((prev) => prev.filter((_, i) => i !== index));
252
+ }, []);
251
253
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("footer", { className: "cw-footer", role: "contentinfo", children: [
252
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
253
- "button",
254
- {
255
- className: "cw-footer__attach-btn",
256
- onClick: handleAttachmentClick,
257
- "aria-label": "Attach file",
258
- type: "button",
259
- disabled,
260
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
261
- "svg",
262
- {
263
- xmlns: "http://www.w3.org/2000/svg",
264
- width: "20",
265
- height: "20",
266
- viewBox: "0 0 24 24",
267
- fill: "none",
268
- stroke: "currentColor",
269
- strokeWidth: "2",
270
- strokeLinecap: "round",
271
- strokeLinejoin: "round",
272
- "aria-hidden": "true",
273
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" })
274
- }
275
- )
276
- }
277
- ),
278
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
279
- "textarea",
280
- {
281
- ref: textareaRef,
282
- className: "cw-footer__input",
283
- value: text,
284
- onChange: handleChange,
285
- onKeyDown: handleKeyDown,
286
- placeholder: "Type a message\u2026",
287
- "aria-label": "Message input",
288
- rows: 1,
289
- disabled
290
- }
291
- ),
292
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
293
- "button",
294
- {
295
- className: `cw-footer__send-btn${isEmpty || disabled ? " cw-footer__send-btn--disabled" : ""}`,
296
- onClick: handleSend,
297
- "aria-label": "Send message",
298
- type: "button",
299
- disabled: isEmpty || disabled,
300
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
301
- "svg",
302
- {
303
- xmlns: "http://www.w3.org/2000/svg",
304
- width: "20",
305
- height: "20",
306
- viewBox: "0 0 24 24",
307
- fill: "currentColor",
308
- "aria-hidden": "true",
309
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" })
310
- }
311
- )
312
- }
313
- ),
314
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
315
- "input",
316
- {
317
- ref: fileInputRef,
318
- type: "file",
319
- className: "cw-footer__file-input",
320
- onChange: handleFileChange,
321
- "aria-hidden": "true",
322
- tabIndex: -1
323
- }
324
- )
254
+ stagedFiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "cw-footer__file-list", "aria-label": "Files to send", children: stagedFiles.map((file, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { className: "cw-footer__file-chip", children: [
255
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "cw-footer__file-chip-name", title: file.name, children: file.name }),
256
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
257
+ "button",
258
+ {
259
+ className: "cw-footer__file-chip-remove",
260
+ onClick: () => handleRemoveStagedFile(i),
261
+ "aria-label": `Remove ${file.name}`,
262
+ type: "button",
263
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "12", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) })
264
+ }
265
+ )
266
+ ] }, `${file.name}-${i}`)) }),
267
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "cw-footer__controls", children: [
268
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
269
+ "button",
270
+ {
271
+ className: "cw-footer__attach-btn",
272
+ onClick: handleAttachmentClick,
273
+ "aria-label": "Attach file",
274
+ type: "button",
275
+ disabled,
276
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
277
+ "svg",
278
+ {
279
+ xmlns: "http://www.w3.org/2000/svg",
280
+ width: "20",
281
+ height: "20",
282
+ viewBox: "0 0 24 24",
283
+ fill: "none",
284
+ stroke: "currentColor",
285
+ strokeWidth: "2",
286
+ strokeLinecap: "round",
287
+ strokeLinejoin: "round",
288
+ "aria-hidden": "true",
289
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" })
290
+ }
291
+ )
292
+ }
293
+ ),
294
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
295
+ "textarea",
296
+ {
297
+ ref: textareaRef,
298
+ className: "cw-footer__input",
299
+ value: text,
300
+ onChange: handleChange,
301
+ onKeyDown: handleKeyDown,
302
+ placeholder: "Type a message\u2026",
303
+ "aria-label": "Message input",
304
+ rows: 1,
305
+ disabled
306
+ }
307
+ ),
308
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
309
+ "button",
310
+ {
311
+ className: `cw-footer__send-btn${isEmpty || disabled ? " cw-footer__send-btn--disabled" : ""}`,
312
+ onClick: handleSend,
313
+ "aria-label": "Send message",
314
+ type: "button",
315
+ disabled: isEmpty || disabled,
316
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
317
+ "svg",
318
+ {
319
+ xmlns: "http://www.w3.org/2000/svg",
320
+ width: "20",
321
+ height: "20",
322
+ viewBox: "0 0 24 24",
323
+ fill: "currentColor",
324
+ "aria-hidden": "true",
325
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" })
326
+ }
327
+ )
328
+ }
329
+ ),
330
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
331
+ "input",
332
+ {
333
+ ref: fileInputRef,
334
+ type: "file",
335
+ className: "cw-footer__file-input",
336
+ onChange: handleFileChange,
337
+ "aria-hidden": "true",
338
+ tabIndex: -1,
339
+ multiple: true
340
+ }
341
+ )
342
+ ] })
325
343
  ] });
326
344
  };
327
345
  var Footer_default = Footer;