@huskel/sdk 0.4.1 → 0.4.2
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/index.css +56 -0
- package/dist/index.css.map +1 -1
- package/dist/index.js +214 -104
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +180 -70
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -521,6 +521,7 @@ function useChat() {
|
|
|
521
521
|
if (!query.trim() || loading) return;
|
|
522
522
|
(_a = abortRef.current) == null ? void 0 : _a.abort();
|
|
523
523
|
abortRef.current = new AbortController();
|
|
524
|
+
const signal = abortRef.current.signal;
|
|
524
525
|
const userMsg = { role: "user", content: query };
|
|
525
526
|
setMessages((prev) => [...prev, userMsg]);
|
|
526
527
|
setLoading(true);
|
|
@@ -528,20 +529,42 @@ function useChat() {
|
|
|
528
529
|
try {
|
|
529
530
|
const history = messages.map((m) => ({ role: m.role, content: m.content }));
|
|
530
531
|
const res = await client.api.chat(query, history);
|
|
531
|
-
|
|
532
|
-
|
|
532
|
+
if (signal.aborted) return;
|
|
533
|
+
const fullAnswer = res.answer || "";
|
|
534
|
+
const words = fullAnswer.split(/(\s+)/);
|
|
535
|
+
setMessages((prev) => [...prev, { role: "assistant", content: "" }]);
|
|
536
|
+
let currentContent = "";
|
|
537
|
+
for (const word of words) {
|
|
538
|
+
if (signal.aborted) return;
|
|
539
|
+
currentContent += word;
|
|
540
|
+
setMessages((prev) => {
|
|
541
|
+
const next = [...prev];
|
|
542
|
+
if (next.length > 0) {
|
|
543
|
+
next[next.length - 1] = { role: "assistant", content: currentContent };
|
|
544
|
+
}
|
|
545
|
+
return next;
|
|
546
|
+
});
|
|
547
|
+
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
548
|
+
}
|
|
549
|
+
if (signal.aborted) return;
|
|
533
550
|
setSources((_b = res.sources) != null ? _b : []);
|
|
534
551
|
} catch (e) {
|
|
552
|
+
if (signal.aborted) return;
|
|
535
553
|
setError((_c = e == null ? void 0 : e.message) != null ? _c : "Chat request failed");
|
|
536
554
|
setMessages((prev) => prev.slice(0, -1));
|
|
537
555
|
} finally {
|
|
538
|
-
|
|
556
|
+
if (!signal.aborted) {
|
|
557
|
+
setLoading(false);
|
|
558
|
+
}
|
|
539
559
|
}
|
|
540
560
|
}, [client, messages, loading]);
|
|
541
561
|
const reset = useCallback3(() => {
|
|
562
|
+
var _a;
|
|
563
|
+
(_a = abortRef.current) == null ? void 0 : _a.abort();
|
|
542
564
|
setMessages([]);
|
|
543
565
|
setSources([]);
|
|
544
566
|
setError(null);
|
|
567
|
+
setLoading(false);
|
|
545
568
|
}, []);
|
|
546
569
|
return { messages, sources, loading, error, send, reset };
|
|
547
570
|
}
|
|
@@ -830,18 +853,105 @@ function Sparkle({
|
|
|
830
853
|
|
|
831
854
|
// src/components/ChatWidget.tsx
|
|
832
855
|
import { useState as useState6, useRef as useRef8, useEffect as useEffect5 } from "react";
|
|
833
|
-
|
|
834
|
-
|
|
856
|
+
|
|
857
|
+
// src/utils/markdown.tsx
|
|
858
|
+
import { Fragment as Fragment2, jsx as jsx4 } from "react/jsx-runtime";
|
|
859
|
+
var parseInline = (text, keyPrefix) => {
|
|
860
|
+
const tokenRegex = /(\[[^\]]+\]\([^)]+\)|\*\*[^*]+\*\*|`[^`]+`)/g;
|
|
861
|
+
const parts = text.split(tokenRegex);
|
|
862
|
+
return parts.map((part, index) => {
|
|
863
|
+
if (!part) return null;
|
|
864
|
+
const key = `${keyPrefix}-inline-${index}`;
|
|
865
|
+
if (part.startsWith("`") && part.endsWith("`")) {
|
|
866
|
+
return /* @__PURE__ */ jsx4("code", { className: "hsk-markdown-code", children: part.slice(1, -1) }, key);
|
|
867
|
+
}
|
|
868
|
+
if (part.startsWith("**") && part.endsWith("**")) {
|
|
869
|
+
return /* @__PURE__ */ jsx4("strong", { children: parseInline(part.slice(2, -2), key) }, key);
|
|
870
|
+
}
|
|
871
|
+
const linkMatch = part.match(/^\[([^\]]+)\]\(([^)]+)\)$/);
|
|
872
|
+
if (linkMatch) {
|
|
873
|
+
const url = linkMatch[2];
|
|
874
|
+
const isSafeUrl = /^(https?|mailto|tel):/i.test(url) || url.startsWith("/");
|
|
875
|
+
if (isSafeUrl) {
|
|
876
|
+
return /* @__PURE__ */ jsx4("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "hsk-markdown-link", children: parseInline(linkMatch[1], key) }, key);
|
|
877
|
+
}
|
|
878
|
+
return /* @__PURE__ */ jsx4("span", { children: parseInline(linkMatch[1], key) }, key);
|
|
879
|
+
}
|
|
880
|
+
return part;
|
|
881
|
+
});
|
|
882
|
+
};
|
|
883
|
+
function renderMarkdown(content) {
|
|
884
|
+
const lines = content.split("\n");
|
|
885
|
+
const elements = [];
|
|
886
|
+
let i = 0;
|
|
887
|
+
while (i < lines.length) {
|
|
888
|
+
const line = lines[i];
|
|
889
|
+
const key = `md-line-${i}`;
|
|
890
|
+
if (!line.trim()) {
|
|
891
|
+
i++;
|
|
892
|
+
continue;
|
|
893
|
+
}
|
|
894
|
+
const headerMatch = line.match(/^(#{1,3})\s+(.*)/);
|
|
895
|
+
if (headerMatch) {
|
|
896
|
+
const level = headerMatch[1].length;
|
|
897
|
+
const Tag = `h${level + 3}`;
|
|
898
|
+
elements.push(/* @__PURE__ */ jsx4(Tag, { className: `hsk-markdown-h${level}`, children: parseInline(headerMatch[2], key) }, key));
|
|
899
|
+
i++;
|
|
900
|
+
continue;
|
|
901
|
+
}
|
|
902
|
+
if (line.match(/^[-*]\s+/)) {
|
|
903
|
+
const listItems = [];
|
|
904
|
+
while (i < lines.length && lines[i].match(/^[-*]\s+/)) {
|
|
905
|
+
const itemText = lines[i].replace(/^[-*]\s+/, "");
|
|
906
|
+
listItems.push(/* @__PURE__ */ jsx4("li", { children: parseInline(itemText, `li-${i}`) }, `li-${i}`));
|
|
907
|
+
i++;
|
|
908
|
+
}
|
|
909
|
+
elements.push(/* @__PURE__ */ jsx4("ul", { className: "hsk-markdown-list", children: listItems }, `ul-${key}`));
|
|
910
|
+
continue;
|
|
911
|
+
}
|
|
912
|
+
if (line.trim().startsWith("|")) {
|
|
913
|
+
const tableRows = [];
|
|
914
|
+
let isHeader = true;
|
|
915
|
+
while (i < lines.length && lines[i].trim().startsWith("|")) {
|
|
916
|
+
const rowLine = lines[i].trim();
|
|
917
|
+
if (rowLine.match(/^\|[-:| ]+\|$/)) {
|
|
918
|
+
i++;
|
|
919
|
+
isHeader = false;
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
const cells = rowLine.split("|").slice(1, -1).map((c) => c.trim());
|
|
923
|
+
const Tag = isHeader ? "th" : "td";
|
|
924
|
+
tableRows.push(
|
|
925
|
+
/* @__PURE__ */ jsx4("tr", { children: cells.map((cell, cIdx) => /* @__PURE__ */ jsx4(Tag, { children: parseInline(cell, `td-${i}-${cIdx}`) }, `td-${i}-${cIdx}`)) }, `tr-${i}`)
|
|
926
|
+
);
|
|
927
|
+
i++;
|
|
928
|
+
}
|
|
929
|
+
elements.push(
|
|
930
|
+
/* @__PURE__ */ jsx4("div", { className: "hsk-table-wrapper", children: /* @__PURE__ */ jsx4("table", { className: "hsk-markdown-table", children: /* @__PURE__ */ jsx4("tbody", { children: tableRows }) }) }, `table-wrapper-${key}`)
|
|
931
|
+
);
|
|
932
|
+
continue;
|
|
933
|
+
}
|
|
934
|
+
elements.push(
|
|
935
|
+
/* @__PURE__ */ jsx4("p", { className: "hsk-markdown-p", children: parseInline(line, key) }, key)
|
|
936
|
+
);
|
|
937
|
+
i++;
|
|
938
|
+
}
|
|
939
|
+
return /* @__PURE__ */ jsx4(Fragment2, { children: elements });
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// src/components/ChatWidget.tsx
|
|
943
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
944
|
+
var SparkleIcon2 = () => /* @__PURE__ */ jsx5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
|
|
835
945
|
var ArrowUpIcon = () => /* @__PURE__ */ jsxs3("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
836
|
-
/* @__PURE__ */
|
|
837
|
-
/* @__PURE__ */
|
|
946
|
+
/* @__PURE__ */ jsx5("path", { d: "m5 12 7-7 7 7" }),
|
|
947
|
+
/* @__PURE__ */ jsx5("path", { d: "M12 19V5" })
|
|
838
948
|
] });
|
|
839
949
|
function SourceCard({ source, defaultCurrency, onSelect }) {
|
|
840
950
|
var _a;
|
|
841
951
|
return /* @__PURE__ */ jsxs3("div", { className: "hsk-source-card", onClick: () => onSelect == null ? void 0 : onSelect(source), children: [
|
|
842
|
-
source.image && /* @__PURE__ */
|
|
952
|
+
source.image && /* @__PURE__ */ jsx5("img", { src: source.image, alt: source.name, className: "hsk-source-img" }),
|
|
843
953
|
/* @__PURE__ */ jsxs3("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
844
|
-
/* @__PURE__ */
|
|
954
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-source-name", children: source.name }),
|
|
845
955
|
source.price && /* @__PURE__ */ jsxs3("div", { className: "hsk-source-price", children: [
|
|
846
956
|
(_a = source.currency) != null ? _a : defaultCurrency,
|
|
847
957
|
" ",
|
|
@@ -896,36 +1006,36 @@ function ChatWidget({
|
|
|
896
1006
|
style: customStyles,
|
|
897
1007
|
children: [
|
|
898
1008
|
/* @__PURE__ */ jsxs3("div", { className: `hsk-chat-header ${classNames.header || ""}`, children: [
|
|
899
|
-
/* @__PURE__ */
|
|
900
|
-
/* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
902
|
-
messages.length > 0 && /* @__PURE__ */
|
|
1009
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-chat-header-icon", children: /* @__PURE__ */ jsx5(SparkleIcon2, {}) }),
|
|
1010
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-chat-title", children: title }),
|
|
1011
|
+
/* @__PURE__ */ jsx5("span", { className: "hsk-chat-badge", children: "AI" }),
|
|
1012
|
+
messages.length > 0 && /* @__PURE__ */ jsx5("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
|
|
903
1013
|
] }),
|
|
904
1014
|
/* @__PURE__ */ jsxs3("div", { className: "hsk-chat-messages", children: [
|
|
905
1015
|
messages.length === 0 ? /* @__PURE__ */ jsxs3("div", { className: "hsk-chat-empty", children: [
|
|
906
|
-
/* @__PURE__ */
|
|
907
|
-
/* @__PURE__ */
|
|
908
|
-
/* @__PURE__ */
|
|
1016
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-chat-empty-icon", children: /* @__PURE__ */ jsx5(SparkleIcon2, {}) }),
|
|
1017
|
+
/* @__PURE__ */ jsx5("div", { children: emptyStateText }),
|
|
1018
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-chat-empty-suggestions", children: emptyStateSuggestions })
|
|
909
1019
|
] }) : messages.map((msg, idx) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
910
1020
|
/* @__PURE__ */ jsxs3("div", { className: `hsk-msg-row ${msg.role}`, children: [
|
|
911
|
-
/* @__PURE__ */
|
|
912
|
-
/* @__PURE__ */
|
|
1021
|
+
/* @__PURE__ */ jsx5("div", { className: `hsk-msg-avatar ${msg.role === "assistant" ? "ai" : "user"}`, children: msg.role === "assistant" ? /* @__PURE__ */ jsx5(SparkleIcon2, {}) : "U" }),
|
|
1022
|
+
/* @__PURE__ */ jsx5("div", { className: `hsk-msg-bubble ${msg.role} ${classNames.messageBubble || ""}`, children: renderMarkdown(msg.content) })
|
|
913
1023
|
] }),
|
|
914
|
-
msg.role === "assistant" && idx === messages.length - 1 && sources.length > 0 && /* @__PURE__ */
|
|
1024
|
+
msg.role === "assistant" && idx === messages.length - 1 && sources.length > 0 && /* @__PURE__ */ jsx5("div", { className: "hsk-sources-container", children: /* @__PURE__ */ jsx5("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ jsx5(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) })
|
|
915
1025
|
] }, idx)),
|
|
916
1026
|
loading && /* @__PURE__ */ jsxs3("div", { className: "hsk-msg-row", children: [
|
|
917
|
-
/* @__PURE__ */
|
|
1027
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-msg-avatar ai", children: /* @__PURE__ */ jsx5(SparkleIcon2, {}) }),
|
|
918
1028
|
/* @__PURE__ */ jsxs3("div", { className: "hsk-typing", children: [
|
|
919
|
-
/* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
1029
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-typing-dot" }),
|
|
1030
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-typing-dot" }),
|
|
1031
|
+
/* @__PURE__ */ jsx5("div", { className: "hsk-typing-dot" })
|
|
922
1032
|
] })
|
|
923
1033
|
] }),
|
|
924
|
-
error && /* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
1034
|
+
error && /* @__PURE__ */ jsx5("div", { className: "hsk-chat-error", children: error }),
|
|
1035
|
+
/* @__PURE__ */ jsx5("div", { ref: bottomRef })
|
|
926
1036
|
] }),
|
|
927
1037
|
/* @__PURE__ */ jsxs3("div", { className: "hsk-chat-input-area", children: [
|
|
928
|
-
/* @__PURE__ */
|
|
1038
|
+
/* @__PURE__ */ jsx5(
|
|
929
1039
|
"textarea",
|
|
930
1040
|
{
|
|
931
1041
|
ref: textareaRef,
|
|
@@ -938,14 +1048,14 @@ function ChatWidget({
|
|
|
938
1048
|
disabled: loading
|
|
939
1049
|
}
|
|
940
1050
|
),
|
|
941
|
-
/* @__PURE__ */
|
|
1051
|
+
/* @__PURE__ */ jsx5(
|
|
942
1052
|
"button",
|
|
943
1053
|
{
|
|
944
1054
|
className: "hsk-chat-send",
|
|
945
1055
|
onClick: handleSend,
|
|
946
1056
|
disabled: !input.trim() || loading,
|
|
947
1057
|
"aria-label": "Send message",
|
|
948
|
-
children: /* @__PURE__ */
|
|
1058
|
+
children: /* @__PURE__ */ jsx5(ArrowUpIcon, {})
|
|
949
1059
|
}
|
|
950
1060
|
)
|
|
951
1061
|
] })
|
|
@@ -957,17 +1067,17 @@ function ChatWidget({
|
|
|
957
1067
|
// src/components/AIChatButton.tsx
|
|
958
1068
|
import { useState as useState7, useEffect as useEffect6, useRef as useRef9, useCallback as useCallback4 } from "react";
|
|
959
1069
|
import { createPortal as createPortal2 } from "react-dom";
|
|
960
|
-
import { Fragment as
|
|
961
|
-
var SparkleIcon3 = ({ className }) => /* @__PURE__ */
|
|
1070
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1071
|
+
var SparkleIcon3 = ({ className }) => /* @__PURE__ */ jsx6("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx6("path", { d: "m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z" }) });
|
|
962
1072
|
var ArrowUpIcon2 = () => /* @__PURE__ */ jsxs4("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
963
|
-
/* @__PURE__ */
|
|
964
|
-
/* @__PURE__ */
|
|
1073
|
+
/* @__PURE__ */ jsx6("path", { d: "m5 12 7-7 7 7" }),
|
|
1074
|
+
/* @__PURE__ */ jsx6("path", { d: "M12 19V5" })
|
|
965
1075
|
] });
|
|
966
1076
|
var CloseIcon2 = () => /* @__PURE__ */ jsxs4("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
967
|
-
/* @__PURE__ */
|
|
968
|
-
/* @__PURE__ */
|
|
1077
|
+
/* @__PURE__ */ jsx6("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1078
|
+
/* @__PURE__ */ jsx6("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
969
1079
|
] });
|
|
970
|
-
var ChevronRightIcon = () => /* @__PURE__ */
|
|
1080
|
+
var ChevronRightIcon = () => /* @__PURE__ */ jsx6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx6("path", { d: "m9 18 6-6-6-6" }) });
|
|
971
1081
|
var DEFAULT_CHIPS = [
|
|
972
1082
|
"Cheapest smartphone",
|
|
973
1083
|
"Smart TV under KSh 20,000",
|
|
@@ -1000,7 +1110,7 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
|
|
|
1000
1110
|
(_a = railRef.current) == null ? void 0 : _a.scrollBy({ left: 170, behavior: "smooth" });
|
|
1001
1111
|
};
|
|
1002
1112
|
return /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-sources-wrap", children: [
|
|
1003
|
-
/* @__PURE__ */
|
|
1113
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-sources", ref: railRef, children: sources.map((src, si) => {
|
|
1004
1114
|
var _a;
|
|
1005
1115
|
return /* @__PURE__ */ jsxs4(
|
|
1006
1116
|
"div",
|
|
@@ -1009,9 +1119,9 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
|
|
|
1009
1119
|
style: { animationDelay: `${si * 50}ms` },
|
|
1010
1120
|
onClick: () => onSelectSource == null ? void 0 : onSelectSource(src),
|
|
1011
1121
|
children: [
|
|
1012
|
-
src.image ? /* @__PURE__ */
|
|
1122
|
+
src.image ? /* @__PURE__ */ jsx6("div", { className: "hsk-cb-src-imgwrap", children: /* @__PURE__ */ jsx6("img", { src: src.image, alt: src.name, loading: "lazy" }) }) : /* @__PURE__ */ jsx6("div", { className: "hsk-cb-src-imgwrap-empty", children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
|
|
1013
1123
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-src-info", children: [
|
|
1014
|
-
/* @__PURE__ */
|
|
1124
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-src-name", children: src.name }),
|
|
1015
1125
|
src.price && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-src-price", children: [
|
|
1016
1126
|
(_a = src.currency) != null ? _a : defaultCurrency,
|
|
1017
1127
|
" ",
|
|
@@ -1023,15 +1133,15 @@ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
|
|
|
1023
1133
|
si
|
|
1024
1134
|
);
|
|
1025
1135
|
}) }),
|
|
1026
|
-
showNext && /* @__PURE__ */ jsxs4(
|
|
1027
|
-
/* @__PURE__ */
|
|
1136
|
+
showNext && /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1137
|
+
/* @__PURE__ */ jsx6(
|
|
1028
1138
|
"div",
|
|
1029
1139
|
{
|
|
1030
1140
|
className: "hsk-cb-sources-fade",
|
|
1031
1141
|
style: { background: "linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))" }
|
|
1032
1142
|
}
|
|
1033
1143
|
),
|
|
1034
|
-
/* @__PURE__ */
|
|
1144
|
+
/* @__PURE__ */ jsx6("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ jsx6(ChevronRightIcon, {}) })
|
|
1035
1145
|
] })
|
|
1036
1146
|
] });
|
|
1037
1147
|
}
|
|
@@ -1095,7 +1205,7 @@ function ChatModal({
|
|
|
1095
1205
|
};
|
|
1096
1206
|
const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur != null ? backdropBlur : "20px";
|
|
1097
1207
|
const customStyles = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, (theme == null ? void 0 : theme.primaryColor) && { "--hsk-primary": theme.primaryColor }), (theme == null ? void 0 : theme.backgroundColor) && { "--hsk-bg": theme.backgroundColor }), (theme == null ? void 0 : theme.textColor) && { "--hsk-text": theme.textColor }), (theme == null ? void 0 : theme.fontFamily) && { "--hsk-font": theme.fontFamily });
|
|
1098
|
-
return /* @__PURE__ */
|
|
1208
|
+
return /* @__PURE__ */ jsx6(
|
|
1099
1209
|
"div",
|
|
1100
1210
|
{
|
|
1101
1211
|
className: `hsk-cb-overlay ${classNames.overlay || ""}`,
|
|
@@ -1107,23 +1217,23 @@ function ChatModal({
|
|
|
1107
1217
|
children: /* @__PURE__ */ jsxs4("div", { className: `hsk-cb-panel ${classNames.panel || ""}`, onClick: (e) => e.stopPropagation(), children: [
|
|
1108
1218
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-topbar", children: [
|
|
1109
1219
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-topbar-left", children: [
|
|
1110
|
-
/* @__PURE__ */
|
|
1220
|
+
/* @__PURE__ */ jsx6("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
|
|
1111
1221
|
/* @__PURE__ */ jsxs4("div", { children: [
|
|
1112
|
-
/* @__PURE__ */
|
|
1113
|
-
/* @__PURE__ */
|
|
1222
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-topbar-title", children: title }),
|
|
1223
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-topbar-sub", children: "Powered by Huskel AI \xB7 searches the whole catalogue" })
|
|
1114
1224
|
] })
|
|
1115
1225
|
] }),
|
|
1116
1226
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-topbar-actions", children: [
|
|
1117
|
-
messages.length > 0 && /* @__PURE__ */
|
|
1118
|
-
/* @__PURE__ */
|
|
1227
|
+
messages.length > 0 && /* @__PURE__ */ jsx6("button", { className: "hsk-cb-topbar-btn", onClick: reset, children: "Clear chat" }),
|
|
1228
|
+
/* @__PURE__ */ jsx6("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx6(CloseIcon2, {}) })
|
|
1119
1229
|
] })
|
|
1120
1230
|
] }),
|
|
1121
1231
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-msgs", children: [
|
|
1122
1232
|
messages.length === 0 ? /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-empty", children: [
|
|
1123
|
-
/* @__PURE__ */
|
|
1124
|
-
/* @__PURE__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
1126
|
-
/* @__PURE__ */
|
|
1233
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-empty-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
|
|
1234
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-empty-title", children: "What can I help you find?" }),
|
|
1235
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-empty-sub", children: "Ask about products, budgets, gift ideas, specs \u2014 I'll search the entire catalogue for you." }),
|
|
1236
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-chips", children: chips.map((chip) => /* @__PURE__ */ jsx6(
|
|
1127
1237
|
"button",
|
|
1128
1238
|
{
|
|
1129
1239
|
className: "hsk-cb-chip",
|
|
@@ -1135,11 +1245,11 @@ function ChatModal({
|
|
|
1135
1245
|
] }) : messages.map((msg, idx) => {
|
|
1136
1246
|
const isLast = idx === messages.length - 1;
|
|
1137
1247
|
const isUser = msg.role === "user";
|
|
1138
|
-
return /* @__PURE__ */
|
|
1139
|
-
/* @__PURE__ */
|
|
1248
|
+
return /* @__PURE__ */ jsx6("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ jsx6("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ jsx6("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-ai-msg", children: [
|
|
1249
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
|
|
1140
1250
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-ai-body", children: [
|
|
1141
|
-
/* @__PURE__ */
|
|
1142
|
-
isLast && sources.length > 0 && /* @__PURE__ */
|
|
1251
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-text", children: renderMarkdown(msg.content) }),
|
|
1252
|
+
isLast && sources.length > 0 && /* @__PURE__ */ jsx6(
|
|
1143
1253
|
SourcesCarousel,
|
|
1144
1254
|
{
|
|
1145
1255
|
sources,
|
|
@@ -1156,9 +1266,9 @@ function ChatModal({
|
|
|
1156
1266
|
className: "hsk-cb-selected-product",
|
|
1157
1267
|
onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
|
|
1158
1268
|
children: [
|
|
1159
|
-
selectedProduct.image && /* @__PURE__ */
|
|
1269
|
+
selectedProduct.image && /* @__PURE__ */ jsx6("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
|
|
1160
1270
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-selected-info", children: [
|
|
1161
|
-
/* @__PURE__ */
|
|
1271
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
|
|
1162
1272
|
selectedProduct.price && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-selected-price", children: [
|
|
1163
1273
|
(_a = selectedProduct.currency) != null ? _a : defaultCurrency,
|
|
1164
1274
|
" ",
|
|
@@ -1169,19 +1279,19 @@ function ChatModal({
|
|
|
1169
1279
|
}
|
|
1170
1280
|
),
|
|
1171
1281
|
loading && /* @__PURE__ */ jsxs4("div", { className: "hsk-cb-typing-row", children: [
|
|
1172
|
-
/* @__PURE__ */
|
|
1282
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
|
|
1173
1283
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-typing", children: [
|
|
1174
|
-
/* @__PURE__ */
|
|
1175
|
-
/* @__PURE__ */
|
|
1176
|
-
/* @__PURE__ */
|
|
1284
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-dot" }),
|
|
1285
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-dot" }),
|
|
1286
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-dot" })
|
|
1177
1287
|
] })
|
|
1178
1288
|
] }),
|
|
1179
|
-
error && /* @__PURE__ */
|
|
1180
|
-
/* @__PURE__ */
|
|
1289
|
+
error && /* @__PURE__ */ jsx6("div", { className: "hsk-cb-error", children: error }),
|
|
1290
|
+
/* @__PURE__ */ jsx6("div", { ref: bottomRef, style: { height: 1 } })
|
|
1181
1291
|
] }),
|
|
1182
1292
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-input-wrap", children: [
|
|
1183
1293
|
/* @__PURE__ */ jsxs4("div", { className: "hsk-cb-input-box", children: [
|
|
1184
|
-
/* @__PURE__ */
|
|
1294
|
+
/* @__PURE__ */ jsx6(
|
|
1185
1295
|
"textarea",
|
|
1186
1296
|
{
|
|
1187
1297
|
ref: textareaRef,
|
|
@@ -1195,18 +1305,18 @@ function ChatModal({
|
|
|
1195
1305
|
autoFocus: true
|
|
1196
1306
|
}
|
|
1197
1307
|
),
|
|
1198
|
-
/* @__PURE__ */
|
|
1308
|
+
/* @__PURE__ */ jsx6(
|
|
1199
1309
|
"button",
|
|
1200
1310
|
{
|
|
1201
1311
|
className: `hsk-cb-send ${classNames.sendButton || ""}`,
|
|
1202
1312
|
onClick: () => handleSend(),
|
|
1203
1313
|
disabled: !input.trim() || loading,
|
|
1204
1314
|
"aria-label": "Send message",
|
|
1205
|
-
children: /* @__PURE__ */
|
|
1315
|
+
children: /* @__PURE__ */ jsx6(ArrowUpIcon2, {})
|
|
1206
1316
|
}
|
|
1207
1317
|
)
|
|
1208
1318
|
] }),
|
|
1209
|
-
/* @__PURE__ */
|
|
1319
|
+
/* @__PURE__ */ jsx6("div", { className: "hsk-cb-hint", children: "Huskel AI \xB7 searches the whole catalogue in real time" })
|
|
1210
1320
|
] })
|
|
1211
1321
|
] })
|
|
1212
1322
|
}
|
|
@@ -1231,7 +1341,7 @@ function AIChatButton({
|
|
|
1231
1341
|
setMounted(true);
|
|
1232
1342
|
}, []);
|
|
1233
1343
|
const customStyles = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, (theme == null ? void 0 : theme.primaryColor) && { "--hsk-primary": theme.primaryColor }), (theme == null ? void 0 : theme.backgroundColor) && { "--hsk-bg": theme.backgroundColor }), (theme == null ? void 0 : theme.textColor) && { "--hsk-text": theme.textColor }), (theme == null ? void 0 : theme.fontFamily) && { "--hsk-font": theme.fontFamily });
|
|
1234
|
-
return /* @__PURE__ */ jsxs4(
|
|
1344
|
+
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1235
1345
|
/* @__PURE__ */ jsxs4(
|
|
1236
1346
|
"button",
|
|
1237
1347
|
{
|
|
@@ -1240,13 +1350,13 @@ function AIChatButton({
|
|
|
1240
1350
|
style: customStyles,
|
|
1241
1351
|
"aria-label": "Open AI chat",
|
|
1242
1352
|
children: [
|
|
1243
|
-
/* @__PURE__ */
|
|
1353
|
+
/* @__PURE__ */ jsx6("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx6(SparkleIcon3, {}) }),
|
|
1244
1354
|
label !== void 0 ? label : null
|
|
1245
1355
|
]
|
|
1246
1356
|
}
|
|
1247
1357
|
),
|
|
1248
1358
|
open && mounted && createPortal2(
|
|
1249
|
-
/* @__PURE__ */
|
|
1359
|
+
/* @__PURE__ */ jsx6(
|
|
1250
1360
|
ChatModal,
|
|
1251
1361
|
{
|
|
1252
1362
|
title,
|