@huskel/sdk 0.4.0 → 0.4.1

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.js CHANGED
@@ -585,134 +585,6 @@ function useChat() {
585
585
  // src/components/SearchBar.tsx
586
586
  var import_react7 = require("react");
587
587
  var import_jsx_runtime2 = require("react/jsx-runtime");
588
- var CSS = `
589
- /* \u2500\u2500 Light mode defaults (CSS custom properties) \u2500\u2500 */
590
- .hsk-sb-wrap {
591
- --hsk-bg: #fff;
592
- --hsk-border: #d1d5db;
593
- --hsk-text: #111;
594
- --hsk-muted: #9ca3af;
595
- --hsk-hover: #f3f4f6;
596
- --hsk-drop-shadow: 0 8px 30px rgba(0,0,0,.12);
597
- position: relative;
598
- width: 100%;
599
- font-family: inherit;
600
- }
601
-
602
- /* \u2500\u2500 Dark mode overrides at wrap level so ALL children inherit \u2500\u2500 */
603
- @media (prefers-color-scheme: dark) {
604
- .hsk-sb-wrap {
605
- --hsk-bg: #1a1a1b;
606
- --hsk-border: #2a2a2d;
607
- --hsk-text: #f3f3f2;
608
- --hsk-muted: #666;
609
- --hsk-hover: #1e1e1f;
610
- --hsk-drop-shadow: 0 12px 40px rgba(0,0,0,.5);
611
- }
612
- }
613
-
614
- /* \u2500\u2500 Input \u2500\u2500 */
615
- .hsk-sb-input {
616
- width: 100%;
617
- padding: 10px 16px 10px 40px;
618
- font-size: 14px;
619
- border-radius: 9999px;
620
- border: 1.5px solid var(--hsk-border);
621
- outline: none;
622
- box-sizing: border-box;
623
- background: var(--hsk-bg);
624
- color: var(--hsk-text);
625
- transition: border-color .15s, box-shadow .15s;
626
- font-family: inherit;
627
- }
628
- .hsk-sb-input::placeholder { color: var(--hsk-muted); }
629
- .hsk-sb-input:focus {
630
- border-color: #ff6a33;
631
- box-shadow: 0 0 0 3px rgba(255,106,51,.12);
632
- }
633
- .hsk-sb-icon {
634
- position: absolute;
635
- left: 14px;
636
- top: 50%;
637
- transform: translateY(-50%);
638
- color: var(--hsk-muted);
639
- pointer-events: none;
640
- display: flex;
641
- align-items: center;
642
- }
643
-
644
- /* \u2500\u2500 Dropdown \u2500\u2500 */
645
- .hsk-sb-drop {
646
- position: absolute;
647
- top: calc(100% + 6px);
648
- left: 0; right: 0;
649
- background: var(--hsk-bg);
650
- border: 1px solid var(--hsk-border);
651
- border-radius: 12px;
652
- box-shadow: var(--hsk-drop-shadow);
653
- z-index: 9999;
654
- overflow: hidden;
655
- padding: 6px 0;
656
- }
657
-
658
- /* \u2500\u2500 Row \u2500\u2500 */
659
- .hsk-sb-row {
660
- display: flex;
661
- align-items: center;
662
- gap: 12px;
663
- padding: 9px 16px;
664
- cursor: pointer;
665
- transition: background .1s;
666
- }
667
- .hsk-sb-row:hover { background: var(--hsk-hover); }
668
- .hsk-sb-row-icon {
669
- color: var(--hsk-muted);
670
- flex-shrink: 0;
671
- display: flex;
672
- align-items: center;
673
- }
674
- .hsk-sb-row-body { flex: 1; min-width: 0; }
675
- .hsk-sb-row-title {
676
- font-size: 13px;
677
- font-weight: 500;
678
- color: var(--hsk-text);
679
- white-space: nowrap;
680
- overflow: hidden;
681
- text-overflow: ellipsis;
682
- line-height: 1.3;
683
- }
684
- .hsk-sb-row-sub {
685
- font-size: 11px;
686
- color: var(--hsk-muted);
687
- margin-top: 2px;
688
- white-space: nowrap;
689
- overflow: hidden;
690
- text-overflow: ellipsis;
691
- }
692
- .hsk-sb-empty {
693
- padding: 14px 16px;
694
- font-size: 13px;
695
- color: var(--hsk-muted);
696
- }
697
-
698
- /* \u2500\u2500 Thin accent bar while loading (non-intrusive, no text) \u2500\u2500 */
699
- .hsk-sb-loading-bar {
700
- height: 2px;
701
- background: linear-gradient(90deg, transparent, #ff6a33, transparent);
702
- background-size: 200% 100%;
703
- animation: hsk-sweep 0.9s linear infinite;
704
- position: absolute;
705
- top: 0; left: 0; right: 0;
706
- }
707
- @keyframes hsk-sweep {
708
- 0% { background-position: 200% 0; }
709
- 100% { background-position: -200% 0; }
710
- }
711
-
712
- /* \u2500\u2500 Staggered fade-in \u2500\u2500 */
713
- .hsk-sb-fade { animation: hsk-fin .1s ease-out both; }
714
- @keyframes hsk-fin { from { opacity:0; transform:translateY(3px); } to { opacity:1; transform:none; } }
715
- `;
716
588
  var SearchIcon = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "15", height: "15", viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
717
589
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "8.5", cy: "8.5", r: "5.5" }),
718
590
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "13", y1: "13", x2: "18", y2: "18" })
@@ -725,7 +597,9 @@ function SearchBar({
725
597
  className,
726
598
  inputClassName,
727
599
  dropdownClassName,
728
- renderResult
600
+ renderResult,
601
+ theme,
602
+ classNames = {}
729
603
  }) {
730
604
  const [query, setQuery] = (0, import_react7.useState)("");
731
605
  const [open, setOpen] = (0, import_react7.useState)(false);
@@ -758,59 +632,57 @@ function SearchBar({
758
632
  onSelect == null ? void 0 : onSelect(r);
759
633
  };
760
634
  const showDrop = open && query.trim().length > 0;
761
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
762
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: CSS }),
763
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `hsk-sb-wrap ${className != null ? className : ""}`, ref: wrap, children: [
764
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hsk-sb-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SearchIcon, {}) }),
765
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
766
- "input",
767
- {
768
- className: `hsk-sb-input ${inputClassName != null ? inputClassName : ""}`,
769
- type: "text",
770
- value: query,
771
- placeholder,
772
- onChange: (e) => setQuery(e.target.value),
773
- onFocus: () => results.length > 0 && query.trim() && setOpen(true),
774
- autoComplete: "off",
775
- spellCheck: false
776
- }
777
- ),
778
- showDrop && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `hsk-sb-drop ${dropdownClassName != null ? dropdownClassName : ""}`, style: { position: "absolute" }, children: [
779
- loading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hsk-sb-loading-bar" }),
780
- results.length === 0 && !loading && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hsk-sb-empty", children: [
781
- "No results for \u201C",
782
- query,
783
- "\u201D"
784
- ] }),
785
- results.map((r, i) => {
786
- var _a;
787
- return renderResult ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
788
- "div",
789
- {
790
- onClick: () => handleSelect(r),
791
- className: "hsk-sb-fade",
792
- style: { animationDelay: `${i * 18}ms` },
793
- children: renderResult(r)
794
- },
795
- r.id
796
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
797
- "div",
798
- {
799
- className: "hsk-sb-row hsk-sb-fade",
800
- style: { animationDelay: `${i * 18}ms` },
801
- onClick: () => handleSelect(r),
802
- children: [
803
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hsk-sb-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SearchIcon, {}) }),
804
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hsk-sb-row-body", children: [
805
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hsk-sb-row-title", children: r.product.name }),
806
- (r.product.category || r.product.brand) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hsk-sb-row-sub", children: (_a = r.product.category) != null ? _a : r.product.brand })
807
- ] })
808
- ]
809
- },
810
- r.id
811
- );
812
- })
813
- ] })
635
+ 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 });
636
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `hsk-sb-wrap ${classNames.root || ""} ${className || ""}`, ref: wrap, style: customStyles, children: [
637
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hsk-sb-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SearchIcon, {}) }),
638
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
639
+ "input",
640
+ {
641
+ className: `hsk-sb-input ${classNames.input || ""} ${inputClassName || ""}`,
642
+ type: "text",
643
+ value: query,
644
+ placeholder,
645
+ onChange: (e) => setQuery(e.target.value),
646
+ onFocus: () => results.length > 0 && query.trim() && setOpen(true),
647
+ autoComplete: "off",
648
+ spellCheck: false
649
+ }
650
+ ),
651
+ showDrop && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `hsk-sb-drop ${classNames.dropdown || ""} ${dropdownClassName || ""}`, style: { position: "absolute" }, children: [
652
+ loading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hsk-sb-loading-bar" }),
653
+ results.length === 0 && !loading && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hsk-sb-empty", children: [
654
+ "No results for \u201C",
655
+ query,
656
+ "\u201D"
657
+ ] }),
658
+ results.map((r, i) => {
659
+ var _a;
660
+ return renderResult ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
661
+ "div",
662
+ {
663
+ onClick: () => handleSelect(r),
664
+ className: "hsk-sb-fade",
665
+ style: { animationDelay: `${i * 18}ms` },
666
+ children: renderResult(r)
667
+ },
668
+ r.id
669
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
670
+ "div",
671
+ {
672
+ className: `hsk-sb-row hsk-sb-fade ${classNames.row || ""}`,
673
+ style: { animationDelay: `${i * 18}ms` },
674
+ onClick: () => handleSelect(r),
675
+ children: [
676
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hsk-sb-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SearchIcon, {}) }),
677
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hsk-sb-row-body", children: [
678
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hsk-sb-row-title", children: r.product.name }),
679
+ (r.product.category || r.product.brand) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hsk-sb-row-sub", children: (_a = r.product.category) != null ? _a : r.product.brand })
680
+ ] })
681
+ ]
682
+ },
683
+ r.id
684
+ );
685
+ })
814
686
  ] })
