@jrapps/my_tickets_chat_ui 0.2.1 → 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.
package/dist/cjs/index.js CHANGED
@@ -1032,7 +1032,7 @@ var defaultTheme = {
1032
1032
  buttonRadius: 8,
1033
1033
  borderRadius: 12
1034
1034
  };
1035
- function buildThemeVars(partial) {
1035
+ function buildThemeVars(partial, width, height) {
1036
1036
  const theme = { ...defaultTheme, ...partial };
1037
1037
  return {
1038
1038
  // Colours
@@ -1054,8 +1054,8 @@ function buildThemeVars(partial) {
1054
1054
  "--cw-font-family": FONT_FAMILY,
1055
1055
  "--cw-font-size": FONT_SIZE,
1056
1056
  "--cw-shadow": SHADOW,
1057
- "--cw-width": WIDTH,
1058
- "--cw-height": HEIGHT,
1057
+ "--cw-width": width !== void 0 ? typeof width === "number" ? `${width}px` : width : WIDTH,
1058
+ "--cw-height": height !== void 0 ? typeof height === "number" ? `${height}px` : height : HEIGHT,
1059
1059
  "--cw-header-height": HEADER_HEIGHT
1060
1060
  };
1061
1061
  }
@@ -1149,7 +1149,7 @@ var import_react9 = require("react");
1149
1149
  if (typeof document !== "undefined" && !document.getElementById("jrapps-style-ebcf221d")) {
1150
1150
  const s = document.createElement("style");
1151
1151
  s.id = "jrapps-style-ebcf221d";
1152
- 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";
1152
+ 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";
1153
1153
  document.head.appendChild(s);
1154
1154
  }
1155
1155
 
@@ -1157,34 +1157,33 @@ if (typeof document !== "undefined" && !document.getElementById("jrapps-style-eb
1157
1157
  var import_jsx_runtime12 = require("react/jsx-runtime");
1158
1158
  var Footer2 = ({ onSend, onAttachment, disabled }) => {
1159
1159
  const [text, setText] = (0, import_react9.useState)("");
1160
+ const [stagedFiles, setStagedFiles] = (0, import_react9.useState)([]);
1160
1161
  const fileInputRef = (0, import_react9.useRef)(null);
1161
1162
  const textareaRef = (0, import_react9.useRef)(null);
1162
- const isEmpty = text.trim().length === 0;
1163
- const handleKeyDown = (0, import_react9.useCallback)(
1164
- (e) => {
1165
- if (e.key === "Enter" && !e.shiftKey) {
1166
- e.preventDefault();
1167
- if (!isEmpty && !disabled) {
1168
- onSend(text.trim());
1169
- setText("");
1170
- if (textareaRef.current) {
1171
- textareaRef.current.style.height = "auto";
1172
- }
1173
- }
1174
- }
1175
- },
1176
- [isEmpty, disabled, onSend, text]
1177
- );
1163
+ const isEmpty = text.trim().length === 0 && stagedFiles.length === 0;
1178
1164
  const handleSend = (0, import_react9.useCallback)(() => {
1179
1165
  if (!isEmpty && !disabled) {
1180
- onSend(text.trim());
1181
- setText("");
1166
+ if (text.trim().length > 0) {
1167
+ onSend(text.trim());
1168
+ setText("");
1169
+ }
1170
+ stagedFiles.forEach((file) => onAttachment(file));
1171
+ setStagedFiles([]);
1182
1172
  if (textareaRef.current) {
1183
1173
  textareaRef.current.style.height = "auto";
1184
1174
  textareaRef.current.focus();
1185
1175
  }
1186
1176
  }
1187
- }, [isEmpty, disabled, onSend, text]);
1177
+ }, [isEmpty, disabled, onSend, text, stagedFiles, onAttachment]);
1178
+ const handleKeyDown = (0, import_react9.useCallback)(
1179
+ (e) => {
1180
+ if (e.key === "Enter" && !e.shiftKey) {
1181
+ e.preventDefault();
1182
+ handleSend();
1183
+ }
1184
+ },
1185
+ [handleSend]
1186
+ );
1188
1187
  const handleChange = (0, import_react9.useCallback)(
1189
1188
  (e) => {
1190
1189
  setText(e.target.value);
@@ -1201,90 +1200,109 @@ var Footer2 = ({ onSend, onAttachment, disabled }) => {
1201
1200
  const handleFileChange = (0, import_react9.useCallback)(
1202
1201
  (e) => {
1203
1202
  var _a;
1204
- const file = (_a = e.target.files) == null ? void 0 : _a[0];
1205
- if (file) {
1206
- onAttachment(file);
1203
+ const files = Array.from((_a = e.target.files) != null ? _a : []);
1204
+ if (files.length > 0) {
1205
+ setStagedFiles((prev) => [...prev, ...files]);
1207
1206
  }
1208
1207
  if (fileInputRef.current) {
1209
1208
  fileInputRef.current.value = "";
1210
1209
  }
1211
1210
  },
1212
- [onAttachment]
1211
+ []
1213
1212
  );
1213
+ const handleRemoveStagedFile = (0, import_react9.useCallback)((index) => {
1214
+ setStagedFiles((prev) => prev.filter((_, i) => i !== index));
1215
+ }, []);
1214
1216
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("footer", { className: "cw-footer", role: "contentinfo", children: [
1215
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1216
- "button",
1217
- {
1218
- className: "cw-footer__attach-btn",
1219
- onClick: handleAttachmentClick,
1220
- "aria-label": "Attach file",
1221
- type: "button",
1222
- disabled,
1223
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1224
- "svg",
1225
- {
1226
- xmlns: "http://www.w3.org/2000/svg",
1227
- width: "20",
1228
- height: "20",
1229
- viewBox: "0 0 24 24",
1230
- fill: "none",
1231
- stroke: "currentColor",
1232
- strokeWidth: "2",
1233
- strokeLinecap: "round",
1234
- strokeLinejoin: "round",
1235
- "aria-hidden": "true",
1236
- children: /* @__PURE__ */ (0, import_jsx_runtime12.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" })
1237
- }
1238
- )
1239
- }
1240
- ),
1241
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1242
- "textarea",
1243
- {
1244
- ref: textareaRef,
1245
- className: "cw-footer__input",
1246
- value: text,
1247
- onChange: handleChange,
1248
- onKeyDown: handleKeyDown,
1249
- placeholder: "Type a message\u2026",
1250
- "aria-label": "Message input",
1251
- rows: 1,
1252
- disabled
1253
- }
1254
- ),
1255
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1256
- "button",
1257
- {
1258
- className: `cw-footer__send-btn${isEmpty || disabled ? " cw-footer__send-btn--disabled" : ""}`,
1259
- onClick: handleSend,
1260
- "aria-label": "Send message",
1261
- type: "button",
1262
- disabled: isEmpty || disabled,
1263
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1264
- "svg",
1265
- {
1266
- xmlns: "http://www.w3.org/2000/svg",
1267
- width: "20",
1268
- height: "20",
1269
- viewBox: "0 0 24 24",
1270
- fill: "currentColor",
1271
- "aria-hidden": "true",
1272
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" })
1273
- }
1274
- )
1275
- }
1276
- ),
1277
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1278
- "input",
1279
- {
1280
- ref: fileInputRef,
1281
- type: "file",
1282
- className: "cw-footer__file-input",
1283
- onChange: handleFileChange,
1284
- "aria-hidden": "true",
1285
- tabIndex: -1
1286
- }
1287
- )
1217
+ stagedFiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { className: "cw-footer__file-list", "aria-label": "Files to send", children: stagedFiles.map((file, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("li", { className: "cw-footer__file-chip", children: [
1218
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "cw-footer__file-chip-name", title: file.name, children: file.name }),
1219
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1220
+ "button",
1221
+ {
1222
+ className: "cw-footer__file-chip-remove",
1223
+ onClick: () => handleRemoveStagedFile(i),
1224
+ "aria-label": `Remove ${file.name}`,
1225
+ type: "button",
1226
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.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_runtime12.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" }) })
1227
+ }
1228
+ )
1229
+ ] }, `${file.name}-${i}`)) }),
1230
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "cw-footer__controls", children: [
1231
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1232
+ "button",
1233
+ {
1234
+ className: "cw-footer__attach-btn",
1235
+ onClick: handleAttachmentClick,
1236
+ "aria-label": "Attach file",
1237
+ type: "button",
1238
+ disabled,
1239
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1240
+ "svg",
1241
+ {
1242
+ xmlns: "http://www.w3.org/2000/svg",
1243
+ width: "20",
1244
+ height: "20",
1245
+ viewBox: "0 0 24 24",
1246
+ fill: "none",
1247
+ stroke: "currentColor",
1248
+ strokeWidth: "2",
1249
+ strokeLinecap: "round",
1250
+ strokeLinejoin: "round",
1251
+ "aria-hidden": "true",
1252
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.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" })
1253
+ }
1254
+ )
1255
+ }
1256
+ ),
1257
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1258
+ "textarea",
1259
+ {
1260
+ ref: textareaRef,
1261
+ className: "cw-footer__input",
1262
+ value: text,
1263
+ onChange: handleChange,
1264
+ onKeyDown: handleKeyDown,
1265
+ placeholder: "Type a message\u2026",
1266
+ "aria-label": "Message input",
1267
+ rows: 1,
1268
+ disabled
1269
+ }
1270
+ ),
1271
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1272
+ "button",
1273
+ {
1274
+ className: `cw-footer__send-btn${isEmpty || disabled ? " cw-footer__send-btn--disabled" : ""}`,
1275
+ onClick: handleSend,
1276
+ "aria-label": "Send message",
1277
+ type: "button",
1278
+ disabled: isEmpty || disabled,
1279
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1280
+ "svg",
1281
+ {
1282
+ xmlns: "http://www.w3.org/2000/svg",
1283
+ width: "20",
1284
+ height: "20",
1285
+ viewBox: "0 0 24 24",
1286
+ fill: "currentColor",
1287
+ "aria-hidden": "true",
1288
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" })
1289
+ }
1290
+ )
1291
+ }
1292
+ ),
1293
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1294
+ "input",
1295
+ {
1296
+ ref: fileInputRef,
1297
+ type: "file",
1298
+ className: "cw-footer__file-input",
1299
+ onChange: handleFileChange,
1300
+ "aria-hidden": "true",
1301
+ tabIndex: -1,
1302
+ multiple: true
1303
+ }
1304
+ )
1305
+ ] })
1288
1306
  ] });
1289
1307
  };
1290
1308
  var Footer_default = Footer2;
@@ -2167,7 +2185,7 @@ var SiteChatComponentNew = import_react12.default.forwardRef(({
2167
2185
  onClose
2168
2186
  }, ref) => {
2169
2187
  const { open, openWidget, closeWidget } = useSiteChatComponentNew(defaultOpen);
2170
- const themeVars = buildThemeVars(theme);
2188
+ const themeVars = buildThemeVars(theme, width, height);
2171
2189
  const handleClose = () => {
2172
2190
  closeWidget();
2173
2191
  onClose == null ? void 0 : onClose();
@@ -2203,7 +2221,6 @@ var SiteChatComponentNew = import_react12.default.forwardRef(({
2203
2221
  role: "dialog",
2204
2222
  "aria-modal": "true",
2205
2223
  "aria-label": `${title} chat widget`,
2206
- style: { ...width !== void 0 && { width }, ...height !== void 0 && { height } },
2207
2224
  children: [
2208
2225
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2209
2226
  Header_default,