@koine/next 2.0.0-beta.80 → 2.0.0-beta.83

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/12.cjs.js CHANGED
@@ -4,50 +4,31 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var router = require('next/router');
7
- var Script = require('next/script');
7
+ var o = require('next/script');
8
8
  var react = require('react');
9
9
  var browser = require('@koine/browser');
10
- var Head = require('next/head');
10
+ var r = require('next/head');
11
11
 
12
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
13
 
14
- var Script__default = /*#__PURE__*/_interopDefaultLegacy(Script);
15
- var Head__default = /*#__PURE__*/_interopDefaultLegacy(Head);
16
-
17
- let AnalyticsGoogle = ({ id }) => {
18
- const uid = id || process.env["NEXT_PUBLIC_GTM_ID"];
19
- const { events, asPath, query } = router.useRouter();
20
- const [ready, setReady] = react.useState(false);
21
- const [routed, setRouted] = react.useState(false);
22
- react.useEffect(() => {
23
- const handleRouteChange = () => {
24
- setRouted(true);
25
- };
26
- events.on("routeChangeComplete", handleRouteChange);
27
- return () => {
28
- events.off("routeChangeComplete", handleRouteChange);
29
- };
30
- }, [events]);
31
- react.useEffect(() => {
32
- if (routed && ready && asPath) {
33
- browser.gtagPageview(asPath);
34
- }
35
- }, [asPath, query, routed, ready]);
36
- if (!uid) {
37
- return null;
38
- }
39
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Script__default["default"], { id: "google-tagmanager", src: `https://www.googletagmanager.com/gtag/js?id=${id}`, strategy: "afterInteractive", onLoad: () => setReady(true) }), jsxRuntime.jsx(Script__default["default"], { id: "google-analytics", strategy: "afterInteractive", children: `
14
+ var o__default = /*#__PURE__*/_interopDefaultLegacy(o);
15
+ var r__default = /*#__PURE__*/_interopDefaultLegacy(r);
16
+
17
+ /** Falls back to `.env` variable `NEXT_PUBLIC_GTM_ID` */let AnalyticsGoogle=({id:s})=>{let l=s||process.env.NEXT_PUBLIC_GTM_ID,{events:m,asPath:c,query:d}=router.useRouter(),[p,f]=react.useState(!1),[w,u]=react.useState(!1);return (// const [url, setUrl] = useState("");
18
+ react.useEffect(()=>{let e=()=>{u(!0);};return m.on("routeChangeComplete",e),()=>{m.off("routeChangeComplete",e);}},[m]),react.useEffect(()=>{w&&p&&c&&// const search = query;
19
+ browser.gtagPageview(c);},[c,d,w,p]),l)?/*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[/*#__PURE__*/jsxRuntime.jsx(o__default["default"],{id:"google-tagmanager",src:`https://www.googletagmanager.com/gtag/js?id=${s}`,strategy:"afterInteractive",onLoad:()=>f(!0)}),/*#__PURE__*/jsxRuntime.jsx(o__default["default"],{id:"google-analytics",strategy:"afterInteractive",children:`
40
20
  window.dataLayer = window.dataLayer || [];
41
21
  function gtag(){window.dataLayer.push(arguments);}
42
22
  gtag('js', new Date());
43
23
 
44
- gtag('config', '${id}', { 'send_page_view': false });
45
- ` })] }));
46
- };
24
+ gtag('config', '${s}', { 'send_page_view': false });
25
+ `})]}):null};
47
26
 
48
- let DisableErrorOverlay = () => (jsxRuntime.jsx(Head__default["default"], { children: process.env["NODE_ENV"] === "development" && (jsxRuntime.jsx("script", { dangerouslySetInnerHTML: {
49
- __html: `window.addEventListener('error',event =>{event.stopImmediatePropagation()});window.addEventListener('unhandledrejection',event =>{event.stopImmediatePropagation()});`,
50
- } })) }));
27
+ /**
28
+ * Disable error overlay during `dev`
29
+ *
30
+ * @see https://github.com/vercel/next.js/discussions/13387#discussioncomment-101564
31
+ */let DisableErrorOverlay=()=>/*#__PURE__*/jsxRuntime.jsx(r__default["default"],{children:"development"===process.env.NODE_ENV&&/*#__PURE__*/jsxRuntime.jsx("script",{dangerouslySetInnerHTML:{__html:"window.addEventListener('error',event =>{event.stopImmediatePropagation()});window.addEventListener('unhandledrejection',event =>{event.stopImmediatePropagation()});"}})});
51
32
 
52
33
  exports.AnalyticsGoogle = AnalyticsGoogle;
53
34
  exports.DisableErrorOverlay = DisableErrorOverlay;
package/12.esm.js CHANGED
@@ -1,43 +1,24 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import { useRouter } from 'next/router';
3
- import Script from 'next/script';
3
+ import o from 'next/script';
4
4
  import { useState, useEffect } from 'react';
5
5
  import { gtagPageview } from '@koine/browser';
6
- import Head from 'next/head';
6
+ import r from 'next/head';
7
7
 