815
687
  ] });
816
688
  }
@@ -819,236 +691,22 @@ function SearchBar({
819
691
  var import_react8 = require("react");
820
692
  var import_react_dom = require("react-dom");
821
693
  var import_jsx_runtime3 = require("react/jsx-runtime");
822
- var CSS2 = `
823
- /* \u2500\u2500 Trigger button \u2500\u2500 */
824
- .hsk-sp-btn {
825
- display: inline-flex;
826
- align-items: center;
827
- justify-content: center;
828
- width: 32px;
829
- height: 32px;
830
- border-radius: 8px;
831
- border: 1px solid var(--hsk-sp-border, rgba(255,106,51,.35));
832
- background: var(--hsk-sp-bg, rgba(255,106,51,.08));
833
- color: #ff6a33;
834
- cursor: pointer;
835
- font-size: 15px;
836
- line-height: 1;
837
- transition: background .15s, border-color .15s, transform .12s;
838
- flex-shrink: 0;
839
- padding: 0;
840
- }
841
- .hsk-sp-btn:hover {
842
- background: rgba(255,106,51,.18);
843
- border-color: rgba(255,106,51,.7);
844
- transform: scale(1.1);
845
- }
846
- .hsk-sp-btn:active { transform: scale(.92); }
847
-
848
- /* \u2500\u2500 Backdrop \u2500\u2500 */
849
- .hsk-sp-backdrop {
850
- position: fixed;
851
- inset: 0;
852
- z-index: 99998;
853
- display: flex;
854
- align-items: flex-start;
855
- justify-content: center;
856
- padding: clamp(48px, 10vh, 96px) 16px 40px;
857
- animation: hsk-bd-in .2s ease-out both;
858
- overflow-y: auto;
859
- }
860
- @keyframes hsk-bd-in { from { opacity:0; } to { opacity:1; } }
861
-
862
- /* \u2500\u2500 Modal card \u2500\u2500 */
863
- .hsk-sp-card {
864
- width: 100%;
865
- max-width: 600px;
866
- border-radius: 18px;
867
- overflow: hidden;
868
- animation: hsk-card-in .24s cubic-bezier(.34,1.36,.64,1) both;
869
- flex-shrink: 0;
870
- /* light */
871
- background: var(--hsk-modal-card-bg, #fff);
872
- border: 1px solid var(--hsk-modal-card-border, rgba(0,0,0,.08));
873
- box-shadow: 0 32px 80px rgba(0,0,0,.18), 0 2px 8px rgba(0,0,0,.06);
874
- }
875
- @keyframes hsk-card-in {
876
- from { opacity:0; transform: scale(.96) translateY(-12px); }
877
- to { opacity:1; transform: scale(1) translateY(0); }
878
- }
879
-
880
- /* \u2500\u2500 Header \u2500\u2500 */
881
- .hsk-sp-header {
882
- display: flex;
883
- align-items: center;
884
- gap: 10px;
885
- padding: 18px 20px 14px;
886
- border-bottom: 1px solid var(--hsk-modal-divide, rgba(0,0,0,.07));
887
- }
888
- .hsk-sp-header-icon { font-size: 18px; color: #ff6a33; flex-shrink: 0; }
889
- .hsk-sp-header-body { flex: 1; min-width: 0; }
890
- .hsk-sp-header-title {
891
- font-size: 14px;
892
- font-weight: 600;
893
- color: var(--hsk-modal-text, #111);
894
- white-space: nowrap;
895
- overflow: hidden;
896
- text-overflow: ellipsis;
897
- }
898
- .hsk-sp-header-sub {
899
- font-size: 11px;
900
- color: var(--hsk-modal-muted, #888);
901
- margin-top: 2px;
902
- }
903
- .hsk-sp-close {
904
- width: 30px; height: 30px;
905
- border-radius: 8px;
906
- border: 1px solid var(--hsk-modal-divide, rgba(0,0,0,.1));
907
- background: none;
908
- color: var(--hsk-modal-muted, #888);
909
- cursor: pointer;
910
- font-size: 18px;
911
- display: flex; align-items: center; justify-content: center;
912
- transition: all .15s;
913
- flex-shrink: 0;
914
- }
915
- .hsk-sp-close:hover { border-color: #ff6a33; color: #ff6a33; }
916
-
917
- /* \u2500\u2500 Thin loading accent bar \u2500\u2500 */
918
- .hsk-sp-bar {
919
- height: 2px;
920
- background: linear-gradient(90deg, transparent 0%, #ff6a33 40%, #ffaa80 60%, transparent 100%);
921
- background-size: 200% 100%;
922
- animation: hsk-bar .9s linear infinite;
923
- }
924
- @keyframes hsk-bar { 0%{background-position:200% 0} 100%{background-position:-200% 0} }
925
-
926
- /* \u2500\u2500 Results list \u2500\u2500 */
927
- .hsk-sp-results { padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
928
- .hsk-sp-empty { padding: 40px; text-align: center; font-size: 13px; color: var(--hsk-modal-muted, #aaa); }
929
-
930
- /* \u2500\u2500 Result card (toast-inspired: slides up from bottom) \u2500\u2500 */
931
- .hsk-sp-item {
932
- display: flex;
933
- gap: 14px;
934
- padding: 14px;
935
- border-radius: 12px;
936
- border: 1px solid var(--hsk-modal-item-border, rgba(0,0,0,.07));
937
- background: var(--hsk-modal-item-bg, #f9f9f9);
938
- animation: hsk-toast-up .28s cubic-bezier(.22,.68,0,1.2) both;
939
- overflow: hidden;
940
- }
941
- @keyframes hsk-toast-up {
942
- from { opacity:0; transform: translateY(18px) scale(.97); }
943
- to { opacity:1; transform: translateY(0) scale(1); }
944
- }
945
-
946
- /* image */
947
- .hsk-sp-img-wrap {
948
- width: 72px; height: 72px;
949
- border-radius: 10px;
950
- background: #fff;
951
- border: 1px solid var(--hsk-modal-divide, rgba(0,0,0,.07));
952
- flex-shrink: 0;
953
- overflow: hidden;
954
- display: flex; align-items: center; justify-content: center;
955
- padding: 6px;
956
- }
957
- .hsk-sp-img-wrap img { max-width: 100%; max-height: 100%; object-fit: contain; }
958
- .hsk-sp-img-placeholder { font-size: 26px; }
959
-
960
- /* body */
961
- .hsk-sp-item-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
962
- .hsk-sp-item-name {
963
- font-size: 14px;
964
- font-weight: 600;
965
- color: var(--hsk-modal-text, #111);
966
- line-height: 1.35;
967
- overflow: hidden;
968
- display: -webkit-box;
969
- -webkit-line-clamp: 2;
970
- -webkit-box-orient: vertical;
971
- }
972
- .hsk-sp-item-cat {
973
- font-size: 11px;
974
- font-weight: 600;
975
- color: #ff6a33;
976
- text-transform: uppercase;
977
- letter-spacing: .05em;
978
- }
979
- .hsk-sp-item-price-row { display: flex; align-items: baseline; gap: 8px; margin-top: 2px; }
980
- .hsk-sp-item-price {
981
- font-size: 18px;
982
- font-weight: 700;
983
- color: var(--hsk-modal-text, #111);
984
- }
985
- .hsk-sp-item-currency { font-size: 12px; color: var(--hsk-modal-muted, #888); }
986
-
987
- /* actions */
988
- .hsk-sp-actions { display: flex; gap: 6px; margin-top: 8px; }
989
- .hsk-sp-action {
990
- flex: 1;
991
- padding: 7px 10px;
992
- border-radius: 8px;
993
- font-size: 12px;
994
- font-weight: 600;
995
- cursor: pointer;
996
- border: 1px solid transparent;
997
- transition: all .15s;
998
- text-align: center;
999
- font-family: inherit;
1000
- }
1001
- .hsk-sp-action-primary {
1002
- background: #ff6a33;
1003
- color: #fff;
1004
- border-color: #ff6a33;
1005
- }
1006
- .hsk-sp-action-primary:hover { background: #e55d2a; }
1007
- .hsk-sp-action-secondary {
1008
- background: var(--hsk-action-sec-bg, rgba(0,0,0,.06));
1009
- color: var(--hsk-modal-muted, #666);
1010
- border-color: var(--hsk-modal-divide, rgba(0,0,0,.1));
1011
- }
1012
- .hsk-sp-action-secondary:hover {
1013
- background: var(--hsk-action-sec-bg-hover, rgba(0,0,0,.1));
1014
- color: var(--hsk-modal-text, #333);
1015
- }
1016
-
1017
- /* \u2500\u2500 Footer \u2500\u2500 */
1018
- .hsk-sp-footer {
1019
- padding: 12px 20px;
1020
- border-top: 1px solid var(--hsk-modal-divide, rgba(0,0,0,.07));
1021
- display: flex;
1022
- align-items: center;
1023
- gap: 8px;
1024
- }
1025
- .hsk-sp-badge {
1026
- font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
1027
- color: #ff6a33;
1028
- background: rgba(255,106,51,.1);
1029
- border: 1px solid rgba(255,106,51,.25);
1030
- padding: 2px 8px;
1031
- border-radius: 999px;
1032
- }
1033
- .hsk-sp-esc { font-size: 11px; color: var(--hsk-modal-muted, #bbb); margin-left: auto; }
1034
-
1035
- /* \u2500\u2500 Dark mode \u2500\u2500 */
1036
- @media (prefers-color-scheme: dark) {
1037
- .hsk-sp-card {
1038
- --hsk-modal-card-bg: #111112;
1039
- --hsk-modal-card-border: rgba(255,255,255,.07);
1040
- --hsk-modal-text: #f3f3f2;
1041
- --hsk-modal-muted: #666;
1042
- --hsk-modal-divide: rgba(255,255,255,.07);
1043
- --hsk-modal-item-bg: #1a1a1b;
1044
- --hsk-modal-item-border: rgba(255,255,255,.06);
1045
- --hsk-action-sec-bg: rgba(255,255,255,.07);
1046
- --hsk-action-sec-bg-hover: rgba(255,255,255,.12);
1047
- }
1048
- .hsk-sp-img-wrap { background: #242425; border-color: rgba(255,255,255,.08); }
1049
- }
1050
- `;
1051
- function SparkleModal({ productName, limit, backdropColor, backdropBlur, onClose, onNavigate, onResult }) {
694
+ var SparkleIcon = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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" }) });
695
+ var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
696
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
697
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
698
+ ] });
699
+ function SparkleModal({
700
+ productName,
701
+ limit,
702
+ backdropColor,
703
+ backdropBlur,
704
+ onClose,
705
+ onNavigate,
706
+ onResult,
707
+ theme,
708
+ classNames = {}
709
+ }) {
1052
710
  const { results, loading, search } = useSearch();
1053
711
  const initiated = (0, import_react8.useRef)(false);
1054
712
  (0, import_react8.useEffect)(() => {
@@ -1076,109 +734,114 @@ function SparkleModal({ productName, limit, backdropColor, backdropBlur, onClose
1076
734
  if (r.product.url) window.location.href = r.product.url;
1077
735
  }
1078
736
  };
1079
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1080
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: CSS2 }),
1081
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1082
- "div",
1083
- {
1084
- className: "hsk-sp-backdrop",
1085
- onClick: onClose,
1086
- style: {
1087
- backdropFilter: `blur(${blurVal})`,
1088
- WebkitBackdropFilter: `blur(${blurVal})`,
1089
- background: bg != null ? bg : void 0
1090
- /* CSS handles light/dark via @media if bg not forced */
1091
- },
1092
- children: [
1093
- !bg && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
1094
- @media (prefers-color-scheme: dark) { .hsk-sp-backdrop { background: rgba(0,0,0,.80); } }
1095
- @media (prefers-color-scheme: light) { .hsk-sp-backdrop { background: rgba(240,240,245,.70); } }
1096
- ` }),
1097
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-card", onClick: (e) => e.stopPropagation(), children: [
1098
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-header", children: [
1099
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-header-icon", children: "\u2726" }),
1100
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-header-body", children: [
1101
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-header-title", children: [
1102
- "Similar to \u201C",
1103
- productName,
1104
- "\u201D"
1105
- ] }),
1106
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-header-sub", children: "AI vector similarity \xB7 instant results" })
1107
- ] }),
1108
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: "\xD7" })
737
+ 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 });
738
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
739
+ "div",
740
+ {
741
+ className: `hsk-sp-backdrop ${classNames.backdrop || ""}`,
742
+ onClick: onClose,
743
+ style: __spreadValues({
744
+ backdropFilter: `blur(${blurVal})`,
745
+ WebkitBackdropFilter: `blur(${blurVal})`,
746
+ background: bg != null ? bg : void 0
747
+ }, customStyles),
748
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `hsk-sp-card ${classNames.card || ""}`, onClick: (e) => e.stopPropagation(), children: [
749
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-header", children: [
750
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-header-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {}) }),
751
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-header-body", children: [
752
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-header-title", children: [
753
+ "Similar to \u201C",
754
+ productName,
755
+ "\u201D"
1109
756
  ] }),
1110
- loading && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-bar" }),
1111
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-results", children: [
1112
- !loading && results.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-empty", children: "No similar products found." }),
1113
- results.map((r, i) => {
1114
- var _a, _b, _c;
1115
- const price = parseFloat(((_a = r.product.price) == null ? void 0 : _a.replace(/[^0-9.]/g, "")) || "0");
1116
- const currency = (_b = r.product.currency) != null ? _b : "KES";
1117
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1118
- "div",
1119
- {
1120
- className: "hsk-sp-item",
1121
- style: { animationDelay: `${i * 55}ms` },
1122
- children: [
1123
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-img-wrap", children: ((_c = r.product.images) == null ? void 0 : _c[0]) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
1124
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-item-body", children: [
1125
- r.product.category && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-item-cat", children: r.product.category }),
1126
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-item-name", children: r.product.name }),
1127
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-item-price-row", children: [
1128
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-item-currency", children: currency }),
1129
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-item-price", children: price.toLocaleString() })
1130
- ] }),
1131
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-actions", children: [
1132
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1133
- "button",
1134
- {
1135
- className: "hsk-sp-action hsk-sp-action-primary",
1136
- onClick: () => handleNav(r),
1137
- children: "View Product"
1138
- }
1139
- ),
1140
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1141
- "button",
1142
- {
1143
- className: "hsk-sp-action hsk-sp-action-secondary",
1144
- onClick: () => onClose(),
1145
- children: "Add to Cart"
1146
- }
1147
- )
1148
- ] })
1149
- ] })
1150
- ]
1151
- },
1152
- r.id
1153
- );
1154
- })
1155
- ] }),
1156
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-footer", children: [
1157
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-badge", children: "\u2726 Huskel AI" }),
1158
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-esc", children: "Esc to close" })
1159
- ] })
1160
- ] })
1161
- ]
1162
- }
1163
- )
1164
- ] });
757
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-header-sub", children: "AI vector similarity \xB7 instant results" })
758
+ ] }),
759
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "hsk-sp-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CloseIcon, {}) })
760
+ ] }),
761
+ loading && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-bar" }),
762
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-results", children: [
763
+ !loading && results.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-empty", children: "No similar products found." }),
764
+ results.map((r, i) => {
765
+ var _a, _b, _c;
766
+ const price = parseFloat(((_a = r.product.price) == null ? void 0 : _a.replace(/[^0-9.]/g, "")) || "0");
767
+ const currency = (_b = r.product.currency) != null ? _b : "KES";
768
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
769
+ "div",
770
+ {
771
+ className: `hsk-sp-item ${classNames.item || ""}`,
772
+ style: { animationDelay: `${i * 55}ms` },
773
+ children: [
774
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-img-wrap", children: ((_c = r.product.images) == null ? void 0 : _c[0]) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { src: r.product.images[0], alt: r.product.name }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-img-placeholder", children: "\u{1F6CD}" }) }),
775
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-item-body", children: [
776
+ r.product.category && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-item-cat", children: r.product.category }),
777
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hsk-sp-item-name", children: r.product.name }),
778
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-item-price-row", children: [
779
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-item-currency", children: currency }),
780
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-item-price", children: price.toLocaleString() })
781
+ ] }),
782
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-actions", children: [
783
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
784
+ "button",
785
+ {
786
+ className: "hsk-sp-action hsk-sp-action-primary",
787
+ onClick: () => handleNav(r),
788
+ children: "View Product"
789
+ }
790
+ ),
791
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
792
+ "button",
793
+ {
794
+ className: "hsk-sp-action hsk-sp-action-secondary",
795
+ onClick: () => onClose(),
796
+ children: "Add to Cart"
797
+ }
798
+ )
799
+ ] })
800
+ ] })
801
+ ]
802
+ },
803
+ r.id
804
+ );
805
+ })
806
+ ] }),
807
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hsk-sp-footer", children: [
808
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "hsk-sp-badge", style: { display: "inline-flex", alignItems: "center", gap: "4px" }, children: [
809
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {}),
810
+ " Huskel AI"
811
+ ] }),
812
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hsk-sp-esc", children: "Esc to close" })
813
+ ] })
814
+ ] })
815
+ }
816
+ );
1165
817
  }
1166
- function Sparkle({ productName, limit = 8, onResult, backdropColor, backdropBlur, className, onNavigate }) {
818
+ function Sparkle({
819
+ productName,
820
+ limit = 8,
821
+ onResult,
822
+ backdropColor,
823
+ backdropBlur,
824
+ className,
825
+ onNavigate,
826
+ theme,
827
+ classNames = {}
828
+ }) {
1167
829
  const [open, setOpen] = (0, import_react8.useState)(false);
1168
830
  const [mounted, setMounted] = (0, import_react8.useState)(false);
1169
831
  (0, import_react8.useEffect)(() => {
1170
832
  setMounted(true);
1171
833
  }, []);
834
+ 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 });
1172
835
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1173
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: CSS2 }),
1174
836
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1175
837
  "button",
1176
838
  {
1177
- className: `hsk-sp-btn ${className != null ? className : ""}`,
839
+ className: `hsk-sp-btn ${classNames.button || ""} ${className || ""}`,
1178
840
  onClick: () => setOpen(true),
841
+ style: customStyles,
1179
842
  title: "Find similar products",
1180
843
  "aria-label": "Find similar products",
1181
- children: "\u2726"
844
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SparkleIcon, {})
1182
845
  }
1183
846
  ),
1184
847
  open && mounted && (0, import_react_dom.createPortal)(
@@ -1191,7 +854,9 @@ function Sparkle({ productName, limit = 8, onResult, backdropColor, backdropBlur
1191
854
  backdropBlur,
1192
855
  onClose: () => setOpen(false),
1193
856
  onResult,
1194
- onNavigate
857
+ onNavigate,
858
+ theme,
859
+ classNames
1195
860
  }
1196
861
  ),
1197
862
  document.body
@@ -1202,59 +867,36 @@ function Sparkle({ productName, limit = 8, onResult, backdropColor, backdropBlur
1202
867
  // src/components/ChatWidget.tsx
1203
868
  var import_react9 = require("react");
1204
869
  var import_jsx_runtime4 = require("react/jsx-runtime");
1205
- var S = `
1206
- .hsk-chat-widget{display:flex;flex-direction:column;height:100%;min-height:320px;font-family:inherit;background:#0f0f10;border:1px solid #2a2a2d;border-radius:12px;overflow:hidden}
1207
- .hsk-chat-header{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid #1e1e1f;background:#111112;flex-shrink:0}
1208
- .hsk-chat-title{font-size:14px;font-weight:600;color:#f3f3f2}
1209
- .hsk-chat-badge{font-size:10px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:#ff6a33;background:#ff6a3315;border:1px solid #ff6a3330;padding:2px 8px;border-radius:20px}
1210
- .hsk-chat-messages{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px;scroll-behavior:smooth}
1211
- .hsk-chat-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:8px;color:#555;font-size:13px;text-align:center;padding:24px}
1212
- .hsk-chat-empty-icon{font-size:28px;margin-bottom:4px}
1213
- .hsk-msg-row{display:flex;gap:8px;align-items:flex-start}
1214
- .hsk-msg-row.user{flex-direction:row-reverse}
1215
- .hsk-msg-avatar{width:28px;height:28px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700}
1216
- .hsk-msg-avatar.ai{background:#ff6a3320;border:1px solid #ff6a3340;color:#ff6a33}
1217
- .hsk-msg-avatar.user{background:#2a2a2d;color:#9a9aa1}
1218
- .hsk-msg-bubble{max-width:78%;padding:10px 14px;border-radius:12px;font-size:13px;line-height:1.6}
1219
- .hsk-msg-bubble.ai{background:#171718;border:1px solid #2a2a2d;color:#e8e8e7;border-radius:4px 12px 12px 12px}
1220
- .hsk-msg-bubble.user{background:#ff6a33;color:#fff;border-radius:12px 4px 12px 12px}
1221
- .hsk-sources{margin-top:10px;display:flex;flex-direction:column;gap:6px}
1222
- .hsk-source-card{display:flex;align-items:center;gap:10px;padding:8px 10px;background:#1a1a1b;border:1px solid #252527;border-radius:8px;cursor:pointer;transition:border-color 0.15s}
1223
- .hsk-source-card:hover{border-color:#ff6a3360}
1224
- .hsk-source-img{width:36px;height:36px;object-fit:cover;border-radius:4px;background:#fff}
1225
- .hsk-source-name{font-size:12px;font-weight:500;color:#e8e8e7;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
1226
- .hsk-source-price{font-size:11px;color:#ff6a33;font-weight:700;margin-top:2px}
1227
- .hsk-typing{display:flex;gap:4px;align-items:center;padding:10px 14px;background:#171718;border:1px solid #2a2a2d;border-radius:4px 12px 12px 12px;width:fit-content}
1228
- .hsk-typing-dot{width:6px;height:6px;background:#ff6a33;border-radius:50%;animation:hsk-chat-bounce 1.2s infinite}
1229
- .hsk-typing-dot:nth-child(2){animation-delay:0.2s}
1230
- .hsk-typing-dot:nth-child(3){animation-delay:0.4s}
1231
- @keyframes hsk-chat-bounce{0%,100%{opacity:0.3;transform:translateY(0)}50%{opacity:1;transform:translateY(-4px)}}
1232
- .hsk-chat-input-area{display:flex;align-items:center;gap:8px;padding:12px 14px;border-top:1px solid #1e1e1f;background:#111112;flex-shrink:0}
1233
- .hsk-chat-input{flex:1;background:#1a1a1b;border:1px solid #2a2a2d;border-radius:8px;padding:9px 14px;font-size:13px;color:#f3f3f2;outline:none;font-family:inherit;transition:border-color 0.2s;resize:none;min-height:38px;max-height:120px;line-height:1.5}
1234
- .hsk-chat-input::placeholder{color:#555}
1235
- .hsk-chat-input:focus{border-color:#ff6a33}
1236
- .hsk-chat-send{width:34px;height:34px;border-radius:8px;background:#ff6a33;border:none;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:16px;transition:opacity 0.15s,transform 0.1s}
1237
- .hsk-chat-send:hover{opacity:0.88}
1238
- .hsk-chat-send:active{transform:scale(0.93)}
1239
- .hsk-chat-send:disabled{opacity:0.4;cursor:not-allowed}
1240
- .hsk-chat-reset{font-size:11px;color:#555;cursor:pointer;padding:0 4px;transition:color 0.15s;background:none;border:none;font-family:inherit}
1241
- .hsk-chat-reset:hover{color:#ff6a33}
1242
- `;
1243
- function SourceCard({ source, onSelect }) {
870
+ var SparkleIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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" }) });
871
+ var ArrowUpIcon = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
872
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m5 12 7-7 7 7" }),
873
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 19V5" })
874
+ ] });
875
+ function SourceCard({ source, defaultCurrency, onSelect }) {
1244
876
  var _a;
1245
877
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-source-card", onClick: () => onSelect == null ? void 0 : onSelect(source), children: [
1246
878
  source.image && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("img", { src: source.image, alt: source.name, className: "hsk-source-img" }),
1247
879
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
1248
880
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-source-name", children: source.name }),
1249
881
  source.price && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-source-price", children: [
1250
- (_a = source.currency) != null ? _a : "KES",
882
+ (_a = source.currency) != null ? _a : defaultCurrency,
1251
883
  " ",
1252
884
  source.price
1253
885
  ] })
1254
886
  ] })
1255
887
  ] });
1256
888
  }
1257
- function ChatWidget({ placeholder = "Ask about anything in our store\u2026", title = "AI Shopping Assistant", className, onSelectSource }) {
889
+ function ChatWidget({
890
+ title = "AI Shopping Assistant",
891
+ placeholder = "Ask about anything in our store\u2026",
892
+ emptyStateText = "Ask me anything about our products",
893
+ emptyStateSuggestions = '"Find me headphones under KSh 5,000" \xB7 "Gift ideas"',
894
+ defaultCurrency = "KES",
895
+ className,
896
+ theme,
897
+ classNames = {},
898
+ onSelectSource
899
+ }) {
1258
900
  const { messages, sources, loading, error, send, reset } = useChat();
1259
901
  const [input, setInput] = (0, import_react9.useState)("");
1260
902
  const bottomRef = (0, import_react9.useRef)(null);
@@ -1282,581 +924,93 @@ function ChatWidget({ placeholder = "Ask about anything in our store\u2026", tit
1282
924
  t.style.height = "auto";
1283
925
  t.style.height = Math.min(t.scrollHeight, 120) + "px";
1284
926
  };
1285
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1286
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: S }),
1287
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `hsk-chat-widget ${className != null ? className : ""}`, children: [
1288
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-chat-header", children: [
1289
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontSize: 16, color: "#ff6a33" }, children: "\u2726" }),
1290
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "hsk-chat-title", children: title }),
1291
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "hsk-chat-badge", children: "AI" }),
1292
- messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
1293
- ] }),
1294
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-chat-messages", children: [
1295
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-chat-empty", children: [
1296
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-chat-empty-icon", children: "\u2726" }),
1297
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { children: "Ask me anything about our products" }),
1298
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 12, color: "#444", marginTop: 4 }, children: '"Find me headphones under KSh 5,000" \xB7 "Gift ideas for a chef"' })
1299
- ] }) : messages.map((msg, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1300
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `hsk-msg-row ${msg.role}`, children: [
1301
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `hsk-msg-avatar ${msg.role === "assistant" ? "ai" : "user"}`, children: msg.role === "assistant" ? "\u2726" : "\u2191" }),
1302
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `hsk-msg-bubble ${msg.role === "assistant" ? "ai" : "user"}`, children: msg.content })
927
+ 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 });
928
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
929
+ "div",
930
+ {
931
+ className: `hsk-chat-widget ${classNames.root || ""} ${className || ""}`,
932
+ style: customStyles,
933
+ children: [
934
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `hsk-chat-header ${classNames.header || ""}`, children: [
935
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "hsk-chat-header-icon", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SparkleIcon2, {}) }),
936
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "hsk-chat-title", children: title }),
937
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "hsk-chat-badge", children: "AI" }),
938
+ messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "hsk-chat-reset", onClick: reset, style: { marginLeft: "auto" }, children: "Clear" })
939
+ ] }),
940
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-chat-messages", children: [
941
+ messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-chat-empty", children: [
942
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-chat-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SparkleIcon2, {}) }),
943
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { children: emptyStateText }),
944
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-chat-empty-suggestions", children: emptyStateSuggestions })
945
+ ] }) : messages.map((msg, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
946
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `hsk-msg-row ${msg.role}`, children: [
947
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `hsk-msg-avatar ${msg.role === "assistant" ? "ai" : "user"}`, children: msg.role === "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SparkleIcon2, {}) : "U" }),
948
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `hsk-msg-bubble ${msg.role} ${classNames.messageBubble || ""}`, children: msg.content })
949
+ ] }),
950
+ msg.role === "assistant" && idx === messages.length - 1 && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-sources-container", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SourceCard, { source: src, defaultCurrency, onSelect: onSelectSource }, si)) }) })
951
+ ] }, idx)),
952
+ loading && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-msg-row", children: [
953
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-msg-avatar ai", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SparkleIcon2, {}) }),
954
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-typing", children: [
955
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-typing-dot" }),
956
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-typing-dot" }),
957
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-typing-dot" })
958
+ ] })
1303
959
  ] }),
1304
- msg.role === "assistant" && idx === messages.length - 1 && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginLeft: 36 }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-sources", children: sources.map((src, si) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SourceCard, { source: src, onSelect: onSelectSource }, si)) }) })
1305
- ] }, idx)),
1306
- loading && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-msg-row", children: [
1307
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-msg-avatar ai", children: "\u2726" }),
1308
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-typing", children: [
1309
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-typing-dot" }),
1310
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-typing-dot" }),
1311
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-typing-dot" })
1312
- ] })
960
+ error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "hsk-chat-error", children: error }),
961
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: bottomRef })
1313
962
  ] }),
1314
- error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: 12, color: "#ef4444", textAlign: "center", padding: 8 }, children: error }),
1315
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: bottomRef })
1316
- ] }),
1317
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-chat-input-area", children: [
1318
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1319
- "textarea",
1320
- {
1321
- ref: textareaRef,
1322
- className: "hsk-chat-input",
1323
- value: input,
1324
- onChange: handleInput,
1325
- onKeyDown: handleKey,
1326
- placeholder,
1327
- rows: 1,
1328
- disabled: loading
1329
- }
1330
- ),
1331
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1332
- "button",
1333
- {
1334
- className: "hsk-chat-send",
1335
- onClick: handleSend,
1336
- disabled: !input.trim() || loading,
1337
- "aria-label": "Send",
1338
- children: "\u2191"
1339
- }
1340
- )
1341
- ] })
1342
- ] })
1343
- ] });
963
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hsk-chat-input-area", children: [
964
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
965
+ "textarea",
966
+ {
967
+ ref: textareaRef,
968
+ className: `hsk-chat-input ${classNames.input || ""}`,
969
+ value: input,
970
+ onChange: handleInput,
971
+ onKeyDown: handleKey,
972
+ placeholder,
973
+ rows: 1,
974
+ disabled: loading
975
+ }
976
+ ),
977
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
978
+ "button",
979
+ {
980
+ className: "hsk-chat-send",
981
+ onClick: handleSend,
982
+ disabled: !input.trim() || loading,
983
+ "aria-label": "Send message",
984
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ArrowUpIcon, {})
985
+ }
986
+ )
987
+ ] })
988
+ ]
989
+ }
990
+ );
1344
991
  }
1345
992
 
1346
993
  // src/components/AIChatButton.tsx
1347
994
  var import_react10 = require("react");
1348
995
  var import_react_dom2 = require("react-dom");
1349
996
  var import_jsx_runtime5 = require("react/jsx-runtime");
1350
- var CSS3 = `
1351
- /* \u2500\u2500 Trigger button \u2500\u2500 */
1352
- .hsk-cb-btn {
1353
- display: inline-flex;
1354
- align-items: center;
1355
- gap: 7px;
1356
- padding: 8px 16px;
1357
- border-radius: 9999px;
1358
- border: 1px solid rgba(255,106,51,.4);
1359
- background: rgba(255,106,51,.1);
1360
- color: #ff6a33;
1361
- font-size: 13px;
1362
- font-weight: 600;
1363
- cursor: pointer;
1364
- transition: background .15s, border-color .15s, transform .12s, box-shadow .15s;
1365
- font-family: inherit;
1366
- white-space: nowrap;
1367
- }
1368
- .hsk-cb-btn:hover {
1369
- background: rgba(255,106,51,.18);
1370
- border-color: rgba(255,106,51,.7);
1371
- box-shadow: 0 4px 16px rgba(255,106,51,.2);
1372
- }
1373
- .hsk-cb-btn:active { transform: scale(.95); }
1374
- .hsk-cb-btn-icon { font-size: 15px; line-height: 1; }
1375
-
1376
- /* \u2500\u2500 Full-screen overlay \u2500\u2500 */
1377
- .hsk-cb-overlay {
1378
- position: fixed;
1379
- inset: 0;
1380
- z-index: 99999;
1381
- display: flex;
1382
- flex-direction: column;
1383
- animation: hsk-overlay-in .2s ease-out both;
1384
- }
1385
- @keyframes hsk-overlay-in {
1386
- from { opacity: 0; }
1387
- to { opacity: 1; }
1388
- }
1389
-
1390
- /* \u2500\u2500 Panel (Claude-style, centered column) \u2500\u2500 */
1391
- .hsk-cb-panel {
1392
- position: relative;
1393
- display: flex;
1394
- flex-direction: column;
1395
- height: 100%;
1396
- max-width: 780px;
1397
- width: 100%;
1398
- margin: 0 auto;
1399
- animation: hsk-panel-in .28s cubic-bezier(.34,1.2,.64,1) both;
1400
- }
1401
- @keyframes hsk-panel-in {
1402
- from { opacity: 0; transform: translateY(24px); }
1403
- to { opacity: 1; transform: translateY(0); }
1404
- }
1405
-
1406
- /* \u2500\u2500 Top bar \u2500\u2500 */
1407
- .hsk-cb-topbar {
1408
- display: flex;
1409
- align-items: center;
1410
- justify-content: space-between;
1411
- padding: 20px 28px 12px;
1412
- flex-shrink: 0;
1413
- }
1414
- .hsk-cb-topbar-left {
1415
- display: flex;
1416
- align-items: center;
1417
- gap: 10px;
1418
- }
1419
- .hsk-cb-topbar-icon {
1420
- font-size: 22px;
1421
- color: #ff6a33;
1422
- line-height: 1;
1423
- animation: hsk-sparkle-spin 6s linear infinite;
1424
- }
1425
- @keyframes hsk-sparkle-spin {
1426
- 0%,100% { transform: rotate(0deg) scale(1); }
1427
- 25% { transform: rotate(15deg) scale(1.1); }
1428
- 75% { transform: rotate(-10deg) scale(.95); }
1429
- }
1430
- .hsk-cb-topbar-title {
1431
- font-size: 16px;
1432
- font-weight: 700;
1433
- color: var(--hsk-chat-text, #111);
1434
- letter-spacing: -.01em;
1435
- }
1436
- .hsk-cb-topbar-sub {
1437
- font-size: 12px;
1438
- color: var(--hsk-chat-muted, #888);
1439
- margin-top: 2px;
1440
- }
1441
- .hsk-cb-topbar-actions {
1442
- display: flex;
1443
- align-items: center;
1444
- gap: 8px;
1445
- }
1446
- .hsk-cb-topbar-btn {
1447
- height: 34px;
1448
- padding: 0 14px;
1449
- border-radius: 8px;
1450
- border: 1px solid var(--hsk-chat-divide, rgba(0,0,0,.1));
1451
- background: none;
1452
- color: var(--hsk-chat-muted, #888);
1453
- font-size: 12px;
1454
- font-weight: 500;
1455
- cursor: pointer;
1456
- transition: all .15s;
1457
- font-family: inherit;
1458
- }
1459
- .hsk-cb-topbar-btn:hover {
1460
- border-color: #ff6a33;
1461
- color: #ff6a33;
1462
- }
1463
- .hsk-cb-close {
1464
- width: 34px; height: 34px;
1465
- border-radius: 8px;
1466
- border: 1px solid var(--hsk-chat-divide, rgba(0,0,0,.1));
1467
- background: none;
1468
- color: var(--hsk-chat-muted, #888);
1469
- cursor: pointer;
1470
- font-size: 20px;
1471
- display: flex; align-items: center; justify-content: center;
1472
- transition: all .15s;
1473
- flex-shrink: 0;
1474
- font-family: inherit;
1475
- line-height: 1;
1476
- }
1477
- .hsk-cb-close:hover { border-color: #ff6a33; color: #ff6a33; }
1478
-
1479
- /* \u2500\u2500 Messages scroll area \u2500\u2500 */
1480
- .hsk-cb-msgs {
1481
- flex: 1;
1482
- overflow-y: auto;
1483
- padding: 8px 28px 0;
1484
- display: flex;
1485
- flex-direction: column;
1486
- gap: 0;
1487
- scroll-behavior: smooth;
1488
- scrollbar-width: thin;
1489
- scrollbar-color: var(--hsk-chat-divide, rgba(0,0,0,.1)) transparent;
1490
- }
1491
-
1492
- /* \u2500\u2500 Empty / welcome state \u2500\u2500 */
1493
- .hsk-cb-empty {
1494
- flex: 1;
1495
- display: flex;
1496
- flex-direction: column;
1497
- align-items: center;
1498
- justify-content: center;
1499
- gap: 20px;
1500
- padding: 60px 32px;
1501
- text-align: center;
1502
- }
1503
- .hsk-cb-empty-icon {
1504
- font-size: 48px;
1505
- color: #ff6a33;
1506
- animation: hsk-sparkle-spin 4s linear infinite;
1507
- }
1508
- .hsk-cb-empty-title {
1509
- font-size: 26px;
1510
- font-weight: 700;
1511
- color: var(--hsk-chat-text, #111);
1512
- letter-spacing: -.02em;
1513
- }
1514
- .hsk-cb-empty-sub {
1515
- font-size: 14px;
1516
- color: var(--hsk-chat-muted, #888);
1517
- line-height: 1.7;
1518
- max-width: 380px;
1519
- }
1520
- .hsk-cb-chips {
1521
- display: flex;
1522
- flex-wrap: wrap;
1523
- gap: 8px;
1524
- justify-content: center;
1525
- margin-top: 4px;
1526
- }
1527
- .hsk-cb-chip {
1528
- padding: 8px 16px;
1529
- border-radius: 9999px;
1530
- border: 1px solid var(--hsk-chat-divide, rgba(0,0,0,.1));
1531
- background: var(--hsk-chat-source-bg, rgba(0,0,0,.03));
1532
- color: var(--hsk-chat-text, #333);
1533
- font-size: 13px;
1534
- cursor: pointer;
1535
- transition: all .15s;
1536
- font-family: inherit;
1537
- }
1538
- .hsk-cb-chip:hover {
1539
- border-color: #ff6a33;
1540
- color: #ff6a33;
1541
- background: rgba(255,106,51,.06);
1542
- }
1543
-
1544
- /* \u2500\u2500 Message rows \u2500\u2500 */
1545
- .hsk-cb-msg-group {
1546
- padding: 20px 0;
1547
- border-bottom: 1px solid var(--hsk-chat-divide, rgba(0,0,0,.05));
1548
- animation: hsk-msg-in .22s ease-out both;
1549
- }
1550
- .hsk-cb-msg-group:last-child { border-bottom: none; }
1551
- @keyframes hsk-msg-in {
1552
- from { opacity: 0; transform: translateY(10px); }
1553
- to { opacity: 1; transform: translateY(0); }
1554
- }
1555
-
1556
- /* User message */
1557
- .hsk-cb-user-msg {
1558
- display: flex;
1559
- justify-content: flex-end;
1560
- margin-bottom: 20px;
1561
- }
1562
- .hsk-cb-user-bubble {
1563
- background: #ff6a33;
1564
- color: #fff;
1565
- padding: 12px 20px;
1566
- border-radius: 22px 22px 6px 22px;
1567
- font-size: 15px;
1568
- line-height: 1.6;
1569
- max-width: 72%;
1570
- font-weight: 500;
1571
- }
1572
-
1573
- /* AI message - no bubble, just clean text like Claude */
1574
- .hsk-cb-ai-msg {
1575
- display: flex;
1576
- align-items: flex-start;
1577
- gap: 14px;
1578
- }
1579
- .hsk-cb-ai-icon {
1580
- width: 28px; height: 28px;
1581
- border-radius: 50%;
1582
- background: rgba(255,106,51,.12);
1583
- border: 1px solid rgba(255,106,51,.25);
1584
- color: #ff6a33;
1585
- font-size: 13px;
1586
- display: flex; align-items: center; justify-content: center;
1587
- flex-shrink: 0;
1588
- margin-top: 2px;
1589
- }
1590
- .hsk-cb-ai-body { flex: 1; min-width: 0; }
1591
- .hsk-cb-ai-text {
1592
- font-size: 15px;
1593
- line-height: 1.75;
1594
- color: var(--hsk-chat-text, #111);
1595
- white-space: pre-wrap;
1596
- }
1597
-
1598
- /* \u2500\u2500 Sources horizontal carousel \u2500\u2500 */
1599
- .hsk-cb-sources-wrap {
1600
- position: relative;
1601
- margin-top: 20px;
1602
- }
1603
- .hsk-cb-sources {
1604
- display: flex;
1605
- flex-direction: row;
1606
- gap: 14px;
1607
- overflow-x: auto;
1608
- scroll-snap-type: x mandatory;
1609
- scrollbar-width: none;
1610
- -ms-overflow-style: none;
1611
- padding-bottom: 4px;
1612
- }
1613
- .hsk-cb-sources::-webkit-scrollbar { display: none; }
1614
- /* Feathered right edge */
1615
- .hsk-cb-sources-fade {
1616
- position: absolute;
1617
- right: 0; top: 0; bottom: 4px;
1618
- width: 90px;
1619
- pointer-events: none;
1620
- }
1621
- /* Scroll-next pill */
1622
- .hsk-cb-sources-next {
1623
- position: absolute;
1624
- right: 10px;
1625
- top: 50%;
1626
- transform: translateY(-50%);
1627
- width: 30px; height: 30px;
1628
- border-radius: 50%;
1629
- border: 1px solid var(--hsk-chat-divide, rgba(0,0,0,.12));
1630
- background: var(--hsk-chat-bg, #0e0e0f);
1631
- color: var(--hsk-chat-text, #eee);
1632
- cursor: pointer;
1633
- font-size: 16px;
1634
- display: flex; align-items: center; justify-content: center;
1635
- box-shadow: 0 2px 12px rgba(0,0,0,.2);
1636
- transition: all .15s;
1637
- z-index: 3;
1638
- font-family: inherit;
1639
- line-height: 1;
1640
- }
1641
- .hsk-cb-sources-next:hover { border-color: #ff6a33; color: #ff6a33; }
1642
- /* Card: no border, no bg, no radius \u2014 clean dark canvas */
1643
- .hsk-cb-source {
1644
- flex: 0 0 188px;
1645
- scroll-snap-align: start;
1646
- border-radius: 0;
1647
- border: none;
1648
- background: transparent;
1649
- cursor: pointer;
1650
- transition: transform .14s, opacity .14s;
1651
- animation: hsk-card-in .26s ease-out both;
1652
- overflow: visible;
1653
- }
1654
- @keyframes hsk-card-in {
1655
- from { opacity: 0; transform: translateX(16px); }
1656
- to { opacity: 1; transform: none; }
1657
- }
1658
- .hsk-cb-source:hover { transform: translateY(-3px); opacity: .92; }
1659
- .hsk-cb-src-imgwrap {
1660
- width: 188px;
1661
- height: 188px;
1662
- overflow: hidden;
1663
- border-radius: 0;
1664
- display: block;
1665
- }
1666
- .hsk-cb-src-imgwrap img {
1667
- width: 100%; height: 100%;
1668
- object-fit: cover;
1669
- transition: transform .22s;
1670
- display: block;
1671
- }
1672
- .hsk-cb-source:hover .hsk-cb-src-imgwrap img { transform: scale(1.05); }
1673
- .hsk-cb-src-imgwrap-empty {
1674
- width: 188px;
1675
- height: 188px;
1676
- background: var(--hsk-chat-divide, rgba(255,255,255,.06));
1677
- display: flex; align-items: center; justify-content: center;
1678
- color: var(--hsk-chat-muted, #555);
1679
- font-size: 32px;
1680
- }
1681
- .hsk-cb-src-info {
1682
- padding: 8px 2px 0;
1683
- }
1684
- .hsk-cb-src-name {
1685
- font-size: 13px;
1686
- font-weight: 600;
1687
- color: var(--hsk-chat-text, #eee);
1688
- line-height: 1.4;
1689
- display: -webkit-box;
1690
- -webkit-line-clamp: 2;
1691
- -webkit-box-orient: vertical;
1692
- overflow: hidden;
1693
- }
1694
- .hsk-cb-src-price {
1695
- font-size: 13px;
1696
- color: #ff6a33;
1697
- font-weight: 700;
1698
- margin-top: 3px;
1699
- }
1700
-
1701
- /* \u2500\u2500 Selected product inline card \u2500\u2500 */
1702
- .hsk-cb-selected-product {
1703
- display: flex;
1704
- align-items: flex-start;
1705
- gap: 14px;
1706
- margin-top: 16px;
1707
- padding: 14px;
1708
- border: 1px solid var(--hsk-chat-divide, rgba(255,255,255,.08));
1709
- border-left: 3px solid #ff6a33;
1710
- background: var(--hsk-chat-source-bg, rgba(255,255,255,.03));
1711
- cursor: pointer;
1712
- transition: border-color .15s;
1713
- animation: hsk-msg-in .2s ease-out both;
1714
- }
1715
- .hsk-cb-selected-product:hover { border-left-color: rgba(255,106,51,.6); }
1716
- .hsk-cb-selected-img {
1717
- width: 64px; height: 64px;
1718
- object-fit: cover;
1719
- flex-shrink: 0;
1720
- }
1721
- .hsk-cb-selected-info { flex: 1; min-width: 0; }
1722
- .hsk-cb-selected-name {
1723
- font-size: 13px; font-weight: 700;
1724
- color: var(--hsk-chat-text, #eee);
1725
- margin-bottom: 3px;
1726
- }
1727
- .hsk-cb-selected-price {
1728
- font-size: 13px; color: #ff6a33; font-weight: 700;
1729
- }
1730
-
1731
- /* \u2500\u2500 Typing indicator \u2500\u2500 */
1732
- .hsk-cb-typing-row {
1733
- display: flex;
1734
- align-items: flex-start;
1735
- gap: 14px;
1736
- padding: 20px 0;
1737
- }
1738
- .hsk-cb-typing {
1739
- display: flex;
1740
- gap: 5px;
1741
- padding: 14px 18px;
1742
- }
1743
- .hsk-cb-dot {
1744
- width: 7px; height: 7px;
1745
- border-radius: 50%;
1746
- background: var(--hsk-chat-muted, #ccc);
1747
- animation: hsk-dot-pulse 1.2s ease-in-out infinite;
1748
- }
1749
- .hsk-cb-dot:nth-child(2) { animation-delay: .18s; }
1750
- .hsk-cb-dot:nth-child(3) { animation-delay: .36s; }
1751
- @keyframes hsk-dot-pulse {
1752
- 0%,100% { opacity: .3; transform: scale(.75); }
1753
- 50% { opacity: 1; transform: scale(1); }
1754
- }
1755
-
1756
- /* \u2500\u2500 Input area \u2500\u2500 */
1757
- .hsk-cb-input-wrap {
1758
- padding: 16px 28px 28px;
1759
- flex-shrink: 0;
1760
- }
1761
- .hsk-cb-input-box {
1762
- display: flex;
1763
- align-items: flex-end;
1764
- gap: 10px;
1765
- background: var(--hsk-chat-input-bg, rgba(0,0,0,.04));
1766
- border: 1.5px solid var(--hsk-chat-divide, rgba(0,0,0,.1));
1767
- border-radius: 18px;
1768
- padding: 14px 14px 14px 20px;
1769
- transition: border-color .15s, box-shadow .15s;
1770
- }
1771
- .hsk-cb-input-box:focus-within {
1772
- border-color: #ff6a33;
1773
- box-shadow: 0 0 0 3px rgba(255,106,51,.1);
1774
- }
1775
- .hsk-cb-textarea {
1776
- flex: 1;
1777
- background: transparent;
1778
- border: none;
1779
- outline: none;
1780
- resize: none;
1781
- font-size: 15px;
1782
- color: var(--hsk-chat-text, #111);
1783
- min-height: 24px;
1784
- max-height: 140px;
1785
- line-height: 1.55;
1786
- font-family: inherit;
1787
- }
1788
- .hsk-cb-textarea::placeholder { color: var(--hsk-chat-muted, #aaa); }
1789
- .hsk-cb-send {
1790
- width: 38px; height: 38px;
1791
- border-radius: 10px;
1792
- background: #ff6a33;
1793
- border: none;
1794
- color: #fff;
1795
- cursor: pointer;
1796
- font-size: 18px;
1797
- display: flex; align-items: center; justify-content: center;
1798
- flex-shrink: 0;
1799
- transition: opacity .15s, transform .1s, background .15s;
1800
- font-family: inherit;
1801
- }
1802
- .hsk-cb-send:hover { opacity: .88; }
1803
- .hsk-cb-send:active { transform: scale(.9); }
1804
- .hsk-cb-send:disabled { opacity: .3; cursor: not-allowed; background: var(--hsk-chat-muted, #ccc); }
1805
- .hsk-cb-hint {
1806
- text-align: center;
1807
- font-size: 11px;
1808
- color: var(--hsk-chat-muted, #bbb);
1809
- margin-top: 10px;
1810
- }
1811
-
1812
- /* \u2500\u2500 Error \u2500\u2500 */
1813
- .hsk-cb-error {
1814
- margin: 8px 0;
1815
- padding: 10px 14px;
1816
- border-radius: 10px;
1817
- background: rgba(239,68,68,.08);
1818
- border: 1px solid rgba(239,68,68,.2);
1819
- color: #ef4444;
1820
- font-size: 13px;
1821
- }
1822
-
1823
- /* \u2500\u2500 Dark mode \u2500\u2500 */
1824
- @media (prefers-color-scheme: dark) {
1825
- .hsk-cb-overlay {
1826
- --hsk-chat-bg: #0e0e0f;
1827
- --hsk-chat-text: #f0efed;
1828
- --hsk-chat-muted: #555;
1829
- --hsk-chat-divide: rgba(255,255,255,.07);
1830
- --hsk-chat-input-bg: rgba(255,255,255,.05);
1831
- --hsk-chat-source-bg: rgba(255,255,255,.04);
1832
- --hsk-fade-bg: #0e0e0f;
1833
- }
1834
- .hsk-cb-overlay {
1835
- background: rgba(0,0,0,.92) !important;
1836
- }
1837
- }
1838
- @media (prefers-color-scheme: light) {
1839
- .hsk-cb-overlay {
1840
- --hsk-chat-bg: #fafafa;
1841
- --hsk-chat-text: #111;
1842
- --hsk-chat-muted: #999;
1843
- --hsk-chat-divide: rgba(0,0,0,.08);
1844
- --hsk-chat-input-bg: rgba(0,0,0,.04);
1845
- --hsk-chat-source-bg: rgba(0,0,0,.025);
1846
- --hsk-fade-bg: #fafafa;
1847
- }
1848
- .hsk-cb-overlay {
1849
- background: rgba(240,240,244,.88) !important;
1850
- }
1851
- }
1852
- `;
1853
- var CHIPS = [
997
+ var SparkleIcon3 = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className, width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("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" }) });
998
+ var ArrowUpIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
999
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m5 12 7-7 7 7" }),
1000
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 19V5" })
1001
+ ] });
1002
+ var CloseIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1003
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1004
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1005
+ ] });
1006
+ var ChevronRightIcon = () => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m9 18 6-6-6-6" }) });
1007
+ var DEFAULT_CHIPS = [
1854
1008
  "Cheapest smartphone",
1855
1009
  "Smart TV under KSh 20,000",
1856
1010
  "Noise-cancelling headphones",
1857
1011
  "Best laptop for students"
1858
1012
  ];
1859
- function SourcesCarousel({ sources, onSelectSource }) {
1013
+ function SourcesCarousel({ sources, defaultCurrency, onSelectSource }) {
1860
1014
  const railRef = (0, import_react10.useRef)(null);
1861
1015
  const [showNext, setShowNext] = (0, import_react10.useState)(false);
1862
1016
  const measure = (0, import_react10.useCallback)(() => {
@@ -1891,11 +1045,11 @@ function SourcesCarousel({ sources, onSelectSource }) {
1891
1045
  style: { animationDelay: `${si * 50}ms` },
1892
1046
  onClick: () => onSelectSource == null ? void 0 : onSelectSource(src),
1893
1047
  children: [
1894
- src.image ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-src-imgwrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: src.image, alt: src.name, loading: "lazy" }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-src-imgwrap-empty", children: "\u2726" }),
1048
+ src.image ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-src-imgwrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: src.image, alt: src.name, loading: "lazy" }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-src-imgwrap-empty", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon3, {}) }),
1895
1049
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-src-info", children: [
1896
1050
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-src-name", children: src.name }),
1897
1051
  src.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-src-price", children: [
1898
- (_a = src.currency) != null ? _a : "KES",
1052
+ (_a = src.currency) != null ? _a : defaultCurrency,
1899
1053
  " ",
1900
1054
  parseFloat(src.price.replace(/[^0-9.]/g, "") || "0").toLocaleString()
1901
1055
  ] })
@@ -1913,7 +1067,7 @@ function SourcesCarousel({ sources, onSelectSource }) {
1913
1067
  style: { background: "linear-gradient(to right, transparent, var(--hsk-fade-bg, #0e0e0f))" }
1914
1068
  }
1915
1069
  ),
1916
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: "\u203A" })
1070
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-sources-next", onClick: scrollNext, "aria-label": "See more", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronRightIcon, {}) })
1917
1071
  ] })
1918
1072
  ] });
1919
1073
  }
@@ -1923,7 +1077,11 @@ function ChatModal({
1923
1077
  backdropColor,
1924
1078
  backdropBlur,
1925
1079
  onClose,
1926
- onSelectSource
1080
+ onSelectSource,
1081
+ defaultCurrency = "KES",
1082
+ chips = DEFAULT_CHIPS,
1083
+ theme,
1084
+ classNames = {}
1927
1085
  }) {
1928
1086
  var _a, _b;
1929
1087
  const { messages, sources, loading, error, send, reset } = useChat();
@@ -1946,7 +1104,7 @@ function ChatModal({
1946
1104
  var _a2;
1947
1105
  setSelectedProduct(src);
1948
1106
  onSelectSource == null ? void 0 : onSelectSource(src);
1949
- const q = `Tell me more about the ${src.name}${src.price ? ` (${(_a2 = src.currency) != null ? _a2 : "KES"} ${src.price})` : ""} \u2014 what are its key specs, who is it best for, and is it worth buying?`;
1107
+ const q = `Tell me more about the ${src.name}${src.price ? ` (${(_a2 = src.currency) != null ? _a2 : defaultCurrency} ${src.price})` : ""} \u2014 what are its key specs, who is it best for, and is it worth buying?`;
1950
1108
  send(q);
1951
1109
  };
1952
1110
  const handleSend = async (text) => {
@@ -1972,124 +1130,123 @@ function ChatModal({
1972
1130
  t.style.height = `${Math.min(t.scrollHeight, 140)}px`;
1973
1131
  };
1974
1132
  const blurVal = typeof backdropBlur === "number" ? `${backdropBlur}px` : backdropBlur != null ? backdropBlur : "20px";
1975
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1976
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: CSS3 }),
1977
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1978
- "div",
1979
- {
1980
- className: "hsk-cb-overlay",
1981
- onClick: onClose,
1982
- style: __spreadValues({
1983
- backdropFilter: `blur(${blurVal})`,
1984
- WebkitBackdropFilter: `blur(${blurVal})`
1985
- }, backdropColor ? { background: backdropColor } : {}),
1986
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-panel", onClick: (e) => e.stopPropagation(), children: [
1987
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar", children: [
1988
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar-left", children: [
1989
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cb-topbar-icon", children: "\u2726" }),
1990
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1991
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-topbar-title", children: title }),
1992
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-topbar-sub", children: "Powered by Huskel AI \xB7 searches the whole catalogue" })
1993
- ] })
1994
- ] }),
1995
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar-actions", children: [
1996
- messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-topbar-btn", onClick: reset, children: "Clear chat" }),
1997
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: "\xD7" })
1133
+ 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 });
1134
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1135
+ "div",
1136
+ {
1137
+ className: `hsk-cb-overlay ${classNames.overlay || ""}`,
1138
+ onClick: onClose,
1139
+ style: __spreadValues(__spreadValues({
1140
+ backdropFilter: `blur(${blurVal})`,
1141
+ WebkitBackdropFilter: `blur(${blurVal})`
1142
+ }, backdropColor ? { background: backdropColor } : {}), customStyles),
1143
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `hsk-cb-panel ${classNames.panel || ""}`, onClick: (e) => e.stopPropagation(), children: [
1144
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar", children: [
1145
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar-left", children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cb-topbar-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon3, {}) }),
1147
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1148
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-topbar-title", children: title }),
1149
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-topbar-sub", children: "Powered by Huskel AI \xB7 searches the whole catalogue" })
1998
1150
  ] })
1999
1151
  ] }),
2000
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-msgs", children: [
2001
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-empty", children: [
2002
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-icon", children: "\u2726" }),
2003
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-title", children: "What can I help you find?" }),
2004
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-sub", children: "Ask about products, budgets, gift ideas, specs \u2014 I'll search the entire catalogue for you." }),
2005
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-chips", children: CHIPS.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2006
- "button",
2007
- {
2008
- className: "hsk-cb-chip",
2009
- onClick: () => handleSend(chip),
2010
- children: chip
2011
- },
2012
- chip
2013
- )) })
2014
- ] }) : messages.map((msg, idx) => {
2015
- const isLast = idx === messages.length - 1;
2016
- const isUser = msg.role === "user";
2017
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
2018
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-icon", children: "\u2726" }),
2019
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-ai-body", children: [
2020
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-text", children: msg.content }),
2021
- isLast && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2022
- SourcesCarousel,
2023
- {
2024
- sources,
2025
- onSelectSource: handleSourceClick
2026
- }
2027
- )
2028
- ] })
2029
- ] }) }, idx);
2030
- }),
2031
- selectedProduct && loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2032
- "div",
1152
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-topbar-actions", children: [
1153
+ messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-topbar-btn", onClick: reset, children: "Clear chat" }),
1154
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "hsk-cb-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseIcon2, {}) })
1155
+ ] })
1156
+ ] }),
1157
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-msgs", children: [
1158
+ messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-empty", children: [
1159
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon3, {}) }),
1160
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-title", children: "What can I help you find?" }),
1161
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-empty-sub", children: "Ask about products, budgets, gift ideas, specs \u2014 I'll search the entire catalogue for you." }),
1162
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-chips", children: chips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1163
+ "button",
2033
1164
  {
2034
- className: "hsk-cb-selected-product",
2035
- onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
2036
- children: [
2037
- selectedProduct.image && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
2038
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-selected-info", children: [
2039
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
2040
- selectedProduct.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-selected-price", children: [
2041
- (_a = selectedProduct.currency) != null ? _a : "KES",
2042
- " ",
2043
- parseFloat(((_b = selectedProduct.price) != null ? _b : "").replace(/[^0-9.]/g, "") || "0").toLocaleString()
2044
- ] })
1165
+ className: "hsk-cb-chip",
1166
+ onClick: () => handleSend(chip),
1167
+ children: chip
1168
+ },
1169
+ chip
1170
+ )) })
1171
+ ] }) : messages.map((msg, idx) => {
1172
+ const isLast = idx === messages.length - 1;
1173
+ const isUser = msg.role === "user";
1174
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-msg-group", children: isUser ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-user-msg", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-user-bubble", children: msg.content }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-ai-msg", children: [
1175
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon3, {}) }),
1176
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-ai-body", children: [
1177
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-text", children: msg.content }),
1178
+ isLast && sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1179
+ SourcesCarousel,
1180
+ {
1181
+ sources,
1182
+ defaultCurrency,
1183
+ onSelectSource: handleSourceClick
1184
+ }
1185
+ )
1186
+ ] })
1187
+ ] }) }, idx);
1188
+ }),
1189
+ selectedProduct && loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1190
+ "div",
1191
+ {
1192
+ className: "hsk-cb-selected-product",
1193
+ onClick: () => selectedProduct.url && window.open(selectedProduct.url, "_blank"),
1194
+ children: [
1195
+ selectedProduct.image && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { className: "hsk-cb-selected-img", src: selectedProduct.image, alt: selectedProduct.name }),
1196
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-selected-info", children: [
1197
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-selected-name", children: selectedProduct.name }),
1198
+ selectedProduct.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-selected-price", children: [
1199
+ (_a = selectedProduct.currency) != null ? _a : defaultCurrency,
1200
+ " ",
1201
+ parseFloat(((_b = selectedProduct.price) != null ? _b : "").replace(/[^0-9.]/g, "") || "0").toLocaleString()
2045
1202
  ] })
2046
- ]
1203
+ ] })
1204
+ ]
1205
+ }
1206
+ ),
1207
+ loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-typing-row", children: [
1208
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon3, {}) }),
1209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-typing", children: [
1210
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" }),
1211
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" }),
1212
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" })
1213
+ ] })
1214
+ ] }),
1215
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-error", children: error }),
1216
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: bottomRef, style: { height: 1 } })
1217
+ ] }),
1218
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
1219
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-input-box", children: [
1220
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1221
+ "textarea",
1222
+ {
1223
+ ref: textareaRef,
1224
+ className: `hsk-cb-textarea ${classNames.input || ""}`,
1225
+ value: input,
1226
+ onChange: handleInput,
1227
+ onKeyDown: handleKeyDown,
1228
+ placeholder,
1229
+ rows: 1,
1230
+ disabled: loading,
1231
+ autoFocus: true
2047
1232
  }
2048
1233
  ),
2049
- loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-typing-row", children: [
2050
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-ai-icon", children: "\u2726" }),
2051
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-typing", children: [
2052
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" }),
2053
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" }),
2054
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-dot" })
2055
- ] })
2056
- ] }),
2057
- error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-error", children: error }),
2058
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: bottomRef, style: { height: 1 } })
1234
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1235
+ "button",
1236
+ {
1237
+ className: `hsk-cb-send ${classNames.sendButton || ""}`,
1238
+ onClick: () => handleSend(),
1239
+ disabled: !input.trim() || loading,
1240
+ "aria-label": "Send message",
1241
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArrowUpIcon2, {})
1242
+ }
1243
+ )
2059
1244
  ] }),
2060
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-input-wrap", children: [
2061
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hsk-cb-input-box", children: [
2062
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2063
- "textarea",
2064
- {
2065
- ref: textareaRef,
2066
- className: "hsk-cb-textarea",
2067
- value: input,
2068
- onChange: handleInput,
2069
- onKeyDown: handleKeyDown,
2070
- placeholder,
2071
- rows: 1,
2072
- disabled: loading,
2073
- autoFocus: true
2074
- }
2075
- ),
2076
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2077
- "button",
2078
- {
2079
- className: "hsk-cb-send",
2080
- onClick: () => handleSend(),
2081
- disabled: !input.trim() || loading,
2082
- "aria-label": "Send",
2083
- children: "\u2191"
2084
- }
2085
- )
2086
- ] }),
2087
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-hint", children: "Huskel AI \xB7 searches the whole catalogue in real time" })
2088
- ] })
1245
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hsk-cb-hint", children: "Huskel AI \xB7 searches the whole catalogue in real time" })
2089
1246
  ] })
2090
- }
2091
- )
2092
- ] });
1247
+ ] })
1248
+ }
1249
+ );
2093
1250
  }
2094
1251
  function AIChatButton({
2095
1252
  label,
@@ -2098,23 +1255,28 @@ function AIChatButton({
2098
1255
  backdropColor,
2099
1256
  backdropBlur,
2100
1257
  className,
2101
- onSelectSource
1258
+ onSelectSource,
1259
+ defaultCurrency,
1260
+ chips,
1261
+ theme,
1262
+ classNames = {}
2102
1263
  }) {
2103
1264
  const [open, setOpen] = (0, import_react10.useState)(false);
2104
1265
  const [mounted, setMounted] = (0, import_react10.useState)(false);
2105
1266
  (0, import_react10.useEffect)(() => {
2106
1267
  setMounted(true);
2107
1268
  }, []);
1269
+ 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 });
2108
1270
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2109
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: CSS3 }),
2110
1271
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2111
1272
  "button",
2112
1273
  {
2113
- className: `hsk-cb-btn ${className != null ? className : ""}`,
1274
+ className: `hsk-cb-btn ${classNames.button || ""} ${className || ""}`,
2114
1275
  onClick: () => setOpen(true),
1276
+ style: customStyles,
2115
1277
  "aria-label": "Open AI chat",
2116
1278
  children: [
2117
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cb-btn-icon", children: "\u2726" }),
1279
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "hsk-cb-btn-icon", style: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SparkleIcon3, {}) }),
2118
1280
  label !== void 0 ? label : null
2119
1281
  ]
2120
1282
  }
@@ -2128,7 +1290,11 @@ function AIChatButton({
2128
1290
  backdropColor,
2129
1291
  backdropBlur,
2130
1292
  onClose: () => setOpen(false),
2131
- onSelectSource
1293
+ onSelectSource,
1294
+ defaultCurrency,
1295
+ chips,
1296
+ theme,
1297
+ classNames
2132
1298
  }
2133
1299
  ),
2134
1300
  document.body