@ngrok/mantle 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/assets/mantle.css CHANGED
@@ -1,7 +1,69 @@
1
- @import url("https://cdn.ngrok.com/static/fonts/fonts.css");
1
+ /* Euclid Square */
2
+ @font-face {
3
+ font-family: EuclidSquare;
4
+ font-style: normal;
5
+ font-weight: normal;
6
+ src: url("https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-Regular-WebS.woff") format("woff");
7
+ }
8
+
9
+ @font-face {
10
+ font-family: EuclidSquare;
11
+ font-style: italic;
12
+ font-weight: normal;
13
+ src: url("https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-RegularItalic-WebS.woff") format("woff");
14
+ }
15
+
16
+ @font-face {
17
+ font-family: EuclidSquare;
18
+ font-style: normal;
19
+ font-weight: 500;
20
+ src: url("https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-Medium-WebS.woff") format("woff");
21
+ }
22
+
23
+ @font-face {
24
+ font-family: EuclidSquare;
25
+ font-style: normal;
26
+ font-weight: 600;
27
+ src: url("https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-Semibold-WebS.woff") format("woff");
28
+ }
29
+
30
+ @font-face {
31
+ font-family: EuclidSquare;
32
+ font-style: italic;
33
+ font-weight: 500;
34
+ src: url("https://cdn.ngrok.com/static/fonts/euclid-square/EuclidSquare-MediumItalic-WebS.woff") format("woff");
35
+ }
36
+
37
+ /* IBM Plex Mono */
2
38
 
3
- /* TODO: Host this on our CDN */
4
- @import url("https://fonts.googleapis.com/css2?family=Nunito+Sans:ital,opsz,wght@0,6..12,200..1000;1,6..12,200..1000&display=swap");
39
+ @font-face {
40
+ font-family: IBMPlexMono;
41
+ font-style: normal;
42
+ font-weight: normal;
43
+ src: url("https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-Text.woff") format("woff");
44
+ }
45
+
46
+ @font-face {
47
+ font-family: IBMPlexMono;
48
+ font-style: italic;
49
+ font-weight: normal;
50
+ src: url("https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-TextItalic.woff") format("woff");
51
+ }
52
+
53
+ /* semibold is actually 600, but mapping it to 500 works better across AntD */
54
+ @font-face {
55
+ font-family: IBMPlexMono;
56
+ font-style: normal;
57
+ font-weight: 500;
58
+ src: url("https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-SemiBold.woff") format("woff");
59
+ }
60
+
61
+ @font-face {
62
+ font-family: IBMPlexMono;
63
+ font-style: italic;
64
+ font-weight: 500;
65
+ src: url("https://cdn.ngrok.com/static/fonts/ibm-plex-mono/IBMPlexMono-SemiBoldItalic.woff") format("woff");
66
+ }
5
67
 
6
68
  @tailwind base;
7
69
  @tailwind components;
@@ -1515,16 +1577,6 @@
1515
1577
  color-scheme: dark;
1516
1578
  }
1517
1579
 
