@intlayer/design-system 9.3.3 → 9.4.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.
Files changed (119) hide show
  1. package/README.md +3 -3
  2. package/dist/esm/api/hooks/analytics.mjs +6 -5
  3. package/dist/esm/api/hooks/analytics.mjs.map +1 -1
  4. package/dist/esm/api/index.mjs +2 -2
  5. package/dist/esm/api/useAuth/useOAuth2.mjs.map +1 -1
  6. package/dist/esm/api/useIntlayerAPI.mjs +1 -3
  7. package/dist/esm/api/useIntlayerAPI.mjs.map +1 -1
  8. package/dist/esm/api/useUser/index.mjs +1 -1
  9. package/dist/esm/components/Accordion/Accordion.mjs +2 -2
  10. package/dist/esm/components/Accordion/Accordion.mjs.map +1 -1
  11. package/dist/esm/components/Carousel/index.mjs +48 -30
  12. package/dist/esm/components/Carousel/index.mjs.map +1 -1
  13. package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs +1 -1
  14. package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs.map +1 -1
  15. package/dist/esm/components/Form/elements/OTPElement.mjs +4 -4
  16. package/dist/esm/components/Form/elements/OTPElement.mjs.map +1 -1
  17. package/dist/esm/components/Link/Link.mjs +10 -5
  18. package/dist/esm/components/Link/Link.mjs.map +1 -1
  19. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +1 -1
  20. package/dist/esm/components/Modal/Modal.mjs +2 -2
  21. package/dist/esm/components/Navbar/MobileNavbar.mjs +25 -3
  22. package/dist/esm/components/Navbar/MobileNavbar.mjs.map +1 -1
  23. package/dist/esm/components/Pagination/Pagination.mjs +4 -4
  24. package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
  25. package/dist/esm/components/Pattern/GridDistortionPattern.mjs +3 -2
  26. package/dist/esm/components/Pattern/GridDistortionPattern.mjs.map +1 -1
  27. package/dist/esm/components/Popover/dynamic.mjs +68 -24
  28. package/dist/esm/components/Popover/dynamic.mjs.map +1 -1
  29. package/dist/esm/components/RightDrawer/RightDrawer.mjs +34 -10
  30. package/dist/esm/components/RightDrawer/RightDrawer.mjs.map +1 -1
  31. package/dist/esm/components/RightDrawer/index.mjs +2 -2
  32. package/dist/esm/components/RightDrawer/useRightDrawer.mjs +37 -5
  33. package/dist/esm/components/RightDrawer/useRightDrawer.mjs.map +1 -1
  34. package/dist/esm/components/SwitchSelector/useSwitchSelector.mjs +2 -2
  35. package/dist/esm/components/SwitchSelector/useSwitchSelector.mjs.map +1 -1
  36. package/dist/esm/components/Tab/Tab.mjs +21 -4
  37. package/dist/esm/components/Tab/Tab.mjs.map +1 -1
  38. package/dist/esm/components/TabSelector/TabSelector.mjs +2 -2
  39. package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
  40. package/dist/esm/components/TechLogo/TechLogo.mjs +1 -0
  41. package/dist/esm/components/TechLogo/TechLogo.mjs.map +1 -1
  42. package/dist/esm/components/TechLogo/logos/Elysia.mjs +62 -0
  43. package/dist/esm/components/TechLogo/logos/Elysia.mjs.map +1 -0
  44. package/dist/esm/components/TechLogo/techLogos.mjs +3 -1
  45. package/dist/esm/components/TechLogo/techLogos.mjs.map +1 -1
  46. package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs +10 -18
  47. package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs.map +1 -1
  48. package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs +14 -13
  49. package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs.map +1 -1
  50. package/dist/esm/components/index.mjs +2 -2
  51. package/dist/esm/hooks/index.mjs +9 -9
  52. package/dist/esm/hooks/useItemSelector.mjs +12 -9
  53. package/dist/esm/hooks/useItemSelector.mjs.map +1 -1
  54. package/dist/esm/hooks/useScrollBlockage/index.mjs +9 -10
  55. package/dist/esm/hooks/useScrollBlockage/index.mjs.map +1 -1
  56. package/dist/esm/hooks/useScrollDetection.mjs +15 -2
  57. package/dist/esm/hooks/useScrollDetection.mjs.map +1 -1
  58. package/dist/esm/hooks/useScrollY.mjs +64 -45
  59. package/dist/esm/hooks/useScrollY.mjs.map +1 -1
  60. package/dist/esm/hooks/useStickToBottom.mjs +69 -0
  61. package/dist/esm/hooks/useStickToBottom.mjs.map +1 -0
  62. package/dist/esm/providers/ThemeProvider.mjs +143 -0
  63. package/dist/esm/providers/ThemeProvider.mjs.map +1 -0
  64. package/dist/esm/providers/index.mjs +2 -1
  65. package/dist/esm/routes.mjs +4 -1
  66. package/dist/esm/routes.mjs.map +1 -1
  67. package/dist/esm/utils/index.mjs +3 -1
  68. package/dist/esm/utils/observeScrollExtent.mjs +39 -0
  69. package/dist/esm/utils/observeScrollExtent.mjs.map +1 -0
  70. package/dist/esm/utils/scheduleFrameTask.mjs +44 -0
  71. package/dist/esm/utils/scheduleFrameTask.mjs.map +1 -0
  72. package/dist/types/api/hooks/analytics.d.ts +5 -3
  73. package/dist/types/api/hooks/analytics.d.ts.map +1 -1
  74. package/dist/types/api/useIntlayerAPI.d.ts +12 -0
  75. package/dist/types/api/useIntlayerAPI.d.ts.map +1 -1
  76. package/dist/types/components/Carousel/index.d.ts.map +1 -1
  77. package/dist/types/components/Navbar/MobileNavbar.d.ts.map +1 -1
  78. package/dist/types/components/Popover/dynamic.d.ts.map +1 -1
  79. package/dist/types/components/RightDrawer/RightDrawer.d.ts.map +1 -1
  80. package/dist/types/components/RightDrawer/index.d.ts +2 -2
  81. package/dist/types/components/RightDrawer/useRightDrawer.d.ts +34 -1
  82. package/dist/types/components/RightDrawer/useRightDrawer.d.ts.map +1 -1
  83. package/dist/types/components/Tab/Tab.d.ts.map +1 -1
  84. package/dist/types/components/TechLogo/TechLogo.d.ts.map +1 -1
  85. package/dist/types/components/TechLogo/logos/Elysia.d.ts +6 -0
  86. package/dist/types/components/TechLogo/logos/Elysia.d.ts.map +1 -0
  87. package/dist/types/components/TechLogo/techLogos.d.ts +3 -2
  88. package/dist/types/components/TechLogo/types.d.ts +1 -1
  89. package/dist/types/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.d.ts +1 -1
  90. package/dist/types/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.d.ts.map +1 -1
  91. package/dist/types/components/ThemeSwitcherDropDown/MobileThemeSwitcher.d.ts +1 -1
  92. package/dist/types/components/ThemeSwitcherDropDown/MobileThemeSwitcher.d.ts.map +1 -1
  93. package/dist/types/components/ThemeSwitcherDropDown/types.d.ts +3 -1
  94. package/dist/types/components/ThemeSwitcherDropDown/types.d.ts.map +1 -1
  95. package/dist/types/components/index.d.ts +2 -2
  96. package/dist/types/hooks/index.d.ts +2 -2
  97. package/dist/types/hooks/useItemSelector.d.ts +2 -0
  98. package/dist/types/hooks/useItemSelector.d.ts.map +1 -1
  99. package/dist/types/hooks/useScrollBlockage/index.d.ts.map +1 -1
  100. package/dist/types/hooks/useScrollDetection.d.ts.map +1 -1
  101. package/dist/types/hooks/useScrollY.d.ts +10 -0
  102. package/dist/types/hooks/useScrollY.d.ts.map +1 -1
  103. package/dist/types/hooks/useStickToBottom.d.ts +41 -0
  104. package/dist/types/hooks/useStickToBottom.d.ts.map +1 -0
  105. package/dist/types/providers/ThemeProvider.d.ts +41 -0
  106. package/dist/types/providers/ThemeProvider.d.ts.map +1 -0
  107. package/dist/types/providers/index.d.ts +2 -1
  108. package/dist/types/routes.d.ts +4 -1
  109. package/dist/types/routes.d.ts.map +1 -1
  110. package/dist/types/utils/index.d.ts +3 -1
  111. package/dist/types/utils/observeScrollExtent.d.ts +22 -0
  112. package/dist/types/utils/observeScrollExtent.d.ts.map +1 -0
  113. package/dist/types/utils/scheduleFrameTask.d.ts +25 -0
  114. package/dist/types/utils/scheduleFrameTask.d.ts.map +1 -0
  115. package/package.json +24 -24
  116. package/dist/esm/hooks/useIsDarkMode.mjs +0 -17
  117. package/dist/esm/hooks/useIsDarkMode.mjs.map +0 -1
  118. package/dist/types/hooks/useIsDarkMode.d.ts +0 -5
  119. package/dist/types/hooks/useIsDarkMode.d.ts.map +0 -1
@@ -1,7 +1,9 @@
1
1
  'use client';
2
2
 
3
+ import { observeScrollExtent } from "../utils/observeScrollExtent.mjs";
4
+ import { scheduleFrameTask } from "../utils/scheduleFrameTask.mjs";
3
5
  import { useGetElementOrWindow } from "./useGetElementOrWindow.mjs";
4
- import { useCallback, useSyncExternalStore } from "react";
6
+ import { useEffect, useState } from "react";
5
7
 
6
8
  //#region src/hooks/useScrollY.ts
