@koine/next 1.0.4 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/Analytics/AnalyticsGoogle.d.ts +5 -6
  2. package/Analytics/AnalyticsGoogle.js +37 -0
  3. package/Analytics/index.d.ts +1 -1
  4. package/Analytics/index.js +1 -0
  5. package/Analytics/package.json +6 -0
  6. package/Auth/helpers.d.ts +17 -17
  7. package/Auth/helpers.js +21 -0
  8. package/Auth/index.d.ts +4 -4
  9. package/Auth/index.js +4 -0
  10. package/Auth/package.json +6 -0
  11. package/Auth/useLogin.d.ts +7 -7
  12. package/Auth/useLogin.js +50 -0
  13. package/Auth/useLoginUrl.d.ts +1 -1
  14. package/Auth/useLoginUrl.js +11 -0
  15. package/Auth/useLogout.d.ts +6 -6
  16. package/Auth/useLogout.js +52 -0
  17. package/Favicon/Favicon.d.ts +3 -4
  18. package/Favicon/Favicon.js +4 -0
  19. package/Favicon/index.d.ts +1 -1
  20. package/Favicon/index.js +1 -0
  21. package/Favicon/package.json +6 -0
  22. package/Forms/index.d.ts +2 -2
  23. package/Forms/index.js +2 -0
  24. package/Forms/package.json +6 -0
  25. package/Forms/useForm.d.ts +32 -32
  26. package/Forms/useForm.js +37 -0
  27. package/Forms/useSubmit.d.ts +24 -24
  28. package/Forms/useSubmit.js +23 -0
  29. package/Head/Head.d.ts +1 -1
  30. package/Head/Head.js +1 -0
  31. package/Head/index.d.ts +1 -1
  32. package/Head/index.js +1 -0
  33. package/Head/package.json +6 -0
  34. package/I18n/I18n.d.ts +44 -48
  35. package/I18n/I18n.js +74 -0
  36. package/I18n/index.d.ts +1 -1
  37. package/I18n/index.js +1 -0
  38. package/I18n/package.json +6 -0
  39. package/Img/Img.d.ts +21 -21
  40. package/Img/Img.js +28 -0
  41. package/Img/index.d.ts +1 -1
  42. package/Img/index.js +1 -0
  43. package/Img/package.json +6 -0
  44. package/Link/Link.d.ts +9 -8
  45. package/Link/Link.js +9 -0
  46. package/Link/index.d.ts +1 -1
  47. package/Link/index.js +1 -0
  48. package/Link/package.json +6 -0
  49. package/NextProgress/NextProgress.d.ts +24 -14
  50. package/NextProgress/NextProgress.js +37 -0
  51. package/NextProgress/index.d.ts +2 -1
  52. package/NextProgress/index.js +1 -0
  53. package/NextProgress/package.json +6 -0
  54. package/README.md +0 -0
  55. package/Seo/Seo.d.ts +3 -3
  56. package/Seo/Seo.js +8 -0
  57. package/Seo/SeoDefaults.d.ts +3 -3
  58. package/Seo/SeoDefaults.js +12 -0
  59. package/Seo/helpers.d.ts +48 -48
  60. package/Seo/helpers.js +111 -0
  61. package/Seo/index.d.ts +12 -12
  62. package/Seo/index.js +12 -0
  63. package/Seo/package.json +6 -0
  64. package/Theme/Theme.d.ts +46 -46
  65. package/Theme/Theme.js +235 -0
  66. package/Theme/index.d.ts +1 -1
  67. package/Theme/index.js +1 -0
  68. package/Theme/package.json +6 -0
  69. package/app/AppHead.d.ts +2 -3
  70. package/app/AppHead.js +5 -0
  71. package/app/AppMain.d.ts +35 -34
  72. package/app/AppMain.js +1 -0
  73. package/app/css/AppMain.d.ts +8 -0
  74. package/app/css/AppMain.js +11 -0
  75. package/app/css/AppTheme.d.ts +10 -0
  76. package/app/css/AppTheme.js +12 -0
  77. package/app/css/auth/index.d.ts +9 -0
  78. package/app/css/auth/index.js +13 -0
  79. package/app/css/auth/package.json +6 -0
  80. package/app/css/index.d.ts +54 -0
  81. package/app/css/index.js +57 -0
  82. package/app/css/package.json +6 -0
  83. package/app/em/AppMain.d.ts +10 -0
  84. package/app/em/AppMain.js +22 -0
  85. package/app/{AppTheme--emotion.d.ts → em/AppTheme.d.ts} +15 -15
  86. package/app/em/AppTheme.js +17 -0
  87. package/app/em/auth/index.d.ts +9 -0
  88. package/app/em/auth/index.js +13 -0
  89. package/app/em/auth/package.json +6 -0
  90. package/app/em/index.d.ts +9 -0
  91. package/app/em/index.js +12 -0
  92. package/app/em/package.json +6 -0
  93. package/app/index.d.ts +2 -11
  94. package/app/index.js +2 -0
  95. package/app/package.json +6 -0
  96. package/app/sc/AppMain.d.ts +10 -0
  97. package/app/sc/AppMain.js +22 -0
  98. package/app/sc/AppTheme.d.ts +13 -0
  99. package/app/sc/AppTheme.js +9 -0
  100. package/app/sc/auth/index.d.ts +9 -0
  101. package/app/sc/auth/index.js +13 -0
  102. package/app/sc/auth/package.json +6 -0
  103. package/app/sc/index.d.ts +56 -0
  104. package/app/sc/index.js +59 -0
  105. package/app/sc/package.json +6 -0
  106. package/config/index.d.ts +71 -58
  107. package/config/index.js +174 -0
  108. package/config/package.json +6 -0
  109. package/document/Document.d.ts +15 -10
  110. package/document/Document.js +19 -0
  111. package/document/css/index.d.ts +22 -0
  112. package/document/css/index.js +30 -0
  113. package/document/css/package.json +6 -0
  114. package/document/em/index.d.ts +16 -0
  115. package/document/em/index.js +68 -0
  116. package/document/em/package.json +6 -0
  117. package/document/index.d.ts +2 -4
  118. package/document/index.js +2 -0
  119. package/document/package.json +6 -0
  120. package/document/{Document--sc.d.ts → sc/index.d.ts} +20 -11
  121. package/document/sc/index.js +44 -0
  122. package/document/sc/package.json +6 -0
  123. package/index.d.ts +12 -12
  124. package/index.js +12 -743
  125. package/node/Analytics/AnalyticsGoogle.js +42 -0
  126. package/node/Analytics/index.js +4 -0
  127. package/node/Auth/helpers.js +26 -0
  128. package/node/Auth/index.js +7 -0
  129. package/node/Auth/useLogin.js +54 -0
  130. package/node/Auth/useLoginUrl.js +15 -0
  131. package/node/Auth/useLogout.js +56 -0
  132. package/node/Favicon/Favicon.js +9 -0
  133. package/node/Favicon/index.js +4 -0
  134. package/node/Forms/index.js +5 -0
  135. package/node/Forms/useForm.js +41 -0
  136. package/node/Forms/useSubmit.js +27 -0
  137. package/node/Head/Head.js +8 -0
  138. package/node/Head/index.js +4 -0
  139. package/node/I18n/I18n.js +82 -0
  140. package/node/I18n/index.js +4 -0
  141. package/node/Img/Img.js +34 -0
  142. package/node/Img/index.js +4 -0
  143. package/node/Link/Link.js +13 -0
  144. package/node/Link/index.js +4 -0
  145. package/node/NextProgress/NextProgress.js +41 -0
  146. package/node/NextProgress/index.js +5 -0
  147. package/node/Seo/Seo.js +12 -0
  148. package/node/Seo/SeoDefaults.js +16 -0
  149. package/node/Seo/helpers.js +115 -0
  150. package/node/Seo/index.js +15 -0
  151. package/node/Theme/Theme.js +241 -0
  152. package/node/Theme/index.js +4 -0
  153. package/node/app/AppHead.js +10 -0
  154. package/node/app/AppMain.js +2 -0
  155. package/node/app/css/AppMain.js +16 -0
  156. package/node/app/css/AppTheme.js +16 -0
  157. package/node/app/css/auth/index.js +18 -0
  158. package/node/app/css/index.js +62 -0
  159. package/node/app/em/AppMain.js +26 -0
  160. package/node/app/em/AppTheme.js +22 -0
  161. package/node/app/em/auth/index.js +18 -0
  162. package/node/app/em/index.js +17 -0
  163. package/node/app/index.js +5 -0
  164. package/node/app/sc/AppMain.js +26 -0
  165. package/node/app/sc/AppTheme.js +13 -0
  166. package/node/app/sc/auth/index.js +18 -0
  167. package/node/app/sc/index.js +64 -0
  168. package/node/config/index.js +184 -0
  169. package/node/document/Document.js +24 -0
  170. package/node/document/css/index.js +35 -0
  171. package/node/document/em/index.js +73 -0
  172. package/node/document/index.js +7 -0
  173. package/node/document/sc/index.js +49 -0
  174. package/node/index.js +15 -0
  175. package/node/utils/api.js +38 -0
  176. package/node/utils/emotion-cache.js +13 -0
  177. package/node/utils/index.js +32 -0
  178. package/package.json +3 -30
  179. package/{types.d.ts → typings.d.ts} +10 -7
  180. package/utils/api.d.ts +55 -55
  181. package/utils/api.js +35 -0
  182. package/{document/emotion.d.ts → utils/emotion-cache.d.ts} +5 -5
  183. package/utils/emotion-cache.js +8 -0
  184. package/utils/index.d.ts +19 -19
  185. package/utils/index.js +26 -0
  186. package/utils/package.json +6 -0
  187. package/Theme.js +0 -1905
  188. package/_tslib.js +0 -41
  189. package/app/App--emotion.d.ts +0 -10
  190. package/app/App--sc.d.ts +0 -10
  191. package/app/App--vanilla.d.ts +0 -10
  192. package/app/AppAuth--emotion.d.ts +0 -10
  193. package/app/AppAuth--sc.d.ts +0 -10
  194. package/app/AppMain--vanilla.d.ts +0 -27
  195. package/app/AppTheme--sc.d.ts +0 -13
  196. package/app/AppTheme--vanilla.d.ts +0 -10
  197. package/app/motion-features.d.ts +0 -2
  198. package/app.js +0 -250
  199. package/config.js +0 -183
  200. package/document/Document--emotion.d.ts +0 -5
  201. package/document/Document--vanilla.d.ts +0 -11
  202. package/document.js +0 -207
  203. package/emotion.js +0 -1329
  204. package/es.object.assign.js +0 -1074
  205. package/es.string.replace.js +0 -785
  206. package/es.string.split.js +0 -201
  207. package/index.esm.js +0 -4600
  208. package/index.umd.js +0 -4638
  209. package/motion-features.js +0 -10
