@korioinc/next-core 2.0.32 → 2.0.35
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 +10 -1
- package/dist/components/locale-switcher/index.d.ts.map +1 -1
- package/dist/components/locale-switcher/index.js +14 -0
- package/dist/components/theme-switcher/index.js +1 -1
- package/dist/i18n/routing.client.d.ts +2 -0
- package/dist/i18n/routing.client.d.ts.map +1 -0
- package/dist/i18n/routing.client.js +7 -0
- package/dist/i18n/routing.d.ts +5 -0
- package/dist/i18n/routing.d.ts.map +1 -1
- package/dist/i18n/routing.js +54 -15
- package/dist/theme/context.d.ts +5 -0
- package/dist/theme/context.d.ts.map +1 -0
- package/dist/theme/context.js +9 -0
- package/dist/theme/index.d.ts +3 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +2 -0
- package/dist/theme/index.server.d.ts +4 -0
- package/dist/theme/index.server.d.ts.map +1 -0
- package/dist/theme/index.server.js +21 -0
- package/dist/theme/script.d.ts +2 -0
- package/dist/theme/script.d.ts.map +1 -0
- package/dist/theme/script.js +92 -0
- package/dist/theme/shared.d.ts +44 -0
- package/dist/theme/shared.d.ts.map +1 -0
- package/dist/theme/shared.js +153 -0
- package/dist/theme/store.d.ts +13 -0
- package/dist/theme/store.d.ts.map +1 -0
- package/dist/theme/store.js +47 -0
- package/dist/theme/theme-provider.client.d.ts +5 -0
- package/dist/theme/theme-provider.client.d.ts.map +1 -0
- package/dist/theme/theme-provider.client.js +130 -0
- package/dist/theme/theme-script.d.ts +3 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +22 -0
- package/dist/theme/types.d.ts +32 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +1 -0
- package/package.json +20 -11
package/README.md
CHANGED
|
@@ -49,6 +49,15 @@ export default function middleware(request: NextRequest) {
|
|
|
49
49
|
|
|
50
50
|
```typescript
|
|
51
51
|
import { ThemeSwitcher, LocaleSwitcher } from '@korioinc/next-core/components';
|
|
52
|
+
import { ThemeProvider } from '@korioinc/next-core/theme/server';
|
|
53
|
+
|
|
54
|
+
export function Layout({ children }: { children: React.ReactNode }) {
|
|
55
|
+
return (
|
|
56
|
+
<ThemeProvider attribute="class" enableSystem defaultTheme="system">
|
|
57
|
+
{children}
|
|
58
|
+
</ThemeProvider>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
52
61
|
|
|
53
62
|
export function Header() {
|
|
54
63
|
return (
|
|
@@ -87,4 +96,4 @@ MIT
|
|
|
87
96
|
|
|
88
97
|
## Contributing
|
|
89
98
|
|
|
90
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
99
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/locale-switcher/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/locale-switcher/index.tsx"],"names":[],"mappings":"AAeA,UAAU,mBAAmB;IAC3B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,SAAS,EAAE,GAAE,mBAAwB,kDAiG7E"}
|
|
@@ -7,6 +7,7 @@ import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/r
|
|
|
7
7
|
import { useLingui } from '@lingui/react';
|
|
8
8
|
import { allLanguages } from './language-options';
|
|
9
9
|
import { resolveVisibleLanguages } from './resolve-visible-languages';
|
|
10
|
+
import { setCookie } from 'cookies-next/client';
|
|
10
11
|
import linguiConfig from 'lingui.config';
|
|
11
12
|
export default function LocaleSwitcher({ languages } = {}) {
|
|
12
13
|
const router = useRouter();
|
|
@@ -16,6 +17,15 @@ export default function LocaleSwitcher({ languages } = {}) {
|
|
|
16
17
|
useEffect(() => {
|
|
17
18
|
setMounted(true);
|
|
18
19
|
}, []);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!mounted || !i18n.locale) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
setCookie('NEXT_LOCALE', i18n.locale, {
|
|
25
|
+
path: '/',
|
|
26
|
+
sameSite: 'lax',
|
|
27
|
+
});
|
|
28
|
+
}, [mounted, i18n.locale]);
|
|
19
29
|
const availableLanguages = resolveVisibleLanguages({
|
|
20
30
|
allLanguages,
|
|
21
31
|
defaultLanguageCodes: linguiConfig.locales,
|
|
@@ -30,6 +40,10 @@ export default function LocaleSwitcher({ languages } = {}) {
|
|
|
30
40
|
const changeLanguage = (nextLocale) => {
|
|
31
41
|
const currentLocale = i18n.locale;
|
|
32
42
|
const newPath = getChangeLocalePath(pathname, currentLocale, nextLocale);
|
|
43
|
+
setCookie('NEXT_LOCALE', nextLocale, {
|
|
44
|
+
path: '/',
|
|
45
|
+
sameSite: 'lax',
|
|
46
|
+
});
|
|
33
47
|
router.replace(newPath);
|
|
34
48
|
router.refresh();
|
|
35
49
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { useTheme } from '
|
|
4
|
+
import { useTheme } from '../../theme';
|
|
5
5
|
const FALLBACK_THEME_ORDER = ['light', 'dark'];
|
|
6
6
|
const isThemeMode = (value) => value === 'light' || value === 'dark' || value === 'system';
|
|
7
7
|
const getThemeOrder = (themes) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.client.d.ts","sourceRoot":"","sources":["../../src/i18n/routing.client.ts"],"names":[],"mappings":"AAMA,wBAAgB,eAAe,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAIlE"}
|
package/dist/i18n/routing.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare function getLocales(): string[];
|
|
|
8
8
|
* Get default locale
|
|
9
9
|
*/
|
|
10
10
|
export declare function getDefaultLocale(): string;
|
|
11
|
+
export declare function getPathLocale(pathname: string): string | undefined;
|
|
11
12
|
export declare function handleLocaleRouting(request: NextRequest): NextResponse<unknown>;
|
|
12
13
|
export declare function getRequestLocale(requestHeaders: Headers): string;
|
|
13
14
|
export declare function getCookieLocale(requestHeaders: Headers, pathname?: string): string | undefined;
|
|
@@ -18,6 +19,10 @@ export declare function getPathname({ locale, href }: {
|
|
|
18
19
|
}): string;
|
|
19
20
|
export declare function getLanguageAlternates(pathname?: string): Record<string, string>;
|
|
20
21
|
export declare function getCurrentPathname(): Promise<string>;
|
|
22
|
+
export declare function getCurrentPathLocale(): Promise<string | undefined>;
|
|
23
|
+
export declare function getPathLocalePathname(pathname: string, href?: string | null): string;
|
|
24
|
+
export declare function toLocalePath(pathname: string, href?: string | null): string;
|
|
25
|
+
export declare function getLocalePathname(href: string): Promise<string>;
|
|
21
26
|
export declare function getCurrentSearchParams(): Promise<URLSearchParams>;
|
|
22
27
|
export declare function getDefaultPathname(): Promise<string>;
|
|
23
28
|
export declare function getCurrentLanguageAlternates(): Promise<Record<string, string>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/i18n/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/i18n/routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoC7D;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,EAAE,CAErC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AA4BD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAElE;AAiFD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,yBA2EvD;AAED,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,OAAO,GAAG,MAAM,CAShE;AAED,wBAAgB,eAAe,CAAC,cAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW9F;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAevG;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,UAY7E;AAsBD,wBAAgB,qBAAqB,CAAC,QAAQ,GAAE,MAAY,0BAwB3D;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAK1D;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAKxE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAuBpF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE3E;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKrE;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,eAAe,CAAC,CAMvE;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAU1D;AAED,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAIpF;AAED,KAAK,aAAa,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAC7C,eAAe,GACf,uBAAuB,GACvB,SAAS,CAAC;AAiDd,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,CAErF;AAED,wBAAsB,UAAU,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAIxE;AAED,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,MAAM,CAAC,CAKnE"}
|
package/dist/i18n/routing.js
CHANGED
|
@@ -19,11 +19,10 @@ const DEFAULT_FALLBACK = () => {
|
|
|
19
19
|
const LOCALE_COOKIE_NAME = 'NEXT_LOCALE';
|
|
20
20
|
const LOCALE_PREFIX = 'as-needed';
|
|
21
21
|
const PATHNAME_HEADER_NAME = 'x-pathname';
|
|
22
|
+
const PATH_LOCALE_HEADER_NAME = 'x-path-locale';
|
|
22
23
|
const SEARCH_PARAMS_HEADER_NAME = 'x-search-params';
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
response.headers.set(SEARCH_PARAMS_HEADER_NAME, search.replace(/^\?/, ''));
|
|
26
|
-
return response;
|
|
24
|
+
const isDocumentRequest = (request) => {
|
|
25
|
+
return request.headers.get('accept')?.includes('text/html') || false;
|
|
27
26
|
};
|
|
28
27
|
/**
|
|
29
28
|
* Get all available locales
|
|
@@ -57,6 +56,16 @@ const getPathLocaleSegment = (pathname) => {
|
|
|
57
56
|
const pathMatch = pathname.match(/^\/([^\\/]+)(?:\/|$)/);
|
|
58
57
|
return pathMatch?.[1];
|
|
59
58
|
};
|
|
59
|
+
export function getPathLocale(pathname) {
|
|
60
|
+
return getCanonicalLocale(getPathLocaleSegment(pathname));
|
|
61
|
+
}
|
|
62
|
+
const setRoutingHeaders = (response, pathname, search) => {
|
|
63
|
+
const pathLocale = getCanonicalLocale(getPathLocaleSegment(pathname));
|
|
64
|
+
response.headers.set(PATHNAME_HEADER_NAME, pathname);
|
|
65
|
+
response.headers.set(PATH_LOCALE_HEADER_NAME, pathLocale || '');
|
|
66
|
+
response.headers.set(SEARCH_PARAMS_HEADER_NAME, search.replace(/^\?/, ''));
|
|
67
|
+
return response;
|
|
68
|
+
};
|
|
60
69
|
const replacePathLocale = (pathname, locale) => {
|
|
61
70
|
return pathname.replace(/^\/[^\\/]+(?=\/|$)/, `/${locale}`);
|
|
62
71
|
};
|
|
@@ -107,6 +116,7 @@ export function handleLocaleRouting(request) {
|
|
|
107
116
|
const localeCookie = request.cookies.get(LOCALE_COOKIE_NAME);
|
|
108
117
|
const cookieLocale = getCanonicalLocale(localeCookie?.value);
|
|
109
118
|
const defaultFallback = DEFAULT_FALLBACK();
|
|
119
|
+
const documentRequest = isDocumentRequest(request);
|
|
110
120
|
// 1. URL에서 locale 감지
|
|
111
121
|
const pathLocaleSegment = getPathLocaleSegment(pathname);
|
|
112
122
|
const pathLocale = getCanonicalLocale(pathLocaleSegment);
|
|
@@ -114,7 +124,7 @@ export function handleLocaleRouting(request) {
|
|
|
114
124
|
// 2. URL에 locale이 포함된 경우
|
|
115
125
|
if (pathnameHasLocale) {
|
|
116
126
|
if (pathLocaleSegment !== pathLocale) {
|
|
117
|
-
return redirectWithLocale(request, pathname, pathLocale, cookieLocale !== pathLocale);
|
|
127
|
+
return redirectWithLocale(request, pathname, pathLocale, cookieLocale !== pathLocale && documentRequest);
|
|
118
128
|
}
|
|
119
129
|
// 이미 path에 locale이 있을 때
|
|
120
130
|
const response = setRoutingHeaders(NextResponse.next(), pathname, request.nextUrl.search);
|
|
@@ -122,9 +132,12 @@ export function handleLocaleRouting(request) {
|
|
|
122
132
|
if (cookieLocale !== pathLocale) {
|
|
123
133
|
// 기본 locale인 경우 URL에서 제거
|
|
124
134
|
if (LOCALE_PREFIX === 'as-needed' && pathLocale === defaultFallback) {
|
|
125
|
-
return redirectWithoutLocale(request, pathname, pathLocale,
|
|
135
|
+
return redirectWithoutLocale(request, pathname, pathLocale, documentRequest);
|
|
126
136
|
}
|
|
127
137
|
// 다른 locale의 경우 쿠키 설정
|
|
138
|
+
if (!documentRequest) {
|
|
139
|
+
return response;
|
|
140
|
+
}
|
|
128
141
|
return setCookie(response, pathLocale);
|
|
129
142
|
}
|
|
130
143
|
// locale은 같지만 기본 locale이고 as-needed 설정인 경우
|
|
@@ -154,7 +167,7 @@ export function handleLocaleRouting(request) {
|
|
|
154
167
|
request.nextUrl.pathname = newPathname;
|
|
155
168
|
const response = setRoutingHeaders(NextResponse.redirect(request.nextUrl), newPathname, request.nextUrl.search);
|
|
156
169
|
// 쿠키가 없는 경우 설정
|
|
157
|
-
if (localeCookie?.value === undefined) {
|
|
170
|
+
if (localeCookie?.value === undefined && documentRequest) {
|
|
158
171
|
setCookie(response, locale);
|
|
159
172
|
}
|
|
160
173
|
return response;
|
|
@@ -178,25 +191,20 @@ export function getCookieLocale(requestHeaders, pathname) {
|
|
|
178
191
|
return getCanonicalLocale(getPathLocaleSegment(pathname));
|
|
179
192
|
}
|
|
180
193
|
export function getChangeLocalePath(pathname, currentLocale, nextLocale) {
|
|
181
|
-
// Create the new path based on whether the current path has a locale segment or not
|
|
182
194
|
let pathNameWithoutLocale;
|
|
183
|
-
// Check if pathname starts with current locale
|
|
184
195
|
if (pathname === `/${currentLocale}` || pathname.startsWith(`/${currentLocale}/`)) {
|
|
185
|
-
|
|
186
|
-
pathNameWithoutLocale = pathname.slice(currentLocale.length + 1); // Remove /locale part
|
|
196
|
+
pathNameWithoutLocale = pathname.slice(currentLocale.length + 1);
|
|
187
197
|
if (pathNameWithoutLocale.startsWith('/')) {
|
|
188
|
-
pathNameWithoutLocale = pathNameWithoutLocale.slice(1);
|
|
198
|
+
pathNameWithoutLocale = pathNameWithoutLocale.slice(1);
|
|
189
199
|
}
|
|
190
200
|
}
|
|
191
201
|
else if (pathname === '/') {
|
|
192
|
-
// Root path
|
|
193
202
|
pathNameWithoutLocale = '';
|
|
194
203
|
}
|
|
195
204
|
else {
|
|
196
|
-
// Path doesn't have locale prefix: /something
|
|
197
205
|
pathNameWithoutLocale = pathname.startsWith('/') ? pathname.slice(1) : pathname;
|
|
198
206
|
}
|
|
199
|
-
return `/${nextLocale}${pathNameWithoutLocale ?
|
|
207
|
+
return `/${nextLocale}${pathNameWithoutLocale ? `/${pathNameWithoutLocale}` : ''}`;
|
|
200
208
|
}
|
|
201
209
|
export function getPathname({ locale, href }) {
|
|
202
210
|
const defaultFallback = DEFAULT_FALLBACK();
|
|
@@ -251,6 +259,37 @@ export async function getCurrentPathname() {
|
|
|
251
259
|
const headersList = await headers();
|
|
252
260
|
return headersList.get(PATHNAME_HEADER_NAME) || '';
|
|
253
261
|
}
|
|
262
|
+
export async function getCurrentPathLocale() {
|
|
263
|
+
const { headers } = await import('next/headers');
|
|
264
|
+
const headersList = await headers();
|
|
265
|
+
return getCanonicalLocale(headersList.get(PATH_LOCALE_HEADER_NAME) || undefined);
|
|
266
|
+
}
|
|
267
|
+
export function getPathLocalePathname(pathname, href) {
|
|
268
|
+
if (href == null || href === '#') {
|
|
269
|
+
return '#';
|
|
270
|
+
}
|
|
271
|
+
const normalizedHref = href === '' ? '/' : href.startsWith('/') ? href : `/${href}`;
|
|
272
|
+
const hrefLocale = getPathLocale(normalizedHref);
|
|
273
|
+
if (hrefLocale) {
|
|
274
|
+
return normalizedHref;
|
|
275
|
+
}
|
|
276
|
+
const pathLocale = getPathLocale(pathname);
|
|
277
|
+
if (!pathLocale) {
|
|
278
|
+
return normalizedHref;
|
|
279
|
+
}
|
|
280
|
+
if (normalizedHref === '/') {
|
|
281
|
+
return `/${pathLocale}`;
|
|
282
|
+
}
|
|
283
|
+
return `/${pathLocale}${normalizedHref}`;
|
|
284
|
+
}
|
|
285
|
+
export function toLocalePath(pathname, href) {
|
|
286
|
+
return getPathLocalePathname(pathname, href);
|
|
287
|
+
}
|
|
288
|
+
export async function getLocalePathname(href) {
|
|
289
|
+
const pathLocale = await getCurrentPathLocale();
|
|
290
|
+
const currentPathname = pathLocale ? `/${pathLocale}` : '/';
|
|
291
|
+
return getPathLocalePathname(currentPathname, href);
|
|
292
|
+
}
|
|
254
293
|
export async function getCurrentSearchParams() {
|
|
255
294
|
const { headers } = await import('next/headers');
|
|
256
295
|
const headersList = await headers();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/theme/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,eAAO,MAAM,YAAY,0CAA4D,CAAC;AAOtF,wBAAgB,QAAQ,kBAEvB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export const ThemeContext = React.createContext(undefined);
|
|
3
|
+
const DEFAULT_CONTEXT = {
|
|
4
|
+
setTheme: () => undefined,
|
|
5
|
+
themes: [],
|
|
6
|
+
};
|
|
7
|
+
export function useTheme() {
|
|
8
|
+
return React.useContext(ThemeContext) ?? DEFAULT_CONTEXT;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ThemeProviderProps, ThemeStorage, ThemeValueMap, UseThemeProps } from './types';
|
|
2
|
+
export declare function ThemeProvider(props: ThemeProviderProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
3
|
+
export type { ThemeProviderProps, ThemeStorage, ThemeValueMap, UseThemeProps };
|
|
4
|
+
//# sourceMappingURL=index.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.server.d.ts","sourceRoot":"","sources":["../../src/theme/index.server.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE9F,wBAAsB,aAAa,CAAC,KAAK,EAAE,kBAAkB,oDAkB5D;AAED,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cookies } from 'next/headers';
|
|
3
|
+
import { getCookieStorageKey, isValidTheme, normalizeThemeProviderProps } from './shared';
|
|
4
|
+
import { ThemeProvider as ClientThemeProvider } from './theme-provider.client';
|
|
5
|
+
export async function ThemeProvider(props) {
|
|
6
|
+
const normalizedProps = normalizeThemeProviderProps(props);
|
|
7
|
+
let initialTheme = props.initialTheme;
|
|
8
|
+
if (!initialTheme && normalizedProps.storage === 'cookie') {
|
|
9
|
+
try {
|
|
10
|
+
const cookieStore = await cookies();
|
|
11
|
+
const storedTheme = cookieStore.get(getCookieStorageKey(normalizedProps.storageKey))?.value;
|
|
12
|
+
if (isValidTheme(storedTheme, normalizedProps.themes, normalizedProps.enableSystem)) {
|
|
13
|
+
initialTheme = storedTheme;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Ignore missing request context and let the client resolve its own theme.
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return _jsx(ClientThemeProvider, { ...props, initialTheme: initialTheme });
|
|
21
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare function themeScript(attribute: 'class' | `data-${string}` | Array<'class' | `data-${string}`>, storageKey: string, defaultTheme: string, forcedTheme: string | undefined, themes: string[], value: Record<string, string> | undefined, enableSystem: boolean, enableColorScheme: boolean, storage: 'localStorage' | 'sessionStorage' | 'cookie' | 'none', initialTheme: string | undefined, disableTransitionOnChange: boolean): void;
|
|
2
|
+
//# sourceMappingURL=script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../src/theme/script.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CACzB,SAAS,EAAE,OAAO,GAAG,QAAQ,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC,EACzE,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACzC,YAAY,EAAE,OAAO,EACrB,iBAAiB,EAAE,OAAO,EAC1B,OAAO,EAAE,cAAc,GAAG,gBAAgB,GAAG,QAAQ,GAAG,MAAM,EAC9D,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,yBAAyB,EAAE,OAAO,QAyHnC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export function themeScript(attribute, storageKey, defaultTheme, forcedTheme, themes, value, enableSystem, enableColorScheme, storage, initialTheme, disableTransitionOnChange) {
|
|
2
|
+
const root = document.documentElement;
|
|
3
|
+
const colorSchemes = ['light', 'dark'];
|
|
4
|
+
function resolveValue(theme) {
|
|
5
|
+
return value && value[theme] ? value[theme] : theme;
|
|
6
|
+
}
|
|
7
|
+
function getThemeTokens(themeValue) {
|
|
8
|
+
return themeValue.split(/\s+/).filter(Boolean);
|
|
9
|
+
}
|
|
10
|
+
function isValidTheme(theme) {
|
|
11
|
+
if (!theme) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (themes.includes(theme)) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return enableSystem && theme === 'system';
|
|
18
|
+
}
|
|
19
|
+
function getCookieStorageKey() {
|
|
20
|
+
return encodeURIComponent(storageKey);
|
|
21
|
+
}
|
|
22
|
+
function readThemeFromCookie() {
|
|
23
|
+
const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${getCookieStorageKey().replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}=([^;]*)`));
|
|
24
|
+
return match?.[1] != null ? decodeURIComponent(match[1]) : null;
|
|
25
|
+
}
|
|
26
|
+
function readStoredTheme() {
|
|
27
|
+
if (storage === 'none') {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
if (storage === 'cookie') {
|
|
31
|
+
return readThemeFromCookie();
|
|
32
|
+
}
|
|
33
|
+
if (storage === 'sessionStorage') {
|
|
34
|
+
return sessionStorage.getItem(storageKey);
|
|
35
|
+
}
|
|
36
|
+
return localStorage.getItem(storageKey);
|
|
37
|
+
}
|
|
38
|
+
function disableTransitions() {
|
|
39
|
+
if (!disableTransitionOnChange) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const style = document.createElement('style');
|
|
43
|
+
style.textContent =
|
|
44
|
+
'*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}';
|
|
45
|
+
document.head.appendChild(style);
|
|
46
|
+
const scheduleFrame = typeof window.requestAnimationFrame === 'function'
|
|
47
|
+
? window.requestAnimationFrame.bind(window)
|
|
48
|
+
: (callback) => window.setTimeout(() => callback(0), 0);
|
|
49
|
+
scheduleFrame(() => {
|
|
50
|
+
scheduleFrame(() => {
|
|
51
|
+
style.remove();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function applyTheme(theme) {
|
|
56
|
+
if (!theme) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
disableTransitions();
|
|
60
|
+
const nextTheme = resolveValue(theme);
|
|
61
|
+
const attributes = Array.isArray(attribute) ? attribute : [attribute];
|
|
62
|
+
attributes.forEach((currentAttribute) => {
|
|
63
|
+
if (currentAttribute === 'class') {
|
|
64
|
+
const classes = themes.flatMap((currentTheme) => getThemeTokens(resolveValue(currentTheme)));
|
|
65
|
+
root.classList.remove(...classes);
|
|
66
|
+
root.classList.add(...getThemeTokens(nextTheme));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
root.setAttribute(currentAttribute, nextTheme);
|
|
70
|
+
});
|
|
71
|
+
if (enableColorScheme) {
|
|
72
|
+
const fallbackColorScheme = colorSchemes.includes(defaultTheme) ? defaultTheme : null;
|
|
73
|
+
const colorScheme = colorSchemes.includes(theme) ? theme : fallbackColorScheme;
|
|
74
|
+
root.style.colorScheme = colorScheme || '';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function getSystemTheme() {
|
|
78
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const storedTheme = isValidTheme(initialTheme) ? initialTheme : readStoredTheme();
|
|
82
|
+
const selectedStoredTheme = isValidTheme(storedTheme ?? undefined) ? (storedTheme ?? defaultTheme) : defaultTheme;
|
|
83
|
+
const selectedTheme = forcedTheme || selectedStoredTheme;
|
|
84
|
+
const resolvedTheme = selectedTheme === 'system' && enableSystem ? getSystemTheme() : selectedTheme;
|
|
85
|
+
applyTheme(resolvedTheme);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
const fallbackTheme = forcedTheme || defaultTheme;
|
|
89
|
+
const resolvedTheme = fallbackTheme === 'system' && enableSystem ? getSystemTheme() : fallbackTheme;
|
|
90
|
+
applyTheme(resolvedTheme);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ThemeAttribute, ThemeProviderProps, ThemeStorage, ThemeValueMap } from './types';
|
|
2
|
+
export declare const DEFAULT_THEMES: string[];
|
|
3
|
+
export declare const DEFAULT_STORAGE_KEY = "theme";
|
|
4
|
+
export declare const DEFAULT_STORAGE: ThemeStorage;
|
|
5
|
+
export declare const MEDIA_QUERY = "(prefers-color-scheme: dark)";
|
|
6
|
+
type NormalizedThemeProviderProps = Omit<ThemeProviderProps, 'children'> & {
|
|
7
|
+
attribute: ThemeAttribute | ThemeAttribute[];
|
|
8
|
+
defaultTheme: string;
|
|
9
|
+
disableTransitionOnChange: boolean;
|
|
10
|
+
enableColorScheme: boolean;
|
|
11
|
+
enableSystem: boolean;
|
|
12
|
+
storage: ThemeStorage;
|
|
13
|
+
storageKey: string;
|
|
14
|
+
themes: string[];
|
|
15
|
+
};
|
|
16
|
+
type ApplyThemeOptions = Pick<NormalizedThemeProviderProps, 'attribute' | 'defaultTheme' | 'disableTransitionOnChange' | 'enableColorScheme' | 'themes' | 'value'> & {
|
|
17
|
+
resolvedTheme: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function getCookieStorageKey(storageKey: string): string;
|
|
20
|
+
export declare function normalizeThemeProviderProps(props: ThemeProviderProps): NormalizedThemeProviderProps;
|
|
21
|
+
export declare function isValidTheme(theme: string | undefined, themes: string[], enableSystem: boolean): boolean;
|
|
22
|
+
export declare function getStoredTheme({ defaultTheme, enableSystem, storage, storageKey, themes, }: {
|
|
23
|
+
defaultTheme: string;
|
|
24
|
+
enableSystem: boolean;
|
|
25
|
+
storage: ThemeStorage;
|
|
26
|
+
storageKey: string;
|
|
27
|
+
themes: string[];
|
|
28
|
+
}): string;
|
|
29
|
+
export declare function saveTheme(storage: ThemeStorage, storageKey: string, value: string): void;
|
|
30
|
+
export declare function getServerThemeFromCookieString({ cookieString, defaultTheme, enableSystem, storageKey, themes, }: {
|
|
31
|
+
cookieString: string;
|
|
32
|
+
defaultTheme: string;
|
|
33
|
+
enableSystem: boolean;
|
|
34
|
+
storageKey: string;
|
|
35
|
+
themes: string[];
|
|
36
|
+
}): string;
|
|
37
|
+
export declare function getSystemTheme(mediaQueryList?: MediaQueryList | MediaQueryListEvent): "light" | "dark" | undefined;
|
|
38
|
+
export declare function resolveThemeValue(theme: string, value?: ThemeValueMap): string;
|
|
39
|
+
export declare function splitThemeValueTokens(themeValue: string): string[];
|
|
40
|
+
export declare function getThemeClassValues(themes: string[], value?: ThemeValueMap): string[];
|
|
41
|
+
export declare function resolveActiveTheme(theme: string | undefined, enableSystem: boolean, systemTheme?: string): string | undefined;
|
|
42
|
+
export declare function applyThemeToDocument({ attribute, defaultTheme, disableTransitionOnChange, enableColorScheme, resolvedTheme, themes, value, }: ApplyThemeOptions): void;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/theme/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE/F,eAAO,MAAM,cAAc,UAAoB,CAAC;AAChD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAC3C,eAAO,MAAM,eAAe,EAAE,YAA6B,CAAC;AAC5D,eAAO,MAAM,WAAW,iCAAiC,CAAC;AAE1D,KAAK,4BAA4B,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,GAAG;IACzE,SAAS,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,yBAAyB,EAAE,OAAO,CAAC;IACnC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,KAAK,iBAAiB,GAAG,IAAI,CAC3B,4BAA4B,EAC5B,WAAW,GAAG,cAAc,GAAG,2BAA2B,GAAG,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CACtG,GAAG;IACF,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAIF,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,UAErD;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,kBAAkB,GAAG,4BAA4B,CAgCnG;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,WAU9F;AAwBD,wBAAgB,cAAc,CAAC,EAC7B,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,UAAU,EACV,MAAM,GACP,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,UAYA;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAkBjF;AAED,wBAAgB,8BAA8B,CAAC,EAC7C,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,MAAM,GACP,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,UAIA;AAED,wBAAgB,cAAc,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,mBAAmB,gCAQnF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,UAErE;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,YAEvD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,aAAa,YAE1E;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,sBAUxG;AAED,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,YAAY,EACZ,yBAAyB,EACzB,iBAAiB,EACjB,aAAa,EACb,MAAM,EACN,KAAK,GACN,EAAE,iBAAiB,QA6BnB"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
export const DEFAULT_THEMES = ['light', 'dark'];
|
|
2
|
+
export const DEFAULT_STORAGE_KEY = 'theme';
|
|
3
|
+
export const DEFAULT_STORAGE = 'localStorage';
|
|
4
|
+
export const MEDIA_QUERY = '(prefers-color-scheme: dark)';
|
|
5
|
+
const COLOR_SCHEMES = new Set(['light', 'dark']);
|
|
6
|
+
export function getCookieStorageKey(storageKey) {
|
|
7
|
+
return encodeURIComponent(storageKey);
|
|
8
|
+
}
|
|
9
|
+
export function normalizeThemeProviderProps(props) {
|
|
10
|
+
const { attribute = 'data-theme', defaultTheme, disableTransitionOnChange = false, enableColorScheme = true, enableSystem = true, forcedTheme, initialTheme, nonce, scriptProps, storage = DEFAULT_STORAGE, storageKey = DEFAULT_STORAGE_KEY, themes = DEFAULT_THEMES, value, } = props;
|
|
11
|
+
return {
|
|
12
|
+
attribute,
|
|
13
|
+
defaultTheme: defaultTheme ?? (enableSystem ? 'system' : 'light'),
|
|
14
|
+
disableTransitionOnChange,
|
|
15
|
+
enableColorScheme,
|
|
16
|
+
enableSystem,
|
|
17
|
+
forcedTheme,
|
|
18
|
+
initialTheme,
|
|
19
|
+
nonce,
|
|
20
|
+
scriptProps,
|
|
21
|
+
storage,
|
|
22
|
+
storageKey,
|
|
23
|
+
themes,
|
|
24
|
+
value,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function isValidTheme(theme, themes, enableSystem) {
|
|
28
|
+
if (!theme) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (themes.includes(theme)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return enableSystem && theme === 'system';
|
|
35
|
+
}
|
|
36
|
+
function readThemeFromCookieString(cookieString, storageKey) {
|
|
37
|
+
const match = cookieString.match(new RegExp(`(?:^|;\\s*)${escapeRegExp(getCookieStorageKey(storageKey))}=([^;]*)`));
|
|
38
|
+
return match?.[1] != null ? decodeURIComponent(match[1]) : null;
|
|
39
|
+
}
|
|
40
|
+
function readThemeFromStorageArea(storage, storageKey) {
|
|
41
|
+
if (typeof window === 'undefined') {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
if (storage === 'cookie') {
|
|
45
|
+
return readThemeFromCookieString(document.cookie, storageKey);
|
|
46
|
+
}
|
|
47
|
+
if (storage === 'sessionStorage') {
|
|
48
|
+
return sessionStorage.getItem(storageKey);
|
|
49
|
+
}
|
|
50
|
+
return localStorage.getItem(storageKey);
|
|
51
|
+
}
|
|
52
|
+
export function getStoredTheme({ defaultTheme, enableSystem, storage, storageKey, themes, }) {
|
|
53
|
+
if (typeof window === 'undefined' || storage === 'none') {
|
|
54
|
+
return defaultTheme;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const storedTheme = readThemeFromStorageArea(storage, storageKey);
|
|
58
|
+
return isValidTheme(storedTheme ?? undefined, themes, enableSystem) ? (storedTheme ?? defaultTheme) : defaultTheme;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return defaultTheme;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function saveTheme(storage, storageKey, value) {
|
|
65
|
+
try {
|
|
66
|
+
if (storage === 'none') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (storage === 'cookie') {
|
|
70
|
+
const secureAttribute = typeof location !== 'undefined' && location.protocol === 'https:' ? '; Secure' : '';
|
|
71
|
+
document.cookie = `${getCookieStorageKey(storageKey)}=${encodeURIComponent(value)}; path=/; max-age=31536000; SameSite=Lax${secureAttribute}`;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const storageArea = storage === 'sessionStorage' ? sessionStorage : localStorage;
|
|
75
|
+
storageArea.setItem(storageKey, value);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Ignore storage failures in unsupported or restricted environments.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function getServerThemeFromCookieString({ cookieString, defaultTheme, enableSystem, storageKey, themes, }) {
|
|
82
|
+
const storedTheme = readThemeFromCookieString(cookieString, storageKey);
|
|
83
|
+
return isValidTheme(storedTheme ?? undefined, themes, enableSystem) ? (storedTheme ?? defaultTheme) : defaultTheme;
|
|
84
|
+
}
|
|
85
|
+
export function getSystemTheme(mediaQueryList) {
|
|
86
|
+
if (typeof window === 'undefined') {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const query = mediaQueryList ?? window.matchMedia(MEDIA_QUERY);
|
|
90
|
+
return query.matches ? 'dark' : 'light';
|
|
91
|
+
}
|
|
92
|
+
export function resolveThemeValue(theme, value) {
|
|
93
|
+
return value?.[theme] ?? theme;
|
|
94
|
+
}
|
|
95
|
+
export function splitThemeValueTokens(themeValue) {
|
|
96
|
+
return themeValue.split(/\s+/).filter(Boolean);
|
|
97
|
+
}
|
|
98
|
+
export function getThemeClassValues(themes, value) {
|
|
99
|
+
return themes.flatMap((theme) => splitThemeValueTokens(resolveThemeValue(theme, value)));
|
|
100
|
+
}
|
|
101
|
+
export function resolveActiveTheme(theme, enableSystem, systemTheme) {
|
|
102
|
+
if (!theme) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
if (theme === 'system' && enableSystem) {
|
|
106
|
+
return systemTheme ?? 'light';
|
|
107
|
+
}
|
|
108
|
+
return theme;
|
|
109
|
+
}
|
|
110
|
+
export function applyThemeToDocument({ attribute, defaultTheme, disableTransitionOnChange, enableColorScheme, resolvedTheme, themes, value, }) {
|
|
111
|
+
if (typeof document === 'undefined' || !resolvedTheme) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const cleanupTransitions = disableTransitionOnChange ? disableTransitions() : null;
|
|
115
|
+
const root = document.documentElement;
|
|
116
|
+
const nextValue = resolveThemeValue(resolvedTheme, value);
|
|
117
|
+
const attributes = Array.isArray(attribute) ? attribute : [attribute];
|
|
118
|
+
attributes.forEach((currentAttribute) => {
|
|
119
|
+
if (currentAttribute === 'class') {
|
|
120
|
+
root.classList.remove(...getThemeClassValues(themes, value));
|
|
121
|
+
root.classList.add(...splitThemeValueTokens(nextValue));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
root.setAttribute(currentAttribute, nextValue);
|
|
125
|
+
});
|
|
126
|
+
if (enableColorScheme) {
|
|
127
|
+
const fallbackColorScheme = COLOR_SCHEMES.has(defaultTheme) ? defaultTheme : null;
|
|
128
|
+
const colorScheme = COLOR_SCHEMES.has(resolvedTheme) ? resolvedTheme : fallbackColorScheme;
|
|
129
|
+
root.style.colorScheme = colorScheme ?? '';
|
|
130
|
+
}
|
|
131
|
+
cleanupTransitions?.();
|
|
132
|
+
}
|
|
133
|
+
function disableTransitions() {
|
|
134
|
+
if (typeof document === 'undefined') {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
const style = document.createElement('style');
|
|
138
|
+
style.appendChild(document.createTextNode('*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}'));
|
|
139
|
+
document.head.appendChild(style);
|
|
140
|
+
return () => {
|
|
141
|
+
const scheduleFrame = typeof window.requestAnimationFrame === 'function'
|
|
142
|
+
? window.requestAnimationFrame.bind(window)
|
|
143
|
+
: (callback) => window.setTimeout(() => callback(0), 0);
|
|
144
|
+
scheduleFrame(() => {
|
|
145
|
+
scheduleFrame(() => {
|
|
146
|
+
style.remove();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function escapeRegExp(value) {
|
|
152
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
153
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface ThemeState {
|
|
2
|
+
theme?: string;
|
|
3
|
+
systemTheme?: 'light' | 'dark';
|
|
4
|
+
}
|
|
5
|
+
export interface ThemeStore {
|
|
6
|
+
subscribe(listener: () => void): () => void;
|
|
7
|
+
getSnapshot(): ThemeState;
|
|
8
|
+
getServerSnapshot(): ThemeState;
|
|
9
|
+
setTheme(theme: string | undefined): void;
|
|
10
|
+
setSystemTheme(systemTheme: 'light' | 'dark' | undefined): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createThemeStore(initialState?: ThemeState): ThemeStore;
|
|
13
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/theme/store.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5C,WAAW,IAAI,UAAU,CAAC;IAC1B,iBAAiB,IAAI,UAAU,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C,cAAc,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CACjE;AAOD,wBAAgB,gBAAgB,CAAC,YAAY,GAAE,UAA4B,GAAG,UAAU,CA+CvF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const SERVER_SNAPSHOT = {
|
|
2
|
+
systemTheme: undefined,
|
|
3
|
+
theme: undefined,
|
|
4
|
+
};
|
|
5
|
+
export function createThemeStore(initialState = SERVER_SNAPSHOT) {
|
|
6
|
+
let state = initialState;
|
|
7
|
+
const listeners = new Set();
|
|
8
|
+
const emit = () => {
|
|
9
|
+
for (const listener of listeners) {
|
|
10
|
+
listener();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
subscribe(listener) {
|
|
15
|
+
listeners.add(listener);
|
|
16
|
+
return () => {
|
|
17
|
+
listeners.delete(listener);
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
getSnapshot() {
|
|
21
|
+
return state;
|
|
22
|
+
},
|
|
23
|
+
getServerSnapshot() {
|
|
24
|
+
return SERVER_SNAPSHOT;
|
|
25
|
+
},
|
|
26
|
+
setTheme(theme) {
|
|
27
|
+
if (state.theme === theme) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
state = {
|
|
31
|
+
...state,
|
|
32
|
+
theme,
|
|
33
|
+
};
|
|
34
|
+
emit();
|
|
35
|
+
},
|
|
36
|
+
setSystemTheme(systemTheme) {
|
|
37
|
+
if (state.systemTheme === systemTheme) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
state = {
|
|
41
|
+
...state,
|
|
42
|
+
systemTheme,
|
|
43
|
+
};
|
|
44
|
+
emit();
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { useTheme } from './context';
|
|
2
|
+
import type { ThemeProviderProps } from './types';
|
|
3
|
+
export { useTheme };
|
|
4
|
+
export declare function ThemeProvider(props: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
//# sourceMappingURL=theme-provider.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-provider.client.d.ts","sourceRoot":"","sources":["../../src/theme/theme-provider.client.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAgB,QAAQ,EAAE,MAAM,WAAW,CAAC;AAanD,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,SAAS,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAEpB,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAQtD"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useServerInsertedHTML } from 'next/navigation';
|
|
5
|
+
import { ThemeContext, useTheme } from './context';
|
|
6
|
+
import { MEDIA_QUERY, applyThemeToDocument, getStoredTheme, getSystemTheme, isValidTheme, normalizeThemeProviderProps, resolveActiveTheme, saveTheme, } from './shared';
|
|
7
|
+
import { createThemeStore } from './store';
|
|
8
|
+
import { ThemeScript } from './theme-script';
|
|
9
|
+
export { useTheme };
|
|
10
|
+
export function ThemeProvider(props) {
|
|
11
|
+
const context = React.useContext(ThemeContext);
|
|
12
|
+
if (context) {
|
|
13
|
+
return _jsx(_Fragment, { children: props.children });
|
|
14
|
+
}
|
|
15
|
+
return _jsx(ThemeProviderInner, { ...props });
|
|
16
|
+
}
|
|
17
|
+
function ThemeProviderInner(props) {
|
|
18
|
+
const { attribute, defaultTheme, disableTransitionOnChange, enableColorScheme, enableSystem, forcedTheme, initialTheme, nonce, scriptProps, storage, storageKey, themes, value, } = normalizeThemeProviderProps(props);
|
|
19
|
+
useServerInsertedHTML(() => (_jsx(ThemeScript, { attribute: attribute, defaultTheme: defaultTheme, disableTransitionOnChange: disableTransitionOnChange, enableColorScheme: enableColorScheme, enableSystem: enableSystem, forcedTheme: forcedTheme, initialTheme: initialTheme, nonce: nonce, scriptProps: scriptProps, storage: storage, storageKey: storageKey, themes: themes, value: value })));
|
|
20
|
+
const storeRef = React.useRef(createThemeStore({
|
|
21
|
+
systemTheme: getSystemTheme(),
|
|
22
|
+
theme: isValidTheme(initialTheme, themes, enableSystem)
|
|
23
|
+
? initialTheme
|
|
24
|
+
: getStoredTheme({
|
|
25
|
+
defaultTheme,
|
|
26
|
+
enableSystem,
|
|
27
|
+
storage,
|
|
28
|
+
storageKey,
|
|
29
|
+
themes,
|
|
30
|
+
}),
|
|
31
|
+
}));
|
|
32
|
+
const store = storeRef.current;
|
|
33
|
+
const { systemTheme, theme } = React.useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);
|
|
34
|
+
const applyResolvedTheme = React.useCallback((selectedTheme) => {
|
|
35
|
+
const resolvedTheme = resolveActiveTheme(selectedTheme, enableSystem, store.getSnapshot().systemTheme);
|
|
36
|
+
if (!resolvedTheme) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
applyThemeToDocument({
|
|
40
|
+
attribute,
|
|
41
|
+
defaultTheme,
|
|
42
|
+
disableTransitionOnChange,
|
|
43
|
+
enableColorScheme,
|
|
44
|
+
resolvedTheme,
|
|
45
|
+
themes,
|
|
46
|
+
value,
|
|
47
|
+
});
|
|
48
|
+
}, [attribute, defaultTheme, disableTransitionOnChange, enableColorScheme, enableSystem, store, themes, value]);
|
|
49
|
+
const setTheme = React.useCallback((nextTheme) => {
|
|
50
|
+
if (forcedTheme) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const currentTheme = store.getSnapshot().theme ?? defaultTheme;
|
|
54
|
+
const selectedTheme = typeof nextTheme === 'function' ? nextTheme(currentTheme) : nextTheme;
|
|
55
|
+
store.setTheme(selectedTheme);
|
|
56
|
+
saveTheme(storage, storageKey, selectedTheme);
|
|
57
|
+
}, [defaultTheme, forcedTheme, storage, storageKey, store]);
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
const mediaQueryList = window.matchMedia(MEDIA_QUERY);
|
|
60
|
+
const handleMediaQueryChange = (event) => {
|
|
61
|
+
store.setSystemTheme(getSystemTheme(event));
|
|
62
|
+
};
|
|
63
|
+
if (typeof mediaQueryList.addEventListener === 'function') {
|
|
64
|
+
mediaQueryList.addEventListener('change', handleMediaQueryChange);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
mediaQueryList.addListener(handleMediaQueryChange);
|
|
68
|
+
}
|
|
69
|
+
handleMediaQueryChange(mediaQueryList);
|
|
70
|
+
return () => {
|
|
71
|
+
if (typeof mediaQueryList.removeEventListener === 'function') {
|
|
72
|
+
mediaQueryList.removeEventListener('change', handleMediaQueryChange);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
mediaQueryList.removeListener(handleMediaQueryChange);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}, [store]);
|
|
79
|
+
React.useEffect(() => {
|
|
80
|
+
if (initialTheme && isValidTheme(initialTheme, themes, enableSystem)) {
|
|
81
|
+
store.setTheme(initialTheme);
|
|
82
|
+
saveTheme(storage, storageKey, initialTheme);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const nextTheme = getStoredTheme({
|
|
86
|
+
defaultTheme,
|
|
87
|
+
enableSystem,
|
|
88
|
+
storage,
|
|
89
|
+
storageKey,
|
|
90
|
+
themes,
|
|
91
|
+
});
|
|
92
|
+
store.setTheme(nextTheme);
|
|
93
|
+
}, [defaultTheme, enableSystem, initialTheme, storage, storageKey, store, themes]);
|
|
94
|
+
React.useEffect(() => {
|
|
95
|
+
if (storage !== 'localStorage') {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const handleStorage = (event) => {
|
|
99
|
+
if (event.key !== storageKey) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (event.storageArea && event.storageArea !== localStorage) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (!event.newValue) {
|
|
106
|
+
store.setTheme(defaultTheme);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!isValidTheme(event.newValue, themes, enableSystem)) {
|
|
110
|
+
store.setTheme(defaultTheme);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
store.setTheme(event.newValue);
|
|
114
|
+
};
|
|
115
|
+
window.addEventListener('storage', handleStorage);
|
|
116
|
+
return () => window.removeEventListener('storage', handleStorage);
|
|
117
|
+
}, [defaultTheme, enableSystem, storage, storageKey, store, themes]);
|
|
118
|
+
React.useEffect(() => {
|
|
119
|
+
applyResolvedTheme(forcedTheme ?? theme);
|
|
120
|
+
}, [applyResolvedTheme, forcedTheme, theme]);
|
|
121
|
+
const contextValue = React.useMemo(() => ({
|
|
122
|
+
forcedTheme,
|
|
123
|
+
resolvedTheme: theme === 'system' ? systemTheme : theme,
|
|
124
|
+
setTheme,
|
|
125
|
+
systemTheme: enableSystem ? systemTheme : undefined,
|
|
126
|
+
theme,
|
|
127
|
+
themes: enableSystem ? [...themes, 'system'] : themes,
|
|
128
|
+
}), [enableSystem, forcedTheme, setTheme, systemTheme, theme, themes]);
|
|
129
|
+
return _jsx(ThemeContext.Provider, { value: contextValue, children: props.children });
|
|
130
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-script.d.ts","sourceRoot":"","sources":["../../src/theme/theme-script.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,2CAyCtE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { themeScript } from './script';
|
|
3
|
+
import { normalizeThemeProviderProps } from './shared';
|
|
4
|
+
export function ThemeScript(props) {
|
|
5
|
+
const { attribute, defaultTheme, disableTransitionOnChange, enableColorScheme, enableSystem, forcedTheme, initialTheme, nonce, scriptProps, storage, storageKey, themes, value, } = normalizeThemeProviderProps(props);
|
|
6
|
+
const scriptArguments = JSON.stringify([
|
|
7
|
+
attribute,
|
|
8
|
+
storageKey,
|
|
9
|
+
defaultTheme,
|
|
10
|
+
forcedTheme,
|
|
11
|
+
themes,
|
|
12
|
+
value,
|
|
13
|
+
enableSystem,
|
|
14
|
+
enableColorScheme,
|
|
15
|
+
storage,
|
|
16
|
+
initialTheme,
|
|
17
|
+
disableTransitionOnChange,
|
|
18
|
+
]).slice(1, -1);
|
|
19
|
+
return (_jsx("script", { ...scriptProps, suppressHydrationWarning: true, nonce: nonce, dangerouslySetInnerHTML: {
|
|
20
|
+
__html: `(${themeScript.toString()})(${scriptArguments})`,
|
|
21
|
+
} }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export type ThemeAttribute = 'class' | `data-${string}`;
|
|
3
|
+
export type ThemeValueMap = Record<string, string>;
|
|
4
|
+
export type ThemeStorage = 'localStorage' | 'sessionStorage' | 'cookie' | 'none';
|
|
5
|
+
export interface ThemeScriptProps extends React.DetailedHTMLProps<React.ScriptHTMLAttributes<HTMLScriptElement>, HTMLScriptElement> {
|
|
6
|
+
[dataAttribute: `data-${string}`]: unknown;
|
|
7
|
+
}
|
|
8
|
+
export type SetThemeValue = React.SetStateAction<string>;
|
|
9
|
+
export interface UseThemeProps {
|
|
10
|
+
themes: string[];
|
|
11
|
+
forcedTheme?: string;
|
|
12
|
+
setTheme: React.Dispatch<SetThemeValue>;
|
|
13
|
+
theme?: string;
|
|
14
|
+
resolvedTheme?: string;
|
|
15
|
+
systemTheme?: 'light' | 'dark';
|
|
16
|
+
}
|
|
17
|
+
export interface ThemeProviderProps extends React.PropsWithChildren {
|
|
18
|
+
themes?: string[];
|
|
19
|
+
forcedTheme?: string;
|
|
20
|
+
enableSystem?: boolean;
|
|
21
|
+
disableTransitionOnChange?: boolean;
|
|
22
|
+
enableColorScheme?: boolean;
|
|
23
|
+
storageKey?: string;
|
|
24
|
+
defaultTheme?: string;
|
|
25
|
+
attribute?: ThemeAttribute | ThemeAttribute[];
|
|
26
|
+
value?: ThemeValueMap;
|
|
27
|
+
storage?: ThemeStorage;
|
|
28
|
+
initialTheme?: string;
|
|
29
|
+
nonce?: string;
|
|
30
|
+
scriptProps?: ThemeScriptProps;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/theme/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC;AAExD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnD,MAAM,MAAM,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEjF,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,iBAAiB,CAC/D,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAC7C,iBAAiB,CAClB;IACC,CAAC,aAAa,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAC5C;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,iBAAiB;IACjE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;IAC9C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@korioinc/next-core",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./ads": {
|
|
@@ -53,6 +53,16 @@
|
|
|
53
53
|
"import": "./dist/components/index.js",
|
|
54
54
|
"default": "./dist/components/index.js"
|
|
55
55
|
},
|
|
56
|
+
"./theme": {
|
|
57
|
+
"types": "./dist/theme/index.d.ts",
|
|
58
|
+
"import": "./dist/theme/index.js",
|
|
59
|
+
"default": "./dist/theme/index.js"
|
|
60
|
+
},
|
|
61
|
+
"./theme/server": {
|
|
62
|
+
"types": "./dist/theme/index.server.d.ts",
|
|
63
|
+
"import": "./dist/theme/index.server.js",
|
|
64
|
+
"default": "./dist/theme/index.server.js"
|
|
65
|
+
},
|
|
56
66
|
"./styles/*": "./dist/styles/*",
|
|
57
67
|
"./types/*": "./dist/types/*"
|
|
58
68
|
},
|
|
@@ -63,16 +73,16 @@
|
|
|
63
73
|
],
|
|
64
74
|
"devDependencies": {
|
|
65
75
|
"@headlessui/react": "^2.2.9",
|
|
66
|
-
"@lingui/conf": "^5.9.
|
|
67
|
-
"@lingui/core": "^5.9.
|
|
68
|
-
"@lingui/react": "^5.9.
|
|
76
|
+
"@lingui/conf": "^5.9.4",
|
|
77
|
+
"@lingui/core": "^5.9.4",
|
|
78
|
+
"@lingui/react": "^5.9.4",
|
|
69
79
|
"@tailwindcss/typography": "^0.5.19",
|
|
70
80
|
"@types/negotiator": "^0.6.4",
|
|
71
81
|
"@types/node": "^25.5.0",
|
|
72
82
|
"@types/react": "^19.2.14",
|
|
73
83
|
"@types/react-dom": "^19.2.3",
|
|
74
84
|
"eslint": "^10.1.0",
|
|
75
|
-
"
|
|
85
|
+
"jsdom": "^29.0.1",
|
|
76
86
|
"react": "^19.2.4",
|
|
77
87
|
"react-dom": "^19.2.4",
|
|
78
88
|
"tailwindcss": "^4.2.2",
|
|
@@ -80,7 +90,7 @@
|
|
|
80
90
|
"tw-animate-css": "^1.4.0",
|
|
81
91
|
"typescript": "^6.0.2",
|
|
82
92
|
"vitest": "^4.1.2",
|
|
83
|
-
"@korioinc/next-configs": "2.0.
|
|
93
|
+
"@korioinc/next-configs": "2.0.35"
|
|
84
94
|
},
|
|
85
95
|
"dependencies": {
|
|
86
96
|
"@floating-ui/react": "^0.27.19",
|
|
@@ -95,7 +105,7 @@
|
|
|
95
105
|
"schema-dts": "^2.0.0",
|
|
96
106
|
"tailwind-merge": "^3.5.0",
|
|
97
107
|
"valtio": "^2.3.1",
|
|
98
|
-
"@korioinc/next-conf": "2.0.
|
|
108
|
+
"@korioinc/next-conf": "2.0.35"
|
|
99
109
|
},
|
|
100
110
|
"publishConfig": {
|
|
101
111
|
"access": "public",
|
|
@@ -109,10 +119,9 @@
|
|
|
109
119
|
"author": "Korio Inc.",
|
|
110
120
|
"peerDependencies": {
|
|
111
121
|
"@headlessui/react": ">=2.2.0",
|
|
112
|
-
"@lingui/core": ">=5.9.
|
|
113
|
-
"@lingui/react": ">=5.9.
|
|
114
|
-
"next": ">=16.1
|
|
115
|
-
"next-themes": ">=0.4.6",
|
|
122
|
+
"@lingui/core": ">=5.9.4",
|
|
123
|
+
"@lingui/react": ">=5.9.4",
|
|
124
|
+
"next": ">=16.2.1",
|
|
116
125
|
"react": ">=19.2.4",
|
|
117
126
|
"react-dom": ">=19.2.4",
|
|
118
127
|
"tailwindcss": ">=4.0.0"
|