8
- let AnalyticsGoogle = ({ id }) => {
9
- const uid = id || process.env["NEXT_PUBLIC_GTM_ID"];
10
- const { events, asPath, query } = useRouter();
11
- const [ready, setReady] = useState(false);
12
- const [routed, setRouted] = useState(false);
13
- useEffect(() => {
14
- const handleRouteChange = () => {
15
- setRouted(true);
16
- };
17
- events.on("routeChangeComplete", handleRouteChange);
18
- return () => {
19
- events.off("routeChangeComplete", handleRouteChange);
20
- };
21
- }, [events]);
22
- useEffect(() => {
23
- if (routed && ready && asPath) {
24
- gtagPageview(asPath);
25
- }
26
- }, [asPath, query, routed, ready]);
27
- if (!uid) {
28
- return null;
29
- }
30
- return (jsxs(Fragment, { children: [jsx(Script, { id: "google-tagmanager", src: `https://www.googletagmanager.com/gtag/js?id=${id}`, strategy: "afterInteractive", onLoad: () => setReady(true) }), jsx(Script, { id: "google-analytics", strategy: "afterInteractive", children: `
8
+ /** Falls back to `.env` variable `NEXT_PUBLIC_GTM_ID` */let AnalyticsGoogle=({id:s})=>{let l=s||process.env.NEXT_PUBLIC_GTM_ID,{events:m,asPath:c,query:d}=useRouter(),[p,f]=useState(!1),[w,u]=useState(!1);return (// const [url, setUrl] = useState("");
9
+ useEffect(()=>{let e=()=>{u(!0);};return m.on("routeChangeComplete",e),()=>{m.off("routeChangeComplete",e);}},[m]),useEffect(()=>{w&&p&&c&&// const search = query;
10
+ gtagPageview(c);},[c,d,w,p]),l)?/*#__PURE__*/jsxs(Fragment,{children:[/*#__PURE__*/jsx(o,{id:"google-tagmanager",src:`https://www.googletagmanager.com/gtag/js?id=${s}`,strategy:"afterInteractive",onLoad:()=>f(!0)}),/*#__PURE__*/jsx(o,{id:"google-analytics",strategy:"afterInteractive",children:`
31
11
  window.dataLayer = window.dataLayer || [];
32
12
  function gtag(){window.dataLayer.push(arguments);}
33
13
  gtag('js', new Date());
34
14
 
35
- gtag('config', '${id}', { 'send_page_view': false });
36
- ` })] }));
37
- };
15
+ gtag('config', '${s}', { 'send_page_view': false });
16
+ `})]}):null};
38
17
 
39
- let DisableErrorOverlay = () => (jsx(Head, { children: process.env["NODE_ENV"] === "development" && (jsx("script", { dangerouslySetInnerHTML: {
40
- __html: `window.addEventListener('error',event =>{event.stopImmediatePropagation()});window.addEventListener('unhandledrejection',event =>{event.stopImmediatePropagation()});`,
41
- } })) }));
18
+ /**
19
+ * Disable error overlay during `dev`
20
+ *
21
+ * @see https://github.com/vercel/next.js/discussions/13387#discussioncomment-101564
22
+ */let DisableErrorOverlay=()=>/*#__PURE__*/jsx(r,{children:"development"===process.env.NODE_ENV&&/*#__PURE__*/jsx("script",{dangerouslySetInnerHTML:{__html:"window.addEventListener('error',event =>{event.stopImmediatePropagation()});window.addEventListener('unhandledrejection',event =>{event.stopImmediatePropagation()});"}})});
42
23
 
43
24
  export { AnalyticsGoogle, DisableErrorOverlay };
@@ -4,10 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var react = require('react');
6
6
 
7
- const ThemeContext = react.createContext({
8
- setTheme: (_) => { },
9
- themes: [],
10
- });
7
+ /** List of all available theme names *//** Forced theme name for the current page *//** Update the theme *//** Active theme name *//** If `enableSystem` is true and the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` *//** If enableSystem is true, returns the System theme preference ("dark" or "light"), regardless what the active theme is */const ThemeContext=/*#__PURE__*/react.createContext({// eslint-disable-next-line @typescript-eslint/no-empty-function
8
+ setTheme:e=>{},themes:[]});
11
9
 
12
10
  exports.ThemeContext = ThemeContext;
13
11
  exports["default"] = ThemeContext;
@@ -1,8 +1,6 @@
1
1
  import { createContext } from 'react';
2
2
 
3
- const ThemeContext = createContext({
4
- setTheme: (_) => { },
5
- themes: [],
6
- });
3
+ /** List of all available theme names *//** Forced theme name for the current page *//** Update the theme *//** Active theme name *//** If `enableSystem` is true and the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` *//** If enableSystem is true, returns the System theme preference ("dark" or "light"), regardless what the active theme is */const ThemeContext=/*#__PURE__*/createContext({// eslint-disable-next-line @typescript-eslint/no-empty-function
4
+ setTheme:e=>{},themes:[]});
7
5
 
8
6
  export { ThemeContext, ThemeContext as default };
@@ -3,212 +3,45 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
- var Script = require('next/script');
6
+ var o = require('next/script');
7
7
  var react = require('react');
8
8
  var utils = require('@koine/utils');
9
9
  var ThemeContext = require('./ThemeContext.cjs.js');
10
10
 
11
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
12
 
13
- var Script__default = /*#__PURE__*/_interopDefaultLegacy(Script);
13
+ var o__default = /*#__PURE__*/_interopDefaultLegacy(o);
14
14
 
15
- const colorSchemes = ["light", "dark"];
16
- const MEDIA = "(prefers-color-scheme: dark)";
17
- const THEME_STORAGE_KEY = "theme";
18
- const ThemeProvider = ({ forcedTheme, disableTransitionOnChange = false, enableSystem = true, enableColorScheme, themes = ["light", "dark"], defaultTheme = enableSystem ? "system" : "light", attribute = "data-theme", value, children, nonce, }) => {
19
- const [theme, setThemeState] = react.useState(() => getTheme(THEME_STORAGE_KEY, defaultTheme));
20
- const [resolvedTheme, setResolvedTheme] = react.useState(() => getTheme(THEME_STORAGE_KEY));
21
- const attrs = !value ? themes : Object.values(value);
22
- const applyTheme = react.useCallback((theme) => {
23
- let resolved = theme;
24
- if (utils.isServer || !resolved)
25
- return;
26
- if (theme === "system" && enableSystem) {
27
- resolved = getSystemTheme();
28
- }
29
- const name = value ? value[resolved] : resolved;
30
- const enable = disableTransitionOnChange ? disableAnimation() : null;
31
- const d = document.documentElement;
32
- if (attribute === "class") {
33
- d.classList.remove(...attrs);
34
- if (name)
35
- d.classList.add(name);
36
- }
37
- else {
38
- if (name) {
39
- d.setAttribute(attribute, name);
40
- }
41
- else {
42
- d.removeAttribute(attribute);
43
- }
44
- }
45
- if (enableColorScheme) {
46
- const fallback = colorSchemes.includes(defaultTheme)
47
- ? defaultTheme
48
- : "";
49
- const colorScheme = colorSchemes.includes(resolved)
50
- ? resolved
51
- : fallback;
52
- d.style.colorScheme = colorScheme;
53
- }
54
- enable?.();
55
- }, [
56
- attribute,
57
- attrs,
58
- defaultTheme,
59
- disableTransitionOnChange,
60
- enableColorScheme,
61
- enableSystem,
62
- value,
63
- ]);
64
- const setTheme = react.useCallback((theme) => {
65
- setThemeState(theme);
66
- try {
67
- localStorage.setItem(THEME_STORAGE_KEY, theme);
68
- }
69
- catch (e) {
70
- }
71
- }, []);
72
- const handleMediaQuery = react.useCallback((e) => {
73
- const resolved = getSystemTheme(e);
74
- setResolvedTheme(resolved);
75
- if (theme === "system" && enableSystem && !forcedTheme) {
76
- applyTheme("system");
77
- }
78
- }, [theme, enableSystem, forcedTheme, applyTheme]);
79
- react.useEffect(() => {
80
- const media = window.matchMedia(MEDIA);
81
- media.addListener(handleMediaQuery);
82
- handleMediaQuery(media);
83
- return () => media.removeListener(handleMediaQuery);
84
- }, [handleMediaQuery]);
85
- react.useEffect(() => {
86
- const handleStorage = (e) => {
87
- if (e.key !== THEME_STORAGE_KEY) {
88
- return;
89
- }
90
- const theme = e.newValue || defaultTheme;
91
- setTheme(theme);
92
- };
93
- window.addEventListener("storage", handleStorage);
94
- return () => window.removeEventListener("storage", handleStorage);
95
- }, [defaultTheme, setTheme]);
96
- react.useEffect(() => {
97
- applyTheme(forcedTheme ?? theme);
98
- }, [applyTheme, forcedTheme, theme]);
99
- return (jsxRuntime.jsxs(ThemeContext.ThemeContext.Provider, { value: {
100
- theme,
101
- setTheme,
102
- forcedTheme,
103
- resolvedTheme: theme === "system" ? resolvedTheme : theme,
104
- themes: enableSystem ? [...themes, "system"] : themes,
105
- systemTheme: (enableSystem ? resolvedTheme : undefined),
106
- }, children: [jsxRuntime.jsx(ThemeScript, { forcedTheme,
107
- disableTransitionOnChange,
108
- enableSystem,
109
- enableColorScheme,
110
- themes,
111
- defaultTheme,
112
- attribute,
113
- value,
114
- children,
115
- attrs,
116
- nonce }), children] }));
117
- };
118
- const ThemeScript = react.memo(({ forcedTheme, attribute, enableSystem, enableColorScheme, defaultTheme, value, attrs, nonce, }) => {
119
- const defaultSystem = defaultTheme === "system";
120
- const optimization = (() => {
121
- const removeClasses = `d.remove(${attrs
122
- .map((t) => `'${t}'`)
123
- .join(",")})`;
124
- return `var d=document.documentElement.classList;${removeClasses};`;
125
- })();
126
- const fallbackColorScheme = (() => {
127
- if (!enableColorScheme) {
128
- return "";
129
- }
130
- const fallback = colorSchemes.includes(defaultTheme)
131
- ? defaultTheme
132
- : null;
133
- if (fallback) {
134
- return `if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${defaultTheme}'`;
135
- }
136
- else {
137
- return `if(e==='light'||e==='dark')d.style.colorScheme=e`;
138
- }
139
- })();
140
- const updateDOM = (name, literal = false, setColorScheme = true) => {
141
- const resolvedName = value ? value[name] : name;
142
- const val = literal ? name + `|| ''` : `'${resolvedName}'`;
143
- let text = "";
144
- if (enableColorScheme &&
145
- setColorScheme &&
146
- !literal &&
147
- colorSchemes.includes(name)) {
148
- text += `d.style.colorScheme = '${name}';`;
149
- }
150
- if (attribute === "class") {
151
- if (literal || resolvedName) {
152
- text += `d.add(${val})`;
153
- }
154
- else {
155
- text += `null`;
156
- }
157
- }
158
- else {
159
- if (resolvedName) {
160
- text += `d[s](n, ${val})`;
161
- }
162
- }
163
- return text;
164
- };
165
- const scriptSrc = (() => {
166
- if (forcedTheme) {
167
- return `!function(){${optimization}${updateDOM(forcedTheme)}}()`;
168
- }
169
- if (enableSystem) {
170
- return `!function(){try {${optimization}var e=localStorage.getItem('${THEME_STORAGE_KEY}');if("system"===e||(!e&&${defaultSystem})){var t="${MEDIA}",m=window.matchMedia(t);if(m.media!==t||m.matches){${updateDOM("dark")}}else{${updateDOM("light")}}}else if(e){${value ? `var x=${JSON.stringify(value)};` : ""}${updateDOM(value ? `x[e]` : "e", true)}}${!defaultSystem
171
- ? `else{` + updateDOM(defaultTheme, false, false) + "}"
172
- : ""}${fallbackColorScheme}}catch(e){}}()`;
173
- }
174
- return `!function(){try{${optimization}var e=localStorage.getItem("${THEME_STORAGE_KEY}");if(e){${value ? `var x=${JSON.stringify(value)};` : ""}${updateDOM(value ? `x[e]` : "e", true)}}else{${updateDOM(defaultTheme, false, false)};}${fallbackColorScheme}}catch(t){}}();`;
175
- })();
176
- const encodedScript = `data:text/javascript;base64,${encodeBase64(scriptSrc)}`;
177
- return (jsxRuntime.jsx(Script__default["default"], { id: "next-theme-script", strategy: "beforeInteractive", src: encodedScript, nonce: nonce }));
178
- }, () => true);
179
- const getTheme = (key, fallback) => {
180
- if (utils.isServer)
181
- return undefined;
182
- let theme;
183
- try {
184
- theme = localStorage.getItem(key) || undefined;
185
- }
186
- catch (e) {
187
- }
188
- return theme || fallback;
189
- };
190
- const disableAnimation = () => {
191
- const d = document;
192
- const css = d.createElement("style");
193
- css.appendChild(d.createTextNode(`*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`));
194
- d.head.appendChild(css);
195
- return () => {
196
- (() => window.getComputedStyle(d.body))();
197
- setTimeout(() => {
198
- d.head.removeChild(css);
199
- }, 1);
200
- };
201
- };
202
- const getSystemTheme = (e) => {
203
- if (!e)
204
- e = window.matchMedia(MEDIA);
205
- const isDark = e.matches;
206
- const systemTheme = isDark ? "dark" : "light";
207
- return systemTheme;
208
- };
209
- const encodeBase64 = (str) => {
210
- return utils.isServer ? Buffer.from(str).toString("base64") : btoa(str);
211
- };
15
+ let l=["light","dark"],d="(prefers-color-scheme: dark)",c="theme";/** List of all available theme names *//** Forced theme name for the current page *//** Whether to switch between dark and light themes based on prefers-color-scheme *//** Disable all CSS transitions when switching themes *//** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons *//** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light *//** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) *//** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value *//** Nonce string to pass to the inline script for CSP headers *//**
16
+ * @borrows [next-themes](https://github.com/pacocoursey/next-themes)
17
+ *
18
+ * Differences:
19
+ *
20
+ * - enableColorScheme: `false` by default (instead of `true`), this plays more
21
+ * nicely with tailwind `dark` class mode as dark theme is supposed to be only
22
+ * controlled by tailwind modifiers
23
+ */const ThemeProvider=({forcedTheme:r,disableTransitionOnChange:o=!1,enableSystem:v=!0,enableColorScheme:y,themes:p=["light","dark"],defaultTheme:g=v?"system":"light",attribute:w="data-theme",value:x,children:S,nonce:k})=>{let[b,L]=react.useState(()=>u(c,g)),[T,j]=react.useState(()=>u(c)),C=x?Object.values(x):p,E=react.useCallback(e=>{let t=e;if(utils.isServer||!t)return;"system"===// If theme is system, resolve it before setting theme
24
+ e&&v&&(t=f());let r=x?x[t]:t,i=o?$():null,n=document.documentElement;if("class"===w?(n.classList.remove(...C),r&&n.classList.add(r)):r?n.setAttribute(w,r):n.removeAttribute(w),y){let e=l.includes(g)?g:"",r=l.includes(t)?t:e;n.style.colorScheme=r;}i?.();},[w,C,g,o,y,v,x]),I=react.useCallback(e=>{L(e);// Save to storage
25
+ try{localStorage.setItem(c,e);}catch(e){}},// Unsupported
26
+ []),M=react.useCallback(e=>{j(f(e)),"system"===b&&v&&!r&&E("system");},[b,v,r,E]);return(// Always listen to System preference
27
+ react.useEffect(()=>{let e=window.matchMedia(d);return(// Intentionally use deprecated listener methods to support iOS & old browsers
28
+ e.addListener(M),M(e),()=>e.removeListener(M))},[M]),// localStorage event handling
29
+ react.useEffect(()=>{let e=e=>{e.key===c&&I(// If default theme set, use it if localstorage === null (happens on local storage manual deletion)
30
+ e.newValue||g);};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[g,I]),// Whenever theme or forcedTheme changes, apply it
31
+ react.useEffect(()=>{E(r??b);},[E,r,b]),/*#__PURE__*/jsxRuntime.jsxs(ThemeContext.ThemeContext.Provider,{value:{theme:b,setTheme:I,forcedTheme:r,resolvedTheme:"system"===b?T:b,themes:v?[...p,"system"]:p,systemTheme:v?T:void 0},children:[/*#__PURE__*/jsxRuntime.jsx(h,{forcedTheme:r,disableTransitionOnChange:o,enableSystem:v,enableColorScheme:y,themes:p,defaultTheme:g,attribute:w,value:x,children:S,attrs:C,nonce:k}),S]}))};let h=/*#__PURE__*/react.memo(({forcedTheme:t,attribute:o,enableSystem:i,enableColorScheme:n,defaultTheme:s,value:a,attrs:m,nonce:h})=>{let u="system"===s,// Code-golfing the amount of characters in the script
32
+ $=(()=>{let e=`d.remove(${m.map(e=>`'${e}'`).join(",")})`;return `var d=document.documentElement.classList;${e};`})(),f=n?(l.includes(s)?s:null)?`if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${s}'`:"if(e==='light'||e==='dark')d.style.colorScheme=e":"",y=(e,t=!1,r=!0)=>{let i=a?a[e]:e,s=t?e+"|| ''":`'${i}'`,m="";return(// MUCH faster to set colorScheme alongside HTML attribute/class
33
+ // as it only incurs 1 style recalculation rather than 2
34
+ // This can save over 250ms of work for pages with big DOM
35
+ n&&r&&!t&&l.includes(e)&&(m+=`d.style.colorScheme = '${e}';`),"class"===o?t||i?m+=`d.add(${s})`:m+="null":i&&(m+=`d[s](n, ${s})`),m)},p=t?`!function(){${$}${y(t)}}()`:i?`!function(){try {${$}var e=localStorage.getItem('${c}');if("system"===e||(!e&&${u})){var t="${d}",m=window.matchMedia(t);if(m.media!==t||m.matches){${y("dark")}}else{${y("light")}}}else if(e){${a?`var x=${JSON.stringify(a)};`:""}${y(a?"x[e]":"e",!0)}}${u?"":"else{"+y(s,!1,!1)+"}"}${f}}catch(e){}}()`:`!function(){try{${$}var e=localStorage.getItem("${c}");if(e){${a?`var x=${JSON.stringify(a)};`:""}${y(a?"x[e]":"e",!0)}}else{${y(s,!1,!1)};}${f}}catch(t){}}();`;return /*#__PURE__*/jsxRuntime.jsx(o__default["default"],{id:"next-theme-script",strategy:"beforeInteractive",src:// We MUST use next/script's `beforeInteractive` strategy to avoid flashing on load.
36
+ // However, it only accepts the `src` prop, not `dangerouslySetInnerHTML` or `children`
37
+ // But our script cannot be external because it changes at runtime based on React props
38
+ // so we trick next/script by passing `src` as a base64 JS script
39
+ `data:text/javascript;base64,${v(p)}`,nonce:h})},// Never re-render this component
40
+ ()=>!0),// Helpers
41
+ u=(e,t)=>{let r;if(!utils.isServer){try{r=localStorage.getItem(e)||void 0;}catch(e){}// Unsupported
42
+ return r||t}},$=()=>{let e=document,t=e.createElement("style");return t.appendChild(e.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),e.head.appendChild(t),()=>{// Force restyle
43
+ window.getComputedStyle(e.body),// Wait for next tick before removing
44
+ setTimeout(()=>{e.head.removeChild(t);},1);}},f=e=>(e||(e=window.matchMedia(d)),e.matches?"dark":"light"),v=e=>utils.isServer?Buffer.from(e).toString("base64"):btoa(e);
212
45
 
213
46
  exports.ThemeProvider = ThemeProvider;
214
47
  exports["default"] = ThemeProvider;
@@ -1,205 +1,38 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import Script from 'next/script';
3
- import { memo, useState, useCallback, useEffect } from 'react';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import o from 'next/script';
3
+ import { useState, useCallback, useEffect, memo } from 'react';
4
4
  import { isServer } from '@koine/utils';
5
5
  import { ThemeContext } from './ThemeContext.esm.js';
6
6
 
7
- const colorSchemes = ["light", "dark"];
8
- const MEDIA = "(prefers-color-scheme: dark)";
9
- const THEME_STORAGE_KEY = "theme";
10
- const ThemeProvider = ({ forcedTheme, disableTransitionOnChange = false, enableSystem = true, enableColorScheme, themes = ["light", "dark"], defaultTheme = enableSystem ? "system" : "light", attribute = "data-theme", value, children, nonce, }) => {
11
- const [theme, setThemeState] = useState(() => getTheme(THEME_STORAGE_KEY, defaultTheme));
12
- const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(THEME_STORAGE_KEY));
13
- const attrs = !value ? themes : Object.values(value);
14
- const applyTheme = useCallback((theme) => {
15
- let resolved = theme;
16
- if (isServer || !resolved)
17
- return;
18
- if (theme === "system" && enableSystem) {
19
- resolved = getSystemTheme();
20
- }
21
- const name = value ? value[resolved] : resolved;
22
- const enable = disableTransitionOnChange ? disableAnimation() : null;
23
- const d = document.documentElement;
24
- if (attribute === "class") {
25
- d.classList.remove(...attrs);
26
- if (name)
27
- d.classList.add(name);
28
- }
29
- else {
30
- if (name) {
31
- d.setAttribute(attribute, name);
32
- }
33
- else {
34
- d.removeAttribute(attribute);
35
- }
36
- }
37
- if (enableColorScheme) {
38
- const fallback = colorSchemes.includes(defaultTheme)
39
- ? defaultTheme
40
- : "";
41
- const colorScheme = colorSchemes.includes(resolved)
42
- ? resolved
43
- : fallback;
44
- d.style.colorScheme = colorScheme;
45
- }
46
- enable?.();
47
- }, [
48
- attribute,
49
- attrs,
50
- defaultTheme,
51
- disableTransitionOnChange,
52
- enableColorScheme,
53
- enableSystem,
54
- value,
55
- ]);
56
- const setTheme = useCallback((theme) => {
57
- setThemeState(theme);
58
- try {
59
- localStorage.setItem(THEME_STORAGE_KEY, theme);
60
- }
61
- catch (e) {
62
- }
63
- }, []);
64
- const handleMediaQuery = useCallback((e) => {
65
- const resolved = getSystemTheme(e);
66
- setResolvedTheme(resolved);
67
- if (theme === "system" && enableSystem && !forcedTheme) {
68
- applyTheme("system");
69
- }
70
- }, [theme, enableSystem, forcedTheme, applyTheme]);
71
- useEffect(() => {
72
- const media = window.matchMedia(MEDIA);
73
- media.addListener(handleMediaQuery);
74
- handleMediaQuery(media);
75
- return () => media.removeListener(handleMediaQuery);
76
- }, [handleMediaQuery]);
77
- useEffect(() => {
78
- const handleStorage = (e) => {
79
- if (e.key !== THEME_STORAGE_KEY) {
80
- return;
81
- }
82
- const theme = e.newValue || defaultTheme;
83
- setTheme(theme);
84
- };
85
- window.addEventListener("storage", handleStorage);
86
- return () => window.removeEventListener("storage", handleStorage);
87
- }, [defaultTheme, setTheme]);
88
- useEffect(() => {
89
- applyTheme(forcedTheme ?? theme);
90
- }, [applyTheme, forcedTheme, theme]);
91
- return (jsxs(ThemeContext.Provider, { value: {
92
- theme,
93
- setTheme,
94
- forcedTheme,
95
- resolvedTheme: theme === "system" ? resolvedTheme : theme,
96
- themes: enableSystem ? [...themes, "system"] : themes,
97
- systemTheme: (enableSystem ? resolvedTheme : undefined),
98
- }, children: [jsx(ThemeScript, { forcedTheme,
99
- disableTransitionOnChange,
100
- enableSystem,
101
- enableColorScheme,
102
- themes,
103
- defaultTheme,
104
- attribute,
105
- value,
106
- children,
107
- attrs,
108
- nonce }), children] }));
109
- };
110
- const ThemeScript = memo(({ forcedTheme, attribute, enableSystem, enableColorScheme, defaultTheme, value, attrs, nonce, }) => {
111
- const defaultSystem = defaultTheme === "system";
112
- const optimization = (() => {
113
- const removeClasses = `d.remove(${attrs
114
- .map((t) => `'${t}'`)
115
- .join(",")})`;
116
- return `var d=document.documentElement.classList;${removeClasses};`;
117
- })();
118
- const fallbackColorScheme = (() => {
119
- if (!enableColorScheme) {
120
- return "";
121
- }
122
- const fallback = colorSchemes.includes(defaultTheme)
123
- ? defaultTheme
124
- : null;
125
- if (fallback) {
126
- return `if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${defaultTheme}'`;
127
- }
128
- else {
129
- return `if(e==='light'||e==='dark')d.style.colorScheme=e`;
130
- }
131
- })();
132
- const updateDOM = (name, literal = false, setColorScheme = true) => {
133
- const resolvedName = value ? value[name] : name;
134
- const val = literal ? name + `|| ''` : `'${resolvedName}'`;
135
- let text = "";
136
- if (enableColorScheme &&
137
- setColorScheme &&
138
- !literal &&
139
- colorSchemes.includes(name)) {
140
- text += `d.style.colorScheme = '${name}';`;
141
- }
142
- if (attribute === "class") {
143
- if (literal || resolvedName) {
144
- text += `d.add(${val})`;
145
- }
146
- else {
147
- text += `null`;
148
- }
149
- }
150
- else {
151
- if (resolvedName) {
152
- text += `d[s](n, ${val})`;
153
- }
154
- }
155
- return text;
156
- };
157
- const scriptSrc = (() => {
158
- if (forcedTheme) {
159
- return `!function(){${optimization}${updateDOM(forcedTheme)}}()`;
160
- }
161
- if (enableSystem) {
162
- return `!function(){try {${optimization}var e=localStorage.getItem('${THEME_STORAGE_KEY}');if("system"===e||(!e&&${defaultSystem})){var t="${MEDIA}",m=window.matchMedia(t);if(m.media!==t||m.matches){${updateDOM("dark")}}else{${updateDOM("light")}}}else if(e){${value ? `var x=${JSON.stringify(value)};` : ""}${updateDOM(value ? `x[e]` : "e", true)}}${!defaultSystem
163
- ? `else{` + updateDOM(defaultTheme, false, false) + "}"
164
- : ""}${fallbackColorScheme}}catch(e){}}()`;
165
- }
166
- return `!function(){try{${optimization}var e=localStorage.getItem("${THEME_STORAGE_KEY}");if(e){${value ? `var x=${JSON.stringify(value)};` : ""}${updateDOM(value ? `x[e]` : "e", true)}}else{${updateDOM(defaultTheme, false, false)};}${fallbackColorScheme}}catch(t){}}();`;
167
- })();
168
- const encodedScript = `data:text/javascript;base64,${encodeBase64(scriptSrc)}`;
169
- return (jsx(Script, { id: "next-theme-script", strategy: "beforeInteractive", src: encodedScript, nonce: nonce }));
170
- }, () => true);
171
- const getTheme = (key, fallback) => {
172
- if (isServer)
173
- return undefined;
174
- let theme;
175
- try {
176
- theme = localStorage.getItem(key) || undefined;
177
- }
178
- catch (e) {
179
- }
180
- return theme || fallback;
181
- };
182
- const disableAnimation = () => {
183
- const d = document;
184
- const css = d.createElement("style");
185
- css.appendChild(d.createTextNode(`*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`));
186
- d.head.appendChild(css);
187
- return () => {
188
- (() => window.getComputedStyle(d.body))();
189
- setTimeout(() => {
190
- d.head.removeChild(css);
191
- }, 1);
192
- };
193
- };
194
- const getSystemTheme = (e) => {
195
- if (!e)
196
- e = window.matchMedia(MEDIA);
197
- const isDark = e.matches;
198
- const systemTheme = isDark ? "dark" : "light";
199
- return systemTheme;
200
- };
201
- const encodeBase64 = (str) => {
202
- return isServer ? Buffer.from(str).toString("base64") : btoa(str);
203
- };
7
+ let l=["light","dark"],d="(prefers-color-scheme: dark)",c="theme";/** List of all available theme names *//** Forced theme name for the current page *//** Whether to switch between dark and light themes based on prefers-color-scheme *//** Disable all CSS transitions when switching themes *//** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons *//** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light *//** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) *//** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value *//** Nonce string to pass to the inline script for CSP headers *//**
8
+ * @borrows [next-themes](https://github.com/pacocoursey/next-themes)
9
+ *
10
+ * Differences:
11
+ *
12
+ * - enableColorScheme: `false` by default (instead of `true`), this plays more
13
+ * nicely with tailwind `dark` class mode as dark theme is supposed to be only
14
+ * controlled by tailwind modifiers
15
+ */const ThemeProvider=({forcedTheme:r,disableTransitionOnChange:o=!1,enableSystem:v=!0,enableColorScheme:y,themes:p=["light","dark"],defaultTheme:g=v?"system":"light",attribute:w="data-theme",value:x,children:S,nonce:k})=>{let[b,L]=useState(()=>u(c,g)),[T,j]=useState(()=>u(c)),C=x?Object.values(x):p,E=useCallback(e=>{let t=e;if(isServer||!t)return;"system"===// If theme is system, resolve it before setting theme
16
+ e&&v&&(t=f());let r=x?x[t]:t,i=o?$():null,n=document.documentElement;if("class"===w?(n.classList.remove(...C),r&&n.classList.add(r)):r?n.setAttribute(w,r):n.removeAttribute(w),y){let e=l.includes(g)?g:"",r=l.includes(t)?t:e;n.style.colorScheme=r;}i?.();},[w,C,g,o,y,v,x]),I=useCallback(e=>{L(e);// Save to storage
17
+ try{localStorage.setItem(c,e);}catch(e){}},// Unsupported
18
+ []),M=useCallback(e=>{j(f(e)),"system"===b&&v&&!r&&E("system");},[b,v,r,E]);return(// Always listen to System preference
19
+ useEffect(()=>{let e=window.matchMedia(d);return(// Intentionally use deprecated listener methods to support iOS & old browsers
20
+ e.addListener(M),M(e),()=>e.removeListener(M))},[M]),// localStorage event handling
21
+ useEffect(()=>{let e=e=>{e.key===c&&I(// If default theme set, use it if localstorage === null (happens on local storage manual deletion)
22
+ e.newValue||g);};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[g,I]),// Whenever theme or forcedTheme changes, apply it
23
+ useEffect(()=>{E(r??b);},[E,r,b]),/*#__PURE__*/jsxs(ThemeContext.Provider,{value:{theme:b,setTheme:I,forcedTheme:r,resolvedTheme:"system"===b?T:b,themes:v?[...p,"system"]:p,systemTheme:v?T:void 0},children:[/*#__PURE__*/jsx(h,{forcedTheme:r,disableTransitionOnChange:o,enableSystem:v,enableColorScheme:y,themes:p,defaultTheme:g,attribute:w,value:x,children:S,attrs:C,nonce:k}),S]}))};let h=/*#__PURE__*/memo(({forcedTheme:t,attribute:o$1,enableSystem:i,enableColorScheme:n,defaultTheme:s,value:a,attrs:m,nonce:h})=>{let u="system"===s,// Code-golfing the amount of characters in the script
24
+ $=(()=>{let e=`d.remove(${m.map(e=>`'${e}'`).join(",")})`;return `var d=document.documentElement.classList;${e};`})(),f=n?(l.includes(s)?s:null)?`if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${s}'`:"if(e==='light'||e==='dark')d.style.colorScheme=e":"",y=(e,t=!1,r=!0)=>{let i=a?a[e]:e,s=t?e+"|| ''":`'${i}'`,m="";return(// MUCH faster to set colorScheme alongside HTML attribute/class
25
+ // as it only incurs 1 style recalculation rather than 2
26
+ // This can save over 250ms of work for pages with big DOM
27
+ n&&r&&!t&&l.includes(e)&&(m+=`d.style.colorScheme = '${e}';`),"class"===o$1?t||i?m+=`d.add(${s})`:m+="null":i&&(m+=`d[s](n, ${s})`),m)},p=t?`!function(){${$}${y(t)}}()`:i?`!function(){try {${$}var e=localStorage.getItem('${c}');if("system"===e||(!e&&${u})){var t="${d}",m=window.matchMedia(t);if(m.media!==t||m.matches){${y("dark")}}else{${y("light")}}}else if(e){${a?`var x=${JSON.stringify(a)};`:""}${y(a?"x[e]":"e",!0)}}${u?"":"else{"+y(s,!1,!1)+"}"}${f}}catch(e){}}()`:`!function(){try{${$}var e=localStorage.getItem("${c}");if(e){${a?`var x=${JSON.stringify(a)};`:""}${y(a?"x[e]":"e",!0)}}else{${y(s,!1,!1)};}${f}}catch(t){}}();`;return /*#__PURE__*/jsx(o,{id:"next-theme-script",strategy:"beforeInteractive",src:// We MUST use next/script's `beforeInteractive` strategy to avoid flashing on load.
28
+ // However, it only accepts the `src` prop, not `dangerouslySetInnerHTML` or `children`
29
+ // But our script cannot be external because it changes at runtime based on React props
30
+ // so we trick next/script by passing `src` as a base64 JS script
31
+ `data:text/javascript;base64,${v(p)}`,nonce:h})},// Never re-render this component
32
+ ()=>!0),// Helpers
33
+ u=(e,t)=>{let r;if(!isServer){try{r=localStorage.getItem(e)||void 0;}catch(e){}// Unsupported
34
+ return r||t}},$=()=>{let e=document,t=e.createElement("style");return t.appendChild(e.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),e.head.appendChild(t),()=>{// Force restyle
35
+ window.getComputedStyle(e.body),// Wait for next tick before removing
36
+ setTimeout(()=>{e.head.removeChild(t);},1);}},f=e=>(e||(e=window.matchMedia(d)),e.matches?"dark":"light"),v=e=>isServer?Buffer.from(e).toString("base64"):btoa(e);
204
37
 
205
38
  export { ThemeProvider, ThemeProvider as default };
package/config.cjs.js CHANGED
@@ -4,81 +4,24 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var next = require('@koine/i18n/next');
6
6
 
7
- let withKoine = (options = {}) => {
8
- const { nx, svg, i18nRoutes, i18nCompiler, ...restNextConfig } = options;
9
- const nextConfig = {
10
- eslint: {
11
- ignoreDuringBuilds: true,
12
- },
13
- typescript: {
14
- ignoreBuildErrors: true,
15
- },
16
- poweredByHeader: false,
17
- experimental: {
18
- scrollRestoration: true,
19
- ...(restNextConfig.experimental || {}),
20
- },
21
- modularizeImports: {
22
- ...(restNextConfig.modularizeImports || {}),
23
- "@koine/api": { transform: "@koine/api/{{member}}" },
24
- "@koine/browser": { transform: "@koine/browser/{{member}}" },
25
- "@koine/dom": { transform: "@koine/dom/{{member}}" },
26
- "@koine/node": { transform: "@koine/node/{{member}}" },
27
- "@koine/i18n/?(((\\w*)?/?)*)": {
28
- transform: "@koine/i18n/{{ matches.[1] }}/{{member}}",
29
- },
30
- "@koine/react/?(((\\w*)?/?)*)": {
31
- transform: "@koine/react/{{ matches.[1] }}/{{member}}",
32
- },
33
- "@koine/next/?(((\\w*)?/?)*)": {
34
- transform: "@koine/next/{{ matches.[1] }}/{{member}}",
35
- },
36
- "@koine/utils": { transform: "@koine/utils/{{member}}" },
37
- },
38
- ...restNextConfig,
39
- };
40
- if (svg) {
41
- if (nx) {
42
- nextConfig["nx"] = { svgr: true };
43
- }
44
- else {
45
- delete nextConfig["nx"];
46
- nextConfig.webpack = (_config, options) => {
47
- const webpackConfig = typeof nextConfig.webpack === "function"
48
- ? nextConfig.webpack(_config, options)
49
- : _config;
50
- webpackConfig.module.rules.push({
51
- test: /\.svg$/,
52
- use: [
53
- {
54
- loader: "@svgr/webpack",
55
- options: {
56
- svgoConfig: {
57
- plugins: [
58
- {
59
- name: "removeViewBox",
60
- active: false,
61
- },
62
- ],
63
- },
64
- },
65
- },
66
- ],
67
- });
68
- return webpackConfig;
69
- };
70
- }
71
- }
72
- if (i18nRoutes) {
73
- return next.withI18nLegacy({ ...nextConfig, i18nRoutes });
74
- }
75
- if (i18nCompiler) {
76
- if (nx) {
77
- return next.withI18nAsync({ ...nextConfig, i18nCompiler });
78
- }
79
- return next.withI18n({ ...nextConfig, i18nCompiler });
80
- }
81
- return nextConfig;
82
- };
7
+ /**
8
+ * Get Next.js config with some basic opinionated defaults
9
+ *
10
+ * @param {object} options
11
+ * @property {boolean} [options.nx=false] Nx monorepo setup
12
+ * @property {boolean} [options.svg=false] SVG to react components
13
+ */let withKoine=(n={})=>{let{nx:i,svg:t,i18nRoutes:m,i18nCompiler:s,...a}=n,k={// @see https://nextjs.org/docs/api-reference/next.config.js/custom-page-extensions#including-non-page-files-in-the-pages-directory
14
+ eslint:{ignoreDuringBuilds:!0},// we have this strict check on each commit
15
+ typescript:{ignoreBuildErrors:!0},// we have this strict check on each commit
16
+ poweredByHeader:!1,experimental:{// @see https://github.com/vercel/vercel/discussions/5973#discussioncomment-472618
17
+ // @see critters error https://github.com/vercel/next.js/issues/20742
18
+ // optimizeCss: true,
19
+ // @see https://github.com/vercel/next.js/discussions/30174#discussion-3643870
20
+ scrollRestoration:!0,...a.experimental||{}},modularizeImports:{...a.modularizeImports||{},// @see https://www.zhoulujun.net/nextjs/advanced-features/compiler.html#modularize-imports
21
+ "@koine/api":{transform:"@koine/api/{{member}}"},"@koine/browser":{transform:"@koine/browser/{{member}}"},"@koine/dom":{transform:"@koine/dom/{{member}}"},"@koine/node":{transform:"@koine/node/{{member}}"},"@koine/i18n/?(((\\w*)?/?)*)":{transform:"@koine/i18n/{{ matches.[1] }}/{{member}}"},"@koine/react/?(((\\w*)?/?)*)":{transform:"@koine/react/{{ matches.[1] }}/{{member}}"},"@koine/next/?(((\\w*)?/?)*)":{transform:"@koine/next/{{ matches.[1] }}/{{member}}"},"@koine/utils":{transform:"@koine/utils/{{member}}"}},...a};return (t&&(i?// @see https://github.com/gregberge/svgr
22
+ k.nx={svgr:!0}:(// if falsy just remove the key
23
+ delete k.nx,k.webpack=(e,r)=>// ...[_config, options]: Parameters<NonNullable<NextConfig['webpack']>>
24
+ {let o="function"==typeof k.webpack?k.webpack(e,r):e;return(// @see https://dev.to/dolearning/importing-svgs-to-next-js-nna#svgr
25
+ o.module.rules.push({test:/\.svg$/,use:[{loader:"@svgr/webpack",options:{svgoConfig:{plugins:[{name:"removeViewBox",active:!1}]}}}]}),o)})),m)?next.withI18nLegacy({...k,i18nRoutes:m}):s?i?next.withI18nAsync({...k,i18nCompiler:s}):next.withI18n({...k,i18nCompiler:s}):k};
83
26
 
84
27
  exports.withKoine = withKoine;
package/config.esm.js CHANGED
@@ -1,80 +1,23 @@
1
1
  import { withI18nLegacy, withI18nAsync, withI18n } from '@koine/i18n/next';
2
2
 
3
- let withKoine = (options = {}) => {
4
- const { nx, svg, i18nRoutes, i18nCompiler, ...restNextConfig } = options;
5
- const nextConfig = {
6
- eslint: {
7
- ignoreDuringBuilds: true,
8
- },
9
- typescript: {
10
- ignoreBuildErrors: true,
11
- },
12
- poweredByHeader: false,
13
- experimental: {
14
- scrollRestoration: true,
15
- ...(restNextConfig.experimental || {}),
16
- },
17
- modularizeImports: {
18
- ...(restNextConfig.modularizeImports || {}),
19
- "@koine/api": { transform: "@koine/api/{{member}}" },
20
- "@koine/browser": { transform: "@koine/browser/{{member}}" },
21
- "@koine/dom": { transform: "@koine/dom/{{member}}" },
22
- "@koine/node": { transform: "@koine/node/{{member}}" },
23
- "@koine/i18n/?(((\\w*)?/?)*)": {
24
- transform: "@koine/i18n/{{ matches.[1] }}/{{member}}",
25
- },
26
- "@koine/react/?(((\\w*)?/?)*)": {
27
- transform: "@koine/react/{{ matches.[1] }}/{{member}}",
28
- },
29
- "@koine/next/?(((\\w*)?/?)*)": {
30
- transform: "@koine/next/{{ matches.[1] }}/{{member}}",
31
- },
32
- "@koine/utils": { transform: "@koine/utils/{{member}}" },
33
- },
34
- ...restNextConfig,
35
- };
36
- if (svg) {
37
- if (nx) {
38
- nextConfig["nx"] = { svgr: true };
39
- }
40
- else {
41
- delete nextConfig["nx"];
42
- nextConfig.webpack = (_config, options) => {
43
- const webpackConfig = typeof nextConfig.webpack === "function"
44
- ? nextConfig.webpack(_config, options)
45
- : _config;
46
- webpackConfig.module.rules.push({
47
- test: /\.svg$/,
48
- use: [
49
- {
50
- loader: "@svgr/webpack",
51
- options: {
52
- svgoConfig: {
53
- plugins: [
54
- {
55
- name: "removeViewBox",
56
- active: false,
57
- },
58
- ],
59
- },
60
- },
61
- },
62
- ],
63
- });
64
- return webpackConfig;
65
- };
66
- }
67
- }
68
- if (i18nRoutes) {
69
- return withI18nLegacy({ ...nextConfig, i18nRoutes });
70
- }
71
- if (i18nCompiler) {
72
- if (nx) {
73
- return withI18nAsync({ ...nextConfig, i18nCompiler });
74
- }
75
- return withI18n({ ...nextConfig, i18nCompiler });
76
- }
77
- return nextConfig;
78
- };
3
+ /**
4
+ * Get Next.js config with some basic opinionated defaults
5
+ *
6
+ * @param {object} options
7
+ * @property {boolean} [options.nx=false] Nx monorepo setup
8
+ * @property {boolean} [options.svg=false] SVG to react components
9
+ */let withKoine=(n={})=>{let{nx:i,svg:t,i18nRoutes:m,i18nCompiler:s,...a}=n,k={// @see https://nextjs.org/docs/api-reference/next.config.js/custom-page-extensions#including-non-page-files-in-the-pages-directory
10
+ eslint:{ignoreDuringBuilds:!0},// we have this strict check on each commit
11
+ typescript:{ignoreBuildErrors:!0},// we have this strict check on each commit
12
+ poweredByHeader:!1,experimental:{// @see https://github.com/vercel/vercel/discussions/5973#discussioncomment-472618
13
+ // @see critters error https://github.com/vercel/next.js/issues/20742
14
+ // optimizeCss: true,
15
+ // @see https://github.com/vercel/next.js/discussions/30174#discussion-3643870
16
+ scrollRestoration:!0,...a.experimental||{}},modularizeImports:{...a.modularizeImports||{},// @see https://www.zhoulujun.net/nextjs/advanced-features/compiler.html#modularize-imports
17
+ "@koine/api":{transform:"@koine/api/{{member}}"},"@koine/browser":{transform:"@koine/browser/{{member}}"},"@koine/dom":{transform:"@koine/dom/{{member}}"},"@koine/node":{transform:"@koine/node/{{member}}"},"@koine/i18n/?(((\\w*)?/?)*)":{transform:"@koine/i18n/{{ matches.[1] }}/{{member}}"},"@koine/react/?(((\\w*)?/?)*)":{transform:"@koine/react/{{ matches.[1] }}/{{member}}"},"@koine/next/?(((\\w*)?/?)*)":{transform:"@koine/next/{{ matches.[1] }}/{{member}}"},"@koine/utils":{transform:"@koine/utils/{{member}}"}},...a};return (t&&(i?// @see https://github.com/gregberge/svgr
18
+ k.nx={svgr:!0}:(// if falsy just remove the key
19
+ delete k.nx,k.webpack=(e,r)=>// ...[_config, options]: Parameters<NonNullable<NextConfig['webpack']>>
20
+ {let o="function"==typeof k.webpack?k.webpack(e,r):e;return(// @see https://dev.to/dolearning/importing-svgs-to-next-js-nna#svgr
21
+ o.module.rules.push({test:/\.svg$/,use:[{loader:"@svgr/webpack",options:{svgoConfig:{plugins:[{name:"removeViewBox",active:!1}]}}}]}),o)})),m)?withI18nLegacy({...k,i18nRoutes:m}):s?i?withI18nAsync({...k,i18nCompiler:s}):withI18n({...k,i18nCompiler:s}):k};
79
22
 
80
23
  export { withKoine };
package/load.cjs.js CHANGED
@@ -2,11 +2,14 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- function load(component, milliseconds) {
6
- return new Promise((resolve) => {
7
- setTimeout(() => resolve(component), milliseconds);
8
- });
9
- }
5
+ /**
6
+ * Utility to load a component with an optional pre-determined delay.
7
+ *
8
+ * This was designed to improve anti spam with async form loading.
9
+ *
10
+ * @see https://github.com/vercel/next.js/blob/main/packages/next/next-server/lib/dynamic.tsx
11
+ * @see https://github.com/vercel/next.js/blob/canary/examples/with-dynamic-import/pages/index.js
12
+ */function load(e,o){return new Promise(t=>{setTimeout(()=>t(e),o);})}
10
13
 
11
14
  exports["default"] = load;
12
15
  exports.load = load;
package/load.esm.js CHANGED
@@ -1,7 +1,10 @@
1
- function load(component, milliseconds) {
2
- return new Promise((resolve) => {
3
- setTimeout(() => resolve(component), milliseconds);
4
- });
5
- }
1
+ /**
2
+ * Utility to load a component with an optional pre-determined delay.
3
+ *
4
+ * This was designed to improve anti spam with async form loading.
5
+ *
6
+ * @see https://github.com/vercel/next.js/blob/main/packages/next/next-server/lib/dynamic.tsx
7
+ * @see https://github.com/vercel/next.js/blob/canary/examples/with-dynamic-import/pages/index.js
8
+ */function load(e,o){return new Promise(t=>{setTimeout(()=>t(e),o);})}
6
9
 
7
10
  export { load as default, load };
package/package.json CHANGED
@@ -2,9 +2,9 @@
2
2
  "name": "@koine/next",
3
3
  "sideEffects": false,
4
4
  "dependencies": {
5
- "@koine/browser": "2.0.0-beta.80",
6
- "@koine/utils": "2.0.0-beta.80",
7
- "@koine/i18n": "2.0.0-beta.80"
5
+ "@koine/browser": "2.0.0-beta.83",
6
+ "@koine/utils": "2.0.0-beta.83",
7
+ "@koine/i18n": "2.0.0-beta.83"
8
8
  },
9
9
  "peerDependencies": {
10
10
  "next": "^14.0.4",
@@ -56,5 +56,5 @@
56
56
  },
57
57
  "module": "./index.esm.js",
58
58
  "main": "./index.cjs.js",
59
- "version": "2.0.0-beta.80"
59
+ "version": "2.0.0-beta.83"
60
60
  }
package/useTheme.cjs.js CHANGED
@@ -5,7 +5,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var react = require('react');
6
6
  var ThemeContext = require('./ThemeContext.cjs.js');
7
7
 
8
- const useTheme = () => react.useContext(ThemeContext.ThemeContext);
8
+ /**
9
+ * @borrows [next-themes](https://github.com/pacocoursey/next-themes)
10
+ */const useTheme=()=>react.useContext(ThemeContext.ThemeContext);
9
11
 
10
12
  exports["default"] = useTheme;
11
13
  exports.useTheme = useTheme;
package/useTheme.esm.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { useContext } from 'react';
2
2
  import { ThemeContext } from './ThemeContext.esm.js';
3
3
 
4
- const useTheme = () => useContext(ThemeContext);
4
+ /**
5
+ * @borrows [next-themes](https://github.com/pacocoursey/next-themes)
6
+ */const useTheme=()=>useContext(ThemeContext);
5
7
 
6
8
  export { useTheme as default, useTheme };