7
9
  const INITIAL_SCROLL_STATE = {
@@ -9,59 +11,76 @@ const INITIAL_SCROLL_STATE = {
9
11
  scrollPercentage: 0,
10
12
  scrollYMax: 0
11
13
  };
12
- let lastSnapshot = INITIAL_SCROLL_STATE;
14
+ /**
15
+ * Tracks the vertical scroll of an element — or of the page — as a position and
16
+ * a 0-to-1 progress.
17
+ *
18
+ * @param props.element - Scrollable element. Defaults to the document.
19
+ * @returns The current offset, its maximum, and the ratio between the two.
20
+ *
21
+ * @example
22
+ * const { scrollPercentage } = useScrollY({ element: contentElement });
23
+ */
13
24
  const useScrollY = (props) => {
14
25
  const { element } = props ?? {};
15
26
  const containerElement = useGetElementOrWindow(element);
16
- const subscribe = useCallback((onChange) => {
17
- if (typeof window === "undefined" || !containerElement) return () => {};
18
- let raf = 0;
19
- const handler = () => {
20
- if (raf) return;
21
- raf = window.requestAnimationFrame(() => {
22
- raf = 0;
23
- onChange();
24
- });
25
- };
26
- containerElement.addEventListener("scroll", handler, { passive: true });
27
- return () => {
28
- containerElement.removeEventListener("scroll", handler);
29
- if (raf) window.cancelAnimationFrame(raf);
27
+ const [scrollState, setScrollState] = useState(INITIAL_SCROLL_STATE);
28
+ useEffect(() => {
29
+ if (typeof window === "undefined" || !containerElement) return;
30
+ const isElementScroll = containerElement instanceof HTMLElement;
31
+ /**
32
+ * Travel available to the scroll, cached between layout changes.
33
+ *
34
+ * `scrollHeight` and `clientHeight` both flush pending layout, so reading
35
+ * them on every scroll frame would recompute the whole page while the user
36
+ * scrolls. Only `scrollTop` is read per frame; the rest is refreshed when
37
+ * the content or the viewport actually resizes.
38
+ */
39
+ let scrollYMax = 0;
40
+ const measureScrollRange = () => {
41
+ const scrollHeight = isElementScroll ? containerElement.scrollHeight : document.documentElement?.scrollHeight ?? document.body?.scrollHeight ?? 0;
42
+ const clientHeight = isElementScroll ? containerElement.clientHeight : document.documentElement?.clientHeight ?? window.innerHeight ?? 0;
43
+ scrollYMax = Math.max(0, scrollHeight - clientHeight);
30
44
  };
31
- }, [containerElement]);
32
- const getSnapshot = () => {
33
- if (typeof window === "undefined" || !containerElement) return INITIAL_SCROLL_STATE;
34
- if (containerElement instanceof HTMLElement) {
35
- const scrollY = containerElement.scrollTop;
36
- const scrollHeight = containerElement.scrollHeight;
37
- const clientHeight = containerElement.clientHeight;
38
- const scrollYMax = Math.max(0, scrollHeight - clientHeight);
45
+ const updateScrollState = () => {
46
+ const scrollY = isElementScroll ? containerElement.scrollTop : window.scrollY ?? document.documentElement?.scrollTop ?? 0;
39
47
  const scrollPercentage = scrollYMax > 0 ? scrollY / scrollYMax : 0;
40
- if (lastSnapshot.scrollY === scrollY && lastSnapshot.scrollPercentage === scrollPercentage && lastSnapshot.scrollYMax === scrollYMax) return lastSnapshot;
41
- lastSnapshot = {
48
+ setScrollState((previousState) => previousState.scrollY === scrollY && previousState.scrollPercentage === scrollPercentage && previousState.scrollYMax === scrollYMax ? previousState : {
42
49
  scrollY,
43
50
  scrollPercentage,
44
51
  scrollYMax
45
- };
46
- return lastSnapshot;
47
- }
48
- const doc = document.documentElement;
49
- const body = document.body;
50
- const scrollY = window.scrollY ?? window.pageYOffset ?? doc?.scrollTop ?? body?.scrollTop ?? 0;
51
- const scrollHeight = doc?.scrollHeight ?? body?.scrollHeight ?? 0;
52
- const clientHeight = doc?.clientHeight ?? window.innerHeight ?? 0;
53
- const scrollYMax = Math.max(0, scrollHeight - clientHeight);
54
- const scrollPercentage = scrollYMax > 0 ? scrollY / scrollYMax : 0;
55
- if (lastSnapshot.scrollY === scrollY && lastSnapshot.scrollPercentage === scrollPercentage && lastSnapshot.scrollYMax === scrollYMax) return lastSnapshot;
56
- lastSnapshot = {
57
- scrollY,
58
- scrollPercentage,
59
- scrollYMax
52
+ });
53
+ };
54
+ let cancelScheduledRead = null;
55
+ const scheduleScrollRead = () => {
56
+ if (cancelScheduledRead) return;
57
+ cancelScheduledRead = scheduleFrameTask(() => {
58
+ cancelScheduledRead = null;
59
+ updateScrollState();
60
+ });
61
+ };
62
+ let cancelScheduledRangeRead = null;
63
+ const scheduleRangeRead = () => {
64
+ if (cancelScheduledRangeRead) return;
65
+ cancelScheduledRangeRead = scheduleFrameTask(() => {
66
+ cancelScheduledRangeRead = null;
67
+ measureScrollRange();
68
+ updateScrollState();
69
+ });
60
70
  };
61
- return lastSnapshot;
62
- };
63
- const getServerSnapshot = () => INITIAL_SCROLL_STATE;
64
- return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
71
+ scheduleRangeRead();
72
+ const stopObservingScrollExtent = observeScrollExtent(isElementScroll ? containerElement : document.documentElement, scheduleRangeRead);
73
+ containerElement.addEventListener("scroll", scheduleScrollRead, { passive: true });
74
+ window.addEventListener("resize", scheduleRangeRead, { passive: true });
75
+ return () => {
76
+ cancelScheduledRead?.();
77
+ cancelScheduledRangeRead?.();
78
+ stopObservingScrollExtent();
79
+ containerElement.removeEventListener("scroll", scheduleScrollRead);
80
+ window.removeEventListener("resize", scheduleRangeRead);
81
+ };
82
+ }, [containerElement]);
83
+ return scrollState;
65
84
  };
66
85
 
67
86
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollY.mjs","names":[],"sources":["../../../src/hooks/useScrollY.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { useGetElementOrWindow } from './useGetElementOrWindow';\n\ntype UseScrollYProps = {\n element?: HTMLElement;\n};\n\ntype UseScrollYResult = {\n scrollY: number;\n scrollPercentage: number;\n scrollYMax: number;\n};\n\nconst INITIAL_SCROLL_STATE: UseScrollYResult = {\n scrollY: 0,\n scrollPercentage: 0,\n scrollYMax: 0,\n};\n\nlet lastSnapshot: UseScrollYResult = INITIAL_SCROLL_STATE;\n\nexport const useScrollY = (props?: UseScrollYProps): UseScrollYResult => {\n const { element } = props ?? {};\n\n const containerElement = useGetElementOrWindow(element);\n\n const subscribe = useCallback(\n (onChange: () => void) => {\n if (typeof window === 'undefined' || !containerElement) return () => {};\n let raf = 0;\n\n const handler = () => {\n if (raf) return;\n raf = window.requestAnimationFrame(() => {\n raf = 0;\n onChange();\n });\n };\n\n containerElement.addEventListener('scroll', handler, { passive: true });\n\n return () => {\n containerElement.removeEventListener('scroll', handler);\n if (raf) window.cancelAnimationFrame(raf);\n };\n },\n [containerElement]\n );\n\n const getSnapshot = (): UseScrollYResult => {\n if (typeof window === 'undefined' || !containerElement) {\n return INITIAL_SCROLL_STATE; // SSR/hydration-safe\n }\n\n // Handle custom element\n if (containerElement instanceof HTMLElement) {\n const scrollY = containerElement.scrollTop;\n const scrollHeight = containerElement.scrollHeight;\n const clientHeight = containerElement.clientHeight;\n const scrollYMax = Math.max(0, scrollHeight - clientHeight);\n const scrollPercentage = scrollYMax > 0 ? scrollY / scrollYMax : 0;\n\n if (\n lastSnapshot.scrollY === scrollY &&\n lastSnapshot.scrollPercentage === scrollPercentage &&\n lastSnapshot.scrollYMax === scrollYMax\n ) {\n return lastSnapshot;\n }\n\n lastSnapshot = { scrollY, scrollPercentage, scrollYMax };\n return lastSnapshot;\n }\n\n // Handle window\n const doc = document.documentElement;\n const body = document.body;\n\n const scrollY =\n window.scrollY ??\n window.pageYOffset ??\n doc?.scrollTop ??\n body?.scrollTop ??\n 0;\n\n const scrollHeight = doc?.scrollHeight ?? body?.scrollHeight ?? 0;\n const clientHeight = doc?.clientHeight ?? window.innerHeight ?? 0;\n const scrollYMax = Math.max(0, scrollHeight - clientHeight);\n const scrollPercentage = scrollYMax > 0 ? scrollY / scrollYMax : 0;\n\n if (\n lastSnapshot.scrollY === scrollY &&\n lastSnapshot.scrollPercentage === scrollPercentage &&\n lastSnapshot.scrollYMax === scrollYMax\n ) {\n return lastSnapshot;\n }\n\n lastSnapshot = { scrollY, scrollPercentage, scrollYMax };\n return lastSnapshot;\n };\n\n const getServerSnapshot = (): UseScrollYResult => INITIAL_SCROLL_STATE;\n\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n};\n"],"mappings":";;;;;;AAeA,MAAM,uBAAyC;CAC7C,SAAS;CACT,kBAAkB;CAClB,YAAY;AACd;AAEA,IAAI,eAAiC;AAErC,MAAa,cAAc,UAA8C;CACvE,MAAM,EAAE,YAAY,SAAS,CAAC;CAE9B,MAAM,mBAAmB,sBAAsB,OAAO;CAEtD,MAAM,YAAY,aACf,aAAyB;EACxB,IAAI,OAAO,WAAW,eAAe,CAAC,kBAAkB,aAAa,CAAC;EACtE,IAAI,MAAM;EAEV,MAAM,gBAAgB;GACpB,IAAI,KAAK;GACT,MAAM,OAAO,4BAA4B;IACvC,MAAM;IACN,SAAS;GACX,CAAC;EACH;EAEA,iBAAiB,iBAAiB,UAAU,SAAS,EAAE,SAAS,KAAK,CAAC;EAEtE,aAAa;GACX,iBAAiB,oBAAoB,UAAU,OAAO;GACtD,IAAI,KAAK,OAAO,qBAAqB,GAAG;EAC1C;CACF,GACA,CAAC,gBAAgB,CACnB;CAEA,MAAM,oBAAsC;EAC1C,IAAI,OAAO,WAAW,eAAe,CAAC,kBACpC,OAAO;EAIT,IAAI,4BAA4B,aAAa;GAC3C,MAAM,UAAU,iBAAiB;GACjC,MAAM,eAAe,iBAAiB;GACtC,MAAM,eAAe,iBAAiB;GACtC,MAAM,aAAa,KAAK,IAAI,GAAG,eAAe,YAAY;GAC1D,MAAM,mBAAmB,aAAa,IAAI,UAAU,aAAa;GAEjE,IACE,aAAa,YAAY,WACzB,aAAa,qBAAqB,oBAClC,aAAa,eAAe,YAE5B,OAAO;GAGT,eAAe;IAAE;IAAS;IAAkB;GAAW;GACvD,OAAO;EACT;EAGA,MAAM,MAAM,SAAS;EACrB,MAAM,OAAO,SAAS;EAEtB,MAAM,UACJ,OAAO,WACP,OAAO,eACP,KAAK,aACL,MAAM,aACN;EAEF,MAAM,eAAe,KAAK,gBAAgB,MAAM,gBAAgB;EAChE,MAAM,eAAe,KAAK,gBAAgB,OAAO,eAAe;EAChE,MAAM,aAAa,KAAK,IAAI,GAAG,eAAe,YAAY;EAC1D,MAAM,mBAAmB,aAAa,IAAI,UAAU,aAAa;EAEjE,IACE,aAAa,YAAY,WACzB,aAAa,qBAAqB,oBAClC,aAAa,eAAe,YAE5B,OAAO;EAGT,eAAe;GAAE;GAAS;GAAkB;EAAW;EACvD,OAAO;CACT;CAEA,MAAM,0BAA4C;CAElD,OAAO,qBAAqB,WAAW,aAAa,iBAAiB;AACvE"}
1
+ {"version":3,"file":"useScrollY.mjs","names":[],"sources":["../../../src/hooks/useScrollY.ts"],"sourcesContent":["'use client';\n\nimport { observeScrollExtent } from '@utils/observeScrollExtent';\nimport { scheduleFrameTask } from '@utils/scheduleFrameTask';\nimport { useEffect, useState } from 'react';\nimport { useGetElementOrWindow } from './useGetElementOrWindow';\n\ntype UseScrollYProps = {\n element?: HTMLElement;\n};\n\ntype UseScrollYResult = {\n scrollY: number;\n scrollPercentage: number;\n scrollYMax: number;\n};\n\nconst INITIAL_SCROLL_STATE: UseScrollYResult = {\n scrollY: 0,\n scrollPercentage: 0,\n scrollYMax: 0,\n};\n\n/**\n * Tracks the vertical scroll of an element — or of the page — as a position and\n * a 0-to-1 progress.\n *\n * @param props.element - Scrollable element. Defaults to the document.\n * @returns The current offset, its maximum, and the ratio between the two.\n *\n * @example\n * const { scrollPercentage } = useScrollY({ element: contentElement });\n */\nexport const useScrollY = (props?: UseScrollYProps): UseScrollYResult => {\n const { element } = props ?? {};\n const containerElement = useGetElementOrWindow(element);\n const [scrollState, setScrollState] =\n useState<UseScrollYResult>(INITIAL_SCROLL_STATE);\n\n useEffect(() => {\n if (typeof window === 'undefined' || !containerElement) return;\n\n const isElementScroll = containerElement instanceof HTMLElement;\n\n /**\n * Travel available to the scroll, cached between layout changes.\n *\n * `scrollHeight` and `clientHeight` both flush pending layout, so reading\n * them on every scroll frame would recompute the whole page while the user\n * scrolls. Only `scrollTop` is read per frame; the rest is refreshed when\n * the content or the viewport actually resizes.\n */\n let scrollYMax = 0;\n\n const measureScrollRange = () => {\n const scrollHeight = isElementScroll\n ? containerElement.scrollHeight\n : (document.documentElement?.scrollHeight ??\n document.body?.scrollHeight ??\n 0);\n\n const clientHeight = isElementScroll\n ? containerElement.clientHeight\n : (document.documentElement?.clientHeight ?? window.innerHeight ?? 0);\n\n scrollYMax = Math.max(0, scrollHeight - clientHeight);\n };\n\n const updateScrollState = () => {\n const scrollY = isElementScroll\n ? containerElement.scrollTop\n : (window.scrollY ?? document.documentElement?.scrollTop ?? 0);\n\n const scrollPercentage = scrollYMax > 0 ? scrollY / scrollYMax : 0;\n\n setScrollState((previousState) =>\n previousState.scrollY === scrollY &&\n previousState.scrollPercentage === scrollPercentage &&\n previousState.scrollYMax === scrollYMax\n ? previousState\n : { scrollY, scrollPercentage, scrollYMax }\n );\n };\n\n let cancelScheduledRead: (() => void) | null = null;\n\n const scheduleScrollRead = () => {\n if (cancelScheduledRead) return;\n\n cancelScheduledRead = scheduleFrameTask(() => {\n cancelScheduledRead = null;\n updateScrollState();\n });\n };\n\n let cancelScheduledRangeRead: (() => void) | null = null;\n\n const scheduleRangeRead = () => {\n if (cancelScheduledRangeRead) return;\n\n cancelScheduledRangeRead = scheduleFrameTask(() => {\n cancelScheduledRangeRead = null;\n measureScrollRange();\n updateScrollState();\n });\n };\n\n // Initial measurement, deferred so that it shares the frame of every other\n // measurement the page schedules while mounting.\n scheduleRangeRead();\n\n const stopObservingScrollExtent = observeScrollExtent(\n isElementScroll ? containerElement : document.documentElement,\n scheduleRangeRead\n );\n\n containerElement.addEventListener('scroll', scheduleScrollRead, {\n passive: true,\n });\n window.addEventListener('resize', scheduleRangeRead, { passive: true });\n\n return () => {\n cancelScheduledRead?.();\n cancelScheduledRangeRead?.();\n stopObservingScrollExtent();\n containerElement.removeEventListener('scroll', scheduleScrollRead);\n window.removeEventListener('resize', scheduleRangeRead);\n };\n }, [containerElement]);\n\n return scrollState;\n};\n"],"mappings":";;;;;;;;AAiBA,MAAM,uBAAyC;CAC7C,SAAS;CACT,kBAAkB;CAClB,YAAY;AACd;;;;;;;;;;;AAYA,MAAa,cAAc,UAA8C;CACvE,MAAM,EAAE,YAAY,SAAS,CAAC;CAC9B,MAAM,mBAAmB,sBAAsB,OAAO;CACtD,MAAM,CAAC,aAAa,kBAClB,SAA2B,oBAAoB;CAEjD,gBAAgB;EACd,IAAI,OAAO,WAAW,eAAe,CAAC,kBAAkB;EAExD,MAAM,kBAAkB,4BAA4B;;;;;;;;;EAUpD,IAAI,aAAa;EAEjB,MAAM,2BAA2B;GAC/B,MAAM,eAAe,kBACjB,iBAAiB,eAChB,SAAS,iBAAiB,gBAC3B,SAAS,MAAM,gBACf;GAEJ,MAAM,eAAe,kBACjB,iBAAiB,eAChB,SAAS,iBAAiB,gBAAgB,OAAO,eAAe;GAErE,aAAa,KAAK,IAAI,GAAG,eAAe,YAAY;EACtD;EAEA,MAAM,0BAA0B;GAC9B,MAAM,UAAU,kBACZ,iBAAiB,YAChB,OAAO,WAAW,SAAS,iBAAiB,aAAa;GAE9D,MAAM,mBAAmB,aAAa,IAAI,UAAU,aAAa;GAEjE,gBAAgB,kBACd,cAAc,YAAY,WAC1B,cAAc,qBAAqB,oBACnC,cAAc,eAAe,aACzB,gBACA;IAAE;IAAS;IAAkB;GAAW,CAC9C;EACF;EAEA,IAAI,sBAA2C;EAE/C,MAAM,2BAA2B;GAC/B,IAAI,qBAAqB;GAEzB,sBAAsB,wBAAwB;IAC5C,sBAAsB;IACtB,kBAAkB;GACpB,CAAC;EACH;EAEA,IAAI,2BAAgD;EAEpD,MAAM,0BAA0B;GAC9B,IAAI,0BAA0B;GAE9B,2BAA2B,wBAAwB;IACjD,2BAA2B;IAC3B,mBAAmB;IACnB,kBAAkB;GACpB,CAAC;EACH;EAIA,kBAAkB;EAElB,MAAM,4BAA4B,oBAChC,kBAAkB,mBAAmB,SAAS,iBAC9C,iBACF;EAEA,iBAAiB,iBAAiB,UAAU,oBAAoB,EAC9D,SAAS,KACX,CAAC;EACD,OAAO,iBAAiB,UAAU,mBAAmB,EAAE,SAAS,KAAK,CAAC;EAEtE,aAAa;GACX,sBAAsB;GACtB,2BAA2B;GAC3B,0BAA0B;GAC1B,iBAAiB,oBAAoB,UAAU,kBAAkB;GACjE,OAAO,oBAAoB,UAAU,iBAAiB;EACxD;CACF,GAAG,CAAC,gBAAgB,CAAC;CAErB,OAAO;AACT"}
@@ -0,0 +1,69 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useEffect, useRef } from "react";
4
+
5
+ //#region src/hooks/useStickToBottom.ts
6
+ /**
7
+ * Distance from the bottom, in pixels, under which the list still counts as
8
+ * pinned. Sub-pixel scroll positions and zoom levels never land exactly on the
9
+ * bottom, so an exact comparison would unpin a list the user never moved.
10
+ */
11
+ const PIN_THRESHOLD = 32;
12
+ /**
13
+ * Keeps a scrolling container pinned to its bottom edge as its content grows,
14
+ * and releases the pin as soon as the user scrolls away from the bottom.
15
+ *
16
+ * Growth is detected with a `ResizeObserver` rather than from a render effect,
17
+ * so a message streaming in token by token follows without the component
18
+ * having to describe what changed. Both the read and the write happen inside
19
+ * the observer callback, which the browser runs once layout is already
20
+ * computed — neither forces a reflow, unlike measuring the same container from
21
+ * an effect that has just committed new nodes.
22
+ *
23
+ * @returns The refs to attach to the container and to its content wrapper.
24
+ *
25
+ * @example
26
+ * const { scrollRef, contentRef } = useStickToBottom<HTMLDivElement, HTMLUListElement>();
27
+ *
28
+ * return (
29
+ * <div ref={scrollRef} className="overflow-auto">
30
+ * <ul ref={contentRef}>{items}</ul>
31
+ * </div>
32
+ * );
33
+ */
34
+ const useStickToBottom = () => {
35
+ const scrollRef = useRef(null);
36
+ const contentRef = useRef(null);
37
+ const isPinnedRef = useRef(true);
38
+ useEffect(() => {
39
+ const scrollElement = scrollRef.current;
40
+ const contentElement = contentRef.current;
41
+ if (!scrollElement || !contentElement) return;
42
+ const getDistanceFromBottom = () => scrollElement.scrollHeight - scrollElement.scrollTop - scrollElement.clientHeight;
43
+ const handleScroll = () => {
44
+ isPinnedRef.current = getDistanceFromBottom() <= PIN_THRESHOLD;
45
+ };
46
+ const resizeObserver = new ResizeObserver(() => {
47
+ if (!isPinnedRef.current) return;
48
+ if (getDistanceFromBottom() <= 0) return;
49
+ scrollElement.scrollTop = scrollElement.scrollHeight - scrollElement.clientHeight;
50
+ });
51
+ resizeObserver.observe(contentElement);
52
+ scrollElement.addEventListener("scroll", handleScroll, { passive: true });
53
+ return () => {
54
+ resizeObserver.disconnect();
55
+ scrollElement.removeEventListener("scroll", handleScroll);
56
+ };
57
+ }, []);
58
+ return {
59
+ scrollRef,
60
+ contentRef,
61
+ unpin: useCallback(() => {
62
+ isPinnedRef.current = false;
63
+ }, [])
64
+ };
65
+ };
66
+
67
+ //#endregion
68
+ export { useStickToBottom };
69
+ //# sourceMappingURL=useStickToBottom.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStickToBottom.mjs","names":[],"sources":["../../../src/hooks/useStickToBottom.ts"],"sourcesContent":["'use client';\n\nimport { type RefObject, useCallback, useEffect, useRef } from 'react';\n\n/**\n * Distance from the bottom, in pixels, under which the list still counts as\n * pinned. Sub-pixel scroll positions and zoom levels never land exactly on the\n * bottom, so an exact comparison would unpin a list the user never moved.\n */\nconst PIN_THRESHOLD = 32;\n\nexport type StickToBottomRefs<\n ScrollElement extends HTMLElement,\n ContentElement extends HTMLElement,\n> = {\n /** Attach to the scrolling container. */\n scrollRef: RefObject<ScrollElement | null>;\n /** Attach to the element wrapping the items, whose growth triggers the follow. */\n contentRef: RefObject<ContentElement | null>;\n /**\n * Releases the pin until the user scrolls back down to the bottom.\n *\n * Call it before growing the content upwards — prepending older items to a\n * pinned list would otherwise scroll straight past what was just revealed.\n */\n unpin: () => void;\n};\n\n/**\n * Keeps a scrolling container pinned to its bottom edge as its content grows,\n * and releases the pin as soon as the user scrolls away from the bottom.\n *\n * Growth is detected with a `ResizeObserver` rather than from a render effect,\n * so a message streaming in token by token follows without the component\n * having to describe what changed. Both the read and the write happen inside\n * the observer callback, which the browser runs once layout is already\n * computed — neither forces a reflow, unlike measuring the same container from\n * an effect that has just committed new nodes.\n *\n * @returns The refs to attach to the container and to its content wrapper.\n *\n * @example\n * const { scrollRef, contentRef } = useStickToBottom<HTMLDivElement, HTMLUListElement>();\n *\n * return (\n * <div ref={scrollRef} className=\"overflow-auto\">\n * <ul ref={contentRef}>{items}</ul>\n * </div>\n * );\n */\nexport const useStickToBottom = <\n ScrollElement extends HTMLElement,\n ContentElement extends HTMLElement,\n>(): StickToBottomRefs<ScrollElement, ContentElement> => {\n const scrollRef = useRef<ScrollElement>(null);\n const contentRef = useRef<ContentElement>(null);\n const isPinnedRef = useRef(true);\n\n useEffect(() => {\n const scrollElement = scrollRef.current;\n const contentElement = contentRef.current;\n\n if (!scrollElement || !contentElement) return;\n\n const getDistanceFromBottom = () =>\n scrollElement.scrollHeight -\n scrollElement.scrollTop -\n scrollElement.clientHeight;\n\n /*\n * Scroll events are dispatched after the browser has laid the page out, so\n * reading the geometry here is free — deferring it to an animation frame\n * would move the read *before* the next layout and force one instead.\n */\n const handleScroll = () => {\n isPinnedRef.current = getDistanceFromBottom() <= PIN_THRESHOLD;\n };\n\n const resizeObserver = new ResizeObserver(() => {\n if (!isPinnedRef.current) return;\n if (getDistanceFromBottom() <= 0) return;\n\n // Jumping rather than animating: a streamed answer resizes on nearly\n // every frame, and a smooth scroll restarted that often never reaches\n // the bottom.\n scrollElement.scrollTop =\n scrollElement.scrollHeight - scrollElement.clientHeight;\n });\n\n resizeObserver.observe(contentElement);\n scrollElement.addEventListener('scroll', handleScroll, { passive: true });\n\n return () => {\n resizeObserver.disconnect();\n scrollElement.removeEventListener('scroll', handleScroll);\n };\n }, []);\n\n const unpin = useCallback(() => {\n isPinnedRef.current = false;\n }, []);\n\n return { scrollRef, contentRef, unpin };\n};\n"],"mappings":";;;;;;;;;;AASA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;AAyCtB,MAAa,yBAG4C;CACvD,MAAM,YAAY,OAAsB,IAAI;CAC5C,MAAM,aAAa,OAAuB,IAAI;CAC9C,MAAM,cAAc,OAAO,IAAI;CAE/B,gBAAgB;EACd,MAAM,gBAAgB,UAAU;EAChC,MAAM,iBAAiB,WAAW;EAElC,IAAI,CAAC,iBAAiB,CAAC,gBAAgB;EAEvC,MAAM,8BACJ,cAAc,eACd,cAAc,YACd,cAAc;EAOhB,MAAM,qBAAqB;GACzB,YAAY,UAAU,sBAAsB,KAAK;EACnD;EAEA,MAAM,iBAAiB,IAAI,qBAAqB;GAC9C,IAAI,CAAC,YAAY,SAAS;GAC1B,IAAI,sBAAsB,KAAK,GAAG;GAKlC,cAAc,YACZ,cAAc,eAAe,cAAc;EAC/C,CAAC;EAED,eAAe,QAAQ,cAAc;EACrC,cAAc,iBAAiB,UAAU,cAAc,EAAE,SAAS,KAAK,CAAC;EAExE,aAAa;GACX,eAAe,WAAW;GAC1B,cAAc,oBAAoB,UAAU,YAAY;EAC1D;CACF,GAAG,CAAC,CAAC;CAML,OAAO;EAAE;EAAW;EAAY,OAJlB,kBAAkB;GAC9B,YAAY,UAAU;EACxB,GAAG,CAAC,CAEgC;CAAE;AACxC"}
@@ -0,0 +1,143 @@
1
+ 'use client';
2
+
3
+ import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
4
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
+
6
+ //#region src/providers/ThemeProvider.tsx
7
+ /** Attribute mirrored on `<html>`; the Tailwind dark variant keys on it. */
8
+ const THEME_ATTRIBUTE = "data-theme";
9
+ /** Media query resolving the OS colour scheme. */
10
+ const DARK_MEDIA_QUERY = "(prefers-color-scheme: dark)";
11
+ const isServer = typeof window === "undefined";
12
+ /**
13
+ * Inline bootstrap applying the persisted theme before the first paint.
14
+ *
15
+ * Serialized through `Function.prototype.toString()` and injected as an inline
16
+ * `<script>`, so it must stay self-contained: no import, no module-scope
17
+ * binding, no reference the bundler could rewrite into a helper call. Every
18
+ * value it needs is passed as an argument.
19
+ */
20
+ const themeScript = (storageKey, themeAttribute, darkMediaQuery) => {
21
+ let storedTheme = null;
22
+ try {
23
+ storedTheme = localStorage.getItem(storageKey);
24
+ } catch {}
25
+ const theme = storedTheme === "light" || storedTheme === "dark" ? storedTheme : window.matchMedia(darkMediaQuery).matches ? "dark" : "light";
26
+ const element = document.documentElement;
27
+ element.setAttribute(themeAttribute, theme);
28
+ element.style.colorScheme = theme;
29
+ };
30
+ /** Serializes the bootstrap and its arguments into inline script source. */
31
+ const buildBootstrap = (storageKey) => `(${themeScript})(${JSON.stringify(storageKey)},${JSON.stringify(THEME_ATTRIBUTE)},${JSON.stringify(DARK_MEDIA_QUERY)})`;
32
+ /** Reads the persisted preference, discarding unknown values. */
33
+ const getStoredTheme = (storageKey) => {
34
+ try {
35
+ const storedTheme = localStorage.getItem(storageKey);
36
+ if (storedTheme === "light" || storedTheme === "dark" || storedTheme === "system") return storedTheme;
37
+ } catch {}
38
+ return "system";
39
+ };
40
+ /**
41
+ * Suppresses CSS transitions while the theme attribute flips, so every themed
42
+ * element repaints at once instead of animating between palettes.
43
+ *
44
+ * @returns Callback restoring transitions, to call once the theme is applied.
45
+ */
46
+ const suppressTransitions = (nonce) => {
47
+ const style = document.createElement("style");
48
+ if (nonce) style.setAttribute("nonce", nonce);
49
+ style.appendChild(document.createTextNode("*,*::before,*::after{transition:none!important}"));
50
+ document.head.appendChild(style);
51
+ return () => {
52
+ getComputedStyle(document.body).getPropertyValue("transition");
53
+ style.remove();
54
+ };
55
+ };
56
+ const useIsomorphicLayoutEffect = isServer ? useEffect : useLayoutEffect;
57
+ const ThemeContext = createContext(void 0);
58
+ /** Served outside of a provider, so consumers render light instead of crashing. */
59
+ const fallbackThemeContext = {
60
+ theme: "system",
61
+ resolvedTheme: void 0,
62
+ setTheme: () => void 0
63
+ };
64
+ /**
65
+ * Reads and updates the current theme.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * const { resolvedTheme, setTheme } = useTheme();
70
+ * ```
71
+ */
72
+ const useTheme = () => useContext(ThemeContext) ?? fallbackThemeContext;
73
+ const Theme = ({ storageKey = "theme", nonce, children }) => {
74
+ const [theme, setThemeState] = useState("system");
75
+ const [systemTheme, setSystemTheme] = useState(void 0);
76
+ const resolvedTheme = theme === "system" ? systemTheme : theme;
77
+ useIsomorphicLayoutEffect(() => {
78
+ const media = window.matchMedia(DARK_MEDIA_QUERY);
79
+ setThemeState(getStoredTheme(storageKey));
80
+ setSystemTheme(media.matches ? "dark" : "light");
81
+ const handleSystemChange = (event) => setSystemTheme(event.matches ? "dark" : "light");
82
+ const handleStorageChange = (event) => {
83
+ if (event.key !== storageKey) return;
84
+ setThemeState(getStoredTheme(storageKey));
85
+ };
86
+ media.addEventListener("change", handleSystemChange);
87
+ window.addEventListener("storage", handleStorageChange);
88
+ return () => {
89
+ media.removeEventListener("change", handleSystemChange);
90
+ window.removeEventListener("storage", handleStorageChange);
91
+ };
92
+ }, [storageKey]);
93
+ useIsomorphicLayoutEffect(() => {
94
+ if (!resolvedTheme) return;
95
+ const element = document.documentElement;
96
+ if (element.getAttribute(THEME_ATTRIBUTE) === resolvedTheme) return;
97
+ const restoreTransitions = suppressTransitions(nonce);
98
+ element.setAttribute(THEME_ATTRIBUTE, resolvedTheme);
99
+ element.style.colorScheme = resolvedTheme;
100
+ restoreTransitions();
101
+ }, [resolvedTheme, nonce]);
102
+ const setTheme = useCallback((nextTheme) => {
103
+ setThemeState(nextTheme);
104
+ try {
105
+ localStorage.setItem(storageKey, nextTheme);
106
+ } catch {}
107
+ }, [storageKey]);
108
+ const value = useMemo(() => ({
109
+ theme,
110
+ resolvedTheme,
111
+ setTheme
112
+ }), [
113
+ theme,
114
+ resolvedTheme,
115
+ setTheme
116
+ ]);
117
+ return /* @__PURE__ */ jsxs(ThemeContext.Provider, {
118
+ value,
119
+ children: [/* @__PURE__ */ jsx("script", {
120
+ nonce: isServer ? nonce : "",
121
+ dangerouslySetInnerHTML: { __html: buildBootstrap(storageKey) }
122
+ }), children]
123
+ });
124
+ };
125
+ /**
126
+ * Applies the persisted theme to `<html>` before the first paint, keeps it in
127
+ * sync with the OS preference and with the other tabs, and exposes it through
128
+ * {@link useTheme}.
129
+ *
130
+ * Nested providers pass through, so a layout can mount one without fighting an
131
+ * outer provider over the `<html>` attribute.
132
+ */
133
+ const ThemeProvider = ({ children, ...props }) => {
134
+ if (useContext(ThemeContext)) return /* @__PURE__ */ jsx(Fragment$1, { children });
135
+ return /* @__PURE__ */ jsx(Theme, {
136
+ ...props,
137
+ children
138
+ });
139
+ };
140
+
141
+ //#endregion
142
+ export { ThemeProvider, useTheme };
143
+ //# sourceMappingURL=ThemeProvider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.mjs","names":[],"sources":["../../../src/providers/ThemeProvider.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n type FC,\n type PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useState,\n} from 'react';\n\n/** Theme actually painted — the OS preference once `system` is resolved. */\nexport type ResolvedTheme = 'light' | 'dark';\n\n/** Theme stored as the user preference. `system` follows the OS setting. */\nexport type Theme = ResolvedTheme | 'system';\n\n/** Attribute mirrored on `<html>`; the Tailwind dark variant keys on it. */\nconst THEME_ATTRIBUTE = 'data-theme';\n\n/** Media query resolving the OS colour scheme. */\nconst DARK_MEDIA_QUERY = '(prefers-color-scheme: dark)';\n\nconst isServer = typeof window === 'undefined';\n\n/**\n * Inline bootstrap applying the persisted theme before the first paint.\n *\n * Serialized through `Function.prototype.toString()` and injected as an inline\n * `<script>`, so it must stay self-contained: no import, no module-scope\n * binding, no reference the bundler could rewrite into a helper call. Every\n * value it needs is passed as an argument.\n */\nconst themeScript = (\n storageKey: string,\n themeAttribute: string,\n darkMediaQuery: string\n): void => {\n let storedTheme: string | null = null;\n\n try {\n storedTheme = localStorage.getItem(storageKey);\n } catch {\n // Storage can throw (private mode, blocked cookies) — fall back to the OS.\n }\n\n const theme =\n storedTheme === 'light' || storedTheme === 'dark'\n ? storedTheme\n : window.matchMedia(darkMediaQuery).matches\n ? 'dark'\n : 'light';\n\n const element = document.documentElement;\n\n element.setAttribute(themeAttribute, theme);\n element.style.colorScheme = theme;\n};\n\n/** Serializes the bootstrap and its arguments into inline script source. */\nconst buildBootstrap = (storageKey: string): string =>\n `(${themeScript})(${JSON.stringify(storageKey)},${JSON.stringify(THEME_ATTRIBUTE)},${JSON.stringify(DARK_MEDIA_QUERY)})`;\n\n/** Reads the persisted preference, discarding unknown values. */\nconst getStoredTheme = (storageKey: string): Theme => {\n try {\n const storedTheme = localStorage.getItem(storageKey);\n\n if (\n storedTheme === 'light' ||\n storedTheme === 'dark' ||\n storedTheme === 'system'\n ) {\n return storedTheme;\n }\n } catch {\n // Storage can throw (private mode, blocked cookies).\n }\n\n return 'system';\n};\n\n/**\n * Suppresses CSS transitions while the theme attribute flips, so every themed\n * element repaints at once instead of animating between palettes.\n *\n * @returns Callback restoring transitions, to call once the theme is applied.\n */\nconst suppressTransitions = (nonce?: string): (() => void) => {\n const style = document.createElement('style');\n\n if (nonce) style.setAttribute('nonce', nonce);\n\n style.appendChild(\n document.createTextNode('*,*::before,*::after{transition:none!important}')\n );\n document.head.appendChild(style);\n\n return () => {\n // Reading a computed value forces a synchronous style recalculation, so\n // the new theme is committed while transitions are still suppressed.\n getComputedStyle(document.body).getPropertyValue('transition');\n style.remove();\n };\n};\n\nconst useIsomorphicLayoutEffect = isServer ? useEffect : useLayoutEffect;\n\ntype ThemeContextValue = {\n /** Persisted preference — `system` while following the OS. */\n theme: Theme;\n /** Theme applied to `<html>`. `undefined` until the client resolves it. */\n resolvedTheme: ResolvedTheme | undefined;\n /** Persists a preference and applies it. */\n setTheme: (theme: Theme) => void;\n};\n\nconst ThemeContext = createContext<ThemeContextValue | undefined>(undefined);\n\n/** Served outside of a provider, so consumers render light instead of crashing. */\nconst fallbackThemeContext: ThemeContextValue = {\n theme: 'system',\n resolvedTheme: undefined,\n setTheme: () => undefined,\n};\n\n/**\n * Reads and updates the current theme.\n *\n * @example\n * ```tsx\n * const { resolvedTheme, setTheme } = useTheme();\n * ```\n */\nexport const useTheme = (): ThemeContextValue =>\n useContext(ThemeContext) ?? fallbackThemeContext;\n\nexport type ThemeProviderProps = {\n /** `localStorage` key holding the preference. Defaults to `theme`. */\n storageKey?: string;\n /** CSP nonce, required when the page forbids unsafe inline scripts. */\n nonce?: string;\n};\n\nconst Theme: FC<PropsWithChildren<ThemeProviderProps>> = ({\n storageKey = 'theme',\n nonce,\n children,\n}) => {\n // Both the server render and the first client one start from `system`, so\n // the hydrated markup matches; the browser state is read back before paint.\n const [theme, setThemeState] = useState<Theme>('system');\n const [systemTheme, setSystemTheme] = useState<ResolvedTheme | undefined>(\n undefined\n );\n\n const resolvedTheme = theme === 'system' ? systemTheme : theme;\n\n // Read the browser state back before the first paint, then keep following\n // the OS preference and the other tabs.\n useIsomorphicLayoutEffect(() => {\n const media = window.matchMedia(DARK_MEDIA_QUERY);\n\n setThemeState(getStoredTheme(storageKey));\n setSystemTheme(media.matches ? 'dark' : 'light');\n\n const handleSystemChange = (event: MediaQueryListEvent) =>\n setSystemTheme(event.matches ? 'dark' : 'light');\n\n const handleStorageChange = (event: StorageEvent) => {\n if (event.key !== storageKey) return;\n\n setThemeState(getStoredTheme(storageKey));\n };\n\n media.addEventListener('change', handleSystemChange);\n window.addEventListener('storage', handleStorageChange);\n\n return () => {\n media.removeEventListener('change', handleSystemChange);\n window.removeEventListener('storage', handleStorageChange);\n };\n }, [storageKey]);\n\n // Mirror the resolved theme onto `<html>`.\n useIsomorphicLayoutEffect(() => {\n if (!resolvedTheme) return;\n\n const element = document.documentElement;\n\n // The inline bootstrap already applied it on the initial load.\n if (element.getAttribute(THEME_ATTRIBUTE) === resolvedTheme) return;\n\n const restoreTransitions = suppressTransitions(nonce);\n\n element.setAttribute(THEME_ATTRIBUTE, resolvedTheme);\n element.style.colorScheme = resolvedTheme;\n\n restoreTransitions();\n }, [resolvedTheme, nonce]);\n\n const setTheme = useCallback(\n (nextTheme: Theme) => {\n setThemeState(nextTheme);\n\n try {\n localStorage.setItem(storageKey, nextTheme);\n } catch {\n // Storage can throw — the choice then only lasts for this page.\n }\n },\n [storageKey]\n );\n\n const value = useMemo<ThemeContextValue>(\n () => ({ theme, resolvedTheme, setTheme }),\n [theme, resolvedTheme, setTheme]\n );\n\n return (\n <ThemeContext.Provider value={value}>\n <script\n // Browsers hide the nonce value from the DOM API, so echoing it while\n // hydrating would mismatch the server markup.\n nonce={isServer ? nonce : ''}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: the bootstrap has to run before hydration, and its content is built from literals\n dangerouslySetInnerHTML={{ __html: buildBootstrap(storageKey) }}\n />\n {children}\n </ThemeContext.Provider>\n );\n};\n\n/**\n * Applies the persisted theme to `<html>` before the first paint, keeps it in\n * sync with the OS preference and with the other tabs, and exposes it through\n * {@link useTheme}.\n *\n * Nested providers pass through, so a layout can mount one without fighting an\n * outer provider over the `<html>` attribute.\n */\nexport const ThemeProvider: FC<PropsWithChildren<ThemeProviderProps>> = ({\n children,\n ...props\n}) => {\n const parentTheme = useContext(ThemeContext);\n\n if (parentTheme) return <>{children}</>;\n\n return <Theme {...props}>{children}</Theme>;\n};\n"],"mappings":";;;;;;;AAqBA,MAAM,kBAAkB;;AAGxB,MAAM,mBAAmB;AAEzB,MAAM,WAAW,OAAO,WAAW;;;;;;;;;AAUnC,MAAM,eACJ,YACA,gBACA,mBACS;CACT,IAAI,cAA6B;CAEjC,IAAI;EACF,cAAc,aAAa,QAAQ,UAAU;CAC/C,QAAQ,CAER;CAEA,MAAM,QACJ,gBAAgB,WAAW,gBAAgB,SACvC,cACA,OAAO,WAAW,cAAc,CAAC,CAAC,UAChC,SACA;CAER,MAAM,UAAU,SAAS;CAEzB,QAAQ,aAAa,gBAAgB,KAAK;CAC1C,QAAQ,MAAM,cAAc;AAC9B;;AAGA,MAAM,kBAAkB,eACtB,IAAI,YAAY,IAAI,KAAK,UAAU,UAAU,EAAE,GAAG,KAAK,UAAU,eAAe,EAAE,GAAG,KAAK,UAAU,gBAAgB,EAAE;;AAGxH,MAAM,kBAAkB,eAA8B;CACpD,IAAI;EACF,MAAM,cAAc,aAAa,QAAQ,UAAU;EAEnD,IACE,gBAAgB,WAChB,gBAAgB,UAChB,gBAAgB,UAEhB,OAAO;CAEX,QAAQ,CAER;CAEA,OAAO;AACT;;;;;;;AAQA,MAAM,uBAAuB,UAAiC;CAC5D,MAAM,QAAQ,SAAS,cAAc,OAAO;CAE5C,IAAI,OAAO,MAAM,aAAa,SAAS,KAAK;CAE5C,MAAM,YACJ,SAAS,eAAe,iDAAiD,CAC3E;CACA,SAAS,KAAK,YAAY,KAAK;CAE/B,aAAa;EAGX,iBAAiB,SAAS,IAAI,CAAC,CAAC,iBAAiB,YAAY;EAC7D,MAAM,OAAO;CACf;AACF;AAEA,MAAM,4BAA4B,WAAW,YAAY;AAWzD,MAAM,eAAe,cAA6C,MAAS;;AAG3E,MAAM,uBAA0C;CAC9C,OAAO;CACP,eAAe;CACf,gBAAgB;AAClB;;;;;;;;;AAUA,MAAa,iBACX,WAAW,YAAY,KAAK;AAS9B,MAAM,SAAoD,EACxD,aAAa,SACb,OACA,eACI;CAGJ,MAAM,CAAC,OAAO,iBAAiB,SAAgB,QAAQ;CACvD,MAAM,CAAC,aAAa,kBAAkB,SACpC,MACF;CAEA,MAAM,gBAAgB,UAAU,WAAW,cAAc;CAIzD,gCAAgC;EAC9B,MAAM,QAAQ,OAAO,WAAW,gBAAgB;EAEhD,cAAc,eAAe,UAAU,CAAC;EACxC,eAAe,MAAM,UAAU,SAAS,OAAO;EAE/C,MAAM,sBAAsB,UAC1B,eAAe,MAAM,UAAU,SAAS,OAAO;EAEjD,MAAM,uBAAuB,UAAwB;GACnD,IAAI,MAAM,QAAQ,YAAY;GAE9B,cAAc,eAAe,UAAU,CAAC;EAC1C;EAEA,MAAM,iBAAiB,UAAU,kBAAkB;EACnD,OAAO,iBAAiB,WAAW,mBAAmB;EAEtD,aAAa;GACX,MAAM,oBAAoB,UAAU,kBAAkB;GACtD,OAAO,oBAAoB,WAAW,mBAAmB;EAC3D;CACF,GAAG,CAAC,UAAU,CAAC;CAGf,gCAAgC;EAC9B,IAAI,CAAC,eAAe;EAEpB,MAAM,UAAU,SAAS;EAGzB,IAAI,QAAQ,aAAa,eAAe,MAAM,eAAe;EAE7D,MAAM,qBAAqB,oBAAoB,KAAK;EAEpD,QAAQ,aAAa,iBAAiB,aAAa;EACnD,QAAQ,MAAM,cAAc;EAE5B,mBAAmB;CACrB,GAAG,CAAC,eAAe,KAAK,CAAC;CAEzB,MAAM,WAAW,aACd,cAAqB;EACpB,cAAc,SAAS;EAEvB,IAAI;GACF,aAAa,QAAQ,YAAY,SAAS;EAC5C,QAAQ,CAER;CACF,GACA,CAAC,UAAU,CACb;CAEA,MAAM,QAAQ,eACL;EAAE;EAAO;EAAe;CAAS,IACxC;EAAC;EAAO;EAAe;CAAQ,CACjC;CAEA,OACE,qBAAC,aAAa,UAAd;EAA8B;YAA9B,CACE,oBAAC,UAAD;GAGE,OAAO,WAAW,QAAQ;GAE1B,yBAAyB,EAAE,QAAQ,eAAe,UAAU,EAAE;EAC/D,IACA,QACoB;;AAE3B;;;;;;;;;AAUA,MAAa,iBAA4D,EACvE,UACA,GAAG,YACC;CAGJ,IAFoB,WAAW,YAEjB,GAAG,OAAO,kCAAG,SAAW;CAEtC,OAAO,oBAAC,OAAD;EAAO,GAAI;EAAQ;CAAgB;AAC5C"}
@@ -1,5 +1,6 @@
1
1
  import { DeferredAuthProvider, useIsAuthFetchEnabled } from "./DeferredAuthProvider.mjs";
2
+ import { ThemeProvider, useTheme } from "./ThemeProvider.mjs";
2
3
  import { ReactQueryProvider, getQueryClient } from "./ReactQueryProvider.mjs";
3
4
  import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
4
5
 
5
- export { DeferredAuthProvider, ReactQueryDevtools, ReactQueryProvider, getQueryClient, useIsAuthFetchEnabled };
6
+ export { DeferredAuthProvider, ReactQueryDevtools, ReactQueryProvider, ThemeProvider, getQueryClient, useIsAuthFetchEnabled, useTheme };
@@ -27,6 +27,8 @@ const App_ReviewerMarketplace_Reviewer_Path = "/find-reviewer/$reviewerId";
27
27
  const App_ReviewerMarketplace_Dashboard_Mission_Path = "/find-reviewer/dashboard/mission/$missionId";
28
28
  const getAppReviewerProfileRoute = (reviewerId) => `/find-reviewer/${reviewerId}`;
29
29
  const getAppReviewerMissionRoute = (missionId) => `/find-reviewer/dashboard/mission/${missionId}`;
30
+ /** Root of the authentication section, usable as a `Disallow` prefix. */
31
+ const App_Auth_Path = "/auth";
30
32
  const App_Auth_SignIn_Path = "/auth/login";
31
33
  const App_Auth_SignUp_Path = "/auth/register";
32
34
  const App_Auth_TwoFactor_Path = "/auth/2fa";
@@ -274,6 +276,7 @@ const Backend_OAuth2_Token = `https://${Backend_Domain}/oauth2/token`;
274
276
  const Mcp_Root = `https://${Mcp_Domain}`;
275
277
  const Mcp_Sse = `https://${Mcp_Domain}/sse`;
276
278
  const WellKnown_ApiCatalog_Path = "/.well-known/api-catalog";
279
+ const WellKnown_AiCatalog_Path = "/.well-known/ai-catalog.json";
277
280
  const WellKnown_OAuthProtectedResource_Path = "/.well-known/oauth-protected-resource";
278
281
  const WellKnown_OAuthAuthorizationServer_Path = "/.well-known/oauth-authorization-server";
279
282
  const WellKnown_McpServerCard_Path = "/.well-known/mcp/server-card.json";
@@ -300,5 +303,5 @@ const External_ExampleIntlayerWithReactNative = "https://github.com/aymericzip/i
300
303
  const External_ExampleIntlayerWithExpress = "https://github.com/aymericzip/intlayer/tree/main/examples/express-app";
301
304
 
302
305
  //#endregion
303
- export { App_Admin, App_Admin_Affiliate, App_Admin_Affiliate_Path, App_Admin_Dashboard, App_Admin_Dashboard_Path, App_Admin_Discussions, App_Admin_Discussions_Path, App_Admin_Management, App_Admin_Management_Path, App_Admin_Organizations, App_Admin_Organizations_Path, App_Admin_Path, App_Admin_Projects, App_Admin_Projects_Path, App_Admin_PromoCodes, App_Admin_PromoCodes_Path, App_Admin_Reviewers, App_Admin_Reviewers_Path, App_Admin_Users, App_Admin_Users_Path, App_Affiliation, App_Affiliation_Path, App_Auth_AskResetPassword, App_Auth_AskResetPassword_Path, App_Auth_ChangePassword, App_Auth_ChangePassword_Path, App_Auth_Demo_Path, App_Auth_ResetPassword, App_Auth_ResetPassword_Path, App_Auth_SignIn, App_Auth_SignIn_Path, App_Auth_SignUp, App_Auth_SignUp_Path, App_Auth_TwoFactor, App_Auth_TwoFactor_Path, App_Dashboard, App_Dashboard_Analytics, App_Dashboard_Analytics_Path, App_Dashboard_Assets_Path, App_Dashboard_Dictionaries, App_Dashboard_Dictionaries_Path, App_Dashboard_Editor, App_Dashboard_Editor_Path, App_Dashboard_IDE, App_Dashboard_IDE_Path, App_Dashboard_Organization, App_Dashboard_Organization_Path, App_Dashboard_Profile, App_Dashboard_Profile_Path, App_Dashboard_Projects, App_Dashboard_Projects_Path, App_Dashboard_Scanner, App_Dashboard_Scanner_Path, App_Dashboard_Tags, App_Dashboard_Tags_Path, App_Dashboard_Translate, App_Dashboard_Translate_Path, App_Demo, App_Demo_Path, App_Domain, App_Home_Path, App_Init_Path, App_NotFound_Path, App_Onboarding, App_Onboarding_Path, App_Pricing, App_Pricing_Path, App_ReviewerMarketplace, App_ReviewerMarketplace_Dashboard, App_ReviewerMarketplace_Dashboard_Mission_Path, App_ReviewerMarketplace_Dashboard_Path, App_ReviewerMarketplace_Path, App_ReviewerMarketplace_Reviewer_Path, AuthMd_Path, Backend_Domain, Backend_Health, Backend_OAuth2_Token, Backend_Root, Doc_Blog_Path, Doc_Blog_Root_Path, Doc_Blog_Search_Path, Doc_Blog_What_is_i18n_Path, Doc_CLI_Fill_Path, Doc_CLI_Review_Path, Doc_CLI_Translate_Path, Doc_Chat_Path, Doc_Contributors_Path, Doc_Environment_Adonis_Path, Doc_Environment_Angular_Path, Doc_Environment_Astro_Path, Doc_Environment_CRA_Path, Doc_Environment_Express_Path, Doc_Environment_Fastify_Path, Doc_Environment_Hono_Path, Doc_Environment_Lit_Path, Doc_Environment_Lynx_Path, Doc_Environment_NestJS_Path, Doc_Environment_NextJS_14_Path, Doc_Environment_NextJS_15_Path, Doc_Environment_NextJS_16_Path, Doc_Environment_NextJS_Path, Doc_Environment_Nodejs_Path, Doc_Environment_NuxtAndVue_Path, Doc_Environment_ReactNativeAndExpo_Path, Doc_Environment_Tanstack_Path, Doc_Environment_ViteAndPreact_Path, Doc_Environment_ViteAndReact_Path, Doc_Environment_ViteAndReact_ReactRouterV7_FSRoutes_Path, Doc_Environment_ViteAndReact_ReactRouterV7_Path, Doc_Environment_ViteAndSolid_Path, Doc_Environment_ViteAndSvelte_Path, Doc_Environment_ViteAndVue_Path, Doc_FrequentQuestions_Path, Doc_IntlayerCMS_Path, Doc_IntlayerVisualEditor_Path, Doc_Intlayer_with_Lynx_and_React_Path, Doc_MCP_Path, Doc_Path, Doc_PrivacyPolicy_Path, Doc_ReleasesV6_Path, Doc_ReleasesV7_Path, Doc_ReleasesV8_Path, Doc_Root_Path, Doc_Search_Path, Doc_ShowcaseSubmit_Path, Doc_Showcase_Path, Doc_TermsOfService_Path, Doc_Why_Path, External_AI_Landing_Page, External_Discord, External_DockerHub_SelfHost, External_ExampleIntlayerWithExpress, External_ExampleIntlayerWithNextjs, External_ExampleIntlayerWithReactJS, External_ExampleIntlayerWithReactNative, External_ExampleIntlayerWithViteAndPreact, External_ExampleIntlayerWithViteAndReact, External_ExampleIntlayerWithViteAndSolid, External_ExampleIntlayerWithViteAndSvelte, External_ExampleIntlayerWithViteAndVue, External_Examples, External_Github, External_Github_i18n_benchmark, External_LinkedIn, External_ShowcaseApp, LlmsTxt_Path, Mcp_Domain, Mcp_Root, Mcp_Sse, Showcase_Domain, Showcase_Root, Showcase_Root_Path, Showcase_Submit, Showcase_Submit_Path, Website_Benchmark, Website_Benchmark_NextJS, Website_Benchmark_NextJS_Path, Website_Benchmark_Path, Website_Benchmark_Tanstack, Website_Benchmark_Tanstack_Path, Website_Blog, Website_Blog_Path, Website_Blog_Root, Website_Blog_Root_Path, Website_Blog_Search, Website_Blog_Search_Path, Website_Blog_What_is_i18n, Website_Blog_What_is_i18n_Path, Website_CMS, Website_CMS_Path, Website_Changelog, Website_Changelog_Path, Website_Contributors, Website_Contributors_Path, Website_Demo, Website_Demo_Path, Website_Doc, Website_Doc_CLI_Fill, Website_Doc_CLI_Fill_Path, Website_Doc_CLI_Review, Website_Doc_CLI_Review_Path, Website_Doc_CLI_Translate, Website_Doc_CLI_Translate_Path, Website_Doc_Chat, Website_Doc_Chat_Path, Website_Doc_Environment_Adonis, Website_Doc_Environment_Adonis_Path, Website_Doc_Environment_Angular, Website_Doc_Environment_Angular_Path, Website_Doc_Environment_Astro, Website_Doc_Environment_Astro_Path, Website_Doc_Environment_CRA, Website_Doc_Environment_CRA_Path, Website_Doc_Environment_Express, Website_Doc_Environment_Express_Path, Website_Doc_Environment_Fastify, Website_Doc_Environment_Fastify_Path, Website_Doc_Environment_Hono, Website_Doc_Environment_Hono_Path, Website_Doc_Environment_Lit, Website_Doc_Environment_Lit_Path, Website_Doc_Environment_Lynx, Website_Doc_Environment_Lynx_Path, Website_Doc_Environment_NestJS, Website_Doc_Environment_NestJS_Path, Website_Doc_Environment_NextJS, Website_Doc_Environment_NextJS_14, Website_Doc_Environment_NextJS_14_Path, Website_Doc_Environment_NextJS_15, Website_Doc_Environment_NextJS_15_Path, Website_Doc_Environment_NextJS_16, Website_Doc_Environment_NextJS_16_Path, Website_Doc_Environment_NextJS_Path, Website_Doc_Environment_Nodejs, Website_Doc_Environment_Nodejs_Path, Website_Doc_Environment_NuxtAndVue, Website_Doc_Environment_NuxtAndVue_Path, Website_Doc_Environment_ReactNativeAndExpo, Website_Doc_Environment_ReactNativeAndExpo_Path, Website_Doc_Environment_Tanstack, Website_Doc_Environment_Tanstack_Path, Website_Doc_Environment_ViteAndPreact, Website_Doc_Environment_ViteAndPreact_Path, Website_Doc_Environment_ViteAndReact, Website_Doc_Environment_ViteAndReact_Path, Website_Doc_Environment_ViteAndReact_ReactRouterV7, Website_Doc_Environment_ViteAndReact_ReactRouterV7_FSRoutes, Website_Doc_Environment_ViteAndReact_ReactRouterV7_FSRoutes_Path, Website_Doc_Environment_ViteAndReact_ReactRouterV7_Path, Website_Doc_Environment_ViteAndSolid, Website_Doc_Environment_ViteAndSolid_Path, Website_Doc_Environment_ViteAndSvelte, Website_Doc_Environment_ViteAndSvelte_Path, Website_Doc_Environment_ViteAndVue, Website_Doc_Environment_ViteAndVue_Path, Website_Doc_IntlayerCMS, Website_Doc_IntlayerCMS_Path, Website_Doc_IntlayerVisualEditor, Website_Doc_IntlayerVisualEditor_Path, Website_Doc_Intlayer_with_Lynx_and_React, Website_Doc_Intlayer_with_Lynx_and_React_Path, Website_Doc_MCP, Website_Doc_MCP_Path, Website_Doc_Path, Website_Doc_Root, Website_Doc_Root_Path, Website_Doc_Search, Website_Doc_Search_Path, Website_Doc_SelfHosting, Website_Doc_SelfHosting_Path, Website_Doc_Why, Website_Doc_Why_Path, Website_Domain, Website_FrequentQuestions, Website_FrequentQuestions_Path, Website_Home, Website_Home_Path, Website_Markdown_Preview, Website_Markdown_Preview_Path, Website_NotFound, Website_NotFound_Path, Website_Playground, Website_Playground_Path, Website_PrivacyPolicy, Website_PrivacyPolicy_Path, Website_ReleasesV6, Website_ReleasesV6_Path, Website_ReleasesV7, Website_ReleasesV7_Path, Website_ReleasesV8, Website_ReleasesV8_Path, Website_ReleasesV9_Path, Website_Scanner, Website_Scanner_Path, Website_TMS, Website_TMS_Path, Website_TermsOfService, Website_TermsOfService_Path, Website_Translate, Website_Translate_Path, WellKnown_AgentSkillsIndex_Path, WellKnown_AgentSkills_Path, WellKnown_ApiCatalog_Path, WellKnown_McpServerCard_Path, WellKnown_OAuthAuthorizationServer_Path, WellKnown_OAuthProtectedResource_Path, getAppAdminAffiliateRoute, getAppAdminOrganizationAbsoluteRoute, getAppAdminOrganizationRoute, getAppAdminProjectAbsoluteRoute, getAppAdminProjectRoute, getAppAdminPromoCodeRoute, getAppAdminReviewerRoute, getAppAdminUserAbsoluteRoute, getAppAdminUserRoute, getAppOnboardingFlowAbsoluteRoute, getAppOnboardingFlowRoute, getAppReviewerMissionRoute, getAppReviewerProfileRoute };
306
+ export { App_Admin, App_Admin_Affiliate, App_Admin_Affiliate_Path, App_Admin_Dashboard, App_Admin_Dashboard_Path, App_Admin_Discussions, App_Admin_Discussions_Path, App_Admin_Management, App_Admin_Management_Path, App_Admin_Organizations, App_Admin_Organizations_Path, App_Admin_Path, App_Admin_Projects, App_Admin_Projects_Path, App_Admin_PromoCodes, App_Admin_PromoCodes_Path, App_Admin_Reviewers, App_Admin_Reviewers_Path, App_Admin_Users, App_Admin_Users_Path, App_Affiliation, App_Affiliation_Path, App_Auth_AskResetPassword, App_Auth_AskResetPassword_Path, App_Auth_ChangePassword, App_Auth_ChangePassword_Path, App_Auth_Demo_Path, App_Auth_Path, App_Auth_ResetPassword, App_Auth_ResetPassword_Path, App_Auth_SignIn, App_Auth_SignIn_Path, App_Auth_SignUp, App_Auth_SignUp_Path, App_Auth_TwoFactor, App_Auth_TwoFactor_Path, App_Dashboard, App_Dashboard_Analytics, App_Dashboard_Analytics_Path, App_Dashboard_Assets_Path, App_Dashboard_Dictionaries, App_Dashboard_Dictionaries_Path, App_Dashboard_Editor, App_Dashboard_Editor_Path, App_Dashboard_IDE, App_Dashboard_IDE_Path, App_Dashboard_Organization, App_Dashboard_Organization_Path, App_Dashboard_Profile, App_Dashboard_Profile_Path, App_Dashboard_Projects, App_Dashboard_Projects_Path, App_Dashboard_Scanner, App_Dashboard_Scanner_Path, App_Dashboard_Tags, App_Dashboard_Tags_Path, App_Dashboard_Translate, App_Dashboard_Translate_Path, App_Demo, App_Demo_Path, App_Domain, App_Home_Path, App_Init_Path, App_NotFound_Path, App_Onboarding, App_Onboarding_Path, App_Pricing, App_Pricing_Path, App_ReviewerMarketplace, App_ReviewerMarketplace_Dashboard, App_ReviewerMarketplace_Dashboard_Mission_Path, App_ReviewerMarketplace_Dashboard_Path, App_ReviewerMarketplace_Path, App_ReviewerMarketplace_Reviewer_Path, AuthMd_Path, Backend_Domain, Backend_Health, Backend_OAuth2_Token, Backend_Root, Doc_Blog_Path, Doc_Blog_Root_Path, Doc_Blog_Search_Path, Doc_Blog_What_is_i18n_Path, Doc_CLI_Fill_Path, Doc_CLI_Review_Path, Doc_CLI_Translate_Path, Doc_Chat_Path, Doc_Contributors_Path, Doc_Environment_Adonis_Path, Doc_Environment_Angular_Path, Doc_Environment_Astro_Path, Doc_Environment_CRA_Path, Doc_Environment_Express_Path, Doc_Environment_Fastify_Path, Doc_Environment_Hono_Path, Doc_Environment_Lit_Path, Doc_Environment_Lynx_Path, Doc_Environment_NestJS_Path, Doc_Environment_NextJS_14_Path, Doc_Environment_NextJS_15_Path, Doc_Environment_NextJS_16_Path, Doc_Environment_NextJS_Path, Doc_Environment_Nodejs_Path, Doc_Environment_NuxtAndVue_Path, Doc_Environment_ReactNativeAndExpo_Path, Doc_Environment_Tanstack_Path, Doc_Environment_ViteAndPreact_Path, Doc_Environment_ViteAndReact_Path, Doc_Environment_ViteAndReact_ReactRouterV7_FSRoutes_Path, Doc_Environment_ViteAndReact_ReactRouterV7_Path, Doc_Environment_ViteAndSolid_Path, Doc_Environment_ViteAndSvelte_Path, Doc_Environment_ViteAndVue_Path, Doc_FrequentQuestions_Path, Doc_IntlayerCMS_Path, Doc_IntlayerVisualEditor_Path, Doc_Intlayer_with_Lynx_and_React_Path, Doc_MCP_Path, Doc_Path, Doc_PrivacyPolicy_Path, Doc_ReleasesV6_Path, Doc_ReleasesV7_Path, Doc_ReleasesV8_Path, Doc_Root_Path, Doc_Search_Path, Doc_ShowcaseSubmit_Path, Doc_Showcase_Path, Doc_TermsOfService_Path, Doc_Why_Path, External_AI_Landing_Page, External_Discord, External_DockerHub_SelfHost, External_ExampleIntlayerWithExpress, External_ExampleIntlayerWithNextjs, External_ExampleIntlayerWithReactJS, External_ExampleIntlayerWithReactNative, External_ExampleIntlayerWithViteAndPreact, External_ExampleIntlayerWithViteAndReact, External_ExampleIntlayerWithViteAndSolid, External_ExampleIntlayerWithViteAndSvelte, External_ExampleIntlayerWithViteAndVue, External_Examples, External_Github, External_Github_i18n_benchmark, External_LinkedIn, External_ShowcaseApp, LlmsTxt_Path, Mcp_Domain, Mcp_Root, Mcp_Sse, Showcase_Domain, Showcase_Root, Showcase_Root_Path, Showcase_Submit, Showcase_Submit_Path, Website_Benchmark, Website_Benchmark_NextJS, Website_Benchmark_NextJS_Path, Website_Benchmark_Path, Website_Benchmark_Tanstack, Website_Benchmark_Tanstack_Path, Website_Blog, Website_Blog_Path, Website_Blog_Root, Website_Blog_Root_Path, Website_Blog_Search, Website_Blog_Search_Path, Website_Blog_What_is_i18n, Website_Blog_What_is_i18n_Path, Website_CMS, Website_CMS_Path, Website_Changelog, Website_Changelog_Path, Website_Contributors, Website_Contributors_Path, Website_Demo, Website_Demo_Path, Website_Doc, Website_Doc_CLI_Fill, Website_Doc_CLI_Fill_Path, Website_Doc_CLI_Review, Website_Doc_CLI_Review_Path, Website_Doc_CLI_Translate, Website_Doc_CLI_Translate_Path, Website_Doc_Chat, Website_Doc_Chat_Path, Website_Doc_Environment_Adonis, Website_Doc_Environment_Adonis_Path, Website_Doc_Environment_Angular, Website_Doc_Environment_Angular_Path, Website_Doc_Environment_Astro, Website_Doc_Environment_Astro_Path, Website_Doc_Environment_CRA, Website_Doc_Environment_CRA_Path, Website_Doc_Environment_Express, Website_Doc_Environment_Express_Path, Website_Doc_Environment_Fastify, Website_Doc_Environment_Fastify_Path, Website_Doc_Environment_Hono, Website_Doc_Environment_Hono_Path, Website_Doc_Environment_Lit, Website_Doc_Environment_Lit_Path, Website_Doc_Environment_Lynx, Website_Doc_Environment_Lynx_Path, Website_Doc_Environment_NestJS, Website_Doc_Environment_NestJS_Path, Website_Doc_Environment_NextJS, Website_Doc_Environment_NextJS_14, Website_Doc_Environment_NextJS_14_Path, Website_Doc_Environment_NextJS_15, Website_Doc_Environment_NextJS_15_Path, Website_Doc_Environment_NextJS_16, Website_Doc_Environment_NextJS_16_Path, Website_Doc_Environment_NextJS_Path, Website_Doc_Environment_Nodejs, Website_Doc_Environment_Nodejs_Path, Website_Doc_Environment_NuxtAndVue, Website_Doc_Environment_NuxtAndVue_Path, Website_Doc_Environment_ReactNativeAndExpo, Website_Doc_Environment_ReactNativeAndExpo_Path, Website_Doc_Environment_Tanstack, Website_Doc_Environment_Tanstack_Path, Website_Doc_Environment_ViteAndPreact, Website_Doc_Environment_ViteAndPreact_Path, Website_Doc_Environment_ViteAndReact, Website_Doc_Environment_ViteAndReact_Path, Website_Doc_Environment_ViteAndReact_ReactRouterV7, Website_Doc_Environment_ViteAndReact_ReactRouterV7_FSRoutes, Website_Doc_Environment_ViteAndReact_ReactRouterV7_FSRoutes_Path, Website_Doc_Environment_ViteAndReact_ReactRouterV7_Path, Website_Doc_Environment_ViteAndSolid, Website_Doc_Environment_ViteAndSolid_Path, Website_Doc_Environment_ViteAndSvelte, Website_Doc_Environment_ViteAndSvelte_Path, Website_Doc_Environment_ViteAndVue, Website_Doc_Environment_ViteAndVue_Path, Website_Doc_IntlayerCMS, Website_Doc_IntlayerCMS_Path, Website_Doc_IntlayerVisualEditor, Website_Doc_IntlayerVisualEditor_Path, Website_Doc_Intlayer_with_Lynx_and_React, Website_Doc_Intlayer_with_Lynx_and_React_Path, Website_Doc_MCP, Website_Doc_MCP_Path, Website_Doc_Path, Website_Doc_Root, Website_Doc_Root_Path, Website_Doc_Search, Website_Doc_Search_Path, Website_Doc_SelfHosting, Website_Doc_SelfHosting_Path, Website_Doc_Why, Website_Doc_Why_Path, Website_Domain, Website_FrequentQuestions, Website_FrequentQuestions_Path, Website_Home, Website_Home_Path, Website_Markdown_Preview, Website_Markdown_Preview_Path, Website_NotFound, Website_NotFound_Path, Website_Playground, Website_Playground_Path, Website_PrivacyPolicy, Website_PrivacyPolicy_Path, Website_ReleasesV6, Website_ReleasesV6_Path, Website_ReleasesV7, Website_ReleasesV7_Path, Website_ReleasesV8, Website_ReleasesV8_Path, Website_ReleasesV9_Path, Website_Scanner, Website_Scanner_Path, Website_TMS, Website_TMS_Path, Website_TermsOfService, Website_TermsOfService_Path, Website_Translate, Website_Translate_Path, WellKnown_AgentSkillsIndex_Path, WellKnown_AgentSkills_Path, WellKnown_AiCatalog_Path, WellKnown_ApiCatalog_Path, WellKnown_McpServerCard_Path, WellKnown_OAuthAuthorizationServer_Path, WellKnown_OAuthProtectedResource_Path, getAppAdminAffiliateRoute, getAppAdminOrganizationAbsoluteRoute, getAppAdminOrganizationRoute, getAppAdminProjectAbsoluteRoute, getAppAdminProjectRoute, getAppAdminPromoCodeRoute, getAppAdminReviewerRoute, getAppAdminUserAbsoluteRoute, getAppAdminUserRoute, getAppOnboardingFlowAbsoluteRoute, getAppOnboardingFlowRoute, getAppReviewerMissionRoute, getAppReviewerProfileRoute };
304
307
  //# sourceMappingURL=routes.mjs.map