@ngrok/mantle 0.55.2 → 0.55.4
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/dist/alert-dialog.js +1 -1
- package/dist/alert-dialog.js.map +1 -1
- package/dist/browser-only.d.ts +18 -1
- package/dist/browser-only.js +1 -1
- package/dist/browser-only.js.map +1 -1
- package/dist/chunk-4CLIEHH3.js +2 -0
- package/dist/chunk-4CLIEHH3.js.map +1 -0
- package/dist/chunk-4R4RBAKU.js +2 -0
- package/dist/chunk-4R4RBAKU.js.map +1 -0
- package/dist/chunk-NJNFZ2EG.js +2 -0
- package/dist/chunk-NJNFZ2EG.js.map +1 -0
- package/dist/{chunk-Q2I2F6IG.js → chunk-WVBQX6DT.js} +2 -2
- package/dist/data-table.js +1 -1
- package/dist/dialog.js +1 -1
- package/dist/dialog.js.map +1 -1
- package/dist/hooks.js +1 -1
- package/dist/icons.d.ts +1 -1
- package/dist/icons.js +1 -1
- package/dist/icons.js.map +1 -1
- package/dist/sheet.js +1 -1
- package/dist/sheet.js.map +1 -1
- package/dist/table.js +1 -1
- package/dist/theme.d.ts +31 -83
- package/dist/theme.js +1 -1
- package/dist/themes-Jy9DUcQe.d.ts +34 -0
- package/dist/toast.js +1 -1
- package/package.json +8 -8
- package/dist/chunk-AINB3F3G.js +0 -97
- package/dist/chunk-AINB3F3G.js.map +0 -1
- package/dist/chunk-W2SMAR4Q.js +0 -2
- package/dist/chunk-W2SMAR4Q.js.map +0 -1
- /package/dist/{chunk-Q2I2F6IG.js.map → chunk-WVBQX6DT.js.map} +0 -0
package/dist/theme.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ComponentProps, PropsWithChildren } from 'react';
|
|
3
|
+
import { T as Theme, R as ResolvedTheme } from './themes-Jy9DUcQe.js';
|
|
4
|
+
export { a as $resolvedTheme, $ as $theme, i as isResolvedTheme, b as isTheme, r as resolvedThemes, t as themes } from './themes-Jy9DUcQe.js';
|
|
3
5
|
|
|
4
6
|
type Props = {
|
|
5
7
|
/**
|
|
@@ -23,66 +25,11 @@ declare const PreloadFonts: {
|
|
|
23
25
|
displayName: string;
|
|
24
26
|
};
|
|
25
27
|
|
|
26
|
-
/**
|
|
27
|
-
* resolvedThemes is a tuple of valid themes that have been resolved from "system" to a specific theme.
|
|
28
|
-
*/
|
|
29
|
-
declare const resolvedThemes: readonly ["light", "dark", "light-high-contrast", "dark-high-contrast"];
|
|
30
|
-
/**
|
|
31
|
-
* ResolvedTheme is a type that represents a theme that has been resolved from "system" to a specific theme.
|
|
32
|
-
*/
|
|
33
|
-
type ResolvedTheme = (typeof resolvedThemes)[number];
|
|
34
|
-
/**
|
|
35
|
-
* themes is a tuple of valid themes.
|
|
36
|
-
*/
|
|
37
|
-
declare const themes: readonly ["system", "light", "dark", "light-high-contrast", "dark-high-contrast"];
|
|
38
|
-
/**
|
|
39
|
-
* Theme is a string literal type that represents a valid theme.
|
|
40
|
-
*/
|
|
41
|
-
type Theme = (typeof themes)[number];
|
|
42
|
-
/**
|
|
43
|
-
* $theme is a helper which translates the Theme type into a string literal type.
|
|
44
|
-
*/
|
|
45
|
-
declare const $theme: <T extends Theme = Theme>(value: T) => T;
|
|
46
|
-
/**
|
|
47
|
-
* Type predicate that checks if a value is a valid theme.
|
|
48
|
-
*/
|
|
49
|
-
declare function isTheme(value: unknown): value is Theme;
|
|
50
|
-
/**
|
|
51
|
-
* $resolvedTheme is a helper which translates the ResolvedTheme type into a string literal type.
|
|
52
|
-
*/
|
|
53
|
-
declare const $resolvedTheme: <T extends ResolvedTheme = ResolvedTheme>(value: T) => T;
|
|
54
|
-
/**
|
|
55
|
-
* Type predicate that checks if a value is a valid resolved theme.
|
|
56
|
-
*/
|
|
57
|
-
declare function isResolvedTheme(value: unknown): value is ResolvedTheme;
|
|
58
28
|
/**
|
|
59
29
|
* ThemeProviderState is the shape of the state returned by the ThemeProviderContext.
|
|
60
30
|
*/
|
|
61
31
|
type ThemeProviderState = [theme: Theme, setTheme: (theme: Theme) => void];
|
|
62
|
-
|
|
63
|
-
* Props for the {@link ThemeProvider} component.
|
|
64
|
-
*/
|
|
65
|
-
type ThemeProviderProps = PropsWithChildren & {
|
|
66
|
-
/**
|
|
67
|
-
* The initial theme to apply if no value is found in storage.
|
|
68
|
-
*
|
|
69
|
-
* Possible values {@link themes}:
|
|
70
|
-
* - `"system"` – follow the user’s system preferences (default).
|
|
71
|
-
* - `"light"` – force light mode.
|
|
72
|
-
* - `"dark"` – force dark mode.
|
|
73
|
-
* - `"light-high-contrast"` – light mode with increased contrast.
|
|
74
|
-
* - `"dark-high-contrast"` – dark mode with increased contrast.
|
|
75
|
-
*/
|
|
76
|
-
defaultTheme?: Theme;
|
|
77
|
-
/**
|
|
78
|
-
* The key used to persist the selected theme in cookies or storage.
|
|
79
|
-
*
|
|
80
|
-
* Defaults to `"theme"` (or the {@link DEFAULT_STORAGE_KEY} constant).
|
|
81
|
-
* Useful if you need to isolate theme settings across multiple apps
|
|
82
|
-
* or contexts.
|
|
83
|
-
*/
|
|
84
|
-
storageKey?: string;
|
|
85
|
-
};
|
|
32
|
+
type ThemeProviderProps = PropsWithChildren;
|
|
86
33
|
/**
|
|
87
34
|
* ThemeProvider is a React Context Provider that provides the current theme and a function to set the theme.
|
|
88
35
|
*
|
|
@@ -95,7 +42,7 @@ type ThemeProviderProps = PropsWithChildren & {
|
|
|
95
42
|
* </ThemeProvider>
|
|
96
43
|
* ```
|
|
97
44
|
*/
|
|
98
|
-
declare function ThemeProvider({ children
|
|
45
|
+
declare function ThemeProvider({ children }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
99
46
|
declare namespace ThemeProvider {
|
|
100
47
|
var displayName: string;
|
|
101
48
|
}
|
|
@@ -105,10 +52,6 @@ declare namespace ThemeProvider {
|
|
|
105
52
|
* @note This function will throw an error if used outside of a ThemeProvider context tree.
|
|
106
53
|
*/
|
|
107
54
|
declare function useTheme(): ThemeProviderState;
|
|
108
|
-
/**
|
|
109
|
-
* Applies the given theme to the `<html>` element.
|
|
110
|
-
*/
|
|
111
|
-
declare function applyTheme(theme: Theme): void;
|
|
112
55
|
/**
|
|
113
56
|
* Read the theme and applied theme from the `<html>` element.
|
|
114
57
|
*/
|
|
@@ -121,22 +64,13 @@ declare function readThemeFromHtmlElement(): {
|
|
|
121
64
|
* This will mirror the result that gets applied to the <html> element.
|
|
122
65
|
*/
|
|
123
66
|
declare function useAppliedTheme(): "dark" | "light" | "light-high-contrast" | "dark-high-contrast";
|
|
124
|
-
type PreventWrongThemeFlashScriptContentOptions = {
|
|
125
|
-
defaultTheme?: Theme;
|
|
126
|
-
storageKey?: string;
|
|
127
|
-
};
|
|
128
67
|
/**
|
|
129
68
|
* preventWrongThemeFlashScriptContent generates a script that prevents the wrong theme from flashing on initial page load.
|
|
130
69
|
* It checks cookies for a stored theme, and if none is found, it sets the default theme.
|
|
131
70
|
* It also applies the correct theme to the `<html>` element based on the user's media query preferences.
|
|
132
71
|
*/
|
|
133
|
-
declare function preventWrongThemeFlashScriptContent(
|
|
72
|
+
declare function preventWrongThemeFlashScriptContent(): string;
|
|
134
73
|
type MantleThemeHeadContentProps = {
|
|
135
|
-
/**
|
|
136
|
-
* The default theme to use if no theme is stored in cookies.
|
|
137
|
-
* @default "system"
|
|
138
|
-
*/
|
|
139
|
-
defaultTheme?: Theme;
|
|
140
74
|
/**
|
|
141
75
|
* An optional CSP nonce to allowlist this inline script. Using this can help
|
|
142
76
|
* you to avoid using the CSP `unsafe-inline` directive, which disables
|
|
@@ -145,11 +79,6 @@ type MantleThemeHeadContentProps = {
|
|
|
145
79
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce
|
|
146
80
|
*/
|
|
147
81
|
nonce?: string;
|
|
148
|
-
/**
|
|
149
|
-
* The key used to store the theme in cookies.
|
|
150
|
-
* @default "mantle-ui-theme"
|
|
151
|
-
*/
|
|
152
|
-
storageKey?: string;
|
|
153
82
|
} & ComponentProps<typeof PreloadFonts>;
|
|
154
83
|
/**
|
|
155
84
|
* MantleThemeHeadContent is a React component that renders a script to prevent
|
|
@@ -159,7 +88,7 @@ type MantleThemeHeadContentProps = {
|
|
|
159
88
|
* Render as high as possible in the <head> element.
|
|
160
89
|
*/
|
|
161
90
|
declare const MantleThemeHeadContent: {
|
|
162
|
-
({
|
|
91
|
+
({ includeNunitoSans, nonce, }: MantleThemeHeadContentProps): react_jsx_runtime.JSX.Element;
|
|
163
92
|
displayName: string;
|
|
164
93
|
};
|
|
165
94
|
type InitialThemeProps = {
|
|
@@ -167,13 +96,32 @@ type InitialThemeProps = {
|
|
|
167
96
|
"data-applied-theme": ResolvedTheme;
|
|
168
97
|
"data-theme": Theme;
|
|
169
98
|
};
|
|
99
|
+
type UseInitialHtmlThemePropsOptions = {
|
|
100
|
+
className?: string;
|
|
101
|
+
};
|
|
170
102
|
/**
|
|
171
103
|
* useInitialHtmlThemeProps returns the initial props that should be applied to the <html> element to prevent react hydration errors.
|
|
172
104
|
*/
|
|
173
|
-
declare function useInitialHtmlThemeProps(props?:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
105
|
+
declare function useInitialHtmlThemeProps(props?: UseInitialHtmlThemePropsOptions): InitialThemeProps;
|
|
106
|
+
type GetStoredThemeOptions = {
|
|
107
|
+
/**
|
|
108
|
+
* raw Cookie header (SSR) or document.cookie (client)
|
|
109
|
+
*/
|
|
110
|
+
cookie: string | null | undefined;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Returns the persisted UI theme from a Cookie header string.
|
|
114
|
+
*
|
|
115
|
+
* Looks for a cookie named by {@link THEME_STORAGE_KEY} and returns its value **iff**
|
|
116
|
+
* it’s a valid `Theme` per `isTheme`. Otherwise, falls back to
|
|
117
|
+
* {@link DEFAULT_THEME}. This function never throws; malformed encodings or
|
|
118
|
+
* missing cookies quietly return the default.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* getStoredTheme({ cookie: `${THEME_STORAGE_KEY}=dark; session=abc` }) // "dark"
|
|
122
|
+
* @example
|
|
123
|
+
* getStoredTheme({ cookie: "" }) // DEFAULT_THEME
|
|
124
|
+
*/
|
|
125
|
+
declare function getStoredTheme({ cookie }: GetStoredThemeOptions): Theme;
|
|
178
126
|
|
|
179
|
-
export {
|
|
127
|
+
export { MantleThemeHeadContent, PreloadFonts, ResolvedTheme, Theme, ThemeProvider, getStoredTheme, preventWrongThemeFlashScriptContent, readThemeFromHtmlElement, useAppliedTheme, useInitialHtmlThemeProps, useTheme };
|
package/dist/theme.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e,b as m,c as
|
|
1
|
+
import{a as e,b as m,c as t,d as o,e as r,f as h,g as s,h as T,i as l,j as d,k as n,l as p,m as i,n as a,o as v}from"./chunk-4CLIEHH3.js";import"./chunk-6J7D73WA.js";import"./chunk-NJNFZ2EG.js";import"./chunk-KMNACVH6.js";import"./chunk-AZ56JGNY.js";export{h as $resolvedTheme,o as $theme,i as MantleThemeHeadContent,e as PreloadFonts,T as ThemeProvider,v as getStoredTheme,s as isResolvedTheme,r as isTheme,p as preventWrongThemeFlashScriptContent,d as readThemeFromHtmlElement,m as resolvedThemes,t as themes,n as useAppliedTheme,a as useInitialHtmlThemeProps,l as useTheme};
|
|
2
2
|
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* resolvedThemes is a tuple of valid themes that have been resolved from "system" to a specific theme.
|
|
3
|
+
*/
|
|
4
|
+
declare const resolvedThemes: readonly ["light", "dark", "light-high-contrast", "dark-high-contrast"];
|
|
5
|
+
/**
|
|
6
|
+
* ResolvedTheme is a type that represents a theme that has been resolved from "system" to a specific theme.
|
|
7
|
+
*/
|
|
8
|
+
type ResolvedTheme = (typeof resolvedThemes)[number];
|
|
9
|
+
/**
|
|
10
|
+
* themes is a tuple of valid themes.
|
|
11
|
+
*/
|
|
12
|
+
declare const themes: readonly ["system", "light", "dark", "light-high-contrast", "dark-high-contrast"];
|
|
13
|
+
/**
|
|
14
|
+
* Theme is a string literal type that represents a valid theme.
|
|
15
|
+
*/
|
|
16
|
+
type Theme = (typeof themes)[number];
|
|
17
|
+
/**
|
|
18
|
+
* $theme is a helper which translates the Theme type into a string literal type.
|
|
19
|
+
*/
|
|
20
|
+
declare const $theme: <T extends Theme = Theme>(value: T) => T;
|
|
21
|
+
/**
|
|
22
|
+
* Type predicate that checks if a value is a valid theme.
|
|
23
|
+
*/
|
|
24
|
+
declare function isTheme(value: unknown): value is Theme;
|
|
25
|
+
/**
|
|
26
|
+
* $resolvedTheme is a helper which translates the ResolvedTheme type into a string literal type.
|
|
27
|
+
*/
|
|
28
|
+
declare const $resolvedTheme: <T extends ResolvedTheme = ResolvedTheme>(value: T) => T;
|
|
29
|
+
/**
|
|
30
|
+
* Type predicate that checks if a value is a valid resolved theme.
|
|
31
|
+
*/
|
|
32
|
+
declare function isResolvedTheme(value: unknown): value is ResolvedTheme;
|
|
33
|
+
|
|
34
|
+
export { $theme as $, type ResolvedTheme as R, type Theme as T, $resolvedTheme as a, isTheme as b, isResolvedTheme as i, resolvedThemes as r, themes as t };
|
package/dist/toast.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as o,b as t,c as r}from"./chunk-
|
|
1
|
+
import{a as o,b as t,c as r}from"./chunk-WVBQX6DT.js";import"./chunk-4CLIEHH3.js";import"./chunk-6J7D73WA.js";import"./chunk-NJNFZ2EG.js";import"./chunk-KMNACVH6.js";import"./chunk-I6T6YV2L.js";import"./chunk-NPTDRQT5.js";import"./chunk-AZ56JGNY.js";export{r as Toast,o as Toaster,t as makeToast};
|
|
2
2
|
//# sourceMappingURL=toast.js.map
|
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.55.
|
|
6
|
+
"version": "0.55.4",
|
|
7
7
|
"homepage": "https://mantle.ngrok.com",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"node": "^22.0.0"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@ariakit/react": "0.4.
|
|
28
|
+
"@ariakit/react": "0.4.19",
|
|
29
29
|
"@headlessui/react": "2.2.9",
|
|
30
30
|
"@radix-ui/react-accordion": "1.2.12",
|
|
31
31
|
"@radix-ui/react-dialog": "1.1.15",
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"class-variance-authority": "0.7.1",
|
|
44
44
|
"clsx": "2.1.1",
|
|
45
45
|
"prismjs": "1.30.0",
|
|
46
|
-
"react-day-picker": "9.11.
|
|
46
|
+
"react-day-picker": "9.11.1",
|
|
47
47
|
"sonner": "2.0.7",
|
|
48
48
|
"tailwind-merge": "3.3.1",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
49
|
+
"tiny-invariant": "1.3.3",
|
|
50
|
+
"tw-animate-css": "1.4.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@phosphor-icons/react": "2.1.10",
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
"@testing-library/react": "16.3.0",
|
|
57
57
|
"@testing-library/user-event": "14.6.1",
|
|
58
58
|
"@types/prismjs": "1.26.5",
|
|
59
|
-
"@types/react": "18.3.
|
|
60
|
-
"@types/react-dom": "
|
|
59
|
+
"@types/react": "18.3.26",
|
|
60
|
+
"@types/react-dom": "19.2.2",
|
|
61
61
|
"browserslist": "4.26.3",
|
|
62
62
|
"date-fns": "4.1.0",
|
|
63
63
|
"jsdom": "27.0.0",
|
|
64
64
|
"react": "18.3.1",
|
|
65
65
|
"react-dom": "18.3.1",
|
|
66
|
-
"react-router": "7.9.
|
|
66
|
+
"react-router": "7.9.4",
|
|
67
67
|
"tailwindcss": "4.1.14",
|
|
68
68
|
"tsup": "8.5.0",
|
|
69
69
|
"typescript": "5.9.3",
|
package/dist/chunk-AINB3F3G.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import{a as y}from"./chunk-6J7D73WA.js";import{Fragment as I,jsx as l,jsxs as D}from"react/jsx-runtime";var R="https://assets.ngrok.com",$=`${R}/fonts`,H=["/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"],N=e=>`${$}${e}`,w=({includeNunitoSans:e=!1})=>D(I,{children:[l("link",{rel:"preconnect",href:R}),H.map(t=>l("link",{rel:"preload",href:N(t),as:"font",type:"font/woff",crossOrigin:"anonymous"},t)),e&&l(q,{})]});w.displayName="PreloadFonts";function q(){return D(I,{children:[l("link",{rel:"preconnect",href:"https://fonts.googleapis.com"}),l("link",{rel:"preconnect",href:"https://fonts.gstatic.com",crossOrigin:"anonymous"}),l("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 L from"clsx";import{createContext as W,useContext as _,useEffect as B,useMemo as F,useRef as V,useState as Y}from"react";import K from"tiny-invariant";import{Fragment as j,jsx as C,jsxs as ee}from"react/jsx-runtime";var h="(prefers-color-scheme: dark)",u="(prefers-contrast: more)",T=["light","dark","light-high-contrast","dark-high-contrast"],U=["system",...T],ce=e=>e;function g(e){return typeof e!="string"?!1:U.includes(e)}var me=e=>e;function O(e){return typeof e!="string"?!1:T.includes(e)}var v="mantle-ui-theme";function A(e,t){let{broadcastChannel:o,pingKey:n}=t;try{if(o){o.postMessage({theme:e,timestamp:Date.now()});return}}catch{}try{localStorage.setItem(n,JSON.stringify({theme:e,timestamp:Date.now()}))}catch{}}var Q=["system",()=>null],E=W(Q),p=()=>typeof window<"u";function z(e,t){if(p())try{let o=new Date;o.setFullYear(o.getFullYear()+1);let{hostname:n,protocol:i}=window.location,r=n==="ngrok.com"||n.endsWith(".ngrok.com")?"; domain=.ngrok.com":"",a=i==="https:"?"; Secure":"";document.cookie=`${e}=${encodeURIComponent(t)}; expires=${o.toUTCString()}; path=/${r}; SameSite=Lax${a}`}catch{}}function S(e,t="system"){let o=t??"system";if(p()){let n=null;try{let r=document.cookie.split(";").find(a=>a.trim().startsWith(`${e}=`));if(r){let a=r.trim().substring(e.length+1);n=a?decodeURIComponent(a):null}}catch{}return g(n)?n:o}return o}function J({children:e,defaultTheme:t="system",storageKey:o=v}){let[n,i]=Y(()=>{let s=S(o,t);return k(s),s}),r=V(null);B(()=>{function s(c){let d=c??S(o,t);i(d),k(d)}s();try{"BroadcastChannel"in window&&(r.current=new BroadcastChannel(o),r.current.onmessage=c=>{let d=c?.data?.theme;g(d)&&s(d)})}catch{}let f=c=>{c.key===`${o}__ping`&&s()};window.addEventListener("storage",f);let M=window.matchMedia(h),P=window.matchMedia(u);function m(){s()}function b(){document.visibilityState==="visible"&&s()}return M.addEventListener("change",m),P.addEventListener("change",m),window.addEventListener("pageshow",m),document.addEventListener("visibilitychange",b),()=>{window.removeEventListener("storage",f),M.removeEventListener("change",m),P.removeEventListener("change",m),window.removeEventListener("pageshow",m),document.removeEventListener("visibilitychange",b);try{r.current?.close()}catch{}r.current=null}},[t,o]);let a=F(()=>[n,s=>{z(o,s),i(s),k(s),A(s,{broadcastChannel:r.current,pingKey:`${o}__ping`})}],[o,n]);return C(E.Provider,{value:a,children:e})}J.displayName="ThemeProvider";function le(){let e=_(E);return K(e,"useTheme must be used within a ThemeProvider"),e}function k(e){if(!p())return;let t=window.document.documentElement,o=window.matchMedia(h).matches,n=window.matchMedia(u).matches,i=x(e,{prefersDarkMode:o,prefersHighContrast:n}),r=t.dataset.theme,a=t.dataset.appliedTheme,s=g(r)?r:void 0,f=O(a)?a:void 0;s===e&&f===i||(t.classList.remove(...T),t.classList.add(i),t.dataset.theme=e,t.dataset.appliedTheme=i)}function de(){if(!p())return{appliedTheme:void 0,theme:void 0};let e=window.document.documentElement,t=g(e.dataset.theme)?e.dataset.theme:void 0;return{appliedTheme:O(e.dataset.appliedTheme)?e.dataset.appliedTheme:void 0,theme:t}}function x(e,{prefersDarkMode:t,prefersHighContrast:o}){return e==="system"?G({prefersDarkMode:t,prefersHighContrast:o}):e}function he(){let e=_(E),t=e!=null?e[0]:"system",o=y(h),n=y(u);return x(t,{prefersDarkMode:o,prefersHighContrast:n})}function G({prefersDarkMode:e,prefersHighContrast:t}){return t?e?"dark-high-contrast":"light-high-contrast":e?"dark":"light"}function X(e){let{defaultTheme:t="system",storageKey:o=v}=e??{};return`
|
|
2
|
-
(function() {
|
|
3
|
-
const RESOLVED = ${JSON.stringify(T)};
|
|
4
|
-
const DEF = "${t}";
|
|
5
|
-
const KEY = "${o}";
|
|
6
|
-
const doc = document, root = doc.documentElement;
|
|
7
|
-
|
|
8
|
-
function isTheme(v) {
|
|
9
|
-
return typeof v === "string" && (v === "system" || RESOLVED.indexOf(v) > -1);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function readCookie(name){
|
|
13
|
-
// Efficient single-pass cookie lookup: "; name=value"
|
|
14
|
-
const all = "; " + doc.cookie, token = "; " + name + "=";
|
|
15
|
-
const startIdx = all.indexOf(token);
|
|
16
|
-
if (startIdx < 0) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
const endIdx = all.indexOf(";", startIdx + token.length);
|
|
20
|
-
const rawValue = all.slice(startIdx + token.length, endIdx < 0 ? void 0 : endIdx) || null;
|
|
21
|
-
try {
|
|
22
|
-
return rawValue ? decodeURIComponent(rawValue) : null;
|
|
23
|
-
} catch(_) {
|
|
24
|
-
return rawValue;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function writeCookie(name, val) {
|
|
29
|
-
try {
|
|
30
|
-
const expires = new Date();
|
|
31
|
-
expires.setFullYear(expires.getFullYear() + 1);
|
|
32
|
-
const hostname = location.hostname;
|
|
33
|
-
const protocol = location.protocol;
|
|
34
|
-
const isDotNgrok = (hostname === "ngrok.com" || hostname.endsWith(".ngrok.com"));
|
|
35
|
-
const domain = isDotNgrok ? "; domain=.ngrok.com" : "";
|
|
36
|
-
const secure = protocol === "https:" ? "; Secure" : "";
|
|
37
|
-
doc.cookie = name + "=" + encodeURIComponent(val) + "; expires=" + expires.toUTCString() + "; path=/" + domain + "; SameSite=Lax" + secure;
|
|
38
|
-
} catch(_) {}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// 1) Read preference: cookie first, fallback to localStorage (migration support)
|
|
42
|
-
let cookieTheme = null, lsTheme = null, storedTheme = null;
|
|
43
|
-
try {
|
|
44
|
-
cookieTheme = readCookie(KEY);
|
|
45
|
-
} catch(_) {}
|
|
46
|
-
|
|
47
|
-
if (isTheme(cookieTheme)) {
|
|
48
|
-
storedTheme = cookieTheme;
|
|
49
|
-
} else {
|
|
50
|
-
try {
|
|
51
|
-
lsTheme = window.localStorage && window.localStorage.getItem(KEY);
|
|
52
|
-
} catch(_) {}
|
|
53
|
-
if (isTheme(lsTheme)) {
|
|
54
|
-
storedTheme = lsTheme;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const preference = isTheme(storedTheme) ? storedTheme : DEF;
|
|
59
|
-
|
|
60
|
-
// 2) Resolve only when needed to avoid unnecessary media queries
|
|
61
|
-
let resolvedTheme = preference;
|
|
62
|
-
if (preference === "system") {
|
|
63
|
-
const isDark = matchMedia("${h}").matches;
|
|
64
|
-
const isHighContrast = matchMedia("${u}").matches;
|
|
65
|
-
resolvedTheme = isHighContrast
|
|
66
|
-
? (isDark ? "dark-high-contrast" : "light-high-contrast")
|
|
67
|
-
: (isDark ? "dark" : "light");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// 3) Only touch DOM if we actually need to change something (SSR optimization)
|
|
71
|
-
if (root.dataset.appliedTheme !== resolvedTheme || root.dataset.theme !== preference) {
|
|
72
|
-
// Remove all theme classes, add the correct one
|
|
73
|
-
for (let i = 0; i < RESOLVED.length; i++) {
|
|
74
|
-
root.classList.remove(RESOLVED[i]);
|
|
75
|
-
}
|
|
76
|
-
root.classList.add(resolvedTheme);
|
|
77
|
-
root.dataset.appliedTheme = resolvedTheme;
|
|
78
|
-
root.dataset.theme = preference;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// 4) Handle persistence/migration synchronously to prevent FOUC
|
|
82
|
-
const hadValidCookie = isTheme(cookieTheme);
|
|
83
|
-
try {
|
|
84
|
-
// Migrate from localStorage to cookies if needed
|
|
85
|
-
if (isTheme(lsTheme)) {
|
|
86
|
-
writeCookie(KEY, lsTheme);
|
|
87
|
-
try {
|
|
88
|
-
window.localStorage.removeItem(KEY);
|
|
89
|
-
} catch(_) {}
|
|
90
|
-
} else if (!hadValidCookie) {
|
|
91
|
-
// Set default cookie if none existed
|
|
92
|
-
writeCookie(KEY, preference);
|
|
93
|
-
}
|
|
94
|
-
} catch (_) {}
|
|
95
|
-
})();
|
|
96
|
-
`.trim()}var Z=({defaultTheme:e="system",includeNunitoSans:t=!1,nonce:o,storageKey:n=v})=>ee(j,{children:[C("script",{dangerouslySetInnerHTML:{__html:X({defaultTheme:e,storageKey:n})},nonce:o}),C(w,{includeNunitoSans:t})]});Z.displayName="MantleThemeHeadContent";function ue(e){let{className:t="",defaultTheme:o="system",storageKey:n=v}=e??{};return F(()=>{if(!p())return{className:L(t),"data-applied-theme":"light","data-theme":"system"};let i=window.matchMedia(h).matches,r=window.matchMedia(u).matches,a=S(n,o),s=x(a,{prefersDarkMode:i,prefersHighContrast:r});return{className:L(t,s),"data-applied-theme":s,"data-theme":a}},[t,o,n])}export{w as a,T as b,U as c,ce as d,g as e,me as f,O as g,J as h,le as i,k as j,de as k,he as l,X as m,Z as n,ue as o};
|
|
97
|
-
//# sourceMappingURL=chunk-AINB3F3G.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/theme/preload-fonts.tsx","../src/components/theme/theme-provider.tsx"],"sourcesContent":["const cdnOrigin = \"https://assets.ngrok.com\";\nconst cdnBase = `${cdnOrigin}/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) =>\n\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.\n *\n * @see https://mantle.ngrok.com/components/theme-provider#api-preload-fonts\n *\n * @example\n * ```tsx\n * <PreloadFonts includeNunitoSans />\n * ```\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\n\t\t\t\tkey={font}\n\t\t\t\trel=\"preload\"\n\t\t\t\thref={fontHref(font)}\n\t\t\t\tas=\"font\"\n\t\t\t\ttype=\"font/woff\"\n\t\t\t\tcrossOrigin=\"anonymous\"\n\t\t\t/>\n\t\t))}\n\t\t{includeNunitoSans && <NunitoSans />}\n\t</>\n);\nPreloadFonts.displayName = \"PreloadFonts\";\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\n\t\t\t\trel=\"preconnect\"\n\t\t\t\thref=\"https://fonts.gstatic.com\"\n\t\t\t\tcrossOrigin=\"anonymous\"\n\t\t\t/>\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","\"use client\";\n\nimport clsx from \"clsx\";\nimport type { ComponentProps, PropsWithChildren } from \"react\";\nimport {\n\tcreateContext,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { useMatchesMediaQuery } from \"../../hooks/use-matches-media-query.js\";\nimport { PreloadFonts } from \"./preload-fonts.js\";\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 = [\n\t\"light\",\n\t\"dark\",\n\t\"light-high-contrast\",\n\t\"dark-high-contrast\",\n] 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) =>\n\tvalue;\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 cookies.\n */\nconst DEFAULT_STORAGE_KEY = \"mantle-ui-theme\";\n\n/**\n * Notifies other open tabs (same origin) that the theme changed.\n *\n * Prefers a shared {@link BroadcastChannel} for immediate, reliable delivery.\n * Falls back to writing a unique “ping” value to `localStorage`, which triggers\n * the cross-tab `storage` event. Both mechanisms only work across the same origin.\n *\n * Uses a timestamp to ensure the storage value always changes so the event fires.\n *\n * @remarks\n * - Same-origin only: BroadcastChannel and the `storage` event do not cross subdomains\n * or different schemes/ports. For cross-subdomain sync, use a postMessage hub or server push.\n * - This function is fire-and-forget and intentionally swallows errors.\n * - Receivers should re-read the cookie/source of truth and then apply the theme;\n * don’t trust the payload blindly.\n *\n * @example\n * // Sender (inside your setter)\n * notifyOtherTabs(nextTheme, {\n * broadcastChannel: broadcastChannelRef.current,\n * pingKey: `${storageKey}__ping`,\n * });\n *\n * @example\n * // Receiver (setup once per tab)\n * const bc = new BroadcastChannel(storageKey);\n * bc.onmessage = () => syncThemeFromCookie();\n * window.addEventListener('storage', (e) => {\n * if (e.key === `${storageKey}__ping`) syncThemeFromCookie();\n * });\n */\nfunction notifyOtherTabs(\n\ttheme: Theme,\n\toptions: {\n\t\tbroadcastChannel: BroadcastChannel | null;\n\t\tpingKey: `${string}__ping`;\n\t},\n) {\n\tconst { broadcastChannel, pingKey } = options;\n\n\t// first try BroadcastChannel\n\ttry {\n\t\tif (broadcastChannel) {\n\t\t\tbroadcastChannel.postMessage({\n\t\t\t\ttheme,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t} catch (_) {}\n\n\t// fallback to storage event: write a \"ping\" key (not the real storageKey)\n\ttry {\n\t\tlocalStorage.setItem(\n\t\t\tpingKey,\n\t\t\tJSON.stringify({ theme, timestamp: Date.now() }),\n\t\t);\n\t} catch (_) {}\n}\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 | null>(\n\tinitialState,\n);\n\n/**\n * isBrowser returns true if the code is running in a browser environment.\n */\nconst isBrowser = () => typeof window !== \"undefined\";\n\n/**\n * Sets a cookie with appropriate domain for the current hostname.\n * Uses .ngrok.com for ngrok domains, otherwise no domain (current domain only).\n */\nfunction setCookie(name: string, value: string) {\n\tif (!isBrowser()) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst expires = new Date();\n\t\texpires.setFullYear(expires.getFullYear() + 1); // 1 year expiration\n\n\t\t// Only set .ngrok.com domain for ngrok domains, otherwise let it default to current domain\n\t\tconst { hostname, protocol } = window.location;\n\t\tconst domainAttribute =\n\t\t\thostname === \"ngrok.com\" || hostname.endsWith(\".ngrok.com\")\n\t\t\t\t? \"; domain=.ngrok.com\"\n\t\t\t\t: \"\";\n\t\tconst secureAttribute = protocol === \"https:\" ? \"; Secure\" : \"\";\n\n\t\tdocument.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires.toUTCString()}; path=/${domainAttribute}; SameSite=Lax${secureAttribute}`;\n\t} catch (_) {\n\t\t// silently swallow errors\n\t}\n}\n\n/**\n * Gets the stored theme from cookies 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\tconst cookies = document.cookie.split(\";\");\n\t\t\tconst themeCookie = cookies.find((cookie) =>\n\t\t\t\tcookie.trim().startsWith(`${storageKey}=`),\n\t\t\t);\n\t\t\tif (themeCookie) {\n\t\t\t\tconst cookieValue = themeCookie.trim().substring(storageKey.length + 1);\n\t\t\t\tstoredTheme = cookieValue ? decodeURIComponent(cookieValue) : null;\n\t\t\t}\n\t\t} catch (_) {}\n\t\treturn isTheme(storedTheme) ? storedTheme : fallbackTheme;\n\t}\n\treturn fallbackTheme;\n}\n\n/**\n * Props for the {@link ThemeProvider} component.\n */\ntype ThemeProviderProps = PropsWithChildren & {\n\t/**\n\t * The initial theme to apply if no value is found in storage.\n\t *\n\t * Possible values {@link themes}:\n\t * - `\"system\"` – follow the user’s system preferences (default).\n\t * - `\"light\"` – force light mode.\n\t * - `\"dark\"` – force dark mode.\n\t * - `\"light-high-contrast\"` – light mode with increased contrast.\n\t * - `\"dark-high-contrast\"` – dark mode with increased contrast.\n\t */\n\tdefaultTheme?: Theme;\n\n\t/**\n\t * The key used to persist the selected theme in cookies or storage.\n\t *\n\t * Defaults to `\"theme\"` (or the {@link DEFAULT_STORAGE_KEY} constant).\n\t * Useful if you need to isolate theme settings across multiple apps\n\t * or contexts.\n\t */\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 *\n * @see https://mantle.ngrok.com/components/theme-provider#api-theme-provider\n *\n * @example\n * ```tsx\n * <ThemeProvider defaultTheme=\"system\" storageKey=\"app-theme\">\n * <App />\n * </ThemeProvider>\n * ```\n */\nfunction ThemeProvider({\n\tchildren,\n\tdefaultTheme = \"system\",\n\tstorageKey = DEFAULT_STORAGE_KEY,\n}: ThemeProviderProps) {\n\t// Init once from cookie and apply immediately to avoid flashes\n\tconst [theme, setTheme] = useState<Theme>(() => {\n\t\tconst storedTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tapplyTheme(storedTheme);\n\t\treturn storedTheme;\n\t});\n\n\tconst broadcastChannelRef = useRef<BroadcastChannel | null>(null);\n\n\tuseEffect(() => {\n\t\tfunction syncThemeFromCookie(next?: Theme) {\n\t\t\tconst newTheme = next ?? getStoredTheme(storageKey, defaultTheme);\n\t\t\tsetTheme(newTheme);\n\t\t\tapplyTheme(newTheme);\n\t\t}\n\n\t\t// initial sync in case defaultTheme or storageKey changed\n\t\tsyncThemeFromCookie();\n\n\t\t// add cross-tab listeners (prefer broadcast channel, use localStorage as fallback)\n\t\ttry {\n\t\t\tif (\"BroadcastChannel\" in window) {\n\t\t\t\tbroadcastChannelRef.current = new BroadcastChannel(storageKey);\n\t\t\t\tbroadcastChannelRef.current.onmessage = (event) => {\n\t\t\t\t\tconst value: unknown = event?.data?.theme;\n\t\t\t\t\tif (isTheme(value)) {\n\t\t\t\t\t\tsyncThemeFromCookie(value);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (_) {}\n\n\t\tconst onStorage = (event: StorageEvent) => {\n\t\t\tif (event.key === `${storageKey}__ping`) {\n\t\t\t\tsyncThemeFromCookie();\n\t\t\t}\n\t\t};\n\t\twindow.addEventListener(\"storage\", onStorage);\n\n\t\t// add media query listeners for system theme changes\n\t\tconst prefersDarkMql = window.matchMedia(prefersDarkModeMediaQuery);\n\t\tconst prefersHighContrastMql = window.matchMedia(\n\t\t\tprefersHighContrastMediaQuery,\n\t\t);\n\n\t\tfunction onChange() {\n\t\t\tsyncThemeFromCookie();\n\t\t}\n\n\t\tfunction onVisibilityChange() {\n\t\t\tif (document.visibilityState === \"visible\") {\n\t\t\t\tsyncThemeFromCookie();\n\t\t\t}\n\t\t}\n\n\t\tprefersDarkMql.addEventListener(\"change\", onChange);\n\t\tprefersHighContrastMql.addEventListener(\"change\", onChange);\n\n\t\t// pageshow fires on bfcache restore (event.persisted === true) and some restore-from-freeze cases.\n\t\twindow.addEventListener(\"pageshow\", onChange);\n\n\t\t// visibilitychange to handle coming back to a tab\n\t\tdocument.addEventListener(\"visibilitychange\", onVisibilityChange);\n\n\t\t// don't forget to clean up your slop!\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"storage\", onStorage);\n\t\t\tprefersDarkMql.removeEventListener(\"change\", onChange);\n\t\t\tprefersHighContrastMql.removeEventListener(\"change\", onChange);\n\t\t\twindow.removeEventListener(\"pageshow\", onChange);\n\t\t\tdocument.removeEventListener(\"visibilitychange\", onVisibilityChange);\n\n\t\t\ttry {\n\t\t\t\tbroadcastChannelRef.current?.close();\n\t\t\t} catch (_) {}\n\t\t\tbroadcastChannelRef.current = null;\n\t\t};\n\t}, [defaultTheme, storageKey]);\n\n\tconst value: ThemeProviderState = useMemo(\n\t\t() => [\n\t\t\ttheme,\n\t\t\t(next: Theme) => {\n\t\t\t\tsetCookie(storageKey, next);\n\t\t\t\tsetTheme(next);\n\t\t\t\tapplyTheme(next);\n\t\t\t\tnotifyOtherTabs(next, {\n\t\t\t\t\tbroadcastChannel: broadcastChannelRef.current,\n\t\t\t\t\tpingKey: `${storageKey}__ping`,\n\t\t\t\t});\n\t\t\t},\n\t\t],\n\t\t[storageKey, theme],\n\t);\n\n\treturn (\n\t\t<ThemeProviderContext.Provider value={value}>\n\t\t\t{children}\n\t\t</ThemeProviderContext.Provider>\n\t);\n}\nThemeProvider.displayName = \"ThemeProvider\";\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 html = window.document.documentElement;\n\n\tconst prefersDarkMode = window.matchMedia(prefersDarkModeMediaQuery).matches;\n\tconst prefersHighContrast = window.matchMedia(\n\t\tprefersHighContrastMediaQuery,\n\t).matches;\n\n\tconst resolvedTheme = resolveTheme(theme, {\n\t\tprefersDarkMode,\n\t\tprefersHighContrast,\n\t});\n\n\tconst htmlTheme = html.dataset.theme;\n\tconst htmlAppliedTheme = html.dataset.appliedTheme;\n\n\tconst currentTheme = isTheme(htmlTheme) ? htmlTheme : undefined;\n\tconst currentResolvedTheme = isResolvedTheme(htmlAppliedTheme)\n\t\t? htmlAppliedTheme\n\t\t: undefined;\n\n\tif (currentTheme === theme && currentResolvedTheme === resolvedTheme) {\n\t\t// nothing to do: input theme and resolved class already match\n\t\treturn;\n\t}\n\n\t// Clear any stale theme class, then apply the new one\n\thtml.classList.remove(...resolvedThemes); // ✅ remove all potential theme classes\n\thtml.classList.add(resolvedTheme);\n\thtml.dataset.theme = theme;\n\thtml.dataset.appliedTheme = resolvedTheme;\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)\n\t\t? htmlElement.dataset.theme\n\t\t: undefined;\n\tconst appliedTheme = isResolvedTheme(htmlElement.dataset.appliedTheme)\n\t\t? htmlElement.dataset.appliedTheme\n\t\t: 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{\n\t\tprefersDarkMode,\n\t\tprefersHighContrast,\n\t}: { prefersDarkMode: boolean; prefersHighContrast: boolean },\n) {\n\tif (theme === \"system\") {\n\t\treturn determineThemeFromMediaQuery({\n\t\t\tprefersDarkMode,\n\t\t\tprefersHighContrast,\n\t\t});\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 themeContext = useContext(ThemeProviderContext);\n\tconst theme = themeContext != null ? themeContext[0] : \"system\";\n\n\tconst prefersDarkMode = useMatchesMediaQuery(prefersDarkModeMediaQuery);\n\tconst prefersHighContrast = useMatchesMediaQuery(\n\t\tprefersHighContrastMediaQuery,\n\t);\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 *\n * @example\n * ```tsx\n * const theme = determineThemeFromMediaQuery({\n * prefersDarkMode: true,\n * prefersHighContrast: false\n * });\n * // Returns: \"dark\"\n *\n * const themeWithContrast = determineThemeFromMediaQuery({\n * prefersDarkMode: false,\n * prefersHighContrast: true\n * });\n * // Returns: \"light-high-contrast\"\n * ```\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\ntype PreventWrongThemeFlashScriptContentOptions = {\n\tdefaultTheme?: Theme;\n\tstorageKey?: string;\n};\n\n/**\n * preventWrongThemeFlashScriptContent generates a script that prevents the wrong theme from flashing on initial page load.\n * It checks cookies for a stored theme, and if none is found, it sets the default theme.\n * It also applies the correct theme to the `<html>` element based on the user's media query preferences.\n */\nfunction preventWrongThemeFlashScriptContent(\n\toptions?: PreventWrongThemeFlashScriptContentOptions,\n) {\n\tconst { defaultTheme = \"system\", storageKey = DEFAULT_STORAGE_KEY } =\n\t\toptions ?? {};\n\n\t// Only resolved themes are ever applied as classes\n\tconst resolved = resolvedThemes;\n\n\treturn `\n(function() {\n\tconst RESOLVED = ${JSON.stringify(resolved)};\n\tconst DEF = \"${defaultTheme}\";\n\tconst KEY = \"${storageKey}\";\n\tconst doc = document, root = doc.documentElement;\n\n\tfunction isTheme(v) {\n\t\treturn typeof v === \"string\" && (v === \"system\" || RESOLVED.indexOf(v) > -1);\n\t}\n\n\tfunction readCookie(name){\n\t\t// Efficient single-pass cookie lookup: \"; name=value\"\n\t\tconst all = \"; \" + doc.cookie, token = \"; \" + name + \"=\";\n\t\tconst startIdx = all.indexOf(token);\n\t\tif (startIdx < 0) {\n\t\t\treturn null;\n\t\t}\n\t\tconst endIdx = all.indexOf(\";\", startIdx + token.length);\n\t\tconst rawValue = all.slice(startIdx + token.length, endIdx < 0 ? void 0 : endIdx) || null;\n\t\ttry { \n\t\t\treturn rawValue ? decodeURIComponent(rawValue) : null;\n\t\t} catch(_) { \n\t\t\treturn rawValue;\n\t\t}\n\t}\n\n\tfunction writeCookie(name, val) {\n\t\ttry {\n\t\t\tconst expires = new Date(); \n\t\t\texpires.setFullYear(expires.getFullYear() + 1);\n\t\t\tconst hostname = location.hostname;\n\t\t\tconst protocol = location.protocol;\n\t\t\tconst isDotNgrok = (hostname === \"ngrok.com\" || hostname.endsWith(\".ngrok.com\"));\n\t\t\tconst domain = isDotNgrok ? \"; domain=.ngrok.com\" : \"\";\n\t\t\tconst secure = protocol === \"https:\" ? \"; Secure\" : \"\";\n\t\t\tdoc.cookie = name + \"=\" + encodeURIComponent(val) + \"; expires=\" + expires.toUTCString() + \"; path=/\" + domain + \"; SameSite=Lax\" + secure;\n\t\t} catch(_) {}\n\t}\n\n\t// 1) Read preference: cookie first, fallback to localStorage (migration support)\n\tlet cookieTheme = null, lsTheme = null, storedTheme = null;\n\ttry { \n\t\tcookieTheme = readCookie(KEY);\n\t} catch(_) {}\n\t\n\tif (isTheme(cookieTheme)) { \n\t\tstoredTheme = cookieTheme;\n\t} else {\n\t\ttry { \n\t\t\tlsTheme = window.localStorage && window.localStorage.getItem(KEY);\n\t\t} catch(_) {}\n\t\tif (isTheme(lsTheme)) {\n\t\t\tstoredTheme = lsTheme;\n\t\t}\n\t}\n\n\tconst preference = isTheme(storedTheme) ? storedTheme : DEF;\n\n\t// 2) Resolve only when needed to avoid unnecessary media queries\n\tlet resolvedTheme = preference;\n\tif (preference === \"system\") {\n\t\tconst isDark = matchMedia(\"${prefersDarkModeMediaQuery}\").matches;\n\t\tconst isHighContrast = matchMedia(\"${prefersHighContrastMediaQuery}\").matches;\n\t\tresolvedTheme = isHighContrast \n\t\t\t? (isDark ? \"dark-high-contrast\" : \"light-high-contrast\")\n\t\t\t: (isDark ? \"dark\" : \"light\");\n\t}\n\n\t// 3) Only touch DOM if we actually need to change something (SSR optimization)\n\tif (root.dataset.appliedTheme !== resolvedTheme || root.dataset.theme !== preference) {\n\t\t// Remove all theme classes, add the correct one\n\t\tfor (let i = 0; i < RESOLVED.length; i++) {\n\t\t\troot.classList.remove(RESOLVED[i]);\n\t\t}\n\t\troot.classList.add(resolvedTheme);\n\t\troot.dataset.appliedTheme = resolvedTheme;\n\t\troot.dataset.theme = preference;\n\t}\n\n\t// 4) Handle persistence/migration synchronously to prevent FOUC\n\tconst hadValidCookie = isTheme(cookieTheme);\n\ttry {\n\t\t// Migrate from localStorage to cookies if needed\n\t\tif (isTheme(lsTheme)) {\n\t\t\twriteCookie(KEY, lsTheme);\n\t\t\ttry { \n\t\t\t\twindow.localStorage.removeItem(KEY);\n\t\t\t} catch(_) {}\n\t\t} else if (!hadValidCookie) {\n\t\t\t// Set default cookie if none existed\n\t\t\twriteCookie(KEY, preference);\n\t\t}\n\t} catch (_) {}\n})();\n`.trim();\n}\n\ntype MantleThemeHeadContentProps = {\n\t/**\n\t * The default theme to use if no theme is stored in cookies.\n\t * @default \"system\"\n\t */\n\tdefaultTheme?: Theme;\n\t/**\n\t * An optional CSP nonce to allowlist this inline script. Using this can help\n\t * you to avoid using the CSP `unsafe-inline` directive, which disables\n\t * XSS protection and would allowlist all inline scripts or styles.\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce\n\t */\n\tnonce?: string;\n\t/**\n\t * The key used to store the theme in cookies.\n\t * @default \"mantle-ui-theme\"\n\t */\n\tstorageKey?: string;\n} & ComponentProps<typeof PreloadFonts>;\n\n/**\n * MantleThemeHeadContent is a React component that renders a script to prevent\n * Flash of Unstyled Content (FOUC), or the wrong theme from flashing on initial\n * page load.\n *\n * Render as high as possible in the <head> element.\n */\nconst MantleThemeHeadContent = ({\n\tdefaultTheme = \"system\",\n\tincludeNunitoSans = false,\n\tnonce,\n\tstorageKey = DEFAULT_STORAGE_KEY,\n}: MantleThemeHeadContentProps) => (\n\t<>\n\t\t<script\n\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t__html: preventWrongThemeFlashScriptContent({\n\t\t\t\t\tdefaultTheme,\n\t\t\t\t\tstorageKey,\n\t\t\t\t}),\n\t\t\t}}\n\t\t\tnonce={nonce}\n\t\t/>\n\t\t<PreloadFonts includeNunitoSans={includeNunitoSans} />\n\t</>\n);\nMantleThemeHeadContent.displayName = \"MantleThemeHeadContent\";\n\ntype InitialThemeProps = {\n\tclassName: string;\n\t\"data-applied-theme\": ResolvedTheme;\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 {\n\t\tclassName = \"\",\n\t\tdefaultTheme = \"system\",\n\t\tstorageKey = DEFAULT_STORAGE_KEY,\n\t} = 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\": \"light\", // assume light on server\n\t\t\t\t\"data-theme\": \"system\",\n\t\t\t};\n\t\t}\n\n\t\tconst prefersDarkMode = window.matchMedia(\n\t\t\tprefersDarkModeMediaQuery,\n\t\t).matches;\n\t\tconst prefersHighContrast = window.matchMedia(\n\t\t\tprefersHighContrastMediaQuery,\n\t\t).matches;\n\t\tconst initialTheme = getStoredTheme(storageKey, defaultTheme);\n\t\tconst resolvedTheme = resolveTheme(initialTheme, {\n\t\t\tprefersDarkMode,\n\t\t\tprefersHighContrast,\n\t\t});\n\n\t\treturn {\n\t\t\tclassName: clsx(className, resolvedTheme),\n\t\t\t\"data-applied-theme\": resolvedTheme,\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"],"mappings":"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","names":["Fragment","jsx","jsxs","cdnOrigin","cdnBase","fonts","fontHref","font","PreloadFonts","includeNunitoSans","NunitoSans","NunitoSans","jsxs","Fragment","jsx","clsx","createContext","useContext","useEffect","useMemo","useRef","useState","invariant","Fragment","jsx","jsxs","prefersDarkModeMediaQuery","prefersHighContrastMediaQuery","resolvedThemes","themes","$theme","value","isTheme","$resolvedTheme","isResolvedTheme","DEFAULT_STORAGE_KEY","notifyOtherTabs","theme","options","broadcastChannel","pingKey","initialState","ThemeProviderContext","createContext","isBrowser","setCookie","name","expires","hostname","protocol","domainAttribute","secureAttribute","getStoredTheme","storageKey","defaultTheme","fallbackTheme","storedTheme","themeCookie","cookie","cookieValue","ThemeProvider","children","setTheme","useState","applyTheme","broadcastChannelRef","useRef","useEffect","syncThemeFromCookie","next","newTheme","event","onStorage","prefersDarkMql","prefersHighContrastMql","onChange","onVisibilityChange","useMemo","useTheme","context","useContext","invariant","html","prefersDarkMode","prefersHighContrast","resolvedTheme","resolveTheme","htmlTheme","htmlAppliedTheme","currentTheme","currentResolvedTheme","readThemeFromHtmlElement","htmlElement","determineThemeFromMediaQuery","useAppliedTheme","themeContext","useMatchesMediaQuery","preventWrongThemeFlashScriptContent","MantleThemeHeadContent","includeNunitoSans","nonce","PreloadFonts","useInitialHtmlThemeProps","props","className","clsx","initialTheme"]}
|
package/dist/chunk-W2SMAR4Q.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as p}from"./chunk-MF2QITTY.js";import{a as n}from"./chunk-AZ56JGNY.js";import{forwardRef as s,useEffect as T,useMemo as x,useRef as g,useState as O}from"react";import{jsx as d}from"react/jsx-runtime";var b=s(({children:t,className:o,...r},e)=>{let a=E();return d("div",{className:n("group/table scrollbar overflow-x-auto rounded-lg border border-card bg-white dark:bg-gray-100 relative w-full",o),"data-sticky-active":a.state.hasOverflow&&!a.state.scrolledToEnd||void 0,"data-x-overflow":a.state.hasOverflow,"data-x-scroll-end":a.state.hasOverflow&&a.state.scrolledToEnd,ref:p(a.ref,e),...r,children:t})});b.displayName="TableRoot";var u=s(({children:t,className:o,...r},e)=>d("table",{ref:e,className:n("table-auto border-collapse caption-bottom w-full min-w-full text-left",o),...r,children:t}));u.displayName="TableElement";var v=s(({children:t,className:o,...r},e)=>d("thead",{ref:e,className:n("border-b border-card-muted","divide-y divide-card-muted","text-strong bg-base","[&>tr]:bg-base",o),...r,children:t}));v.displayName="TableHead";var h=s(({children:t,className:o,...r},e)=>d("tbody",{className:n("divide-y divide-card-muted","text-body","[thead+&]:border-t [thead+&]:border-card-muted","[&>tr]:bg-card [&>tr]:not-only:hover:bg-card-hover",o),ref:e,...r,children:t}));h.displayName="TableBody";var y=s(({children:t,className:o,...r},e)=>d("tfoot",{ref:e,className:n("font-medium text-body","border-t border-card-muted","divide-y divide-card-muted","[&>tr]:bg-gray-50/50 [&>tr]:hover:bg-card-hover",o),...r,children:t}));y.displayName="TableFoot";var C=s(({children:t,className:o,...r},e)=>d("tr",{ref:e,className:n(o),...r,children:t}));C.displayName="TableRow";var w=s(({children:t,className:o,...r},e)=>d("th",{ref:e,className:n("h-12 px-4 text-left align-middle text-sm font-medium [&:has([role=checkbox])]:pr-0",o),...r,children:t}));w.displayName="TableHeader";var R=s(({children:t,className:o,...r},e)=>d("td",{ref:e,className:n("p-4 align-middle [&:has([role=checkbox])]:pr-0 font-mono text-size-mono",o),...r,children:t}));R.displayName="TableCell";var N=s(({children:t,className:o,...r},e)=>d("caption",{ref:e,className:n("py-4 text-sm text-gray-500","border-t border-card-muted",o),...r,children:t}));N.displayName="TableCaption";var z={Body:h,Caption:N,Cell:R,Element:u,Foot:y,Head:v,Header:w,Root:b,Row:C};function E(){let t=g(null),[o,r]=O({hasOverflow:!1,scrolledToEnd:!1});return T(()=>{let e=t.current;if(!e)return;let a=()=>{let i=e.scrollWidth>e.clientWidth,f=Math.abs(e.scrollWidth-e.scrollLeft-e.clientWidth)<1;r(l=>l.hasOverflow!==i||l.scrolledToEnd!==f?{hasOverflow:i,scrolledToEnd:f}:l)},c=new ResizeObserver(a);c.observe(e);let m=new MutationObserver(a);return m.observe(e,{childList:!0,subtree:!0}),e.addEventListener("scroll",a,{passive:!0}),a(),()=>{c.disconnect(),m.disconnect(),e.removeEventListener("scroll",a)}},[]),x(()=>({ref:t,state:o}),[o])}export{z as a};
|
|
2
|
-
//# sourceMappingURL=chunk-W2SMAR4Q.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/table/table.tsx"],"sourcesContent":["import type { ComponentProps, ComponentRef } from \"react\";\nimport { forwardRef, useEffect, useMemo, useRef, useState } from \"react\";\nimport { composeRefs } from \"../../utils/compose-refs/compose-refs.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\n\n/**\n * The `<Table.Root>` is the root container element for all `Table`s.\n * It provides styling and additional functionality, such as horizontal overflow\n * detection.\n *\n * Must be used as the parent of a `<Table.Element>`.\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-root\n */\nconst Root = forwardRef<ComponentRef<\"div\">, ComponentProps<\"div\">>(\n\t({ children, className, ...props }, ref) => {\n\t\tconst horizontalOverflow =\n\t\t\tuseHorizontalOverflowObserver<ComponentRef<\"div\">>();\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"group/table scrollbar overflow-x-auto rounded-lg border border-card bg-white dark:bg-gray-100 relative w-full\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tdata-sticky-active={\n\t\t\t\t\t(horizontalOverflow.state.hasOverflow &&\n\t\t\t\t\t\t!horizontalOverflow.state.scrolledToEnd) ||\n\t\t\t\t\tundefined\n\t\t\t\t}\n\t\t\t\tdata-x-overflow={horizontalOverflow.state.hasOverflow}\n\t\t\t\tdata-x-scroll-end={\n\t\t\t\t\thorizontalOverflow.state.hasOverflow &&\n\t\t\t\t\thorizontalOverflow.state.scrolledToEnd\n\t\t\t\t}\n\t\t\t\tref={composeRefs(horizontalOverflow.ref, ref)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nRoot.displayName = \"TableRoot\";\n\n/**\n * The `<Table.Element>` is a structured way to display data in rows and columns. The API\n * matches the HTML `<table>` element 1:1.\n *\n * Permitted content in this order:\n * 1. optional: `<Table.Caption>`\n * 2. 0 or more: `<colgroup>` elements\n * 3. optional: `<Table.Head>`\n * 4. either one of the following:\n * - 0 or more: `<Table.Body>`\n * - 0 or more: `<Table.Row>`\n * 5. optional: `<Table.Foot>`\n *\n * @description\n * Establishes a table formatting context. Elements inside the `<Table.Element>`\n * generate rectangular boxes. Each box occupies a number of table cells\n * according to the following rules:\n * 1. The row boxes fill the table in the source code order from top to bottom.\n * Each row box occupies one row of cells.\n * 2. A row group box occupies one or more row boxes.\n * 3. Column boxes are placed next to each other in source code order.\n * Depending on the value of the dir attribute, the columns are laid in\n * left-to-right or right-to-left direction. A column box occupies one or\n * more columns of table cells.\n * 4. A column group box occupies one or more column boxes.\n * 5. A cell box may span over multiple rows and columns. User agents trim\n * cells to fit in the available number of rows and columns.\n * Table cells do have padding. Boxes that make up a table do not have margins.\n * For more in depth information, see the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table).\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table\n */\nconst Element = forwardRef<ComponentRef<\"table\">, ComponentProps<\"table\">>(\n\t({ children, className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<table\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"table-auto border-collapse caption-bottom w-full min-w-full text-left\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</table>\n\t\t);\n\t},\n);\nElement.displayName = \"TableElement\";\n\n/**\n * The `<Table.Head>` is a container for the table's column headers.\n * Encapsulates a set of `<Table.Row>`s, indicating that they comprise the head\n * of a table with information about the table's columns. This is usually in the\n * form of column headers (`<Table.Header>`).\n *\n * Must be used as a child of a `<Table.Element>`. It should only come after any\n * `<Table.Caption>` or `<colgroup>` and before any `<Table.Body>` or `<Table.Foot>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Row>`\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-header\n */\nconst Head = forwardRef<ComponentRef<\"thead\">, ComponentProps<\"thead\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<thead\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t//,\n\t\t\t\t\"border-b border-card-muted\",\n\t\t\t\t\"divide-y divide-card-muted\",\n\t\t\t\t\"text-strong bg-base\",\n\t\t\t\t\"[&>tr]:bg-base\", // Row styling\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</thead>\n\t),\n);\nHead.displayName = \"TableHead\";\n\n/**\n * The `<Table.Body>` encapsulates a set of `<Table.Row>`s, indicating that they\n * comprise the body of a table's (main) data.\n *\n * Must be used as a child of a `<Table.Element>` and only come after any\n * `<Table.Caption>`, `<colgroup>`, or `<Table.Head>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Row>`\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-body\n */\nconst Body = forwardRef<ComponentRef<\"tbody\">, ComponentProps<\"tbody\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<tbody\n\t\t\tclassName={cx(\n\t\t\t\t//,\n\t\t\t\t\"divide-y divide-card-muted\",\n\t\t\t\t\"text-body\",\n\t\t\t\t\"[thead+&]:border-t [thead+&]:border-card-muted\",\n\t\t\t\t\"[&>tr]:bg-card [&>tr]:not-only:hover:bg-card-hover\", // Body row styling\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</tbody>\n\t),\n);\nBody.displayName = \"TableBody\";\n\n/**\n * The `<Table.Foot>` encapsulates a set of `<Table.Row>`s, indicating that they\n * comprise the foot of a table with information about the table's columns. This\n * is usually a summary of the columns, e.g., a sum of the given numbers in a\n * column.\n *\n * Must be used as a child of a `<Table.Element>` and only come after any\n * `<Table.Caption>`, `<colgroup>`, `<Table.Head>`, and `<Table.Body>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Row>` elements\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-foot\n */\nconst Foot = forwardRef<ComponentRef<\"tfoot\">, ComponentProps<\"tfoot\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<tfoot\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t//,\n\t\t\t\t\"font-medium text-body\",\n\t\t\t\t\"border-t border-card-muted\",\n\t\t\t\t\"divide-y divide-card-muted\",\n\t\t\t\t\"[&>tr]:bg-gray-50/50 [&>tr]:hover:bg-card-hover\", // Row styling\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</tfoot>\n\t),\n);\nFoot.displayName = \"TableFoot\";\n\n/**\n * The `<Table.Row>` defines a row of cells in a table. The row's cells can then\n * be established using a mix of `<Table.Cell>` and `<Table.Header>` components.\n *\n * Must be used as a child of a `<Table.Head>`, `<Table.Body>`, or `<Table.Foot>`.\n *\n * Permitted Content:\n * 1. 0 or more: `<Table.Header>` or `<Table.Cell>`\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-row\n */\nconst Row = forwardRef<ComponentRef<\"tr\">, ComponentProps<\"tr\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<tr\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t// This could be removed, or simplified\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</tr>\n\t),\n);\nRow.displayName = \"TableRow\";\n\n/**\n * The `<Table.Header>` defines a cell as the header of a group of table cells\n * and may be used as a child of a `<Table.Row>`. The exact nature of this group\n * is defined by the scope and headers attributes.\n *\n * Must be used as a child of a `<Table.Row>`.\n *\n * Permitted Content:\n * 1. Flow content, but with no header, footer, sectioning content, or heading\n * content descendants.\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-header\n */\nconst Header = forwardRef<ComponentRef<\"th\">, ComponentProps<\"th\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<th\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t\"h-12 px-4 text-left align-middle text-sm font-medium [&:has([role=checkbox])]:pr-0\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</th>\n\t),\n);\nHeader.displayName = \"TableHeader\";\n\n/**\n * The `<Table.Cell>` defines a cell of a table that contains data and may be\n * used as a child of a `<Table.Row>`.\n *\n * Must be used as a child of a `<Table.Row>`.\n *\n * Permitted Content:\n * 1. Flow content\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-cell\n */\nconst Cell = forwardRef<ComponentRef<\"td\">, ComponentProps<\"td\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<td\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t\"p-4 align-middle [&:has([role=checkbox])]:pr-0 font-mono text-size-mono\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</td>\n\t),\n);\nCell.displayName = \"TableCell\";\n\n/**\n * The optional `<Table.Caption>` specifies the caption (or title) of a table,\n * providing the table an accessible description.\n *\n * If used, must be the first child of a `<Table.Element>`.\n *\n * Permitted Content:\n * 1. Flow content\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n *\n * @see https://mantle.ngrok.com/components/table#api-table-caption\n */\nconst Caption = forwardRef<ComponentRef<\"caption\">, ComponentProps<\"caption\">>(\n\t({ children, className, ...props }, ref) => (\n\t\t<caption\n\t\t\tref={ref}\n\t\t\tclassName={cx(\n\t\t\t\t\"py-4 text-sm text-gray-500\",\n\t\t\t\t\"border-t border-card-muted\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</caption>\n\t),\n);\nCaption.displayName = \"TableCaption\";\n\n/**\n * A structured way to display data in rows and columns. The API matches the\n * HTML table element 1:1.\n *\n * @see https://mantle.ngrok.com/components/table\n *\n * @example\n * ```tsx\n * <Table.Root>\n * <Table.Element>\n * <Table.Caption>A list of your recent invoices.</Table.Caption>\n * <Table.Head>\n * <Table.Row>\n * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n * <Table.Header>Status</Table.Header>\n * <Table.Header>Method</Table.Header>\n * <Table.Header className=\"text-right\">Amount</Table.Header>\n * </Table.Row>\n * </Table.Head>\n * <Table.Body>\n * {invoices.map((invoice) => (\n * <Table.Row key={invoice.invoice}>\n * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * <Table.Foot>\n * <Table.Row>\n * <Table.Cell colSpan={3}>Total</Table.Cell>\n * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n * </Table.Row>\n * </Table.Foot>\n * </Table.Element>\n * </Table.Root>\n * ```\n */\nconst Table = {\n\t/**\n\t * The body section of the table. Encapsulates a set of table rows comprising the body of a table's main data.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-body\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tBody,\n\t/**\n\t * An optional caption that specifies the caption (or title) of a table, providing an accessible description.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-caption\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tCaption,\n\t/**\n\t * A cell that contains data and may be used as a child of a table row.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-cell\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tCell,\n\t/**\n\t * A structured way to display data in rows and columns. The API matches the HTML table element 1:1.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-element\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tElement,\n\t/**\n\t * The foot section of a table. Encapsulates a set of table rows comprising the foot with summary information.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-foot\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tFoot,\n\t/**\n\t * The head section of a table. Contains the table's column headers information.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-header\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tHead,\n\t/**\n\t * A cell that defines the header of a group of table cells as a child of a table row.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-header\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tHeader,\n\t/**\n\t * The root container element for all tables. Provides styling and additional functionality like horizontal overflow detection.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-root\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * Defines a row of cells in a table. Contains a mix of table cells and table headers.\n\t *\n\t * @see https://mantle.ngrok.com/components/table#api-table-row\n\t *\n\t * @example\n\t * ```tsx\n\t * <Table.Root>\n\t * <Table.Element>\n\t * <Table.Caption>A list of your recent invoices.</Table.Caption>\n\t * <Table.Head>\n\t * <Table.Row>\n\t * <Table.Header className=\"w-[100px]\">Invoice</Table.Header>\n\t * <Table.Header>Status</Table.Header>\n\t * <Table.Header>Method</Table.Header>\n\t * <Table.Header className=\"text-right\">Amount</Table.Header>\n\t * </Table.Row>\n\t * </Table.Head>\n\t * <Table.Body>\n\t * {invoices.map((invoice) => (\n\t * <Table.Row key={invoice.invoice}>\n\t * <Table.Cell className=\"font-medium\">{invoice.invoice}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentStatus}</Table.Cell>\n\t * <Table.Cell>{invoice.paymentMethod}</Table.Cell>\n\t * <Table.Cell className=\"text-right\">{invoice.totalAmount}</Table.Cell>\n\t * </Table.Row>\n\t * ))}\n\t * </Table.Body>\n\t * <Table.Foot>\n\t * <Table.Row>\n\t * <Table.Cell colSpan={3}>Total</Table.Cell>\n\t * <Table.Cell className=\"text-right\">$2,500.00</Table.Cell>\n\t * </Table.Row>\n\t * </Table.Foot>\n\t * </Table.Element>\n\t * </Table.Root>\n\t * ```\n\t */\n\tRow,\n} as const;\n\nexport {\n\t//,\n\tTable,\n};\n\n/**\n * A custom hook that observes the horizontal overflow of an element and determines\n * if it has overflow and if it is scrolled to the end.\n *\n * @private\n */\nfunction useHorizontalOverflowObserver<T extends HTMLElement>() {\n\tconst ref = useRef<T | null>(null);\n\tconst [state, setState] = useState({\n\t\thasOverflow: false,\n\t\tscrolledToEnd: false,\n\t});\n\n\tuseEffect(() => {\n\t\tconst element = ref.current;\n\t\tif (!element) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst checkState = () => {\n\t\t\tconst hasOverflow = element.scrollWidth > element.clientWidth;\n\t\t\tconst scrolledToEnd =\n\t\t\t\tMath.abs(\n\t\t\t\t\telement.scrollWidth - element.scrollLeft - element.clientWidth,\n\t\t\t\t) < 1;\n\n\t\t\tsetState((previous) => {\n\t\t\t\tif (\n\t\t\t\t\tprevious.hasOverflow !== hasOverflow ||\n\t\t\t\t\tprevious.scrolledToEnd !== scrolledToEnd\n\t\t\t\t) {\n\t\t\t\t\treturn { hasOverflow, scrolledToEnd };\n\t\t\t\t}\n\t\t\t\treturn previous; // No state change\n\t\t\t});\n\t\t};\n\n\t\tconst resizeObserver = new ResizeObserver(checkState);\n\t\tresizeObserver.observe(element);\n\n\t\tconst mutationObserver = new MutationObserver(checkState);\n\t\tmutationObserver.observe(element, { childList: true, subtree: true });\n\n\t\telement.addEventListener(\"scroll\", checkState, { passive: true });\n\n\t\tcheckState();\n\n\t\treturn () => {\n\t\t\tresizeObserver.disconnect();\n\t\t\tmutationObserver.disconnect();\n\t\t\telement.removeEventListener(\"scroll\", checkState);\n\t\t};\n\t}, []);\n\n\treturn useMemo(() => ({ ref, state }), [state]);\n}\n"],"mappings":"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","names":["forwardRef","useEffect","useMemo","useRef","useState","jsx","Root","forwardRef","children","className","props","ref","horizontalOverflow","useHorizontalOverflowObserver","cx","composeRefs","Element","Head","Body","Foot","Row","Header","Cell","Caption","Table","useHorizontalOverflowObserver","ref","useRef","state","setState","useState","useEffect","element","checkState","hasOverflow","scrolledToEnd","previous","resizeObserver","mutationObserver","useMemo"]}
|
|
File without changes
|