@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.
- package/README.md +3 -3
- package/dist/esm/api/hooks/analytics.mjs +6 -5
- package/dist/esm/api/hooks/analytics.mjs.map +1 -1
- package/dist/esm/api/index.mjs +2 -2
- package/dist/esm/api/useAuth/useOAuth2.mjs.map +1 -1
- package/dist/esm/api/useIntlayerAPI.mjs +1 -3
- package/dist/esm/api/useIntlayerAPI.mjs.map +1 -1
- package/dist/esm/api/useUser/index.mjs +1 -1
- package/dist/esm/components/Accordion/Accordion.mjs +2 -2
- package/dist/esm/components/Accordion/Accordion.mjs.map +1 -1
- package/dist/esm/components/Carousel/index.mjs +48 -30
- package/dist/esm/components/Carousel/index.mjs.map +1 -1
- package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs +1 -1
- package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs.map +1 -1
- package/dist/esm/components/Form/elements/OTPElement.mjs +4 -4
- package/dist/esm/components/Form/elements/OTPElement.mjs.map +1 -1
- package/dist/esm/components/Link/Link.mjs +10 -5
- package/dist/esm/components/Link/Link.mjs.map +1 -1
- package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +1 -1
- package/dist/esm/components/Modal/Modal.mjs +2 -2
- package/dist/esm/components/Navbar/MobileNavbar.mjs +25 -3
- package/dist/esm/components/Navbar/MobileNavbar.mjs.map +1 -1
- package/dist/esm/components/Pagination/Pagination.mjs +4 -4
- package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
- package/dist/esm/components/Pattern/GridDistortionPattern.mjs +3 -2
- package/dist/esm/components/Pattern/GridDistortionPattern.mjs.map +1 -1
- package/dist/esm/components/Popover/dynamic.mjs +68 -24
- package/dist/esm/components/Popover/dynamic.mjs.map +1 -1
- package/dist/esm/components/RightDrawer/RightDrawer.mjs +34 -10
- package/dist/esm/components/RightDrawer/RightDrawer.mjs.map +1 -1
- package/dist/esm/components/RightDrawer/index.mjs +2 -2
- package/dist/esm/components/RightDrawer/useRightDrawer.mjs +37 -5
- package/dist/esm/components/RightDrawer/useRightDrawer.mjs.map +1 -1
- package/dist/esm/components/SwitchSelector/useSwitchSelector.mjs +2 -2
- package/dist/esm/components/SwitchSelector/useSwitchSelector.mjs.map +1 -1
- package/dist/esm/components/Tab/Tab.mjs +21 -4
- package/dist/esm/components/Tab/Tab.mjs.map +1 -1
- package/dist/esm/components/TabSelector/TabSelector.mjs +2 -2
- package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
- package/dist/esm/components/TechLogo/TechLogo.mjs +1 -0
- package/dist/esm/components/TechLogo/TechLogo.mjs.map +1 -1
- package/dist/esm/components/TechLogo/logos/Elysia.mjs +62 -0
- package/dist/esm/components/TechLogo/logos/Elysia.mjs.map +1 -0
- package/dist/esm/components/TechLogo/techLogos.mjs +3 -1
- package/dist/esm/components/TechLogo/techLogos.mjs.map +1 -1
- package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs +10 -18
- package/dist/esm/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.mjs.map +1 -1
- package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs +14 -13
- package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs.map +1 -1
- package/dist/esm/components/index.mjs +2 -2
- package/dist/esm/hooks/index.mjs +9 -9
- package/dist/esm/hooks/useItemSelector.mjs +12 -9
- package/dist/esm/hooks/useItemSelector.mjs.map +1 -1
- package/dist/esm/hooks/useScrollBlockage/index.mjs +9 -10
- package/dist/esm/hooks/useScrollBlockage/index.mjs.map +1 -1
- package/dist/esm/hooks/useScrollDetection.mjs +15 -2
- package/dist/esm/hooks/useScrollDetection.mjs.map +1 -1
- package/dist/esm/hooks/useScrollY.mjs +64 -45
- package/dist/esm/hooks/useScrollY.mjs.map +1 -1
- package/dist/esm/hooks/useStickToBottom.mjs +69 -0
- package/dist/esm/hooks/useStickToBottom.mjs.map +1 -0
- package/dist/esm/providers/ThemeProvider.mjs +143 -0
- package/dist/esm/providers/ThemeProvider.mjs.map +1 -0
- package/dist/esm/providers/index.mjs +2 -1
- package/dist/esm/routes.mjs +4 -1
- package/dist/esm/routes.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +3 -1
- package/dist/esm/utils/observeScrollExtent.mjs +39 -0
- package/dist/esm/utils/observeScrollExtent.mjs.map +1 -0
- package/dist/esm/utils/scheduleFrameTask.mjs +44 -0
- package/dist/esm/utils/scheduleFrameTask.mjs.map +1 -0
- package/dist/types/api/hooks/analytics.d.ts +5 -3
- package/dist/types/api/hooks/analytics.d.ts.map +1 -1
- package/dist/types/api/useIntlayerAPI.d.ts +12 -0
- package/dist/types/api/useIntlayerAPI.d.ts.map +1 -1
- package/dist/types/components/Carousel/index.d.ts.map +1 -1
- package/dist/types/components/Navbar/MobileNavbar.d.ts.map +1 -1
- package/dist/types/components/Popover/dynamic.d.ts.map +1 -1
- package/dist/types/components/RightDrawer/RightDrawer.d.ts.map +1 -1
- package/dist/types/components/RightDrawer/index.d.ts +2 -2
- package/dist/types/components/RightDrawer/useRightDrawer.d.ts +34 -1
- package/dist/types/components/RightDrawer/useRightDrawer.d.ts.map +1 -1
- package/dist/types/components/Tab/Tab.d.ts.map +1 -1
- package/dist/types/components/TechLogo/TechLogo.d.ts.map +1 -1
- package/dist/types/components/TechLogo/logos/Elysia.d.ts +6 -0
- package/dist/types/components/TechLogo/logos/Elysia.d.ts.map +1 -0
- package/dist/types/components/TechLogo/techLogos.d.ts +3 -2
- package/dist/types/components/TechLogo/types.d.ts +1 -1
- package/dist/types/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.d.ts +1 -1
- package/dist/types/components/ThemeSwitcherDropDown/DesktopThemeSwitcher.d.ts.map +1 -1
- package/dist/types/components/ThemeSwitcherDropDown/MobileThemeSwitcher.d.ts +1 -1
- package/dist/types/components/ThemeSwitcherDropDown/MobileThemeSwitcher.d.ts.map +1 -1
- package/dist/types/components/ThemeSwitcherDropDown/types.d.ts +3 -1
- package/dist/types/components/ThemeSwitcherDropDown/types.d.ts.map +1 -1
- package/dist/types/components/index.d.ts +2 -2
- package/dist/types/hooks/index.d.ts +2 -2
- package/dist/types/hooks/useItemSelector.d.ts +2 -0
- package/dist/types/hooks/useItemSelector.d.ts.map +1 -1
- package/dist/types/hooks/useScrollBlockage/index.d.ts.map +1 -1
- package/dist/types/hooks/useScrollDetection.d.ts.map +1 -1
- package/dist/types/hooks/useScrollY.d.ts +10 -0
- package/dist/types/hooks/useScrollY.d.ts.map +1 -1
- package/dist/types/hooks/useStickToBottom.d.ts +41 -0
- package/dist/types/hooks/useStickToBottom.d.ts.map +1 -0
- package/dist/types/providers/ThemeProvider.d.ts +41 -0
- package/dist/types/providers/ThemeProvider.d.ts.map +1 -0
- package/dist/types/providers/index.d.ts +2 -1
- package/dist/types/routes.d.ts +4 -1
- package/dist/types/routes.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +3 -1
- package/dist/types/utils/observeScrollExtent.d.ts +22 -0
- package/dist/types/utils/observeScrollExtent.d.ts.map +1 -0
- package/dist/types/utils/scheduleFrameTask.d.ts +25 -0
- package/dist/types/utils/scheduleFrameTask.d.ts.map +1 -0
- package/package.json +24 -24
- package/dist/esm/hooks/useIsDarkMode.mjs +0 -17
- package/dist/esm/hooks/useIsDarkMode.mjs.map +0 -1
- package/dist/types/hooks/useIsDarkMode.d.ts +0 -5
- 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 {
|
|
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
|
-
|
|
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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 {
|
|
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 };
|
package/dist/esm/routes.mjs
CHANGED
|
@@ -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
|