@samirify/messenger 0.1.4 → 0.1.6

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/web/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { useMessengerUi, useUnreadTotal } from '../chunk-OTJZXVON.js';
2
- export { MessengerUiProvider, useMessengerUi, useOptionalMessengerUi } from '../chunk-OTJZXVON.js';
1
+ import { useMessengerUi, useUnreadTotal } from '../chunk-OUM2PDMW.js';
2
+ export { MessengerUiProvider, useMessengerUi, useOptionalMessengerUi } from '../chunk-OUM2PDMW.js';
3
3
  import { useMessengerConfig, useThreads, useOpenThread, MessengerI18n, useThread, useSendMessage } from '../chunk-O5XNJHGZ.js';
4
4
  export { MessengerProvider, useMessengerConfig, useOptionalMessengerConfig } from '../chunk-O5XNJHGZ.js';
5
5
  import { AnimatePresence, motion } from 'framer-motion';
6
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
6
  import { useState, useRef, useEffect } from 'react';
7
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
8
 
9
9
  function initials(name) {
10
10
  const parts = name.trim().split(/\s+/).filter(Boolean);
@@ -14,7 +14,8 @@ function initials(name) {
14
14
  }
15
15
  function ThreadRow({
16
16
  thread,
17
- onSelect
17
+ onSelect,
18
+ active
18
19
  }) {
19
20
  const { user, t, isRtl, theme } = useMessengerConfig();
20
21
  const unread = Number(thread.unread_count ?? 0);
@@ -34,17 +35,19 @@ function ThreadRow({
34
35
  textAlign: isRtl ? "right" : "left",
35
36
  padding: "12px 14px",
36
37
  margin: "0 8px",
37
- border: "none",
38
+ border: active ? `1px solid color-mix(in srgb, ${theme.accentColor} 28%, transparent)` : "1px solid transparent",
38
39
  borderRadius: 16,
39
- background: unread > 0 ? `color-mix(in srgb, ${theme.accentColor} 8%, transparent)` : "transparent",
40
+ background: active ? `color-mix(in srgb, ${theme.accentColor} 14%, ${theme.colors.surface})` : unread > 0 ? `color-mix(in srgb, ${theme.accentColor} 8%, transparent)` : "transparent",
40
41
  cursor: "pointer",
41
42
  color: theme.colors.text,
42
- transition: "background 160ms ease"
43
+ transition: "background 160ms ease, border-color 160ms ease"
43
44
  },
44
45
  onMouseEnter: (e) => {
46
+ if (active) return;
45
47
  e.currentTarget.style.background = `color-mix(in srgb, ${theme.accentColor} 12%, ${theme.colors.surfaceSecondary})`;
46
48
  },
47
49
  onMouseLeave: (e) => {
50
+ if (active) return;
48
51
  e.currentTarget.style.background = unread > 0 ? `color-mix(in srgb, ${theme.accentColor} 8%, transparent)` : "transparent";
49
52
  },
50
53
  children: [
@@ -147,7 +150,8 @@ function ThreadRow({
147
150
  );
148
151
  }
149
152
  function ThreadList({
150
- onSelectThread
153
+ onSelectThread,
154
+ activeThreadId
151
155
  }) {
152
156
  const { user, t, theme } = useMessengerConfig();
153
157
  const threadsQuery = useThreads();
@@ -278,7 +282,15 @@ function ThreadList({
278
282
  gap: 2,
279
283
  paddingBottom: 8
280
284
  },
281
- children: threads.map((th) => /* @__PURE__ */ jsx(ThreadRow, { thread: th, onSelect: onSelectThread }, th.id))
285
+ children: threads.map((th) => /* @__PURE__ */ jsx(
286
+ ThreadRow,
287
+ {
288
+ thread: th,
289
+ onSelect: onSelectThread,
290
+ active: activeThreadId === th.id
291
+ },
292
+ th.id
293
+ ))
282
294
  }
283
295
  )
284
296
  ]
@@ -756,6 +768,15 @@ function ChatPanel({
756
768
  variant = "dock"
757
769
  }) {
758
770
  const { enabled, t, isRtl, theme, onFeatureOff } = useMessengerConfig();
771
+ const [wide, setWide] = useState(false);
772
+ useEffect(() => {
773
+ if (variant !== "page" || typeof window === "undefined") return;
774
+ const mq = window.matchMedia("(min-width: 768px)");
775
+ const apply = () => setWide(mq.matches);
776
+ apply();
777
+ mq.addEventListener("change", apply);
778
+ return () => mq.removeEventListener("change", apply);
779
+ }, [variant]);
759
780
  if (!enabled) {
760
781
  if (onFeatureOff) return /* @__PURE__ */ jsx(Fragment, { children: onFeatureOff() });
761
782
  return /* @__PURE__ */ jsx(
@@ -771,17 +792,17 @@ function ChatPanel({
771
792
  }
772
793
  );
773
794
  }
795
+ const inThread = threadId != null;
796
+ const pageSplit = variant === "page" && wide;
774
797
  const shell = variant === "page" ? {
775
798
  display: "flex",
776
- flexDirection: "column",
777
- height: "min(70vh, 640px)",
778
- maxWidth: 720,
779
- margin: "0 auto",
780
- borderRadius: 24,
799
+ flexDirection: pageSplit ? isRtl ? "row-reverse" : "row" : "column",
800
+ height: "100%",
801
+ width: "100%",
781
802
  overflow: "hidden",
782
- border: `1px solid ${theme.colors.border}`,
783
803
  background: theme.colors.surface,
784
- boxShadow: `0 24px 64px color-mix(in srgb, ${theme.colors.text} 14%, transparent)`
804
+ border: `1px solid color-mix(in srgb, ${theme.colors.border} 85%, transparent)`,
805
+ borderRadius: 0
785
806
  } : {
786
807
  display: "flex",
787
808
  flexDirection: "column",
@@ -792,105 +813,184 @@ function ChatPanel({
792
813
  ${theme.colors.surface}
793
814
  `
794
815
  };
795
- const inThread = threadId != null;
796
- return /* @__PURE__ */ jsxs("div", { style: shell, children: [
797
- !inThread ? /* @__PURE__ */ jsxs(
798
- "header",
799
- {
800
- style: {
801
- display: "flex",
802
- flexDirection: isRtl ? "row-reverse" : "row",
803
- alignItems: "center",
804
- gap: 12,
805
- padding: "16px 16px 14px",
806
- borderBottom: `1px solid color-mix(in srgb, ${theme.colors.border} 80%, transparent)`,
807
- background: `linear-gradient(180deg, color-mix(in srgb, ${theme.colors.surface} 92%, transparent), color-mix(in srgb, ${theme.colors.surface} 70%, transparent))`,
808
- backdropFilter: "blur(12px)"
809
- },
810
- children: [
811
- /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, textAlign: isRtl ? "right" : "left" }, children: [
812
- /* @__PURE__ */ jsx(
813
- "div",
814
- {
815
- style: {
816
- fontFamily: theme.fonts.displayBold,
817
- fontWeight: 700,
818
- fontSize: 20,
819
- letterSpacing: "-0.02em",
820
- color: theme.colors.text,
821
- lineHeight: 1.15
822
- },
823
- children: t(MessengerI18n.messages.key, MessengerI18n.messages.fallback)
824
- }
825
- ),
826
- /* @__PURE__ */ jsx(
827
- "div",
828
- {
829
- style: {
830
- marginTop: 3,
831
- fontFamily: theme.fonts.body,
832
- fontSize: 12.5,
833
- color: theme.colors.textMuted
834
- },
835
- children: t(MessengerI18n.messagesHint.key, MessengerI18n.messagesHint.fallback)
836
- }
837
- )
838
- ] }),
839
- onClose ? /* @__PURE__ */ jsx(
840
- "button",
841
- {
842
- type: "button",
843
- onClick: onClose,
844
- "aria-label": "Close",
845
- style: {
846
- border: `1px solid color-mix(in srgb, ${theme.colors.border} 90%, transparent)`,
847
- background: `color-mix(in srgb, ${theme.colors.surfaceSecondary} 80%, transparent)`,
848
- color: theme.colors.textSecondary,
849
- width: 36,
850
- height: 36,
851
- borderRadius: 12,
852
- cursor: "pointer",
853
- display: "grid",
854
- placeItems: "center",
855
- flexShrink: 0
856
- },
857
- children: /* @__PURE__ */ jsx(CloseIcon, { size: 16 })
858
- }
859
- ) : null
860
- ]
861
- }
862
- ) : null,
863
- /* @__PURE__ */ jsx("div", { style: { flex: 1, minHeight: 0, position: "relative" }, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: inThread ? /* @__PURE__ */ jsx(
864
- motion.div,
865
- {
866
- initial: { opacity: 0, x: isRtl ? -16 : 16 },
867
- animate: { opacity: 1, x: 0 },
868
- exit: { opacity: 0, x: isRtl ? 12 : -12 },
869
- transition: { duration: 0.22, ease: [0.22, 1, 0.36, 1] },
870
- style: { height: "100%" },
871
- children: /* @__PURE__ */ jsx(
872
- Conversation,
816
+ const listPane = /* @__PURE__ */ jsxs(
817
+ "div",
818
+ {
819
+ style: {
820
+ display: "flex",
821
+ flexDirection: "column",
822
+ height: "100%",
823
+ width: pageSplit ? 320 : "100%",
824
+ flexShrink: 0,
825
+ borderInlineEnd: pageSplit ? `1px solid color-mix(in srgb, ${theme.colors.border} 80%, transparent)` : void 0,
826
+ background: pageSplit ? `linear-gradient(180deg, color-mix(in srgb, ${theme.colors.surfaceSecondary} 55%, ${theme.colors.surface}), ${theme.colors.surface})` : void 0
827
+ },
828
+ children: [
829
+ /* @__PURE__ */ jsxs(
830
+ "header",
873
831
  {
874
- threadId,
875
- onBack: onBackToList,
876
- onClose
832
+ style: {
833
+ display: "flex",
834
+ flexDirection: isRtl ? "row-reverse" : "row",
835
+ alignItems: "center",
836
+ gap: 12,
837
+ padding: "16px 16px 14px",
838
+ borderBottom: `1px solid color-mix(in srgb, ${theme.colors.border} 80%, transparent)`
839
+ },
840
+ children: [
841
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, textAlign: isRtl ? "right" : "left" }, children: [
842
+ /* @__PURE__ */ jsx(
843
+ "div",
844
+ {
845
+ style: {
846
+ fontFamily: theme.fonts.displayBold,
847
+ fontWeight: 700,
848
+ fontSize: pageSplit ? 18 : 20,
849
+ letterSpacing: "-0.02em",
850
+ color: theme.colors.text,
851
+ lineHeight: 1.15
852
+ },
853
+ children: t(MessengerI18n.messages.key, MessengerI18n.messages.fallback)
854
+ }
855
+ ),
856
+ /* @__PURE__ */ jsx(
857
+ "div",
858
+ {
859
+ style: {
860
+ marginTop: 3,
861
+ fontFamily: theme.fonts.body,
862
+ fontSize: 12.5,
863
+ color: theme.colors.textMuted
864
+ },
865
+ children: t(MessengerI18n.messagesHint.key, MessengerI18n.messagesHint.fallback)
866
+ }
867
+ )
868
+ ] }),
869
+ onClose && !pageSplit ? /* @__PURE__ */ jsx(
870
+ "button",
871
+ {
872
+ type: "button",
873
+ onClick: onClose,
874
+ "aria-label": "Close",
875
+ style: {
876
+ border: `1px solid color-mix(in srgb, ${theme.colors.border} 90%, transparent)`,
877
+ background: `color-mix(in srgb, ${theme.colors.surfaceSecondary} 80%, transparent)`,
878
+ color: theme.colors.textSecondary,
879
+ width: 36,
880
+ height: 36,
881
+ borderRadius: 12,
882
+ cursor: "pointer",
883
+ display: "grid",
884
+ placeItems: "center",
885
+ flexShrink: 0
886
+ },
887
+ children: /* @__PURE__ */ jsx(CloseIcon, { size: 16 })
888
+ }
889
+ ) : null
890
+ ]
877
891
  }
878
- )
879
- },
880
- `thread-${threadId}`
881
- ) : /* @__PURE__ */ jsx(
882
- motion.div,
883
- {
884
- initial: { opacity: 0, x: isRtl ? 16 : -16 },
885
- animate: { opacity: 1, x: 0 },
886
- exit: { opacity: 0, x: isRtl ? -12 : 12 },
887
- transition: { duration: 0.22, ease: [0.22, 1, 0.36, 1] },
888
- style: { height: "100%" },
889
- children: /* @__PURE__ */ jsx(ThreadList, { onSelectThread })
892
+ ),
893
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsx(
894
+ ThreadList,
895
+ {
896
+ onSelectThread,
897
+ activeThreadId: threadId
898
+ }
899
+ ) })
900
+ ]
901
+ }
902
+ );
903
+ const emptyPane = /* @__PURE__ */ jsxs(
904
+ "div",
905
+ {
906
+ style: {
907
+ flex: 1,
908
+ minWidth: 0,
909
+ height: "100%",
910
+ display: "flex",
911
+ flexDirection: "column",
912
+ alignItems: "center",
913
+ justifyContent: "center",
914
+ gap: 10,
915
+ padding: 32,
916
+ background: `
917
+ radial-gradient(80% 60% at 50% 0%, color-mix(in srgb, ${theme.accentColor} 10%, transparent), transparent 60%),
918
+ ${theme.colors.surface}
919
+ `
890
920
  },
891
- "list"
892
- ) }) })
893
- ] });
921
+ children: [
922
+ /* @__PURE__ */ jsx(
923
+ "div",
924
+ {
925
+ "aria-hidden": true,
926
+ style: {
927
+ width: 64,
928
+ height: 64,
929
+ borderRadius: 20,
930
+ display: "grid",
931
+ placeItems: "center",
932
+ background: `color-mix(in srgb, ${theme.accentColor} 12%, ${theme.colors.surfaceSecondary})`,
933
+ color: theme.accentColor,
934
+ fontSize: 26,
935
+ marginBottom: 4
936
+ },
937
+ children: "\u2726"
938
+ }
939
+ ),
940
+ /* @__PURE__ */ jsx(
941
+ "div",
942
+ {
943
+ style: {
944
+ fontFamily: theme.fonts.displaySemiBold,
945
+ fontWeight: 600,
946
+ fontSize: 16,
947
+ color: theme.colors.text
948
+ },
949
+ children: t(MessengerI18n.messages.key, MessengerI18n.messages.fallback)
950
+ }
951
+ ),
952
+ /* @__PURE__ */ jsx(
953
+ "div",
954
+ {
955
+ style: {
956
+ fontFamily: theme.fonts.body,
957
+ fontSize: 13.5,
958
+ color: theme.colors.textMuted,
959
+ maxWidth: 280,
960
+ textAlign: "center",
961
+ lineHeight: 1.45
962
+ },
963
+ children: t(MessengerI18n.messagesHint.key, MessengerI18n.messagesHint.fallback)
964
+ }
965
+ )
966
+ ]
967
+ }
968
+ );
969
+ if (variant === "page" && pageSplit) {
970
+ return /* @__PURE__ */ jsxs("div", { style: shell, children: [
971
+ listPane,
972
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0, minHeight: 0, height: "100%" }, children: inThread ? /* @__PURE__ */ jsx(Conversation, { threadId }) : emptyPane })
973
+ ] });
974
+ }
975
+ return /* @__PURE__ */ jsx("div", { style: shell, children: !inThread ? listPane : /* @__PURE__ */ jsx("div", { style: { flex: 1, minHeight: 0, position: "relative", height: "100%" }, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: /* @__PURE__ */ jsx(
976
+ motion.div,
977
+ {
978
+ initial: { opacity: 0, x: isRtl ? -16 : 16 },
979
+ animate: { opacity: 1, x: 0 },
980
+ exit: { opacity: 0, x: isRtl ? 12 : -12 },
981
+ transition: { duration: 0.22, ease: [0.22, 1, 0.36, 1] },
982
+ style: { height: "100%" },
983
+ children: /* @__PURE__ */ jsx(
984
+ Conversation,
985
+ {
986
+ threadId,
987
+ onBack: onBackToList,
988
+ onClose
989
+ }
990
+ )
991
+ },
992
+ `thread-${threadId}`
993
+ ) }) }) });
894
994
  }
895
995
  function ChatDock() {
896
996
  const { enabled, isRtl, theme, t } = useMessengerConfig();