package/Seo/helpers.js ADDED
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { isArray } from "@koine/utils";
3
+ const defaults = {
4
+ tplTitle: "",
5
+ };
6
+ /**
7
+ * We do a couple of things in addition while many other are removed.
8
+ *
9
+ * - Add `seo` meta object coming from a CMS probably
10
+ * - Add `ogimage` and `openGraph.image` as single image source
11
+ * - Add `og` alias to define `openGraph`
12
+ * - Add check for `title` equale to `templateTitle` to avoid meta titles like
13
+ * "My site | My site" often happening in homepages
14
+ * - Remove the open graph videos and images
15
+ *
16
+ * - Shorter code
17
+ *
18
+ * @returns
19
+ */
20
+ export const buildTags = ({ seo, hidden, keywords, title = "", titleTemplate, defaultTitle, noindex, nofollow, description, languageAlternates = [], twitter, facebook, openGraph, og: ogAlias, canonical, metaTags, linkTags, } = {}) => {
21
+ const render = [];
22
+ const $names = {};
23
+ const $properties = {};
24
+ if (titleTemplate) {
25
+ defaults.tplTitle = titleTemplate;
26
+ }
27
+ title = title || seo?.title || "";
28
+ if (title) {
29
+ if (defaults.tplTitle && defaults.tplTitle !== title) {
30
+ title = defaults.tplTitle.replace(/%s/g, title);
31
+ }
32
+ }
33
+ else if (defaultTitle) {
34
+ title = defaultTitle;
35
+ }
36
+ if (title) {
37
+ render.push(_jsx("title", { children: title }, "title"));
38
+ $properties["og:title"] = title; // overridden later...
39
+ }
40
+ $names["robots"] = `${noindex || hidden ? "noindex" : "index"},${nofollow || hidden ? "nofollow" : "follow"}`;
41
+ description = description || seo?.description;
42
+ if (description) {
43
+ $names["description"] = description;
44
+ $properties["og:description"] = description; // overridden later...
45
+ }
46
+ keywords = keywords || seo?.keywords;
47
+ if (keywords) {
48
+ $names["keywords"] = isArray(keywords) ? keywords.join(", ") : keywords;
49
+ }
50
+ if (languageAlternates?.length > 0) {
51
+ languageAlternates.forEach((languageAlternate) => {
52
+ render.push(_jsx("link", { rel: "alternate", hrefLang: languageAlternate.hrefLang, href: languageAlternate.href }, `languageAlternate-${languageAlternate.hrefLang}`));
53
+ });
54
+ }
55
+ if (canonical) {
56
+ render.push(_jsx("link", { rel: "canonical", href: canonical }, "canonical"));
57
+ $properties["og:url"] = canonical;
58
+ }
59
+ if (facebook?.appId)
60
+ $properties["fb:app_id"] = facebook.appId;
61
+ if (twitter) {
62
+ if (twitter.cardType)
63
+ $names["twitter:card"] = twitter.cardType;
64
+ if (twitter.site)
65
+ $names["twitter:site"] = twitter.site;
66
+ if (twitter.handle)
67
+ $names["twitter:creator"] = twitter.handle;
68
+ }
69
+ const og = ogAlias || openGraph;
70
+ if (og?.title)
71
+ $properties["og:title"] = og?.title;
72
+ if (og?.description)
73
+ $properties["og:description"] = og?.description;
74
+ if (og?.url)
75
+ $properties["og:url"] = og.url;
76
+ if (og?.type)
77
+ $properties["og:type"] = og.type.toLowerCase();
78
+ if (og?.locale)
79
+ $properties["og:locale"] = og.locale;
80
+ if (og?.site_name)
81
+ $properties["og:site_name"] = og.site_name;
82
+ const ogimage = og?.image || seo?.ogimage;
83
+ if (ogimage)
84
+ $properties["og:image"] = ogimage;
85
+ Object.keys($names).forEach((key) => {
86
+ render.push(_jsx("meta", { name: key, content: $names[key] }, key));
87
+ });
88
+ Object.keys($properties).forEach((key) => {
89
+ render.push(_jsx("meta", { property: key, content: $properties[key] }, key));
90
+ });
91
+ if (metaTags && metaTags.length > 0) {
92
+ metaTags.forEach((tag) => {
93
+ render.push(_jsx("meta", { ...tag }, `meta:${tag.keyOverride ?? tag.name ?? tag.property ?? tag.httpEquiv}`));
94
+ });
95
+ }
96
+ if (linkTags?.length) {
97
+ linkTags.forEach((tag) => {
98
+ render.push(_jsx("link", { ...tag }, `link${tag.keyOverride ?? tag.href}${tag.rel}`));
99
+ });
100
+ }
101
+ // TODO: alternates and canonical
102
+ // canonical = 'https://www.domain.com/';
103
+ // languageAlternates={[{
104
+ // hrefLang: 'en',
105
+ // href: 'https://www.domain.com/en',
106
+ // }]}
107
+ // <link rel="alternate" hreflang="x-default" href="https://www.domain.com/nl/">
108
+ // <link rel="alternate" hreflang="nl" href="https://www.domain.com/nl/">
109
+ // <link rel="alternate" hreflang="en" href="https://www.domain.com/en/">
110
+ return render;
111
+ };
package/Seo/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- /**
2
- * @file
3
- *
4
- * Adapted from https://github.com/garmeeh/next-seo
5
- *
6
- * See also:
7
- * - https://github.com/catnose99/next-head-seo
8
- * - https://nextjs.org/docs/api-reference/next/head
9
- */
10
- export * from "./helpers";
11
- export * from "./Seo";
12
- export * from "./SeoDefaults";
1
+ /**
2
+ * @file
3
+ *
4
+ * Adapted from https://github.com/garmeeh/next-seo
5
+ *
6
+ * See also:
7
+ * - https://github.com/catnose99/next-head-seo
8
+ * - https://nextjs.org/docs/api-reference/next/head
9
+ */
10
+ export * from "./helpers";
11
+ export * from "./Seo";
12
+ export * from "./SeoDefaults";
package/Seo/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Adapted from https://github.com/garmeeh/next-seo
5
+ *
6
+ * See also:
7
+ * - https://github.com/catnose99/next-head-seo
8
+ * - https://nextjs.org/docs/api-reference/next/head
9
+ */
10
+ export * from "./helpers";
11
+ export * from "./Seo";
12
+ export * from "./SeoDefaults";
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "./index.js",
4
+ "main": "../node/Seo/index.js",
5
+ "types": "./index.d.ts"
6
+ }
package/Theme/Theme.d.ts CHANGED
@@ -1,46 +1,46 @@
1
- /**
2
- * @file
3
- *
4
- * Adapted from [next-themes](https://github.com/pacocoursey/next-themes)
5
- */
6
- import React from "react";
7
- declare type ValueObject = {
8
- [themeName: string]: string;
9
- };
10
- export declare type UseThemeProps = {
11
- /** List of all available theme names */
12
- themes: string[];
13
- /** Forced theme name for the current page */
14
- forcedTheme?: string;
15
- /** Update the theme */
16
- setTheme: (theme: string) => void;
17
- /** Active theme name */
18
- theme?: string;
19
- /** 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` */
20
- resolvedTheme?: string;
21
- /** If enableSystem is true, returns the System theme preference ("dark" or "light"), regardless what the active theme is */
22
- systemTheme?: "dark" | "light";
23
- };
24
- export declare type ThemeProviderProps = {
25
- /** List of all available theme names */
26
- themes?: string[];
27
- /** Forced theme name for the current page */
28
- forcedTheme?: string;
29
- /** Whether to switch between dark and light themes based on prefers-color-scheme */
30
- enableSystem?: boolean;
31
- /** Disable all CSS transitions when switching themes */
32
- disableTransitionOnChange?: boolean;
33
- /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */
34
- enableColorScheme?: boolean;
35
- /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */
36
- defaultTheme?: string;
37
- /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */
38
- attribute?: string | "class";
39
- /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */
40
- value?: ValueObject;
41
- /** Nonce string to pass to the inline script for CSP headers */
42
- nonce?: string;
43
- };
44
- export declare const useTheme: () => UseThemeProps;
45
- export declare const ThemeProvider: React.FC<ThemeProviderProps>;
46
- export {};
1
+ /**
2
+ * @file
3
+ *
4
+ * Adapted from [next-themes](https://github.com/pacocoursey/next-themes)
5
+ */
6
+ import React from "react";
7
+ declare type ValueObject = {
8
+ [themeName: string]: string;
9
+ };
10
+ export declare type UseThemeProps = {
11
+ /** List of all available theme names */
12
+ themes: string[];
13
+ /** Forced theme name for the current page */
14
+ forcedTheme?: string;
15
+ /** Update the theme */
16
+ setTheme: (theme: string) => void;
17
+ /** Active theme name */
18
+ theme?: string;
19
+ /** 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` */
20
+ resolvedTheme?: string;
21
+ /** If enableSystem is true, returns the System theme preference ("dark" or "light"), regardless what the active theme is */
22
+ systemTheme?: "dark" | "light";
23
+ };
24
+ export declare type ThemeProviderProps = React.PropsWithChildren<{
25
+ /** List of all available theme names */
26
+ themes?: string[];
27
+ /** Forced theme name for the current page */
28
+ forcedTheme?: string;
29
+ /** Whether to switch between dark and light themes based on prefers-color-scheme */
30
+ enableSystem?: boolean;
31
+ /** Disable all CSS transitions when switching themes */
32
+ disableTransitionOnChange?: boolean;
33
+ /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */
34
+ enableColorScheme?: boolean;
35
+ /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */
36
+ defaultTheme?: string;
37
+ /** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */
38
+ attribute?: string | "class";
39
+ /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */
40
+ value?: ValueObject;
41
+ /** Nonce string to pass to the inline script for CSP headers */
42
+ nonce?: string;
43
+ }>;
44
+ export declare const useTheme: () => UseThemeProps;
45
+ export declare const ThemeProvider: ({ forcedTheme, disableTransitionOnChange, enableSystem, enableColorScheme, themes, defaultTheme, attribute, value, children, nonce, }: ThemeProviderProps) => JSX.Element;
46
+ export {};
package/Theme/Theme.js ADDED
@@ -0,0 +1,235 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @file
4
+ *
5
+ * Adapted from [next-themes](https://github.com/pacocoursey/next-themes)
6
+ */
7
+ import { createContext, useCallback, useContext, useEffect, useState, memo, } from "react";
8
+ import NextScript from "next/script";
9
+ import { isServer } from "@koine/utils";
10
+ const THEME_STORAGE_KEY = "theme";
11
+ const colorSchemes = ["light", "dark"];
12
+ const MEDIA = "(prefers-color-scheme: dark)";
13
+ const ThemeContext = createContext({
14
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
15
+ setTheme: (_) => { },
16
+ themes: [],
17
+ });
18
+ export const useTheme = () => useContext(ThemeContext);
19
+ export const ThemeProvider = ({ forcedTheme, disableTransitionOnChange = false, enableSystem = true, enableColorScheme = true, themes = ["light", "dark"], defaultTheme = enableSystem ? "system" : "light", attribute = "data-theme", value, children, nonce, }) => {
20
+ const [theme, setThemeState] = useState(() => getTheme(THEME_STORAGE_KEY, defaultTheme));
21
+ const [resolvedTheme, setResolvedTheme] = useState(() => getTheme(THEME_STORAGE_KEY));
22
+ const attrs = !value ? themes : Object.values(value);
23
+ const applyTheme = useCallback((theme) => {
24
+ let resolved = theme;
25
+ if (isServer || !resolved)
26
+ return;
27
+ // If theme is system, resolve it before setting theme
28
+ if (theme === "system" && enableSystem) {
29
+ resolved = getSystemTheme();
30
+ }
31
+ const name = value ? value[resolved] : resolved;
32
+ const enable = disableTransitionOnChange ? disableAnimation() : null;
33
+ const d = document.documentElement;
34
+ if (attribute === "class") {
35
+ d.classList.remove(...attrs);
36
+ if (name)
37
+ d.classList.add(name);
38
+ }
39
+ else {
40
+ if (name) {
41
+ d.setAttribute(attribute, name);
42
+ }
43
+ else {
44
+ d.removeAttribute(attribute);
45
+ }
46
+ }
47
+ if (enableColorScheme) {
48
+ const fallback = colorSchemes.includes(defaultTheme)
49
+ ? defaultTheme
50
+ : "";
51
+ const colorScheme = colorSchemes.includes(resolved)
52
+ ? resolved
53
+ : fallback;
54
+ d.style.colorScheme = colorScheme;
55
+ }
56
+ enable?.();
57
+ }, [
58
+ attribute,
59
+ attrs,
60
+ defaultTheme,
61
+ disableTransitionOnChange,
62
+ enableColorScheme,
63
+ enableSystem,
64
+ value,
65
+ ]);
66
+ const setTheme = useCallback((theme) => {
67
+ setThemeState(theme);
68
+ // Save to storage
69
+ try {
70
+ localStorage.setItem(THEME_STORAGE_KEY, theme);
71
+ }
72
+ catch (e) {
73
+ // Unsupported
74
+ }
75
+ }, []);
76
+ const handleMediaQuery = useCallback((e) => {
77
+ const resolved = getSystemTheme(e);
78
+ setResolvedTheme(resolved);
79
+ if (theme === "system" && enableSystem && !forcedTheme) {
80
+ applyTheme("system");
81
+ }
82
+ }, [theme, enableSystem, forcedTheme, applyTheme]);
83
+ // Always listen to System preference
84
+ useEffect(() => {
85
+ const media = window.matchMedia(MEDIA);
86
+ // Intentionally use deprecated listener methods to support iOS & old browsers
87
+ media.addListener(handleMediaQuery);
88
+ handleMediaQuery(media);
89
+ return () => media.removeListener(handleMediaQuery);
90
+ }, [handleMediaQuery]);
91
+ // localStorage event handling
92
+ useEffect(() => {
93
+ const handleStorage = (e) => {
94
+ if (e.key !== THEME_STORAGE_KEY) {
95
+ return;
96
+ }
97
+ // If default theme set, use it if localstorage === null (happens on local storage manual deletion)
98
+ const theme = e.newValue || defaultTheme;
99
+ setTheme(theme);
100
+ };
101
+ window.addEventListener("storage", handleStorage);
102
+ return () => window.removeEventListener("storage", handleStorage);
103
+ }, [defaultTheme, setTheme]);
104
+ // Whenever theme or forcedTheme changes, apply it
105
+ useEffect(() => {
106
+ applyTheme(forcedTheme ?? theme);
107
+ }, [applyTheme, forcedTheme, theme]);
108
+ return (_jsxs(ThemeContext.Provider, { value: {
109
+ theme,
110
+ setTheme,
111
+ forcedTheme,
112
+ resolvedTheme: theme === "system" ? resolvedTheme : theme,
113
+ themes: enableSystem ? [...themes, "system"] : themes,
114
+ systemTheme: (enableSystem ? resolvedTheme : undefined),
115
+ }, children: [_jsx(ThemeScript, { ...{
116
+ forcedTheme,
117
+ disableTransitionOnChange,
118
+ enableSystem,
119
+ enableColorScheme,
120
+ themes,
121
+ defaultTheme,
122
+ attribute,
123
+ value,
124
+ children,
125
+ attrs,
126
+ nonce,
127
+ } }), children] }));
128
+ };
129
+ const ThemeScript = memo(({ forcedTheme, attribute, enableSystem, enableColorScheme, defaultTheme, value, attrs, nonce, }) => {
130
+ const defaultSystem = defaultTheme === "system";
131
+ // Code-golfing the amount of characters in the script
132
+ const optimization = (() => {
133
+ const removeClasses = `d.remove(${attrs
134
+ .map((t) => `'${t}'`)
135
+ .join(",")})`;
136
+ return `var d=document.documentElement.classList;${removeClasses};`;
137
+ })();
138
+ const fallbackColorScheme = (() => {
139
+ if (!enableColorScheme) {
140
+ return "";
141
+ }
142
+ const fallback = colorSchemes.includes(defaultTheme)
143
+ ? defaultTheme
144
+ : null;
145
+ if (fallback) {
146
+ return `if(e==='light'||e==='dark'||!e)d.style.colorScheme=e||'${defaultTheme}'`;
147
+ }
148
+ else {
149
+ return `if(e==='light'||e==='dark')d.style.colorScheme=e`;
150
+ }
151
+ })();
152
+ const updateDOM = (name, literal = false, setColorScheme = true) => {
153
+ const resolvedName = value ? value[name] : name;
154
+ const val = literal ? name + `|| ''` : `'${resolvedName}'`;
155
+ let text = "";
156
+ // MUCH faster to set colorScheme alongside HTML attribute/class
157
+ // as it only incurs 1 style recalculation rather than 2
158
+ // This can save over 250ms of work for pages with big DOM
159
+ if (enableColorScheme &&
160
+ setColorScheme &&
161
+ !literal &&
162
+ colorSchemes.includes(name)) {
163
+ text += `d.style.colorScheme = '${name}';`;
164
+ }
165
+ if (attribute === "class") {
166
+ if (literal || resolvedName) {
167
+ text += `d.add(${val})`;
168
+ }
169
+ else {
170
+ text += `null`;
171
+ }
172
+ }
173
+ else {
174
+ if (resolvedName) {
175
+ text += `d[s](n, ${val})`;
176
+ }
177
+ }
178
+ return text;
179
+ };
180
+ const scriptSrc = (() => {
181
+ if (forcedTheme) {
182
+ return `!function(){${optimization}${updateDOM(forcedTheme)}}()`;
183
+ }
184
+ if (enableSystem) {
185
+ 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
186
+ ? `else{` + updateDOM(defaultTheme, false, false) + "}"
187
+ : ""}${fallbackColorScheme}}catch(e){}}()`;
188
+ }
189
+ 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){}}();`;
190
+ })();
191
+ // We MUST use next/script's `beforeInteractive` strategy to avoid flashing on load.
192
+ // However, it only accepts the `src` prop, not `dangerouslySetInnerHTML` or `children`
193
+ // But our script cannot be external because it changes at runtime based on React props
194
+ // so we trick next/script by passing `src` as a base64 JS script
195
+ const encodedScript = `data:text/javascript;base64,${encodeBase64(scriptSrc)}`;
196
+ return (_jsx(NextScript, { id: "next-theme-script", strategy: "beforeInteractive", src: encodedScript, nonce: nonce }));
197
+ },
198
+ // Never re-render this component
199
+ () => true);
200
+ // Helpers
201
+ const getTheme = (key, fallback) => {
202
+ if (isServer)
203
+ return undefined;
204
+ let theme;
205
+ try {
206
+ theme = localStorage.getItem(key) || undefined;
207
+ }
208
+ catch (e) {
209
+ // Unsupported
210
+ }
211
+ return theme || fallback;
212
+ };
213
+ const disableAnimation = () => {
214
+ const css = document.createElement("style");
215
+ css.appendChild(document.createTextNode(`*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}`));
216
+ document.head.appendChild(css);
217
+ return () => {
218
+ // Force restyle
219
+ (() => window.getComputedStyle(document.body))();
220
+ // Wait for next tick before removing
221
+ setTimeout(() => {
222
+ document.head.removeChild(css);
223
+ }, 1);
224
+ };
225
+ };
226
+ const getSystemTheme = (e) => {
227
+ if (!e)
228
+ e = window.matchMedia(MEDIA);
229
+ const isDark = e.matches;
230
+ const systemTheme = isDark ? "dark" : "light";
231
+ return systemTheme;
232
+ };
233
+ const encodeBase64 = (str) => {
234
+ return isServer ? Buffer.from(str).toString("base64") : btoa(str);
235
+ };
package/Theme/index.d.ts CHANGED
@@ -1 +1 @@
1
- export * from "./Theme";
1
+ export * from "./Theme";
package/Theme/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./Theme";
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "./index.js",
4
+ "main": "../node/Theme/index.js",
5
+ "types": "./index.d.ts"
6
+ }
package/app/AppHead.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- import React from "react";
2
- export declare type AppHeadProps = unknown;
3
- export declare const AppHead: React.FC<AppHeadProps>;
1
+ export declare type AppHeadProps = unknown;
2
+ export declare const AppHead: () => JSX.Element;
package/app/AppHead.js ADDED
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Head from "next/head";
3
+ export const AppHead = () => {
4
+ return (_jsx(Head, { children: _jsx("meta", { name: "viewport", content: "width=device-width" }) }));
5
+ };
package/app/AppMain.d.ts CHANGED
@@ -1,34 +1,35 @@
1
- import React from "react";
2
- import { AppProps as NextAppProps } from "next/app";
3
- import { HTMLMotionProps } from "framer-motion";
4
- import { SeoDefaultsProps } from "../Seo";
5
- export declare type AppMainProps = NextAppProps & {
6
- /**
7
- * A wrapping layout component
8
- */
9
- Layout: React.FC<Record<string, unknown>>;
10
- /**
11
- * Seo site wide default configuration
12
- */
13
- seo?: SeoDefaultsProps;
14
- /**
15
- * It defaults to fade in/out
16
- */
17
- transition?: Omit<HTMLMotionProps<"div">, "key">;
18
- /**
19
- * JSX to render just after SEO
20
- */
21
- pre?: React.ReactNode;
22
- /**
23
- * JSX to render just at the end of the markup
24
- */
25
- post?: React.ReactNode;
26
- };
27
- /**
28
- * App main
29
- *
30
- * It implies a setup for `styled-components` and `framer-motion` libraries.
31
- *
32
- * About the page transition [wallis' blog post](https://wallis.dev/blog/nextjs-page-transitions-with-framer-motion)
33
- */
34
- export declare const AppMain: React.FC<AppMainProps>;
1
+ import React from "react";
2
+ import type { AppProps as NextAppProps } from "next/app";
3
+ import type { HTMLMotionProps } from "framer-motion";
4
+ import type { SeoDefaultsProps } from "../Seo";
5
+ import type { NextProgressProps } from "../NextProgress";
6
+ import type { MotionProviderFeatures } from "@koine/react/m";
7
+ export declare type AppMainBaseProps = NextAppProps & {
8
+ /**
9
+ * A wrapping layout component
10
+ */
11
+ Layout: React.FC<Record<string, unknown>>;
12
+ /**
13
+ * A Progress' Overlay component
14
+ */
15
+ ProgressOverlay?: NextProgressProps["Overlay"];
16
+ /**
17
+ * Seo site wide default configuration
18
+ */
19
+ seo?: SeoDefaultsProps;
20
+ /**
21
+ * JSX to render just after SEO
22
+ */
23
+ pre?: React.ReactNode;
24
+ /**
25
+ * JSX to render just at the end of the markup
26
+ */
27
+ post?: React.ReactNode;
28
+ };
29
+ export declare type AppMainFramerProps = {
30
+ motion: MotionProviderFeatures;
31
+ /**
32
+ * Default layout transition, by default it is a simple fade in/out
33
+ */
34
+ transition?: Omit<HTMLMotionProps<"div">, "key">;
35
+ };
package/app/AppMain.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { AppMainBaseProps } from "../AppMain";
2
+ export declare type AppMainProps = Omit<AppMainBaseProps, "ProgressOverlay">;
3
+ /**
4
+ * App main
5
+ *
6
+ * It does not imply any specific styling or animation solution
7
+ */
8
+ export declare const AppMain: ({ Component, pageProps, Layout, seo, pre, post, }: AppMainProps) => JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { SeoDefaults } from "../../Seo";
4
+ /**
5
+ * App main
6
+ *
7
+ * It does not imply any specific styling or animation solution
8
+ */
9
+ export const AppMain = ({ Component, pageProps, Layout, seo, pre, post, }) => {
10
+ return (_jsxs(React.Fragment, { children: [_jsx(SeoDefaults, { ...seo }), pre, _jsx(Layout, { children: _jsx(Component, { ...pageProps }) }), post] }));
11
+ };
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { AppProps as NextAppProps } from "next/app";
3
+ import { ThemeProviderProps } from "../../Theme";
4
+ export declare type AppThemeProps = React.PropsWithChildren<NextAppProps & {
5
+ theme: ThemeProviderProps["defaultTheme"];
6
+ }>;
7
+ /**
8
+ * App theme with vanilla class based theme (good for `tailwindcss`)
9
+ */
10
+ export declare const AppTheme: ({ theme, children }: AppThemeProps) => JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // import { ThemeVanillaProvider, ThemeVanillaValue } from "@koine/react";
3
+ import { ThemeProvider } from "../../Theme";
4
+ /**
5
+ * App theme with vanilla class based theme (good for `tailwindcss`)
6
+ */
7
+ export const AppTheme = ({ theme, children }) => {
8
+ // return (
9
+ // <ThemeVanillaProvider initialTheme={theme}>{children}</ThemeVanillaProvider>
10
+ // );
11
+ return (_jsx(ThemeProvider, { defaultTheme: theme, attribute: "class", children: children }));
12
+ };
@@ -0,0 +1,9 @@
1
+ import { AppProps } from "next/app";
2
+ import { AppThemeProps } from "../AppTheme";
3
+ import { AppMainProps } from "../AppMain";
4
+ export declare type NextAppProps = AppProps & AppThemeProps & AppMainProps;
5
+ /**
6
+ * App with authentication provided by `next-auth`
7
+ */
8
+ export declare const NextApp: (props: NextAppProps) => JSX.Element;
9
+ export default NextApp;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { SessionProvider } from "next-auth/react";
4
+ import { AppHead } from "../../AppHead";
5
+ import { AppTheme } from "../AppTheme";
6
+ import { AppMain } from "../AppMain";
7
+ /**
8
+ * App with authentication provided by `next-auth`
9
+ */
10
+ export const NextApp = (props) => {
11
+ return (_jsxs(React.StrictMode, { children: [_jsx(AppHead, {}), _jsx(SessionProvider, { session: props.pageProps.session, children: _jsx(AppTheme, { ...props, children: _jsx(AppMain, { ...props }) }) })] }));
12
+ };
13
+ export default NextApp;