1518
- /* .stop-current-color {
1519
- stop-color: currentColor;
1520
- }
1521
- .stop-opacity-100 {
1522
- stop-opacity: 1;
1523
- }
1524
- .stop-opacity-0 {
1525
- stop-opacity: 0;
1526
- } */
1527
-
1528
1580
  .scrollbar::-webkit-scrollbar {
1529
1581
  width: 0.5rem;
1530
1582
  height: 0.5rem;
@@ -1,5 +1,18 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { PropsWithChildren } from 'react';
2
+ import { PropsWithChildren, ComponentProps } from 'react';
3
+
4
+ type Props = {
5
+ /**
6
+ * If set, will also preload and include the optional Nunito Sans font from Google Fonts.
7
+ * @default false
8
+ */
9
+ includeNunitoSans?: boolean;
10
+ };
11
+ /**
12
+ * Preload custom fonts used in the theme. This should be added to the head of the document in your application, preferably as high as possible.
13
+ * Normally you won't use this directly, but instead use the `MantleThemeHeadContent` component which includes this.
14
+ */
15
+ declare const PreloadFonts: ({ includeNunitoSans }: Props) => react_jsx_runtime.JSX.Element;
3
16
 
4
17
  /**
5
18
  * resolvedThemes is a tuple of valid themes that have been resolved from "system" to a specific theme.
@@ -71,14 +84,15 @@ declare function preventWrongThemeFlashScriptContent({ defaultTheme, storageKey,
71
84
  defaultTheme?: Theme;
72
85
  storageKey?: string;
73
86
  }): string;
87
+ type MantleThemeHeadContentProps = {
88
+ defaultTheme?: Theme;
89
+ storageKey?: string;
90
+ } & ComponentProps<typeof PreloadFonts>;
74
91
  /**
75
92
  * MantleThemeHeadContent is a React component that prevents the wrong theme from flashing on initial page load.
76
93
  * Render as high as possible in the <head> element.
77
94
  */
78
- declare const MantleThemeHeadContent: ({ defaultTheme, storageKey, }: {
79
- defaultTheme?: Theme;
80
- storageKey?: string;
81
- }) => react_jsx_runtime.JSX.Element;
95
+ declare const MantleThemeHeadContent: ({ defaultTheme, storageKey, includeNunitoSans, }: MantleThemeHeadContentProps) => react_jsx_runtime.JSX.Element;
82
96
  type InitialThemeProps = {
83
97
  className: string;
84
98
  "data-applied-theme": Omit<Theme, "system">;
@@ -93,10 +107,4 @@ declare function useInitialHtmlThemeProps(props?: {
93
107
  storageKey?: string;
94
108
  }): InitialThemeProps;
95
109
 
96
- /**
97
- * Preload custom fonts used in the theme. This should be added to the head of the document in your application, preferably as high as possible.
98
- * Normally you won't use this directly, but instead use the `MantleThemeHeadContent` component which includes this.
99
- */
100
- declare const PreloadFonts: () => react_jsx_runtime.JSX.Element;
101
-
102
110
  export { $resolvedTheme, $theme, MantleThemeHeadContent, PreloadFonts, type Theme, ThemeProvider, type ThemeProviderProps, applyTheme, isResolvedTheme, isTheme, preventWrongThemeFlashScriptContent, readThemeFromHtmlElement, resolvedThemes, themes, useAppliedTheme, useInitialHtmlThemeProps, useTheme };
@@ -1,6 +1,6 @@
1
- import{a as p}from"./chunk-D3XF6J5A.js";import P from"clsx";import{createContext as D,useContext as L,useEffect as b,useMemo as k,useState as $}from"react";import W from"tiny-invariant";import{Fragment as F,jsx as M}from"react/jsx-runtime";var I="https://cdn.ngrok.com/static/fonts",q=["euclid-square/EuclidSquare-Regular-WebS.woff","euclid-square/EuclidSquare-RegularItalic-WebS.woff","euclid-square/EuclidSquare-Medium-WebS.woff","euclid-square/EuclidSquare-Semibold-WebS.woff","euclid-square/EuclidSquare-MediumItalic-WebS.woff","ibm-plex-mono/IBMPlexMono-Text.woff","ibm-plex-mono/IBMPlexMono-TextItalic.woff","ibm-plex-mono/IBMPlexMono-SemiBold.woff","ibm-plex-mono/IBMPlexMono-SemiBoldItalic.woff"],R=e=>[I,e].join("/"),g=()=>M(F,{children:q.map(e=>M("link",{rel:"preload",href:R(e),as:"font",type:"font/woff",crossOrigin:"anonymous"},e))});import{Fragment as Y,jsx as w,jsxs as z}from"react/jsx-runtime";var a="(prefers-color-scheme: dark)",h="(prefers-contrast: more)",v=["light","dark","light-high-contrast","dark-high-contrast"],c=["system",...v],B=e=>e;function y(e){return typeof e!="string"?!1:c.includes(e)}var _=e=>e;function E(e){return typeof e!="string"?!1:v.includes(e)}var T="mantle-ui-theme",N=["system",()=>null],x=D(N),u=()=>typeof window<"u";function d(e,t="system"){let o=t??"system";if(u()){let r=null;try{r="localStorage"in window?window.localStorage.getItem(e):null}catch{}return y(r)?r:o}return o}function A({children:e,defaultTheme:t="system",storageKey:o=T}){let[r,s]=$(()=>{let n=d(o,t);return i(n),n});b(()=>{let n=d(o,t);s(n),i(n)},[t,o]),b(()=>{let n=window.matchMedia(a),m=window.matchMedia(h),l=()=>{d(o,t)==="system"&&i("system")};return n.addEventListener("change",l),m.addEventListener("change",l),()=>{n.removeEventListener("change",l),m.removeEventListener("change",l)}},[t,o]);let f=k(()=>[r,n=>{try{"localStorage"in window&&window.localStorage.setItem(o,n)}catch{}s(n),i(n)}],[o,r]);return w(x.Provider,{value:f,children:e})}function C(){let e=L(x);return W(e,"useTheme must be used within a ThemeProvider"),e}function i(e){if(!u())return;let t=window.document.documentElement;t.classList.remove(...c);let o=window.matchMedia(a).matches,r=window.matchMedia(h).matches,s=S(e,{prefersDarkMode:o,prefersHighContrast:r});t.classList.add(s),t.dataset.appliedTheme=s,t.dataset.theme=e}function O(){if(!u())return{appliedTheme:void 0,theme:void 0};let e=window.document.documentElement,t=y(e.dataset.theme)?e.dataset.theme:void 0;return{appliedTheme:E(e.dataset.appliedTheme)?e.dataset.appliedTheme:void 0,theme:t}}function S(e,{prefersDarkMode:t,prefersHighContrast:o}){return e==="system"?G({prefersDarkMode:t,prefersHighContrast:o}):e}function Q(){let[e]=C(),t=p(a),o=p(h);return S(e,{prefersDarkMode:t,prefersHighContrast:o})}function G({prefersDarkMode:e,prefersHighContrast:t}){return t?e?"dark-high-contrast":"light-high-contrast":e?"dark":"light"}function H({defaultTheme:e="system",storageKey:t=T}){return`
1
+ import{a as g}from"./chunk-D3XF6J5A.js";import E from"clsx";import{createContext as N,useContext as W,useEffect as x,useMemo as C,useState as B}from"react";import _ from"tiny-invariant";import{Fragment as k,jsx as i,jsxs as b}from"react/jsx-runtime";var M="https://cdn.ngrok.com",q=`${M}/static/fonts`,R=["/euclid-square/EuclidSquare-Regular-WebS.woff","/euclid-square/EuclidSquare-RegularItalic-WebS.woff","/euclid-square/EuclidSquare-Medium-WebS.woff","/euclid-square/EuclidSquare-Semibold-WebS.woff","/euclid-square/EuclidSquare-MediumItalic-WebS.woff","/ibm-plex-mono/IBMPlexMono-Text.woff","/ibm-plex-mono/IBMPlexMono-TextItalic.woff","/ibm-plex-mono/IBMPlexMono-SemiBold.woff","/ibm-plex-mono/IBMPlexMono-SemiBoldItalic.woff"],D=e=>`${q}${e}`,y=({includeNunitoSans:e=!1})=>b(k,{children:[i("link",{rel:"preconnect",href:M}),R.map(t=>i("link",{rel:"preload",href:D(t),as:"font",type:"font/woff",crossOrigin:"anonymous"},t)),e&&i(L,{})]});function L(){return b(k,{children:[i("link",{rel:"preconnect",href:"https://fonts.googleapis.com"}),i("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"}),i("link",{href:"https://fonts.googleapis.com/css2?family=Nunito+Sans:ital,opsz,wght@0,6..12,200..1000;1,6..12,200..1000&display=swap",rel:"stylesheet"})]})}import{Fragment as X,jsx as w,jsxs as Z}from"react/jsx-runtime";var h="(prefers-color-scheme: dark)",l="(prefers-contrast: more)",v=["light","dark","light-high-contrast","dark-high-contrast"],p=["system",...v],O=e=>e;function S(e){return typeof e!="string"?!1:p.includes(e)}var A=e=>e;function H(e){return typeof e!="string"?!1:v.includes(e)}var f="mantle-ui-theme",Q=["system",()=>null],I=N(Q),u=()=>typeof window<"u";function c(e,t="system"){let o=t??"system";if(u()){let r=null;try{r="localStorage"in window?window.localStorage.getItem(e):null}catch{}return S(r)?r:o}return o}function z({children:e,defaultTheme:t="system",storageKey:o=f}){let[r,s]=B(()=>{let n=c(o,t);return a(n),n});x(()=>{let n=c(o,t);s(n),a(n)},[t,o]),x(()=>{let n=window.matchMedia(h),m=window.matchMedia(l),d=()=>{c(o,t)==="system"&&a("system")};return n.addEventListener("change",d),m.addEventListener("change",d),()=>{n.removeEventListener("change",d),m.removeEventListener("change",d)}},[t,o]);let T=C(()=>[r,n=>{try{"localStorage"in window&&window.localStorage.setItem(o,n)}catch{}s(n),a(n)}],[o,r]);return w(I.Provider,{value:T,children:e})}function F(){let e=W(I);return _(e,"useTheme must be used within a ThemeProvider"),e}function a(e){if(!u())return;let t=window.document.documentElement;t.classList.remove(...p);let o=window.matchMedia(h).matches,r=window.matchMedia(l).matches,s=P(e,{prefersDarkMode:o,prefersHighContrast:r});t.classList.add(s),t.dataset.appliedTheme=s,t.dataset.theme=e}function G(){if(!u())return{appliedTheme:void 0,theme:void 0};let e=window.document.documentElement,t=S(e.dataset.theme)?e.dataset.theme:void 0;return{appliedTheme:H(e.dataset.appliedTheme)?e.dataset.appliedTheme:void 0,theme:t}}function P(e,{prefersDarkMode:t,prefersHighContrast:o}){return e==="system"?U({prefersDarkMode:t,prefersHighContrast:o}):e}function J(){let[e]=F(),t=g(h),o=g(l);return P(e,{prefersDarkMode:t,prefersHighContrast:o})}function U({prefersDarkMode:e,prefersHighContrast:t}){return t?e?"dark-high-contrast":"light-high-contrast":e?"dark":"light"}function $({defaultTheme:e="system",storageKey:t=f}){return`
2
2
  (function() {
3
- const themes = ${JSON.stringify(c)};
3
+ const themes = ${JSON.stringify(p)};
4
4
  const isTheme = (value) => typeof value === "string" && themes.includes(value);
5
5
  const fallbackTheme = "${e}" ?? "system";
6
6
  let maybeStoredTheme = null;
@@ -14,8 +14,8 @@ import{a as p}from"./chunk-D3XF6J5A.js";import P from"clsx";import{createContext
14
14
  } catch (_) {}
15
15
  }
16
16
  const themePreference = hasStoredTheme ? maybeStoredTheme : fallbackTheme;
17
- const prefersDarkMode = window.matchMedia("${a}").matches;
18
- const prefersHighContrast = window.matchMedia("${h}").matches;
17
+ const prefersDarkMode = window.matchMedia("${h}").matches;
18
+ const prefersHighContrast = window.matchMedia("${l}").matches;
19
19
  let initialTheme = themePreference;
20
20
  if (initialTheme === "system") {
21
21
  if (prefersHighContrast) {
@@ -30,5 +30,5 @@ import{a as p}from"./chunk-D3XF6J5A.js";import P from"clsx";import{createContext
30
30
  htmlElement.dataset.appliedTheme = initialTheme;
31
31
  htmlElement.dataset.theme = themePreference;
32
32
  })();
33
- `.trim()}var J=({defaultTheme:e="system",storageKey:t=T})=>z(Y,{children:[w("script",{dangerouslySetInnerHTML:{__html:H({defaultTheme:e,storageKey:t})}}),w(g,{})]});function U(e){let{className:t="",defaultTheme:o="system",storageKey:r=T}=e??{};return k(()=>{if(!u())return{className:P(t),"data-applied-theme":"system","data-theme":"system"};let s=window.matchMedia(a).matches,f=window.matchMedia(h).matches,n=d(r,o),m=S(n,{prefersDarkMode:s,prefersHighContrast:f});return{className:P(t,m),"data-applied-theme":m,"data-theme":n}},[t,o,r])}export{_ as $resolvedTheme,B as $theme,J as MantleThemeHeadContent,g as PreloadFonts,A as ThemeProvider,i as applyTheme,E as isResolvedTheme,y as isTheme,H as preventWrongThemeFlashScriptContent,O as readThemeFromHtmlElement,v as resolvedThemes,c as themes,Q as useAppliedTheme,U as useInitialHtmlThemeProps,C as useTheme};
33
+ `.trim()}var Y=({defaultTheme:e="system",storageKey:t=f,includeNunitoSans:o=!1})=>Z(X,{children:[w("script",{dangerouslySetInnerHTML:{__html:$({defaultTheme:e,storageKey:t})}}),w(y,{includeNunitoSans:o})]});function V(e){let{className:t="",defaultTheme:o="system",storageKey:r=f}=e??{};return C(()=>{if(!u())return{className:E(t),"data-applied-theme":"system","data-theme":"system"};let s=window.matchMedia(h).matches,T=window.matchMedia(l).matches,n=c(r,o),m=P(n,{prefersDarkMode:s,prefersHighContrast:T});return{className:E(t,m),"data-applied-theme":m,"data-theme":n}},[t,o,r])}export{A as $resolvedTheme,O as $theme,Y as MantleThemeHeadContent,y as PreloadFonts,z as ThemeProvider,a as applyTheme,H as isResolvedTheme,S as isTheme,$ as preventWrongThemeFlashScriptContent,G as readThemeFromHtmlElement,v as resolvedThemes,p as themes,J as useAppliedTheme,V as useInitialHtmlThemeProps,F as useTheme};
34
34
  //# sourceMappingURL=theme-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/theme-provider/theme-provider.tsx","../src/components/theme-provider/preload-fonts.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { PropsWithChildren } from \"react\";\nimport { createContext, useContext, useEffect, useMemo, useState } from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { useMatchesMediaQuery } from \"../../hooks/use-matches-media-query\";\nimport { PreloadFonts } from \"./preload-fonts\";\n\n/**\n * prefersDarkModeMediaQuery is the media query used to detect if the user prefers dark mode.\n */\nconst prefersDarkModeMediaQuery = \"(prefers-color-scheme: dark)\";\n\n/**\n * prefersHighContrastMediaQuery is the media query used to detect if the user prefers high contrast mode.\n */\nconst prefersHighContrastMediaQuery = \"(prefers-contrast: more)\";\n\n/**\n * resolvedThemes is a tuple of valid themes that have been resolved from \"system\" to a specific theme.\n */\nconst resolvedThemes = [\"light\", \"dark\", \"light-high-contrast\", \"dark-high-contrast\"] as const;\n\n/**\n * ResolvedTheme is a type that represents a theme that has been resolved from \"system\" to a specific theme.\n */\ntype ResolvedTheme = (typeof resolvedThemes)[number];\n\n/**\n * themes is a tuple of valid themes.\n */\nconst themes = [\"system\", ...resolvedThemes] as const;\n\n/**\n * Theme is a string literal type that represents a valid theme.\n */\ntype Theme = (typeof themes)[number];\n\n/**\n * $theme is a helper which translates the Theme type into a string literal type.\n */\nconst $theme = <T extends Theme = Theme>(value: T) => value;\n\n/**\n * Type predicate that checks if a value is a valid theme.\n */\nfunction isTheme(value: unknown): value is Theme {\n\tif (typeof value !== \"string\") {\n\t\treturn false;\n\t}\n\n\treturn themes.includes(value as Theme);\n}\n\n/**\n * $resolvedTheme is a helper which translates the ResolvedTheme type into a string literal type.\n */\nconst $resolvedTheme = <T extends ResolvedTheme = ResolvedTheme>(value: T) => value;\n\n/**\n * Type predicate that checks if a value is a valid resolved theme.\n */\nfunction isResolvedTheme(value: unknown): value is ResolvedTheme {\n\tif (typeof value !== \"string\") {\n\t\treturn false;\n\t}\n\n\treturn resolvedThemes.includes(value as ResolvedTheme);\n}\n\n/**\n * DEFAULT_STORAGE_KEY is the default key used to store the theme in localStorage.\n */\nconst DEFAULT_STORAGE_KEY = \"mantle-ui-theme\";\n\n/**\n * ThemeProviderState is the shape of the state returned by the ThemeProviderContext.\n */\ntype ThemeProviderState = [theme: Theme, setTheme: (theme: Theme) => void];\n\n/**\n * Initial state for the ThemeProviderContext.\n */\nconst initialState: ThemeProviderState = [\"system\", () => null];\n\n/**\n * ThemeProviderContext is a React Context that provides the current theme and a function to set the theme.\n */\nconst ThemeProviderContext = createContext<ThemeProviderState>(initialState);\n\n/**\n * isBrowser returns true if the code is running in a browser environment.\n */\nconst isBrowser = () => typeof window !== \"undefined\";\n\n/**\n * Gets the stored theme from localStorage or returns the default theme if no theme is stored.\n */\nfunction getStoredTheme(storageKey: string, defaultTheme: Theme = \"system\") {\n\tconst fallbackTheme = defaultTheme ?? \"system\";\n\tif (isBrowser()) {\n\t\tlet storedTheme: string | null = null;\n\t\ttry {\n\t\t\tstoredTheme = \"localStorage\" in window ? window.localStorage.getItem(storageKey) : null;\n\t\t} catch (_) {}\n\t\treturn isTheme(storedTheme) ? storedTheme : fallbackTheme;\n\t}\n\treturn fallbackTheme;\n}\n\ntype ThemeProviderProps = PropsWithChildren & {\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n};\n\n/**\n * ThemeProvider is a React Context Provider that provides the current theme and a function to set the theme.\n */\nfunction ThemeProvider({ children, defaultTheme = \"system\", storageKey = DEFAULT_STORAGE_KEY }: ThemeProviderProps) {\n\tconst [theme, setTheme] = useState<Theme>(() => {\n\t\tconst initialTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tapplyTheme(initialTheme);\n\t\treturn initialTheme;\n\t});\n\n\tuseEffect(() => {\n\t\tconst storedTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tsetTheme(storedTheme);\n\t\tapplyTheme(storedTheme);\n\t}, [defaultTheme, storageKey]);\n\n\tuseEffect(() => {\n\t\tconst prefersDarkMql = window.matchMedia(prefersDarkModeMediaQuery);\n\t\tconst prefersHighContrastMql = window.matchMedia(prefersHighContrastMediaQuery);\n\n\t\tconst onChange = () => {\n\t\t\tconst storedTheme = getStoredTheme(storageKey, defaultTheme);\n\n\t\t\t// If the stored theme is not \"system\", then the user has explicitly set a theme and we should not\n\t\t\t// automatically change the theme when the user's system preferences change.\n\t\t\tif (storedTheme !== \"system\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tapplyTheme(\"system\");\n\t\t};\n\n\t\tprefersDarkMql.addEventListener(\"change\", onChange);\n\t\tprefersHighContrastMql.addEventListener(\"change\", onChange);\n\n\t\treturn () => {\n\t\t\tprefersDarkMql.removeEventListener(\"change\", onChange);\n\t\t\tprefersHighContrastMql.removeEventListener(\"change\", onChange);\n\t\t};\n\t}, [defaultTheme, storageKey]);\n\n\tconst value: ThemeProviderState = useMemo(\n\t\t() => [\n\t\t\ttheme,\n\t\t\t(theme: Theme) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (\"localStorage\" in window) {\n\t\t\t\t\t\twindow.localStorage.setItem(storageKey, theme);\n\t\t\t\t\t}\n\t\t\t\t} catch (_) {}\n\t\t\t\tsetTheme(theme);\n\t\t\t\tapplyTheme(theme);\n\t\t\t},\n\t\t],\n\t\t[storageKey, theme],\n\t);\n\n\treturn <ThemeProviderContext.Provider value={value}>{children}</ThemeProviderContext.Provider>;\n}\n\n/**\n * useTheme returns the current theme and a function to set the theme.\n *\n * @note This function will throw an error if used outside of a ThemeProvider context tree.\n */\nfunction useTheme() {\n\tconst context = useContext(ThemeProviderContext);\n\n\tinvariant(context, \"useTheme must be used within a ThemeProvider\");\n\n\treturn context;\n}\n\n/**\n * Applies the given theme to the `<html>` element.\n */\nfunction applyTheme(theme: Theme) {\n\tif (!isBrowser()) {\n\t\treturn;\n\t}\n\n\tconst htmlElement = window.document.documentElement;\n\thtmlElement.classList.remove(...themes);\n\tconst prefersDarkMode = window.matchMedia(prefersDarkModeMediaQuery).matches;\n\tconst prefersHighContrast = window.matchMedia(prefersHighContrastMediaQuery).matches;\n\tconst newTheme = resolveTheme(theme, { prefersDarkMode, prefersHighContrast });\n\thtmlElement.classList.add(newTheme);\n\thtmlElement.dataset.appliedTheme = newTheme;\n\thtmlElement.dataset.theme = theme;\n}\n\n/**\n * Read the theme and applied theme from the `<html>` element.\n */\nfunction readThemeFromHtmlElement() {\n\tif (!isBrowser()) {\n\t\treturn {\n\t\t\tappliedTheme: undefined,\n\t\t\ttheme: undefined,\n\t\t};\n\t}\n\n\tconst htmlElement = window.document.documentElement;\n\tconst theme = isTheme(htmlElement.dataset.theme) ? htmlElement.dataset.theme : undefined;\n\tconst appliedTheme = isResolvedTheme(htmlElement.dataset.appliedTheme) ? htmlElement.dataset.appliedTheme : undefined;\n\n\treturn {\n\t\tappliedTheme,\n\t\ttheme,\n\t};\n}\n\n/**\n * If the theme is \"system\", it will resolve the theme based on the user's media query preferences, otherwise it will return the theme as is.\n * This will mirror the result that gets applied to the <html> element.\n */\nfunction resolveTheme(\n\ttheme: Theme,\n\t{ prefersDarkMode, prefersHighContrast }: { prefersDarkMode: boolean; prefersHighContrast: boolean },\n) {\n\tif (theme === \"system\") {\n\t\treturn determineThemeFromMediaQuery({ prefersDarkMode, prefersHighContrast });\n\t}\n\n\treturn theme;\n}\n\n/**\n * If the theme is \"system\", it will resolve the theme based on the user's media query preferences, otherwise it will return the theme as is.\n * This will mirror the result that gets applied to the <html> element.\n */\nfunction useAppliedTheme() {\n\tconst [theme] = useTheme();\n\n\tconst prefersDarkMode = useMatchesMediaQuery(prefersDarkModeMediaQuery);\n\tconst prefersHighContrast = useMatchesMediaQuery(prefersHighContrastMediaQuery);\n\n\treturn resolveTheme(theme, { prefersDarkMode, prefersHighContrast });\n}\n\n/**\n * determineThemeFromMediaQuery returns the theme that should be used based on the user's media query preferences.\n * @private\n */\nexport function determineThemeFromMediaQuery({\n\tprefersDarkMode,\n\tprefersHighContrast,\n}: {\n\tprefersDarkMode: boolean;\n\tprefersHighContrast: boolean;\n}): ResolvedTheme {\n\tif (prefersHighContrast) {\n\t\treturn prefersDarkMode ? \"dark-high-contrast\" : \"light-high-contrast\";\n\t}\n\n\treturn prefersDarkMode ? \"dark\" : \"light\";\n}\n\nfunction preventWrongThemeFlashScriptContent({\n\tdefaultTheme = \"system\",\n\tstorageKey = DEFAULT_STORAGE_KEY,\n}: {\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n}) {\n\treturn `\n(function() {\n\tconst themes = ${JSON.stringify(themes)};\n\tconst isTheme = (value) => typeof value === \"string\" && themes.includes(value);\n\tconst fallbackTheme = \"${defaultTheme}\" ?? \"system\";\n\tlet maybeStoredTheme = null;\n\ttry {\n\t\tmaybeStoredTheme = \"localStorage\" in window ? window.localStorage.getItem(\"${storageKey}\") : null;\n\t} catch (_) {}\n\tconst hasStoredTheme = isTheme(maybeStoredTheme);\n\tif (!hasStoredTheme && \"localStorage\" in window) {\n\t\ttry {\n\t\t\twindow.localStorage.setItem(\"${storageKey}\", fallbackTheme);\n\t\t} catch (_) {}\n\t}\n\tconst themePreference = hasStoredTheme ? maybeStoredTheme : fallbackTheme;\n\tconst prefersDarkMode = window.matchMedia(\"${prefersDarkModeMediaQuery}\").matches;\n\tconst prefersHighContrast = window.matchMedia(\"${prefersHighContrastMediaQuery}\").matches;\n\tlet initialTheme = themePreference;\n\tif (initialTheme === \"system\") {\n\t\tif (prefersHighContrast) {\n\t\t\tinitialTheme = prefersDarkMode ? \"dark-high-contrast\" : \"light-high-contrast\";\n\t\t} else {\n\t\t\tinitialTheme = prefersDarkMode ? \"dark\" : \"light\";\n\t\t}\n\t}\n\tconst htmlElement = document.documentElement;\n\thtmlElement.classList.remove(...themes);\n\thtmlElement.classList.add(initialTheme);\n\thtmlElement.dataset.appliedTheme = initialTheme;\n\thtmlElement.dataset.theme = themePreference;\n})();\n`.trim();\n}\n\n/**\n * MantleThemeHeadContent is a React component that prevents the wrong theme from flashing on initial page load.\n * Render as high as possible in the <head> element.\n */\nconst MantleThemeHeadContent = ({\n\tdefaultTheme = \"system\",\n\tstorageKey = DEFAULT_STORAGE_KEY,\n}: {\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n}) => (\n\t<>\n\t\t<script\n\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t__html: preventWrongThemeFlashScriptContent({ defaultTheme, storageKey }),\n\t\t\t}}\n\t\t/>\n\t\t<PreloadFonts />\n\t</>\n);\n\ntype InitialThemeProps = {\n\tclassName: string;\n\t\"data-applied-theme\": Omit<Theme, \"system\">;\n\t\"data-theme\": Theme;\n};\n\n/**\n * useInitialHtmlThemeProps returns the initial props that should be applied to the <html> element to prevent react hydration errors.\n */\nfunction useInitialHtmlThemeProps(props?: {\n\tclassName?: string;\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n}): InitialThemeProps {\n\tconst { className = \"\", defaultTheme = \"system\", storageKey = DEFAULT_STORAGE_KEY } = props ?? {};\n\n\treturn useMemo(() => {\n\t\tif (!isBrowser()) {\n\t\t\treturn {\n\t\t\t\tclassName: clsx(className),\n\t\t\t\t\"data-applied-theme\": \"system\",\n\t\t\t\t\"data-theme\": \"system\",\n\t\t\t};\n\t\t}\n\n\t\tconst prefersDarkMode = window.matchMedia(prefersDarkModeMediaQuery).matches;\n\t\tconst prefersHighContrast = window.matchMedia(prefersHighContrastMediaQuery).matches;\n\t\tconst initialTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tconst reolvedTheme = resolveTheme(initialTheme, { prefersDarkMode, prefersHighContrast });\n\n\t\treturn {\n\t\t\tclassName: clsx(className, reolvedTheme),\n\t\t\t\"data-applied-theme\": reolvedTheme,\n\t\t\t\"data-theme\": initialTheme,\n\t\t};\n\t}, [className, defaultTheme, storageKey]);\n}\n\nexport {\n\t//,\n\t$resolvedTheme,\n\t$theme,\n\tapplyTheme,\n\tisResolvedTheme,\n\tisTheme,\n\tMantleThemeHeadContent,\n\tpreventWrongThemeFlashScriptContent,\n\treadThemeFromHtmlElement,\n\tresolvedThemes,\n\tThemeProvider,\n\tthemes,\n\tuseAppliedTheme,\n\tuseInitialHtmlThemeProps,\n\tuseTheme,\n};\n\nexport type {\n\t//,\n\tResolvedTheme,\n\tTheme,\n\tThemeProviderProps,\n};\n","const cdnBase = \"https://cdn.ngrok.com/static/fonts\";\n\nconst fonts = [\n\t\"euclid-square/EuclidSquare-Regular-WebS.woff\",\n\t\"euclid-square/EuclidSquare-RegularItalic-WebS.woff\",\n\t\"euclid-square/EuclidSquare-Medium-WebS.woff\",\n\t\"euclid-square/EuclidSquare-Semibold-WebS.woff\",\n\t\"euclid-square/EuclidSquare-MediumItalic-WebS.woff\",\n\t\"ibm-plex-mono/IBMPlexMono-Text.woff\",\n\t\"ibm-plex-mono/IBMPlexMono-TextItalic.woff\",\n\t\"ibm-plex-mono/IBMPlexMono-SemiBold.woff\",\n\t\"ibm-plex-mono/IBMPlexMono-SemiBoldItalic.woff\",\n] as const;\n\ntype Font = (typeof fonts)[number];\n\nconst fontHref = <T extends Font>(font: T) => [cdnBase, font].join(\"/\");\n\n/**\n * Preload custom fonts used in the theme. This should be added to the head of the document in your application, preferably as high as possible.\n * Normally you won't use this directly, but instead use the `MantleThemeHeadContent` component which includes this.\n */\nconst PreloadFonts = () => (\n\t<>\n\t\t{fonts.map((font) => (\n\t\t\t<link key={font} rel=\"preload\" href={fontHref(font)} as=\"font\" type=\"font/woff\" crossOrigin=\"anonymous\" />\n\t\t))}\n\t</>\n);\n\nexport { PreloadFonts };\n"],"mappings":"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","names":["clsx","createContext","useContext","useEffect","useMemo","useState","invariant","Fragment","jsx","cdnBase","fonts","fontHref","font","PreloadFonts","Fragment","jsx","jsxs","prefersDarkModeMediaQuery","prefersHighContrastMediaQuery","resolvedThemes","themes","$theme","value","isTheme","$resolvedTheme","isResolvedTheme","DEFAULT_STORAGE_KEY","initialState","ThemeProviderContext","createContext","isBrowser","getStoredTheme","storageKey","defaultTheme","fallbackTheme","storedTheme","ThemeProvider","children","theme","setTheme","useState","initialTheme","applyTheme","useEffect","prefersDarkMql","prefersHighContrastMql","onChange","useMemo","useTheme","context","useContext","invariant","htmlElement","prefersDarkMode","prefersHighContrast","newTheme","resolveTheme","readThemeFromHtmlElement","determineThemeFromMediaQuery","useAppliedTheme","useMatchesMediaQuery","preventWrongThemeFlashScriptContent","MantleThemeHeadContent","PreloadFonts","useInitialHtmlThemeProps","props","className","clsx","reolvedTheme"]}
1
+ {"version":3,"sources":["../src/components/theme-provider/theme-provider.tsx","../src/components/theme-provider/preload-fonts.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type { ComponentProps, PropsWithChildren } from \"react\";\nimport { createContext, useContext, useEffect, useMemo, useState } from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { useMatchesMediaQuery } from \"../../hooks/use-matches-media-query\";\nimport { PreloadFonts } from \"./preload-fonts\";\n\n/**\n * prefersDarkModeMediaQuery is the media query used to detect if the user prefers dark mode.\n */\nconst prefersDarkModeMediaQuery = \"(prefers-color-scheme: dark)\";\n\n/**\n * prefersHighContrastMediaQuery is the media query used to detect if the user prefers high contrast mode.\n */\nconst prefersHighContrastMediaQuery = \"(prefers-contrast: more)\";\n\n/**\n * resolvedThemes is a tuple of valid themes that have been resolved from \"system\" to a specific theme.\n */\nconst resolvedThemes = [\"light\", \"dark\", \"light-high-contrast\", \"dark-high-contrast\"] as const;\n\n/**\n * ResolvedTheme is a type that represents a theme that has been resolved from \"system\" to a specific theme.\n */\ntype ResolvedTheme = (typeof resolvedThemes)[number];\n\n/**\n * themes is a tuple of valid themes.\n */\nconst themes = [\"system\", ...resolvedThemes] as const;\n\n/**\n * Theme is a string literal type that represents a valid theme.\n */\ntype Theme = (typeof themes)[number];\n\n/**\n * $theme is a helper which translates the Theme type into a string literal type.\n */\nconst $theme = <T extends Theme = Theme>(value: T) => value;\n\n/**\n * Type predicate that checks if a value is a valid theme.\n */\nfunction isTheme(value: unknown): value is Theme {\n\tif (typeof value !== \"string\") {\n\t\treturn false;\n\t}\n\n\treturn themes.includes(value as Theme);\n}\n\n/**\n * $resolvedTheme is a helper which translates the ResolvedTheme type into a string literal type.\n */\nconst $resolvedTheme = <T extends ResolvedTheme = ResolvedTheme>(value: T) => value;\n\n/**\n * Type predicate that checks if a value is a valid resolved theme.\n */\nfunction isResolvedTheme(value: unknown): value is ResolvedTheme {\n\tif (typeof value !== \"string\") {\n\t\treturn false;\n\t}\n\n\treturn resolvedThemes.includes(value as ResolvedTheme);\n}\n\n/**\n * DEFAULT_STORAGE_KEY is the default key used to store the theme in localStorage.\n */\nconst DEFAULT_STORAGE_KEY = \"mantle-ui-theme\";\n\n/**\n * ThemeProviderState is the shape of the state returned by the ThemeProviderContext.\n */\ntype ThemeProviderState = [theme: Theme, setTheme: (theme: Theme) => void];\n\n/**\n * Initial state for the ThemeProviderContext.\n */\nconst initialState: ThemeProviderState = [\"system\", () => null];\n\n/**\n * ThemeProviderContext is a React Context that provides the current theme and a function to set the theme.\n */\nconst ThemeProviderContext = createContext<ThemeProviderState>(initialState);\n\n/**\n * isBrowser returns true if the code is running in a browser environment.\n */\nconst isBrowser = () => typeof window !== \"undefined\";\n\n/**\n * Gets the stored theme from localStorage or returns the default theme if no theme is stored.\n */\nfunction getStoredTheme(storageKey: string, defaultTheme: Theme = \"system\") {\n\tconst fallbackTheme = defaultTheme ?? \"system\";\n\tif (isBrowser()) {\n\t\tlet storedTheme: string | null = null;\n\t\ttry {\n\t\t\tstoredTheme = \"localStorage\" in window ? window.localStorage.getItem(storageKey) : null;\n\t\t} catch (_) {}\n\t\treturn isTheme(storedTheme) ? storedTheme : fallbackTheme;\n\t}\n\treturn fallbackTheme;\n}\n\ntype ThemeProviderProps = PropsWithChildren & {\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n};\n\n/**\n * ThemeProvider is a React Context Provider that provides the current theme and a function to set the theme.\n */\nfunction ThemeProvider({ children, defaultTheme = \"system\", storageKey = DEFAULT_STORAGE_KEY }: ThemeProviderProps) {\n\tconst [theme, setTheme] = useState<Theme>(() => {\n\t\tconst initialTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tapplyTheme(initialTheme);\n\t\treturn initialTheme;\n\t});\n\n\tuseEffect(() => {\n\t\tconst storedTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tsetTheme(storedTheme);\n\t\tapplyTheme(storedTheme);\n\t}, [defaultTheme, storageKey]);\n\n\tuseEffect(() => {\n\t\tconst prefersDarkMql = window.matchMedia(prefersDarkModeMediaQuery);\n\t\tconst prefersHighContrastMql = window.matchMedia(prefersHighContrastMediaQuery);\n\n\t\tconst onChange = () => {\n\t\t\tconst storedTheme = getStoredTheme(storageKey, defaultTheme);\n\n\t\t\t// If the stored theme is not \"system\", then the user has explicitly set a theme and we should not\n\t\t\t// automatically change the theme when the user's system preferences change.\n\t\t\tif (storedTheme !== \"system\") {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tapplyTheme(\"system\");\n\t\t};\n\n\t\tprefersDarkMql.addEventListener(\"change\", onChange);\n\t\tprefersHighContrastMql.addEventListener(\"change\", onChange);\n\n\t\treturn () => {\n\t\t\tprefersDarkMql.removeEventListener(\"change\", onChange);\n\t\t\tprefersHighContrastMql.removeEventListener(\"change\", onChange);\n\t\t};\n\t}, [defaultTheme, storageKey]);\n\n\tconst value: ThemeProviderState = useMemo(\n\t\t() => [\n\t\t\ttheme,\n\t\t\t(theme: Theme) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (\"localStorage\" in window) {\n\t\t\t\t\t\twindow.localStorage.setItem(storageKey, theme);\n\t\t\t\t\t}\n\t\t\t\t} catch (_) {}\n\t\t\t\tsetTheme(theme);\n\t\t\t\tapplyTheme(theme);\n\t\t\t},\n\t\t],\n\t\t[storageKey, theme],\n\t);\n\n\treturn <ThemeProviderContext.Provider value={value}>{children}</ThemeProviderContext.Provider>;\n}\n\n/**\n * useTheme returns the current theme and a function to set the theme.\n *\n * @note This function will throw an error if used outside of a ThemeProvider context tree.\n */\nfunction useTheme() {\n\tconst context = useContext(ThemeProviderContext);\n\n\tinvariant(context, \"useTheme must be used within a ThemeProvider\");\n\n\treturn context;\n}\n\n/**\n * Applies the given theme to the `<html>` element.\n */\nfunction applyTheme(theme: Theme) {\n\tif (!isBrowser()) {\n\t\treturn;\n\t}\n\n\tconst htmlElement = window.document.documentElement;\n\thtmlElement.classList.remove(...themes);\n\tconst prefersDarkMode = window.matchMedia(prefersDarkModeMediaQuery).matches;\n\tconst prefersHighContrast = window.matchMedia(prefersHighContrastMediaQuery).matches;\n\tconst newTheme = resolveTheme(theme, { prefersDarkMode, prefersHighContrast });\n\thtmlElement.classList.add(newTheme);\n\thtmlElement.dataset.appliedTheme = newTheme;\n\thtmlElement.dataset.theme = theme;\n}\n\n/**\n * Read the theme and applied theme from the `<html>` element.\n */\nfunction readThemeFromHtmlElement() {\n\tif (!isBrowser()) {\n\t\treturn {\n\t\t\tappliedTheme: undefined,\n\t\t\ttheme: undefined,\n\t\t};\n\t}\n\n\tconst htmlElement = window.document.documentElement;\n\tconst theme = isTheme(htmlElement.dataset.theme) ? htmlElement.dataset.theme : undefined;\n\tconst appliedTheme = isResolvedTheme(htmlElement.dataset.appliedTheme) ? htmlElement.dataset.appliedTheme : undefined;\n\n\treturn {\n\t\tappliedTheme,\n\t\ttheme,\n\t};\n}\n\n/**\n * If the theme is \"system\", it will resolve the theme based on the user's media query preferences, otherwise it will return the theme as is.\n * This will mirror the result that gets applied to the <html> element.\n */\nfunction resolveTheme(\n\ttheme: Theme,\n\t{ prefersDarkMode, prefersHighContrast }: { prefersDarkMode: boolean; prefersHighContrast: boolean },\n) {\n\tif (theme === \"system\") {\n\t\treturn determineThemeFromMediaQuery({ prefersDarkMode, prefersHighContrast });\n\t}\n\n\treturn theme;\n}\n\n/**\n * If the theme is \"system\", it will resolve the theme based on the user's media query preferences, otherwise it will return the theme as is.\n * This will mirror the result that gets applied to the <html> element.\n */\nfunction useAppliedTheme() {\n\tconst [theme] = useTheme();\n\n\tconst prefersDarkMode = useMatchesMediaQuery(prefersDarkModeMediaQuery);\n\tconst prefersHighContrast = useMatchesMediaQuery(prefersHighContrastMediaQuery);\n\n\treturn resolveTheme(theme, { prefersDarkMode, prefersHighContrast });\n}\n\n/**\n * determineThemeFromMediaQuery returns the theme that should be used based on the user's media query preferences.\n * @private\n */\nexport function determineThemeFromMediaQuery({\n\tprefersDarkMode,\n\tprefersHighContrast,\n}: {\n\tprefersDarkMode: boolean;\n\tprefersHighContrast: boolean;\n}): ResolvedTheme {\n\tif (prefersHighContrast) {\n\t\treturn prefersDarkMode ? \"dark-high-contrast\" : \"light-high-contrast\";\n\t}\n\n\treturn prefersDarkMode ? \"dark\" : \"light\";\n}\n\nfunction preventWrongThemeFlashScriptContent({\n\tdefaultTheme = \"system\",\n\tstorageKey = DEFAULT_STORAGE_KEY,\n}: {\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n}) {\n\treturn `\n(function() {\n\tconst themes = ${JSON.stringify(themes)};\n\tconst isTheme = (value) => typeof value === \"string\" && themes.includes(value);\n\tconst fallbackTheme = \"${defaultTheme}\" ?? \"system\";\n\tlet maybeStoredTheme = null;\n\ttry {\n\t\tmaybeStoredTheme = \"localStorage\" in window ? window.localStorage.getItem(\"${storageKey}\") : null;\n\t} catch (_) {}\n\tconst hasStoredTheme = isTheme(maybeStoredTheme);\n\tif (!hasStoredTheme && \"localStorage\" in window) {\n\t\ttry {\n\t\t\twindow.localStorage.setItem(\"${storageKey}\", fallbackTheme);\n\t\t} catch (_) {}\n\t}\n\tconst themePreference = hasStoredTheme ? maybeStoredTheme : fallbackTheme;\n\tconst prefersDarkMode = window.matchMedia(\"${prefersDarkModeMediaQuery}\").matches;\n\tconst prefersHighContrast = window.matchMedia(\"${prefersHighContrastMediaQuery}\").matches;\n\tlet initialTheme = themePreference;\n\tif (initialTheme === \"system\") {\n\t\tif (prefersHighContrast) {\n\t\t\tinitialTheme = prefersDarkMode ? \"dark-high-contrast\" : \"light-high-contrast\";\n\t\t} else {\n\t\t\tinitialTheme = prefersDarkMode ? \"dark\" : \"light\";\n\t\t}\n\t}\n\tconst htmlElement = document.documentElement;\n\thtmlElement.classList.remove(...themes);\n\thtmlElement.classList.add(initialTheme);\n\thtmlElement.dataset.appliedTheme = initialTheme;\n\thtmlElement.dataset.theme = themePreference;\n})();\n`.trim();\n}\n\ntype MantleThemeHeadContentProps = {\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n} & ComponentProps<typeof PreloadFonts>;\n\n/**\n * MantleThemeHeadContent is a React component that prevents the wrong theme from flashing on initial page load.\n * Render as high as possible in the <head> element.\n */\nconst MantleThemeHeadContent = ({\n\tdefaultTheme = \"system\",\n\tstorageKey = DEFAULT_STORAGE_KEY,\n\tincludeNunitoSans = false,\n}: MantleThemeHeadContentProps) => (\n\t<>\n\t\t<script\n\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t__html: preventWrongThemeFlashScriptContent({ defaultTheme, storageKey }),\n\t\t\t}}\n\t\t/>\n\t\t<PreloadFonts includeNunitoSans={includeNunitoSans} />\n\t</>\n);\n\ntype InitialThemeProps = {\n\tclassName: string;\n\t\"data-applied-theme\": Omit<Theme, \"system\">;\n\t\"data-theme\": Theme;\n};\n\n/**\n * useInitialHtmlThemeProps returns the initial props that should be applied to the <html> element to prevent react hydration errors.\n */\nfunction useInitialHtmlThemeProps(props?: {\n\tclassName?: string;\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n}): InitialThemeProps {\n\tconst { className = \"\", defaultTheme = \"system\", storageKey = DEFAULT_STORAGE_KEY } = props ?? {};\n\n\treturn useMemo(() => {\n\t\tif (!isBrowser()) {\n\t\t\treturn {\n\t\t\t\tclassName: clsx(className),\n\t\t\t\t\"data-applied-theme\": \"system\",\n\t\t\t\t\"data-theme\": \"system\",\n\t\t\t};\n\t\t}\n\n\t\tconst prefersDarkMode = window.matchMedia(prefersDarkModeMediaQuery).matches;\n\t\tconst prefersHighContrast = window.matchMedia(prefersHighContrastMediaQuery).matches;\n\t\tconst initialTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tconst reolvedTheme = resolveTheme(initialTheme, { prefersDarkMode, prefersHighContrast });\n\n\t\treturn {\n\t\t\tclassName: clsx(className, reolvedTheme),\n\t\t\t\"data-applied-theme\": reolvedTheme,\n\t\t\t\"data-theme\": initialTheme,\n\t\t};\n\t}, [className, defaultTheme, storageKey]);\n}\n\nexport {\n\t//,\n\t$resolvedTheme,\n\t$theme,\n\tapplyTheme,\n\tisResolvedTheme,\n\tisTheme,\n\tMantleThemeHeadContent,\n\tpreventWrongThemeFlashScriptContent,\n\treadThemeFromHtmlElement,\n\tresolvedThemes,\n\tThemeProvider,\n\tthemes,\n\tuseAppliedTheme,\n\tuseInitialHtmlThemeProps,\n\tuseTheme,\n};\n\nexport type {\n\t//,\n\tResolvedTheme,\n\tTheme,\n\tThemeProviderProps,\n};\n","const cdnOrigin = \"https://cdn.ngrok.com\";\nconst cdnBase = `${cdnOrigin}/static/fonts`;\n\nconst fonts = [\n\t\"/euclid-square/EuclidSquare-Regular-WebS.woff\",\n\t\"/euclid-square/EuclidSquare-RegularItalic-WebS.woff\",\n\t\"/euclid-square/EuclidSquare-Medium-WebS.woff\",\n\t\"/euclid-square/EuclidSquare-Semibold-WebS.woff\",\n\t\"/euclid-square/EuclidSquare-MediumItalic-WebS.woff\",\n\t\"/ibm-plex-mono/IBMPlexMono-Text.woff\",\n\t\"/ibm-plex-mono/IBMPlexMono-TextItalic.woff\",\n\t\"/ibm-plex-mono/IBMPlexMono-SemiBold.woff\",\n\t\"/ibm-plex-mono/IBMPlexMono-SemiBoldItalic.woff\",\n] as const;\n\ntype Font = (typeof fonts)[number];\n\nconst fontHref = <T extends Font = Font>(font: T) => `${cdnBase}${font}` as const;\n\ntype Props = {\n\t/**\n\t * If set, will also preload and include the optional Nunito Sans font from Google Fonts.\n\t * @default false\n\t */\n\tincludeNunitoSans?: boolean;\n};\n\n/**\n * Preload custom fonts used in the theme. This should be added to the head of the document in your application, preferably as high as possible.\n * Normally you won't use this directly, but instead use the `MantleThemeHeadContent` component which includes this.\n */\nconst PreloadFonts = ({ includeNunitoSans = false }: Props) => (\n\t<>\n\t\t<link rel=\"preconnect\" href={cdnOrigin} />\n\t\t{fonts.map((font) => (\n\t\t\t<link key={font} rel=\"preload\" href={fontHref(font)} as=\"font\" type=\"font/woff\" crossOrigin=\"anonymous\" />\n\t\t))}\n\t\t{includeNunitoSans && <NunitoSans />}\n\t</>\n);\n\nexport {\n\t//,\n\tPreloadFonts,\n};\n\nfunction NunitoSans() {\n\treturn (\n\t\t<>\n\t\t\t<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n\t\t\t<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossOrigin=\"anonymous\" />\n\t\t\t<link\n\t\t\t\thref=\"https://fonts.googleapis.com/css2?family=Nunito+Sans:ital,opsz,wght@0,6..12,200..1000;1,6..12,200..1000&display=swap\"\n\t\t\t\trel=\"stylesheet\"\n\t\t\t/>\n\t\t</>\n\t);\n}\n"],"mappings":"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","names":["clsx","createContext","useContext","useEffect","useMemo","useState","invariant","Fragment","jsx","jsxs","cdnOrigin","cdnBase","fonts","fontHref","font","PreloadFonts","includeNunitoSans","NunitoSans","NunitoSans","jsxs","Fragment","jsx","Fragment","jsx","jsxs","prefersDarkModeMediaQuery","prefersHighContrastMediaQuery","resolvedThemes","themes","$theme","value","isTheme","$resolvedTheme","isResolvedTheme","DEFAULT_STORAGE_KEY","initialState","ThemeProviderContext","createContext","isBrowser","getStoredTheme","storageKey","defaultTheme","fallbackTheme","storedTheme","ThemeProvider","children","theme","setTheme","useState","initialTheme","applyTheme","useEffect","prefersDarkMql","prefersHighContrastMql","onChange","useMemo","useTheme","context","useContext","invariant","htmlElement","prefersDarkMode","prefersHighContrast","newTheme","resolveTheme","readThemeFromHtmlElement","determineThemeFromMediaQuery","useAppliedTheme","useMatchesMediaQuery","preventWrongThemeFlashScriptContent","MantleThemeHeadContent","includeNunitoSans","PreloadFonts","useInitialHtmlThemeProps","props","className","clsx","reolvedTheme"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "mantle is ngrok's UI library and design system.",
4
4
  "author": "ngrok",
5
5
  "license": "MIT",
6
- "version": "0.3.0",
6
+ "version": "0.4.0",
7
7
  "homepage": "https://mantle.ngrok.com",
8
8
  "repository": {
9
9
  "type": "git",
@@ -49,15 +49,15 @@
49
49
  "@testing-library/dom": "10.4.0",
50
50
  "@testing-library/react": "16.0.1",
51
51
  "@testing-library/user-event": "14.5.2",
52
- "@types/node": "20.16.6",
52
+ "@types/node": "20.16.9",
53
53
  "@types/prismjs": "1.26.4",
54
54
  "@types/react": "18.3.9",
55
55
  "@types/react-dom": "18.3.0",
56
56
  "@vitejs/plugin-react": "4.3.1",
57
57
  "@vitest/ui": "2.1.1",
58
58
  "autoprefixer": "10.4.20",
59
- "browserslist": "4.23.3",
60
- "date-fns": "4.1.0",
59
+ "browserslist": "4.24.0",
60
+ "date-fns": "3.6.0",
61
61
  "jsdom": "25.0.1",
62
62
  "postcss": "8.4.47",
63
63
  "react": "18.3.1",
@@ -66,15 +66,15 @@
66
66
  "tailwindcss": "3.4.13",
67
67
  "tsup": "8.3.0",
68
68
  "typescript": "5.6.2",
69
- "vite": "5.4.7",
70
- "vitest": "2.0.5",
69
+ "vite": "5.4.8",
70
+ "vitest": "2.1.1",
71
71
  "vitest-dom": "0.1.1",
72
72
  "zod": "3.23.8",
73
73
  "@cfg/tsconfig": "1.0.0"
74
74
  },
75
75
  "peerDependencies": {
76
76
  "@phosphor-icons/react": "2.1.7",
77
- "date-fns": "^4.1.0",
77
+ "date-fns": "^3.6.0",
78
78
  "postcss": "^8.4.47",
79
79
  "react": "^18.3.1",
80
80
  "react-dom": "^18.3.1",