@smwb/ui-react 2.1.3 → 2.2.0

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.
@@ -1,5 +1,6 @@
1
- import { useRef as c, useEffect as M, useLayoutEffect as T } from "react";
2
- function L(t, r = 24) {
1
+ import { useRef as c, useEffect as M } from "react";
2
+ import { useSafeLayoutEffect as S } from "../../../hooks/useSafeLayoutEffect.js";
3
+ function T(t, r = 24) {
3
4
  return t.scrollHeight - t.scrollTop - t.clientHeight <= r;
4
5
  }
5
6
  function h(t) {
@@ -12,15 +13,15 @@ function B({ containerRef: t, messages: r, threshold: l = 24 }) {
12
13
  if (!e)
13
14
  return;
14
15
  const o = () => {
15
- n.current = L(e, l);
16
+ n.current = T(e, l);
16
17
  };
17
18
  return o(), e.addEventListener("scroll", o, { passive: !0 }), () => e.removeEventListener("scroll", o);
18
- }, [t, l]), T(() => {
19
- var g, a;
19
+ }, [t, l]), S(() => {
20
+ var a, g;
20
21
  const e = t.current;
21
22
  if (!e)
22
23
  return;
23
- const o = u.current, p = d.current, v = f.current, i = (g = r[0]) == null ? void 0 : g.id, s = (a = r[r.length - 1]) == null ? void 0 : a.id;
24
+ const o = u.current, p = d.current, v = f.current, i = (a = r[0]) == null ? void 0 : a.id, s = (g = r[r.length - 1]) == null ? void 0 : g.id;
24
25
  if (p === void 0)
25
26
  h(e), n.current = !0;
26
27
  else {
@@ -31,7 +32,7 @@ function B({ containerRef: t, messages: r, threshold: l = 24 }) {
31
32
  }, [t, r]);
32
33
  }
33
34
  export {
34
- L as isScrolledToBottom,
35
+ T as isScrolledToBottom,
35
36
  h as scrollChatToBottom,
36
37
  B as useChatStickToBottom
37
38
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useChatStickToBottom.js","sources":["../../../../src/components/dataDisplay/chat/useChatStickToBottom.ts"],"sourcesContent":["import { RefObject, useEffect, useLayoutEffect, useRef } from \"react\";\n\nexport interface UseChatStickToBottomParams {\n containerRef: RefObject<HTMLElement | null>;\n messages: readonly { id: string }[];\n threshold?: number;\n}\n\nexport function isScrolledToBottom(element: HTMLElement, threshold = 24): boolean {\n return element.scrollHeight - element.scrollTop - element.clientHeight <= threshold;\n}\n\nexport function scrollChatToBottom(element: HTMLElement): void {\n element.scrollTop = element.scrollHeight;\n}\n\nexport function useChatStickToBottom({ containerRef, messages, threshold = 24 }: UseChatStickToBottomParams) {\n const isAtBottomRef = useRef(true);\n const previousScrollHeightRef = useRef(0);\n const previousFirstMessageIdRef = useRef<string | undefined>();\n const previousLastMessageIdRef = useRef<string | undefined>();\n\n useEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const handleScroll = () => {\n isAtBottomRef.current = isScrolledToBottom(element, threshold);\n };\n\n handleScroll();\n element.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => element.removeEventListener(\"scroll\", handleScroll);\n }, [containerRef, threshold]);\n\n useLayoutEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const previousScrollHeight = previousScrollHeightRef.current;\n const previousFirstMessageId = previousFirstMessageIdRef.current;\n const previousLastMessageId = previousLastMessageIdRef.current;\n const firstMessageId = messages[0]?.id;\n const lastMessageId = messages[messages.length - 1]?.id;\n\n if (previousFirstMessageId === undefined) {\n scrollChatToBottom(element);\n isAtBottomRef.current = true;\n } else {\n const prepended =\n firstMessageId !== undefined &&\n firstMessageId !== previousFirstMessageId &&\n lastMessageId === previousLastMessageId;\n const appended = lastMessageId !== undefined && lastMessageId !== previousLastMessageId;\n\n if (prepended && previousScrollHeight > 0) {\n element.scrollTop += element.scrollHeight - previousScrollHeight;\n } else if (appended && isAtBottomRef.current) {\n scrollChatToBottom(element);\n }\n }\n\n previousScrollHeightRef.current = element.scrollHeight;\n previousFirstMessageIdRef.current = firstMessageId;\n previousLastMessageIdRef.current = lastMessageId;\n }, [containerRef, messages]);\n}\n"],"names":["isScrolledToBottom","element","threshold","scrollChatToBottom","useChatStickToBottom","containerRef","messages","isAtBottomRef","useRef","previousScrollHeightRef","previousFirstMessageIdRef","previousLastMessageIdRef","useEffect","handleScroll","useLayoutEffect","previousScrollHeight","previousFirstMessageId","previousLastMessageId","firstMessageId","_a","lastMessageId","_b","prepended","appended"],"mappings":";AAQO,SAASA,EAAmBC,GAAsBC,IAAY,IAAa;AAChF,SAAOD,EAAQ,eAAeA,EAAQ,YAAYA,EAAQ,gBAAgBC;AAC5E;AAEO,SAASC,EAAmBF,GAA4B;AAC7D,EAAAA,EAAQ,YAAYA,EAAQ;AAC9B;AAEO,SAASG,EAAqB,EAAE,cAAAC,GAAc,UAAAC,GAAU,WAAAJ,IAAY,MAAkC;AAC3G,QAAMK,IAAgBC,EAAO,EAAI,GAC3BC,IAA0BD,EAAO,CAAC,GAClCE,IAA4BF,EAAA,GAC5BG,IAA2BH,EAAA;AAEjC,EAAAI,EAAU,MAAM;AACd,UAAMX,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMY,IAAe,MAAM;AACzB,MAAAN,EAAc,UAAUP,EAAmBC,GAASC,CAAS;AAAA,IAC/D;AAEA,WAAAW,EAAA,GACAZ,EAAQ,iBAAiB,UAAUY,GAAc,EAAE,SAAS,IAAM,GAE3D,MAAMZ,EAAQ,oBAAoB,UAAUY,CAAY;AAAA,EACjE,GAAG,CAACR,GAAcH,CAAS,CAAC,GAE5BY,EAAgB,MAAM;;AACpB,UAAMb,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMc,IAAuBN,EAAwB,SAC/CO,IAAyBN,EAA0B,SACnDO,IAAwBN,EAAyB,SACjDO,KAAiBC,IAAAb,EAAS,CAAC,MAAV,gBAAAa,EAAa,IAC9BC,KAAgBC,IAAAf,EAASA,EAAS,SAAS,CAAC,MAA5B,gBAAAe,EAA+B;AAErD,QAAIL,MAA2B;AAC7B,MAAAb,EAAmBF,CAAO,GAC1BM,EAAc,UAAU;AAAA,SACnB;AACL,YAAMe,IACJJ,MAAmB,UACnBA,MAAmBF,KACnBI,MAAkBH,GACdM,IAAWH,MAAkB,UAAaA,MAAkBH;AAElE,MAAIK,KAAaP,IAAuB,IACtCd,EAAQ,aAAaA,EAAQ,eAAec,IACnCQ,KAAYhB,EAAc,WACnCJ,EAAmBF,CAAO;AAAA,IAE9B;AAEA,IAAAQ,EAAwB,UAAUR,EAAQ,cAC1CS,EAA0B,UAAUQ,GACpCP,EAAyB,UAAUS;AAAA,EACrC,GAAG,CAACf,GAAcC,CAAQ,CAAC;AAC7B;"}
1
+ {"version":3,"file":"useChatStickToBottom.js","sources":["../../../../src/components/dataDisplay/chat/useChatStickToBottom.ts"],"sourcesContent":["import { RefObject, useEffect, useRef } from \"react\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\n\nexport interface UseChatStickToBottomParams {\n containerRef: RefObject<HTMLElement | null>;\n messages: readonly { id: string }[];\n threshold?: number;\n}\n\nexport function isScrolledToBottom(element: HTMLElement, threshold = 24): boolean {\n return element.scrollHeight - element.scrollTop - element.clientHeight <= threshold;\n}\n\nexport function scrollChatToBottom(element: HTMLElement): void {\n element.scrollTop = element.scrollHeight;\n}\n\nexport function useChatStickToBottom({ containerRef, messages, threshold = 24 }: UseChatStickToBottomParams) {\n const isAtBottomRef = useRef(true);\n const previousScrollHeightRef = useRef(0);\n const previousFirstMessageIdRef = useRef<string | undefined>();\n const previousLastMessageIdRef = useRef<string | undefined>();\n\n useEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const handleScroll = () => {\n isAtBottomRef.current = isScrolledToBottom(element, threshold);\n };\n\n handleScroll();\n element.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => element.removeEventListener(\"scroll\", handleScroll);\n }, [containerRef, threshold]);\n\n useSafeLayoutEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const previousScrollHeight = previousScrollHeightRef.current;\n const previousFirstMessageId = previousFirstMessageIdRef.current;\n const previousLastMessageId = previousLastMessageIdRef.current;\n const firstMessageId = messages[0]?.id;\n const lastMessageId = messages[messages.length - 1]?.id;\n\n if (previousFirstMessageId === undefined) {\n scrollChatToBottom(element);\n isAtBottomRef.current = true;\n } else {\n const prepended =\n firstMessageId !== undefined &&\n firstMessageId !== previousFirstMessageId &&\n lastMessageId === previousLastMessageId;\n const appended = lastMessageId !== undefined && lastMessageId !== previousLastMessageId;\n\n if (prepended && previousScrollHeight > 0) {\n element.scrollTop += element.scrollHeight - previousScrollHeight;\n } else if (appended && isAtBottomRef.current) {\n scrollChatToBottom(element);\n }\n }\n\n previousScrollHeightRef.current = element.scrollHeight;\n previousFirstMessageIdRef.current = firstMessageId;\n previousLastMessageIdRef.current = lastMessageId;\n }, [containerRef, messages]);\n}\n"],"names":["isScrolledToBottom","element","threshold","scrollChatToBottom","useChatStickToBottom","containerRef","messages","isAtBottomRef","useRef","previousScrollHeightRef","previousFirstMessageIdRef","previousLastMessageIdRef","useEffect","handleScroll","useSafeLayoutEffect","previousScrollHeight","previousFirstMessageId","previousLastMessageId","firstMessageId","_a","lastMessageId","_b","prepended","appended"],"mappings":";;AASO,SAASA,EAAmBC,GAAsBC,IAAY,IAAa;AAChF,SAAOD,EAAQ,eAAeA,EAAQ,YAAYA,EAAQ,gBAAgBC;AAC5E;AAEO,SAASC,EAAmBF,GAA4B;AAC7D,EAAAA,EAAQ,YAAYA,EAAQ;AAC9B;AAEO,SAASG,EAAqB,EAAE,cAAAC,GAAc,UAAAC,GAAU,WAAAJ,IAAY,MAAkC;AAC3G,QAAMK,IAAgBC,EAAO,EAAI,GAC3BC,IAA0BD,EAAO,CAAC,GAClCE,IAA4BF,EAAA,GAC5BG,IAA2BH,EAAA;AAEjC,EAAAI,EAAU,MAAM;AACd,UAAMX,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMY,IAAe,MAAM;AACzB,MAAAN,EAAc,UAAUP,EAAmBC,GAASC,CAAS;AAAA,IAC/D;AAEA,WAAAW,EAAA,GACAZ,EAAQ,iBAAiB,UAAUY,GAAc,EAAE,SAAS,IAAM,GAE3D,MAAMZ,EAAQ,oBAAoB,UAAUY,CAAY;AAAA,EACjE,GAAG,CAACR,GAAcH,CAAS,CAAC,GAE5BY,EAAoB,MAAM;;AACxB,UAAMb,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMc,IAAuBN,EAAwB,SAC/CO,IAAyBN,EAA0B,SACnDO,IAAwBN,EAAyB,SACjDO,KAAiBC,IAAAb,EAAS,CAAC,MAAV,gBAAAa,EAAa,IAC9BC,KAAgBC,IAAAf,EAASA,EAAS,SAAS,CAAC,MAA5B,gBAAAe,EAA+B;AAErD,QAAIL,MAA2B;AAC7B,MAAAb,EAAmBF,CAAO,GAC1BM,EAAc,UAAU;AAAA,SACnB;AACL,YAAMe,IACJJ,MAAmB,UACnBA,MAAmBF,KACnBI,MAAkBH,GACdM,IAAWH,MAAkB,UAAaA,MAAkBH;AAElE,MAAIK,KAAaP,IAAuB,IACtCd,EAAQ,aAAaA,EAAQ,eAAec,IACnCQ,KAAYhB,EAAc,WACnCJ,EAAmBF,CAAO;AAAA,IAE9B;AAEA,IAAAQ,EAAwB,UAAUR,EAAQ,cAC1CS,EAA0B,UAAUQ,GACpCP,EAAyB,UAAUS;AAAA,EACrC,GAAG,CAACf,GAAcC,CAAQ,CAAC;AAC7B;"}
@@ -1,5 +1,6 @@
1
- import { useRef as c, useEffect as M, useLayoutEffect as T } from "react";
2
- function L(t, r = 24) {
1
+ import { useRef as c, useEffect as M } from "react";
2
+ import { useSafeLayoutEffect as S } from "../../../hooks/useSafeLayoutEffect.js";
3
+ function T(t, r = 24) {
3
4
  return t.scrollHeight - t.scrollTop - t.clientHeight <= r;
4
5
  }
5
6
  function h(t) {
@@ -12,15 +13,15 @@ function B({ containerRef: t, messages: r, threshold: l = 24 }) {
12
13
  if (!e)
13
14
  return;
14
15
  const o = () => {
15
- n.current = L(e, l);
16
+ n.current = T(e, l);
16
17
  };
17
18
  return o(), e.addEventListener("scroll", o, { passive: !0 }), () => e.removeEventListener("scroll", o);
18
- }, [t, l]), T(() => {
19
- var g, a;
19
+ }, [t, l]), S(() => {
20
+ var a, g;
20
21
  const e = t.current;
21
22
  if (!e)
22
23
  return;
23
- const o = u.current, p = d.current, v = f.current, i = (g = r[0]) == null ? void 0 : g.id, s = (a = r[r.length - 1]) == null ? void 0 : a.id;
24
+ const o = u.current, p = d.current, v = f.current, i = (a = r[0]) == null ? void 0 : a.id, s = (g = r[r.length - 1]) == null ? void 0 : g.id;
24
25
  if (p === void 0)
25
26
  h(e), n.current = !0;
26
27
  else {
@@ -31,7 +32,7 @@ function B({ containerRef: t, messages: r, threshold: l = 24 }) {
31
32
  }, [t, r]);
32
33
  }
33
34
  export {
34
- L as isScrolledToBottom,
35
+ T as isScrolledToBottom,
35
36
  h as scrollChatToBottom,
36
37
  B as useChatStickToBottom
37
38
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useChatStickToBottom.js","sources":["../../../../../src/components/dataDisplay/chat/useChatStickToBottom.ts"],"sourcesContent":["import { RefObject, useEffect, useLayoutEffect, useRef } from \"react\";\n\nexport interface UseChatStickToBottomParams {\n containerRef: RefObject<HTMLElement | null>;\n messages: readonly { id: string }[];\n threshold?: number;\n}\n\nexport function isScrolledToBottom(element: HTMLElement, threshold = 24): boolean {\n return element.scrollHeight - element.scrollTop - element.clientHeight <= threshold;\n}\n\nexport function scrollChatToBottom(element: HTMLElement): void {\n element.scrollTop = element.scrollHeight;\n}\n\nexport function useChatStickToBottom({ containerRef, messages, threshold = 24 }: UseChatStickToBottomParams) {\n const isAtBottomRef = useRef(true);\n const previousScrollHeightRef = useRef(0);\n const previousFirstMessageIdRef = useRef<string | undefined>();\n const previousLastMessageIdRef = useRef<string | undefined>();\n\n useEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const handleScroll = () => {\n isAtBottomRef.current = isScrolledToBottom(element, threshold);\n };\n\n handleScroll();\n element.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => element.removeEventListener(\"scroll\", handleScroll);\n }, [containerRef, threshold]);\n\n useLayoutEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const previousScrollHeight = previousScrollHeightRef.current;\n const previousFirstMessageId = previousFirstMessageIdRef.current;\n const previousLastMessageId = previousLastMessageIdRef.current;\n const firstMessageId = messages[0]?.id;\n const lastMessageId = messages[messages.length - 1]?.id;\n\n if (previousFirstMessageId === undefined) {\n scrollChatToBottom(element);\n isAtBottomRef.current = true;\n } else {\n const prepended =\n firstMessageId !== undefined &&\n firstMessageId !== previousFirstMessageId &&\n lastMessageId === previousLastMessageId;\n const appended = lastMessageId !== undefined && lastMessageId !== previousLastMessageId;\n\n if (prepended && previousScrollHeight > 0) {\n element.scrollTop += element.scrollHeight - previousScrollHeight;\n } else if (appended && isAtBottomRef.current) {\n scrollChatToBottom(element);\n }\n }\n\n previousScrollHeightRef.current = element.scrollHeight;\n previousFirstMessageIdRef.current = firstMessageId;\n previousLastMessageIdRef.current = lastMessageId;\n }, [containerRef, messages]);\n}\n"],"names":["isScrolledToBottom","element","threshold","scrollChatToBottom","useChatStickToBottom","containerRef","messages","isAtBottomRef","useRef","previousScrollHeightRef","previousFirstMessageIdRef","previousLastMessageIdRef","useEffect","handleScroll","useLayoutEffect","previousScrollHeight","previousFirstMessageId","previousLastMessageId","firstMessageId","_a","lastMessageId","_b","prepended","appended"],"mappings":";AAQO,SAASA,EAAmBC,GAAsBC,IAAY,IAAa;AAChF,SAAOD,EAAQ,eAAeA,EAAQ,YAAYA,EAAQ,gBAAgBC;AAC5E;AAEO,SAASC,EAAmBF,GAA4B;AAC7D,EAAAA,EAAQ,YAAYA,EAAQ;AAC9B;AAEO,SAASG,EAAqB,EAAE,cAAAC,GAAc,UAAAC,GAAU,WAAAJ,IAAY,MAAkC;AAC3G,QAAMK,IAAgBC,EAAO,EAAI,GAC3BC,IAA0BD,EAAO,CAAC,GAClCE,IAA4BF,EAAA,GAC5BG,IAA2BH,EAAA;AAEjC,EAAAI,EAAU,MAAM;AACd,UAAMX,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMY,IAAe,MAAM;AACzB,MAAAN,EAAc,UAAUP,EAAmBC,GAASC,CAAS;AAAA,IAC/D;AAEA,WAAAW,EAAA,GACAZ,EAAQ,iBAAiB,UAAUY,GAAc,EAAE,SAAS,IAAM,GAE3D,MAAMZ,EAAQ,oBAAoB,UAAUY,CAAY;AAAA,EACjE,GAAG,CAACR,GAAcH,CAAS,CAAC,GAE5BY,EAAgB,MAAM;;AACpB,UAAMb,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMc,IAAuBN,EAAwB,SAC/CO,IAAyBN,EAA0B,SACnDO,IAAwBN,EAAyB,SACjDO,KAAiBC,IAAAb,EAAS,CAAC,MAAV,gBAAAa,EAAa,IAC9BC,KAAgBC,IAAAf,EAASA,EAAS,SAAS,CAAC,MAA5B,gBAAAe,EAA+B;AAErD,QAAIL,MAA2B;AAC7B,MAAAb,EAAmBF,CAAO,GAC1BM,EAAc,UAAU;AAAA,SACnB;AACL,YAAMe,IACJJ,MAAmB,UACnBA,MAAmBF,KACnBI,MAAkBH,GACdM,IAAWH,MAAkB,UAAaA,MAAkBH;AAElE,MAAIK,KAAaP,IAAuB,IACtCd,EAAQ,aAAaA,EAAQ,eAAec,IACnCQ,KAAYhB,EAAc,WACnCJ,EAAmBF,CAAO;AAAA,IAE9B;AAEA,IAAAQ,EAAwB,UAAUR,EAAQ,cAC1CS,EAA0B,UAAUQ,GACpCP,EAAyB,UAAUS;AAAA,EACrC,GAAG,CAACf,GAAcC,CAAQ,CAAC;AAC7B;"}
1
+ {"version":3,"file":"useChatStickToBottom.js","sources":["../../../../../src/components/dataDisplay/chat/useChatStickToBottom.ts"],"sourcesContent":["import { RefObject, useEffect, useRef } from \"react\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\n\nexport interface UseChatStickToBottomParams {\n containerRef: RefObject<HTMLElement | null>;\n messages: readonly { id: string }[];\n threshold?: number;\n}\n\nexport function isScrolledToBottom(element: HTMLElement, threshold = 24): boolean {\n return element.scrollHeight - element.scrollTop - element.clientHeight <= threshold;\n}\n\nexport function scrollChatToBottom(element: HTMLElement): void {\n element.scrollTop = element.scrollHeight;\n}\n\nexport function useChatStickToBottom({ containerRef, messages, threshold = 24 }: UseChatStickToBottomParams) {\n const isAtBottomRef = useRef(true);\n const previousScrollHeightRef = useRef(0);\n const previousFirstMessageIdRef = useRef<string | undefined>();\n const previousLastMessageIdRef = useRef<string | undefined>();\n\n useEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const handleScroll = () => {\n isAtBottomRef.current = isScrolledToBottom(element, threshold);\n };\n\n handleScroll();\n element.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => element.removeEventListener(\"scroll\", handleScroll);\n }, [containerRef, threshold]);\n\n useSafeLayoutEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const previousScrollHeight = previousScrollHeightRef.current;\n const previousFirstMessageId = previousFirstMessageIdRef.current;\n const previousLastMessageId = previousLastMessageIdRef.current;\n const firstMessageId = messages[0]?.id;\n const lastMessageId = messages[messages.length - 1]?.id;\n\n if (previousFirstMessageId === undefined) {\n scrollChatToBottom(element);\n isAtBottomRef.current = true;\n } else {\n const prepended =\n firstMessageId !== undefined &&\n firstMessageId !== previousFirstMessageId &&\n lastMessageId === previousLastMessageId;\n const appended = lastMessageId !== undefined && lastMessageId !== previousLastMessageId;\n\n if (prepended && previousScrollHeight > 0) {\n element.scrollTop += element.scrollHeight - previousScrollHeight;\n } else if (appended && isAtBottomRef.current) {\n scrollChatToBottom(element);\n }\n }\n\n previousScrollHeightRef.current = element.scrollHeight;\n previousFirstMessageIdRef.current = firstMessageId;\n previousLastMessageIdRef.current = lastMessageId;\n }, [containerRef, messages]);\n}\n"],"names":["isScrolledToBottom","element","threshold","scrollChatToBottom","useChatStickToBottom","containerRef","messages","isAtBottomRef","useRef","previousScrollHeightRef","previousFirstMessageIdRef","previousLastMessageIdRef","useEffect","handleScroll","useSafeLayoutEffect","previousScrollHeight","previousFirstMessageId","previousLastMessageId","firstMessageId","_a","lastMessageId","_b","prepended","appended"],"mappings":";;AASO,SAASA,EAAmBC,GAAsBC,IAAY,IAAa;AAChF,SAAOD,EAAQ,eAAeA,EAAQ,YAAYA,EAAQ,gBAAgBC;AAC5E;AAEO,SAASC,EAAmBF,GAA4B;AAC7D,EAAAA,EAAQ,YAAYA,EAAQ;AAC9B;AAEO,SAASG,EAAqB,EAAE,cAAAC,GAAc,UAAAC,GAAU,WAAAJ,IAAY,MAAkC;AAC3G,QAAMK,IAAgBC,EAAO,EAAI,GAC3BC,IAA0BD,EAAO,CAAC,GAClCE,IAA4BF,EAAA,GAC5BG,IAA2BH,EAAA;AAEjC,EAAAI,EAAU,MAAM;AACd,UAAMX,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMY,IAAe,MAAM;AACzB,MAAAN,EAAc,UAAUP,EAAmBC,GAASC,CAAS;AAAA,IAC/D;AAEA,WAAAW,EAAA,GACAZ,EAAQ,iBAAiB,UAAUY,GAAc,EAAE,SAAS,IAAM,GAE3D,MAAMZ,EAAQ,oBAAoB,UAAUY,CAAY;AAAA,EACjE,GAAG,CAACR,GAAcH,CAAS,CAAC,GAE5BY,EAAoB,MAAM;;AACxB,UAAMb,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMc,IAAuBN,EAAwB,SAC/CO,IAAyBN,EAA0B,SACnDO,IAAwBN,EAAyB,SACjDO,KAAiBC,IAAAb,EAAS,CAAC,MAAV,gBAAAa,EAAa,IAC9BC,KAAgBC,IAAAf,EAASA,EAAS,SAAS,CAAC,MAA5B,gBAAAe,EAA+B;AAErD,QAAIL,MAA2B;AAC7B,MAAAb,EAAmBF,CAAO,GAC1BM,EAAc,UAAU;AAAA,SACnB;AACL,YAAMe,IACJJ,MAAmB,UACnBA,MAAmBF,KACnBI,MAAkBH,GACdM,IAAWH,MAAkB,UAAaA,MAAkBH;AAElE,MAAIK,KAAaP,IAAuB,IACtCd,EAAQ,aAAaA,EAAQ,eAAec,IACnCQ,KAAYhB,EAAc,WACnCJ,EAAmBF,CAAO;AAAA,IAE9B;AAEA,IAAAQ,EAAwB,UAAUR,EAAQ,cAC1CS,EAA0B,UAAUQ,GACpCP,EAAyB,UAAUS;AAAA,EACrC,GAAG,CAACf,GAAcC,CAAQ,CAAC;AAC7B;"}
@@ -1,11 +1,12 @@
1
- import e from "react";
2
- function a(t) {
3
- const r = e.useRef(t);
4
- return e.useLayoutEffect(() => {
5
- r.current = t;
6
- }), e.useCallback((...u) => (0, r.current)(...u), []);
1
+ import t from "react";
2
+ import { useSafeLayoutEffect as c } from "./useSafeLayoutEffect.js";
3
+ function f(e) {
4
+ const r = t.useRef(e);
5
+ return c(() => {
6
+ r.current = e;
7
+ }), t.useCallback((...u) => (0, r.current)(...u), []);
7
8
  }
8
9
  export {
9
- a as useEventCallback
10
+ f as useEventCallback
10
11
  };
11
12
  //# sourceMappingURL=useEventCallback.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useEventCallback.js","sources":["../../../src/hooks/useEventCallback.ts"],"sourcesContent":["import React from \"react\";\n\n/**\n * https://github.com/facebook/react/issues/14099#issuecomment-440013892\n */\nexport function useEventCallback<Args extends unknown[], Return>(\n fn: (...args: Args) => Return\n): (...args: Args) => Return {\n const ref = React.useRef(fn);\n\n React.useLayoutEffect(() => {\n ref.current = fn;\n });\n\n return React.useCallback((...args: Args) => (0, ref.current)(...args), []);\n}\n"],"names":["useEventCallback","fn","ref","React","args"],"mappings":";AAKO,SAASA,EACdC,GAC2B;AAC3B,QAAMC,IAAMC,EAAM,OAAOF,CAAE;AAE3B,SAAAE,EAAM,gBAAgB,MAAM;AAC1B,IAAAD,EAAI,UAAUD;AAAA,EAChB,CAAC,GAEME,EAAM,YAAY,IAAIC,UAAmBF,EAAI,SAAS,GAAGE,CAAI,GAAG,EAAE;AAC3E;"}
1
+ {"version":3,"file":"useEventCallback.js","sources":["../../../src/hooks/useEventCallback.ts"],"sourcesContent":["import React from \"react\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\n/**\n * https://github.com/facebook/react/issues/14099#issuecomment-440013892\n */\nexport function useEventCallback<Args extends unknown[], Return>(\n fn: (...args: Args) => Return\n): (...args: Args) => Return {\n const ref = React.useRef(fn);\n\n // useSafeLayoutEffect falls back to useEffect on the server so this hook does\n // not emit React's \"useLayoutEffect does nothing on the server\" SSR warning.\n useSafeLayoutEffect(() => {\n ref.current = fn;\n });\n\n return React.useCallback((...args: Args) => (0, ref.current)(...args), []);\n}\n"],"names":["useEventCallback","fn","ref","React","useSafeLayoutEffect","args"],"mappings":";;AAMO,SAASA,EACdC,GAC2B;AAC3B,QAAMC,IAAMC,EAAM,OAAOF,CAAE;AAI3B,SAAAG,EAAoB,MAAM;AACxB,IAAAF,EAAI,UAAUD;AAAA,EAChB,CAAC,GAEME,EAAM,YAAY,IAAIE,UAAmBH,EAAI,SAAS,GAAGG,CAAI,GAAG,EAAE;AAC3E;"}
@@ -1,37 +1,38 @@
1
- import { useRef as n, useLayoutEffect as c, useEffect as l } from "react";
2
- import { Observable as d } from "../utils/observable.js";
3
- import { useObservable as u } from "./useObservable.js";
1
+ import { useRef as n, useEffect as c } from "react";
2
+ import { Observable as l } from "../utils/observable.js";
3
+ import { useObservable as d } from "./useObservable.js";
4
+ import { useSafeLayoutEffect as u } from "./useSafeLayoutEffect.js";
4
5
  var i = /* @__PURE__ */ ((t) => (t.dark = "dark", t.light = "light", t))(i || {});
5
- const s = "smui-theme", a = new d(
6
+ const r = "smui-theme", a = new l(
6
7
  "light"
7
8
  /* light */
8
- ), E = () => {
9
- const t = u(a), r = n(!0);
10
- c(() => {
11
- const e = localStorage.getItem(s);
12
- if (r.current)
13
- if (r.current = !1, e)
9
+ ), b = () => {
10
+ const t = d(a), s = n(!0);
11
+ u(() => {
12
+ const e = localStorage.getItem(r);
13
+ if (s.current)
14
+ if (s.current = !1, e)
14
15
  a.setValue(e), document.documentElement.dataset.theme = e;
15
16
  else {
16
17
  const o = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
17
- e !== t && a.setValue(o), localStorage.setItem(s, o), document.documentElement.dataset.theme = o;
18
+ e !== t && a.setValue(o), localStorage.setItem(r, o), document.documentElement.dataset.theme = o;
18
19
  }
19
20
  }, [t]);
20
21
  const m = function(e) {
21
22
  if (e.storageArea === localStorage) {
22
- const o = localStorage.getItem(s);
23
+ const o = localStorage.getItem(r);
23
24
  document.documentElement.dataset.theme = o, a.setValue(o);
24
25
  }
25
26
  };
26
- return l(() => (window.addEventListener("storage", m), () => window.removeEventListener("storage", m)), []), {
27
+ return c(() => (window.addEventListener("storage", m), () => window.removeEventListener("storage", m)), []), {
27
28
  theme: t,
28
29
  setTheme: (e) => {
29
- localStorage.setItem(s, e), a.setValue.bind(a)(e), document.documentElement.dataset.theme = e;
30
+ localStorage.setItem(r, e), a.setValue.bind(a)(e), document.documentElement.dataset.theme = e;
30
31
  }
31
32
  };
32
33
  };
33
34
  export {
34
35
  i as Theme,
35
- E as default
36
+ b as default
36
37
  };
37
38
  //# sourceMappingURL=useTheme.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useTheme.js","sources":["../../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef } from \"react\";\nimport { Observable } from \"../utils/observable\";\nimport { useObservable } from \"./useObservable\";\n\nexport enum Theme {\n dark = \"dark\",\n light = \"light\",\n}\n\nconst themeStorageKey = \"smui-theme\";\n\nconst themeObservable = new Observable<Theme>(Theme.light);\n\nconst useTheme = () => {\n const theme = useObservable(themeObservable);\n // Начальная инициализация\n const firstUpdate = useRef(true);\n useLayoutEffect(() => {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n if (firstUpdate.current) {\n firstUpdate.current = false;\n if (savedTheme) {\n themeObservable.setValue(savedTheme);\n document.documentElement.dataset.theme = savedTheme;\n } else {\n const defaultTheme: Theme = window.matchMedia(\"(prefers-color-scheme: light)\").matches\n ? Theme.light\n : Theme.dark;\n if (savedTheme !== theme) {\n themeObservable.setValue(defaultTheme);\n }\n localStorage.setItem(themeStorageKey, defaultTheme);\n document.documentElement.dataset.theme = defaultTheme;\n }\n }\n }, [theme]);\n\n const themeListener = function (event: StorageEvent) {\n if (event.storageArea === localStorage) {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n document.documentElement.dataset.theme = savedTheme;\n themeObservable.setValue(savedTheme);\n }\n };\n\n useEffect(() => {\n window.addEventListener(\"storage\", themeListener);\n return () => window.removeEventListener(\"storage\", themeListener);\n }, []);\n\n return {\n theme,\n setTheme: (value: Theme) => {\n localStorage.setItem(themeStorageKey, value);\n themeObservable.setValue.bind(themeObservable)(value);\n document.documentElement.dataset.theme = value;\n },\n };\n};\n\nexport default useTheme;\n"],"names":["Theme","themeStorageKey","themeObservable","Observable","useTheme","theme","useObservable","firstUpdate","useRef","useLayoutEffect","savedTheme","defaultTheme","themeListener","event","useEffect","value"],"mappings":";;;AAIO,IAAKA,sBAAAA,OACVA,EAAA,OAAO,QACPA,EAAA,QAAQ,SAFEA,IAAAA,KAAA,CAAA,CAAA;AAKZ,MAAMC,IAAkB,cAElBC,IAAkB,IAAIC;AAAA,EAAkB;AAAA;AAAA,GAExCC,IAAW,MAAM;AACrB,QAAMC,IAAQC,EAAcJ,CAAe,GAErCK,IAAcC,EAAO,EAAI;AAC/B,EAAAC,EAAgB,MAAM;AACpB,UAAMC,IAAa,aAAa,QAAQT,CAAe;AACvD,QAAIM,EAAY;AAEd,UADAA,EAAY,UAAU,IAClBG;AACF,QAAAR,EAAgB,SAASQ,CAAU,GACnC,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,WACpC;AACL,cAAMC,IAAsB,OAAO,WAAW,+BAA+B,EAAE,UAC3E,UACA;AACJ,QAAID,MAAeL,KACjBH,EAAgB,SAASS,CAAY,GAEvC,aAAa,QAAQV,GAAiBU,CAAY,GAClD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,MAC3C;AAAA,EAEJ,GAAG,CAACN,CAAK,CAAC;AAEV,QAAMO,IAAgB,SAAUC,GAAqB;AACnD,QAAIA,EAAM,gBAAgB,cAAc;AACtC,YAAMH,IAAa,aAAa,QAAQT,CAAe;AACvD,eAAS,gBAAgB,QAAQ,QAAQS,GACzCR,EAAgB,SAASQ,CAAU;AAAA,IACrC;AAAA,EACF;AAEA,SAAAI,EAAU,OACR,OAAO,iBAAiB,WAAWF,CAAa,GACzC,MAAM,OAAO,oBAAoB,WAAWA,CAAa,IAC/D,CAAA,CAAE,GAEE;AAAA,IACL,OAAAP;AAAA,IACA,UAAU,CAACU,MAAiB;AAC1B,mBAAa,QAAQd,GAAiBc,CAAK,GAC3Cb,EAAgB,SAAS,KAAKA,CAAe,EAAEa,CAAK,GACpD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,IAC3C;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"useTheme.js","sources":["../../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { Observable } from \"../utils/observable\";\nimport { useObservable } from \"./useObservable\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\nexport enum Theme {\n dark = \"dark\",\n light = \"light\",\n}\n\nconst themeStorageKey = \"smui-theme\";\n\nconst themeObservable = new Observable<Theme>(Theme.light);\n\nconst useTheme = () => {\n const theme = useObservable(themeObservable);\n // Начальная инициализация\n const firstUpdate = useRef(true);\n useSafeLayoutEffect(() => {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n if (firstUpdate.current) {\n firstUpdate.current = false;\n if (savedTheme) {\n themeObservable.setValue(savedTheme);\n document.documentElement.dataset.theme = savedTheme;\n } else {\n const defaultTheme: Theme = window.matchMedia(\"(prefers-color-scheme: light)\").matches\n ? Theme.light\n : Theme.dark;\n if (savedTheme !== theme) {\n themeObservable.setValue(defaultTheme);\n }\n localStorage.setItem(themeStorageKey, defaultTheme);\n document.documentElement.dataset.theme = defaultTheme;\n }\n }\n }, [theme]);\n\n const themeListener = function (event: StorageEvent) {\n if (event.storageArea === localStorage) {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n document.documentElement.dataset.theme = savedTheme;\n themeObservable.setValue(savedTheme);\n }\n };\n\n useEffect(() => {\n window.addEventListener(\"storage\", themeListener);\n return () => window.removeEventListener(\"storage\", themeListener);\n }, []);\n\n return {\n theme,\n setTheme: (value: Theme) => {\n localStorage.setItem(themeStorageKey, value);\n themeObservable.setValue.bind(themeObservable)(value);\n document.documentElement.dataset.theme = value;\n },\n };\n};\n\nexport default useTheme;\n"],"names":["Theme","themeStorageKey","themeObservable","Observable","useTheme","theme","useObservable","firstUpdate","useRef","useSafeLayoutEffect","savedTheme","defaultTheme","themeListener","event","useEffect","value"],"mappings":";;;;AAKO,IAAKA,sBAAAA,OACVA,EAAA,OAAO,QACPA,EAAA,QAAQ,SAFEA,IAAAA,KAAA,CAAA,CAAA;AAKZ,MAAMC,IAAkB,cAElBC,IAAkB,IAAIC;AAAA,EAAkB;AAAA;AAAA,GAExCC,IAAW,MAAM;AACrB,QAAMC,IAAQC,EAAcJ,CAAe,GAErCK,IAAcC,EAAO,EAAI;AAC/B,EAAAC,EAAoB,MAAM;AACxB,UAAMC,IAAa,aAAa,QAAQT,CAAe;AACvD,QAAIM,EAAY;AAEd,UADAA,EAAY,UAAU,IAClBG;AACF,QAAAR,EAAgB,SAASQ,CAAU,GACnC,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,WACpC;AACL,cAAMC,IAAsB,OAAO,WAAW,+BAA+B,EAAE,UAC3E,UACA;AACJ,QAAID,MAAeL,KACjBH,EAAgB,SAASS,CAAY,GAEvC,aAAa,QAAQV,GAAiBU,CAAY,GAClD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,MAC3C;AAAA,EAEJ,GAAG,CAACN,CAAK,CAAC;AAEV,QAAMO,IAAgB,SAAUC,GAAqB;AACnD,QAAIA,EAAM,gBAAgB,cAAc;AACtC,YAAMH,IAAa,aAAa,QAAQT,CAAe;AACvD,eAAS,gBAAgB,QAAQ,QAAQS,GACzCR,EAAgB,SAASQ,CAAU;AAAA,IACrC;AAAA,EACF;AAEA,SAAAI,EAAU,OACR,OAAO,iBAAiB,WAAWF,CAAa,GACzC,MAAM,OAAO,oBAAoB,WAAWA,CAAa,IAC/D,CAAA,CAAE,GAEE;AAAA,IACL,OAAAP;AAAA,IACA,UAAU,CAACU,MAAiB;AAC1B,mBAAa,QAAQd,GAAiBc,CAAK,GAC3Cb,EAAgB,SAAS,KAAKA,CAAe,EAAEa,CAAK,GACpD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,IAC3C;AAAA,EAAA;AAEJ;"}
@@ -1,11 +1,12 @@
1
- import e from "react";
2
- function a(t) {
3
- const r = e.useRef(t);
4
- return e.useLayoutEffect(() => {
5
- r.current = t;
6
- }), e.useCallback((...u) => (0, r.current)(...u), []);
1
+ import t from "react";
2
+ import { useSafeLayoutEffect as c } from "./useSafeLayoutEffect.js";
3
+ function f(e) {
4
+ const r = t.useRef(e);
5
+ return c(() => {
6
+ r.current = e;
7
+ }), t.useCallback((...u) => (0, r.current)(...u), []);
7
8
  }
8
9
  export {
9
- a as useEventCallback
10
+ f as useEventCallback
10
11
  };
11
12
  //# sourceMappingURL=useEventCallback.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useEventCallback.js","sources":["../../src/hooks/useEventCallback.ts"],"sourcesContent":["import React from \"react\";\n\n/**\n * https://github.com/facebook/react/issues/14099#issuecomment-440013892\n */\nexport function useEventCallback<Args extends unknown[], Return>(\n fn: (...args: Args) => Return\n): (...args: Args) => Return {\n const ref = React.useRef(fn);\n\n React.useLayoutEffect(() => {\n ref.current = fn;\n });\n\n return React.useCallback((...args: Args) => (0, ref.current)(...args), []);\n}\n"],"names":["useEventCallback","fn","ref","React","args"],"mappings":";AAKO,SAASA,EACdC,GAC2B;AAC3B,QAAMC,IAAMC,EAAM,OAAOF,CAAE;AAE3B,SAAAE,EAAM,gBAAgB,MAAM;AAC1B,IAAAD,EAAI,UAAUD;AAAA,EAChB,CAAC,GAEME,EAAM,YAAY,IAAIC,UAAmBF,EAAI,SAAS,GAAGE,CAAI,GAAG,EAAE;AAC3E;"}
1
+ {"version":3,"file":"useEventCallback.js","sources":["../../src/hooks/useEventCallback.ts"],"sourcesContent":["import React from \"react\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\n/**\n * https://github.com/facebook/react/issues/14099#issuecomment-440013892\n */\nexport function useEventCallback<Args extends unknown[], Return>(\n fn: (...args: Args) => Return\n): (...args: Args) => Return {\n const ref = React.useRef(fn);\n\n // useSafeLayoutEffect falls back to useEffect on the server so this hook does\n // not emit React's \"useLayoutEffect does nothing on the server\" SSR warning.\n useSafeLayoutEffect(() => {\n ref.current = fn;\n });\n\n return React.useCallback((...args: Args) => (0, ref.current)(...args), []);\n}\n"],"names":["useEventCallback","fn","ref","React","useSafeLayoutEffect","args"],"mappings":";;AAMO,SAASA,EACdC,GAC2B;AAC3B,QAAMC,IAAMC,EAAM,OAAOF,CAAE;AAI3B,SAAAG,EAAoB,MAAM;AACxB,IAAAF,EAAI,UAAUD;AAAA,EAChB,CAAC,GAEME,EAAM,YAAY,IAAIE,UAAmBH,EAAI,SAAS,GAAGG,CAAI,GAAG,EAAE;AAC3E;"}
@@ -1,37 +1,38 @@
1
- import { useRef as n, useLayoutEffect as c, useEffect as l } from "react";
2
- import { Observable as d } from "../utils/observable.js";
3
- import { useObservable as u } from "./useObservable.js";
1
+ import { useRef as n, useEffect as c } from "react";
2
+ import { Observable as l } from "../utils/observable.js";
3
+ import { useObservable as d } from "./useObservable.js";
4
+ import { useSafeLayoutEffect as u } from "./useSafeLayoutEffect.js";
4
5
  var i = /* @__PURE__ */ ((t) => (t.dark = "dark", t.light = "light", t))(i || {});
5
- const s = "smui-theme", a = new d(
6
+ const r = "smui-theme", a = new l(
6
7
  "light"
7
8
  /* light */
8
- ), E = () => {
9
- const t = u(a), r = n(!0);
10
- c(() => {
11
- const e = localStorage.getItem(s);
12
- if (r.current)
13
- if (r.current = !1, e)
9
+ ), b = () => {
10
+ const t = d(a), s = n(!0);
11
+ u(() => {
12
+ const e = localStorage.getItem(r);
13
+ if (s.current)
14
+ if (s.current = !1, e)
14
15
  a.setValue(e), document.documentElement.dataset.theme = e;
15
16
  else {
16
17
  const o = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
17
- e !== t && a.setValue(o), localStorage.setItem(s, o), document.documentElement.dataset.theme = o;
18
+ e !== t && a.setValue(o), localStorage.setItem(r, o), document.documentElement.dataset.theme = o;
18
19
  }
19
20
  }, [t]);
20
21
  const m = function(e) {
21
22
  if (e.storageArea === localStorage) {
22
- const o = localStorage.getItem(s);
23
+ const o = localStorage.getItem(r);
23
24
  document.documentElement.dataset.theme = o, a.setValue(o);
24
25
  }
25
26
  };
26
- return l(() => (window.addEventListener("storage", m), () => window.removeEventListener("storage", m)), []), {
27
+ return c(() => (window.addEventListener("storage", m), () => window.removeEventListener("storage", m)), []), {
27
28
  theme: t,
28
29
  setTheme: (e) => {
29
- localStorage.setItem(s, e), a.setValue.bind(a)(e), document.documentElement.dataset.theme = e;
30
+ localStorage.setItem(r, e), a.setValue.bind(a)(e), document.documentElement.dataset.theme = e;
30
31
  }
31
32
  };
32
33
  };
33
34
  export {
34
35
  i as Theme,
35
- E as default
36
+ b as default
36
37
  };
37
38
  //# sourceMappingURL=useTheme.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useTheme.js","sources":["../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef } from \"react\";\nimport { Observable } from \"../utils/observable\";\nimport { useObservable } from \"./useObservable\";\n\nexport enum Theme {\n dark = \"dark\",\n light = \"light\",\n}\n\nconst themeStorageKey = \"smui-theme\";\n\nconst themeObservable = new Observable<Theme>(Theme.light);\n\nconst useTheme = () => {\n const theme = useObservable(themeObservable);\n // Начальная инициализация\n const firstUpdate = useRef(true);\n useLayoutEffect(() => {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n if (firstUpdate.current) {\n firstUpdate.current = false;\n if (savedTheme) {\n themeObservable.setValue(savedTheme);\n document.documentElement.dataset.theme = savedTheme;\n } else {\n const defaultTheme: Theme = window.matchMedia(\"(prefers-color-scheme: light)\").matches\n ? Theme.light\n : Theme.dark;\n if (savedTheme !== theme) {\n themeObservable.setValue(defaultTheme);\n }\n localStorage.setItem(themeStorageKey, defaultTheme);\n document.documentElement.dataset.theme = defaultTheme;\n }\n }\n }, [theme]);\n\n const themeListener = function (event: StorageEvent) {\n if (event.storageArea === localStorage) {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n document.documentElement.dataset.theme = savedTheme;\n themeObservable.setValue(savedTheme);\n }\n };\n\n useEffect(() => {\n window.addEventListener(\"storage\", themeListener);\n return () => window.removeEventListener(\"storage\", themeListener);\n }, []);\n\n return {\n theme,\n setTheme: (value: Theme) => {\n localStorage.setItem(themeStorageKey, value);\n themeObservable.setValue.bind(themeObservable)(value);\n document.documentElement.dataset.theme = value;\n },\n };\n};\n\nexport default useTheme;\n"],"names":["Theme","themeStorageKey","themeObservable","Observable","useTheme","theme","useObservable","firstUpdate","useRef","useLayoutEffect","savedTheme","defaultTheme","themeListener","event","useEffect","value"],"mappings":";;;AAIO,IAAKA,sBAAAA,OACVA,EAAA,OAAO,QACPA,EAAA,QAAQ,SAFEA,IAAAA,KAAA,CAAA,CAAA;AAKZ,MAAMC,IAAkB,cAElBC,IAAkB,IAAIC;AAAA,EAAkB;AAAA;AAAA,GAExCC,IAAW,MAAM;AACrB,QAAMC,IAAQC,EAAcJ,CAAe,GAErCK,IAAcC,EAAO,EAAI;AAC/B,EAAAC,EAAgB,MAAM;AACpB,UAAMC,IAAa,aAAa,QAAQT,CAAe;AACvD,QAAIM,EAAY;AAEd,UADAA,EAAY,UAAU,IAClBG;AACF,QAAAR,EAAgB,SAASQ,CAAU,GACnC,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,WACpC;AACL,cAAMC,IAAsB,OAAO,WAAW,+BAA+B,EAAE,UAC3E,UACA;AACJ,QAAID,MAAeL,KACjBH,EAAgB,SAASS,CAAY,GAEvC,aAAa,QAAQV,GAAiBU,CAAY,GAClD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,MAC3C;AAAA,EAEJ,GAAG,CAACN,CAAK,CAAC;AAEV,QAAMO,IAAgB,SAAUC,GAAqB;AACnD,QAAIA,EAAM,gBAAgB,cAAc;AACtC,YAAMH,IAAa,aAAa,QAAQT,CAAe;AACvD,eAAS,gBAAgB,QAAQ,QAAQS,GACzCR,EAAgB,SAASQ,CAAU;AAAA,IACrC;AAAA,EACF;AAEA,SAAAI,EAAU,OACR,OAAO,iBAAiB,WAAWF,CAAa,GACzC,MAAM,OAAO,oBAAoB,WAAWA,CAAa,IAC/D,CAAA,CAAE,GAEE;AAAA,IACL,OAAAP;AAAA,IACA,UAAU,CAACU,MAAiB;AAC1B,mBAAa,QAAQd,GAAiBc,CAAK,GAC3Cb,EAAgB,SAAS,KAAKA,CAAe,EAAEa,CAAK,GACpD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,IAC3C;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"useTheme.js","sources":["../../src/hooks/useTheme.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { Observable } from \"../utils/observable\";\nimport { useObservable } from \"./useObservable\";\nimport { useSafeLayoutEffect } from \"./useSafeLayoutEffect\";\n\nexport enum Theme {\n dark = \"dark\",\n light = \"light\",\n}\n\nconst themeStorageKey = \"smui-theme\";\n\nconst themeObservable = new Observable<Theme>(Theme.light);\n\nconst useTheme = () => {\n const theme = useObservable(themeObservable);\n // Начальная инициализация\n const firstUpdate = useRef(true);\n useSafeLayoutEffect(() => {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n if (firstUpdate.current) {\n firstUpdate.current = false;\n if (savedTheme) {\n themeObservable.setValue(savedTheme);\n document.documentElement.dataset.theme = savedTheme;\n } else {\n const defaultTheme: Theme = window.matchMedia(\"(prefers-color-scheme: light)\").matches\n ? Theme.light\n : Theme.dark;\n if (savedTheme !== theme) {\n themeObservable.setValue(defaultTheme);\n }\n localStorage.setItem(themeStorageKey, defaultTheme);\n document.documentElement.dataset.theme = defaultTheme;\n }\n }\n }, [theme]);\n\n const themeListener = function (event: StorageEvent) {\n if (event.storageArea === localStorage) {\n const savedTheme = localStorage.getItem(themeStorageKey) as Theme;\n document.documentElement.dataset.theme = savedTheme;\n themeObservable.setValue(savedTheme);\n }\n };\n\n useEffect(() => {\n window.addEventListener(\"storage\", themeListener);\n return () => window.removeEventListener(\"storage\", themeListener);\n }, []);\n\n return {\n theme,\n setTheme: (value: Theme) => {\n localStorage.setItem(themeStorageKey, value);\n themeObservable.setValue.bind(themeObservable)(value);\n document.documentElement.dataset.theme = value;\n },\n };\n};\n\nexport default useTheme;\n"],"names":["Theme","themeStorageKey","themeObservable","Observable","useTheme","theme","useObservable","firstUpdate","useRef","useSafeLayoutEffect","savedTheme","defaultTheme","themeListener","event","useEffect","value"],"mappings":";;;;AAKO,IAAKA,sBAAAA,OACVA,EAAA,OAAO,QACPA,EAAA,QAAQ,SAFEA,IAAAA,KAAA,CAAA,CAAA;AAKZ,MAAMC,IAAkB,cAElBC,IAAkB,IAAIC;AAAA,EAAkB;AAAA;AAAA,GAExCC,IAAW,MAAM;AACrB,QAAMC,IAAQC,EAAcJ,CAAe,GAErCK,IAAcC,EAAO,EAAI;AAC/B,EAAAC,EAAoB,MAAM;AACxB,UAAMC,IAAa,aAAa,QAAQT,CAAe;AACvD,QAAIM,EAAY;AAEd,UADAA,EAAY,UAAU,IAClBG;AACF,QAAAR,EAAgB,SAASQ,CAAU,GACnC,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,WACpC;AACL,cAAMC,IAAsB,OAAO,WAAW,+BAA+B,EAAE,UAC3E,UACA;AACJ,QAAID,MAAeL,KACjBH,EAAgB,SAASS,CAAY,GAEvC,aAAa,QAAQV,GAAiBU,CAAY,GAClD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,MAC3C;AAAA,EAEJ,GAAG,CAACN,CAAK,CAAC;AAEV,QAAMO,IAAgB,SAAUC,GAAqB;AACnD,QAAIA,EAAM,gBAAgB,cAAc;AACtC,YAAMH,IAAa,aAAa,QAAQT,CAAe;AACvD,eAAS,gBAAgB,QAAQ,QAAQS,GACzCR,EAAgB,SAASQ,CAAU;AAAA,IACrC;AAAA,EACF;AAEA,SAAAI,EAAU,OACR,OAAO,iBAAiB,WAAWF,CAAa,GACzC,MAAM,OAAO,oBAAoB,WAAWA,CAAa,IAC/D,CAAA,CAAE,GAEE;AAAA,IACL,OAAAP;AAAA,IACA,UAAU,CAACU,MAAiB;AAC1B,mBAAa,QAAQd,GAAiBc,CAAK,GAC3Cb,EAAgB,SAAS,KAAKA,CAAe,EAAEa,CAAK,GACpD,SAAS,gBAAgB,QAAQ,QAAQA;AAAA,IAC3C;AAAA,EAAA;AAEJ;"}