@mui/docs 9.0.0-alpha.2 → 9.0.0-alpha.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/Ad/Ad.js +33 -42
- package/Ad/AdCarbon.js +18 -27
- package/Ad/AdDisplay.js +22 -29
- package/Ad/AdGuest.js +8 -15
- package/Ad/AdInHouse.js +4 -11
- package/Ad/AdManager.js +8 -17
- package/Ad/AdProvider.js +5 -13
- package/Ad/ad.styles.js +5 -13
- package/Ad/index.js +6 -62
- package/CHANGELOG.md +191 -0
- package/CodeCopy/CodeCopy.js +10 -19
- package/CodeCopy/CodeCopyButton.js +9 -16
- package/CodeCopy/index.js +3 -40
- package/CodeCopy/useClipboardCopy.js +4 -12
- package/ComponentLinkHeader/ComponentLinkHeader.js +46 -54
- package/ComponentLinkHeader/index.js +2 -24
- package/DemoContext/DemoContext.d.ts +86 -0
- package/DemoContext/DemoContext.js +13 -0
- package/DemoContext/index.d.ts +2 -0
- package/DemoContext/index.js +1 -0
- package/DocsApp/AnalyticsProvider.d.ts +17 -0
- package/DocsApp/AnalyticsProvider.js +225 -0
- package/DocsApp/DocsApp.d.ts +79 -0
- package/DocsApp/DocsApp.js +105 -0
- package/DocsApp/GoogleAnalytics.d.ts +9 -0
- package/DocsApp/GoogleAnalytics.js +129 -0
- package/DocsApp/StyledEngineProvider.d.ts +8 -0
- package/DocsApp/StyledEngineProvider.js +38 -0
- package/DocsApp/consoleBanner.d.ts +1 -0
- package/DocsApp/consoleBanner.js +19 -0
- package/DocsApp/createEmotionCache.d.ts +1 -0
- package/DocsApp/createEmotionCache.js +12 -0
- package/DocsApp/createGetInitialProps.d.ts +30 -0
- package/DocsApp/createGetInitialProps.js +29 -0
- package/DocsApp/index.d.ts +5 -0
- package/DocsApp/index.js +4 -0
- package/DocsApp/loadDependencies.d.ts +1 -0
- package/DocsApp/loadDependencies.js +11 -0
- package/DocsApp/reportWebVitals.d.ts +13 -0
- package/DocsApp/reportWebVitals.js +24 -0
- package/DocsApp/serviceWorker.d.ts +1 -0
- package/DocsApp/serviceWorker.js +61 -0
- package/DocsProvider/DocsProvider.js +9 -17
- package/DocsProvider/index.js +1 -16
- package/Document/Document.d.ts +16 -0
- package/Document/Document.js +147 -0
- package/Document/getInitialProps.d.ts +18 -0
- package/Document/getInitialProps.js +62 -0
- package/Document/index.d.ts +2 -0
- package/Document/index.js +2 -0
- package/HighlightedCode/HighlightedCode.js +18 -26
- package/HighlightedCode/index.js +1 -16
- package/HighlightedCodeWithTabs/HighlightedCodeWithTabs.js +22 -31
- package/HighlightedCodeWithTabs/index.js +2 -24
- package/IconImage/IconImage.js +13 -21
- package/IconImage/index.js +1 -13
- package/InfoCard/InfoCard.js +20 -29
- package/InfoCard/index.js +1 -16
- package/Link/Link.js +17 -25
- package/Link/MarkdownLinks.d.ts +2 -0
- package/Link/MarkdownLinks.js +84 -0
- package/Link/SkipLink.d.ts +1 -0
- package/Link/SkipLink.js +66 -0
- package/Link/index.d.ts +3 -1
- package/Link/index.js +3 -16
- package/MarkdownElement/MarkdownElement.js +178 -186
- package/MarkdownElement/index.js +1 -16
- package/MuiPage/MuiPage.d.ts +67 -0
- package/MuiPage/MuiPage.js +1 -0
- package/MuiPage/index.d.ts +1 -0
- package/MuiPage/index.js +1 -0
- package/NextNProgressBar/NextNProgressBar.d.ts +1 -0
- package/NextNProgressBar/NextNProgressBar.js +44 -0
- package/NextNProgressBar/index.d.ts +1 -0
- package/NextNProgressBar/index.js +1 -0
- package/PageContext/PageContext.d.ts +32 -0
- package/PageContext/PageContext.js +6 -0
- package/PageContext/index.d.ts +2 -0
- package/PageContext/index.js +1 -0
- package/SectionHeadline/SectionHeadline.js +9 -17
- package/SectionHeadline/index.js +2 -25
- package/SectionTitle/SectionTitle.js +7 -13
- package/SectionTitle/index.js +1 -16
- package/ThemeContext/ThemeContext.js +26 -38
- package/ThemeContext/index.js +1 -42
- package/branding/BrandingCssVarsProvider.d.ts +27 -0
- package/branding/BrandingCssVarsProvider.js +170 -0
- package/branding/BrandingProvider.js +8 -15
- package/branding/brandingTheme.js +184 -188
- package/branding/index.d.ts +2 -1
- package/branding/index.js +3 -27
- package/codeStyling/codeStyling.d.ts +7 -0
- package/codeStyling/codeStyling.js +80 -0
- package/codeStyling/index.d.ts +1 -0
- package/codeStyling/index.js +1 -0
- package/codeVariant/codeVariant.d.ts +7 -0
- package/codeVariant/codeVariant.js +69 -0
- package/codeVariant/index.d.ts +1 -0
- package/codeVariant/index.js +1 -0
- package/constants/constants.d.ts +13 -0
- package/constants/constants.js +15 -0
- package/constants/index.d.ts +1 -0
- package/constants/index.js +1 -0
- package/findActivePage/findActivePage.d.ts +5 -0
- package/findActivePage/findActivePage.js +35 -0
- package/findActivePage/index.d.ts +1 -0
- package/findActivePage/index.js +1 -0
- package/getProductInfoFromUrl/getProductInfoFromUrl.d.ts +8 -0
- package/getProductInfoFromUrl/getProductInfoFromUrl.js +50 -0
- package/getProductInfoFromUrl/index.d.ts +2 -0
- package/getProductInfoFromUrl/index.js +1 -0
- package/globalSelector/globalSelector.d.ts +2 -0
- package/globalSelector/globalSelector.js +17 -0
- package/globalSelector/index.d.ts +1 -0
- package/globalSelector/index.js +1 -0
- package/helpers/helpers.d.ts +31 -0
- package/helpers/helpers.js +87 -0
- package/helpers/index.d.ts +2 -0
- package/helpers/index.js +1 -0
- package/i18n/i18n.js +17 -29
- package/i18n/index.js +1 -16
- package/mapApiPageTranslations/index.d.ts +1 -0
- package/mapApiPageTranslations/index.js +1 -0
- package/mapApiPageTranslations/mapApiPageTranslations.d.ts +11 -0
- package/mapApiPageTranslations/mapApiPageTranslations.js +46 -0
- package/nextFonts/index.js +8 -15
- package/package.json +217 -132
- package/svgIcons/BundleSizeIcon.js +5 -11
- package/svgIcons/FigmaIcon.js +8 -14
- package/svgIcons/FileDownload.js +5 -12
- package/svgIcons/JavaScript.js +5 -12
- package/svgIcons/MarkdownIcon.js +7 -14
- package/svgIcons/MaterialDesignIcon.js +6 -12
- package/svgIcons/SketchIcon.js +10 -16
- package/svgIcons/TypeScript.js +5 -12
- package/svgIcons/W3CIcon.js +6 -12
- package/translations/index.js +3 -10
- package/translations/translations.json +0 -1
- package/useLazyCSS/index.js +1 -13
- package/useLazyCSS/useLazyCSS.js +5 -11
- package/utils/index.d.ts +1 -0
- package/utils/index.js +2 -0
- package/utils/loadScript.js +1 -7
- package/webpack/index.d.ts +17 -0
- package/webpack/index.js +1 -0
- package/Ad/Ad.d.mts +0 -5
- package/Ad/Ad.mjs +0 -226
- package/Ad/AdCarbon.d.mts +0 -2
- package/Ad/AdCarbon.mjs +0 -125
- package/Ad/AdDisplay.d.mts +0 -16
- package/Ad/AdDisplay.mjs +0 -86
- package/Ad/AdGuest.d.mts +0 -10
- package/Ad/AdGuest.mjs +0 -29
- package/Ad/AdInHouse.d.mts +0 -4
- package/Ad/AdInHouse.mjs +0 -14
- package/Ad/AdManager.d.mts +0 -19
- package/Ad/AdManager.mjs +0 -36
- package/Ad/AdProvider.d.mts +0 -15
- package/Ad/AdProvider.mjs +0 -24
- package/Ad/ad.styles.d.mts +0 -4512
- package/Ad/ad.styles.mjs +0 -91
- package/Ad/index.d.mts +0 -5
- package/Ad/index.mjs +0 -7
- package/CodeCopy/CodeCopy.d.mts +0 -22
- package/CodeCopy/CodeCopy.mjs +0 -172
- package/CodeCopy/CodeCopyButton.d.mts +0 -4
- package/CodeCopy/CodeCopyButton.mjs +0 -40
- package/CodeCopy/index.d.mts +0 -3
- package/CodeCopy/index.mjs +0 -3
- package/CodeCopy/useClipboardCopy.d.mts +0 -4
- package/CodeCopy/useClipboardCopy.mjs +0 -21
- package/ComponentLinkHeader/ComponentLinkHeader.d.mts +0 -8
- package/ComponentLinkHeader/ComponentLinkHeader.mjs +0 -197
- package/ComponentLinkHeader/index.d.mts +0 -2
- package/ComponentLinkHeader/index.mjs +0 -2
- package/DocsProvider/DocsProvider.d.mts +0 -24
- package/DocsProvider/DocsProvider.mjs +0 -31
- package/DocsProvider/index.d.mts +0 -1
- package/DocsProvider/index.mjs +0 -1
- package/HighlightedCode/HighlightedCode.d.mts +0 -14
- package/HighlightedCode/HighlightedCode.mjs +0 -67
- package/HighlightedCode/index.d.mts +0 -1
- package/HighlightedCode/index.mjs +0 -1
- package/HighlightedCodeWithTabs/HighlightedCodeWithTabs.d.mts +0 -28
- package/HighlightedCodeWithTabs/HighlightedCodeWithTabs.mjs +0 -362
- package/HighlightedCodeWithTabs/index.d.mts +0 -2
- package/HighlightedCodeWithTabs/index.mjs +0 -2
- package/IconImage/IconImage.d.mts +0 -11
- package/IconImage/IconImage.mjs +0 -83
- package/IconImage/index.d.mts +0 -1
- package/IconImage/index.mjs +0 -1
- package/InfoCard/InfoCard.d.mts +0 -22
- package/InfoCard/InfoCard.mjs +0 -87
- package/InfoCard/index.d.mts +0 -1
- package/InfoCard/index.mjs +0 -1
- package/Link/Link.d.mts +0 -25
- package/Link/Link.mjs +0 -75
- package/Link/index.d.mts +0 -1
- package/Link/index.mjs +0 -1
- package/MarkdownElement/MarkdownElement.d.mts +0 -7
- package/MarkdownElement/MarkdownElement.mjs +0 -847
- package/MarkdownElement/index.d.mts +0 -1
- package/MarkdownElement/index.mjs +0 -1
- package/NProgressBar/NProgressBar.d.mts +0 -6
- package/NProgressBar/NProgressBar.js +0 -98
- package/NProgressBar/index.d.mts +0 -2
- package/NProgressBar/index.d.ts +0 -2
- package/NProgressBar/index.js +0 -13
- package/NProgressBar/index.mjs +0 -1
- package/SectionHeadline/SectionHeadline.d.mts +0 -13
- package/SectionHeadline/SectionHeadline.mjs +0 -81
- package/SectionHeadline/index.d.mts +0 -2
- package/SectionHeadline/index.mjs +0 -2
- package/SectionTitle/SectionTitle.d.mts +0 -6
- package/SectionTitle/SectionTitle.mjs +0 -29
- package/SectionTitle/index.d.mts +0 -1
- package/SectionTitle/index.mjs +0 -1
- package/ThemeContext/ThemeContext.d.mts +0 -92
- package/ThemeContext/ThemeContext.mjs +0 -200
- package/ThemeContext/index.d.mts +0 -1
- package/ThemeContext/index.mjs +0 -1
- package/branding/BrandingProvider.d.mts +0 -9
- package/branding/BrandingProvider.mjs +0 -17
- package/branding/brandingTheme.d.mts +0 -147
- package/branding/brandingTheme.mjs +0 -1527
- package/branding/index.d.mts +0 -2
- package/branding/index.mjs +0 -2
- package/i18n/i18n.d.mts +0 -27
- package/i18n/i18n.mjs +0 -111
- package/i18n/index.d.mts +0 -1
- package/i18n/index.mjs +0 -1
- package/nextFonts/index.d.mts +0 -6
- package/nextFonts/index.mjs +0 -59
- package/svgIcons/BundleSizeIcon.d.mts +0 -4
- package/svgIcons/BundleSizeIcon.mjs +0 -13
- package/svgIcons/FigmaIcon.d.mts +0 -4
- package/svgIcons/FigmaIcon.mjs +0 -22
- package/svgIcons/FileDownload.d.mts +0 -6
- package/svgIcons/FileDownload.mjs +0 -13
- package/svgIcons/JavaScript.d.mts +0 -6
- package/svgIcons/JavaScript.mjs +0 -13
- package/svgIcons/MarkdownIcon.d.mts +0 -2
- package/svgIcons/MarkdownIcon.mjs +0 -22
- package/svgIcons/MaterialDesignIcon.d.mts +0 -4
- package/svgIcons/MaterialDesignIcon.mjs +0 -18
- package/svgIcons/SketchIcon.d.mts +0 -4
- package/svgIcons/SketchIcon.mjs +0 -27
- package/svgIcons/TypeScript.d.mts +0 -6
- package/svgIcons/TypeScript.mjs +0 -13
- package/svgIcons/W3CIcon.d.mts +0 -4
- package/svgIcons/W3CIcon.mjs +0 -15
- package/translations/index.d.mts +0 -3
- package/translations/index.mjs +0 -4
- package/useLazyCSS/index.d.mts +0 -1
- package/useLazyCSS/index.mjs +0 -1
- package/useLazyCSS/useLazyCSS.d.mts +0 -11
- package/useLazyCSS/useLazyCSS.mjs +0 -70
- package/utils/loadScript.d.mts +0 -1
- package/utils/loadScript.mjs +0 -7
- /package/{NProgressBar → NextNProgressBar}/NProgressBar.d.ts +0 -0
- /package/{NProgressBar/NProgressBar.mjs → NextNProgressBar/NProgressBar.js} +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MuiProductId } from "../getProductInfoFromUrl/index.js";
|
|
3
|
+
export type CodeVariant = 'TS' | 'JS';
|
|
4
|
+
type RelativeModule = {
|
|
5
|
+
module: string;
|
|
6
|
+
raw: string;
|
|
7
|
+
};
|
|
8
|
+
export interface DemoData {
|
|
9
|
+
title: string;
|
|
10
|
+
language: string;
|
|
11
|
+
raw: string;
|
|
12
|
+
codeVariant: CodeVariant;
|
|
13
|
+
githubLocation: string;
|
|
14
|
+
productId?: Exclude<MuiProductId, 'null'>;
|
|
15
|
+
relativeModules?: RelativeModule[];
|
|
16
|
+
}
|
|
17
|
+
export interface SandboxConfig {
|
|
18
|
+
/**
|
|
19
|
+
* Generates the root index.js/tsx content for CodeSandbox/StackBlitz.
|
|
20
|
+
* Receives codeVariant ('TS' | 'JS') for type assertion.
|
|
21
|
+
*/
|
|
22
|
+
getRootIndex?: (codeVariant: CodeVariant) => string;
|
|
23
|
+
/**
|
|
24
|
+
* Primary npm package for this product, used in sandbox generation.
|
|
25
|
+
* e.g., "@mui/material", "@mui/joy", "@mui/x-data-grid"
|
|
26
|
+
*/
|
|
27
|
+
primaryPackage: string;
|
|
28
|
+
/**
|
|
29
|
+
* Default dependency to add when generating sandbox (e.g., '@mui/material' for StyledEngineProvider)
|
|
30
|
+
* Used when the root index template requires a specific package.
|
|
31
|
+
*/
|
|
32
|
+
fallbackDependency?: {
|
|
33
|
+
name: string;
|
|
34
|
+
version: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Hook to add extra peer dependencies to sandbox.
|
|
38
|
+
*/
|
|
39
|
+
includePeerDependencies?: (deps: Record<string, string>, options: {
|
|
40
|
+
versions: Record<string, string>;
|
|
41
|
+
}) => Record<string, string>;
|
|
42
|
+
/**
|
|
43
|
+
* Hook to override default package versions.
|
|
44
|
+
*/
|
|
45
|
+
getVersions?: (versions: Record<string, string>, options: {
|
|
46
|
+
muiCommitRef?: string;
|
|
47
|
+
}) => Record<string, string>;
|
|
48
|
+
/**
|
|
49
|
+
* Hook to resolve custom imports to dependencies.
|
|
50
|
+
*/
|
|
51
|
+
postProcessImport?: (importName: string) => Record<string, string> | null;
|
|
52
|
+
}
|
|
53
|
+
export interface IframeWrapperProps {
|
|
54
|
+
/**
|
|
55
|
+
* The demo content (already cloned with `window` prop by FramedDemo).
|
|
56
|
+
* The wrapper should just render {children} - no cloning needed.
|
|
57
|
+
*/
|
|
58
|
+
children: React.ReactElement;
|
|
59
|
+
/** The iframe's document, for setting attributes or observing color scheme */
|
|
60
|
+
document: Document;
|
|
61
|
+
/** If true, the demo is isolated and should not inject theme CSS variables */
|
|
62
|
+
isolated?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface DemoContextValue {
|
|
65
|
+
/**
|
|
66
|
+
* Display name shown in demo titles, e.g., "Material UI", "Joy UI", "MUI X"
|
|
67
|
+
*/
|
|
68
|
+
productDisplayName: string;
|
|
69
|
+
/**
|
|
70
|
+
* Optional wrapper component for iframe demo content.
|
|
71
|
+
* Responsible for:
|
|
72
|
+
* - Creating and injecting CSS theme variables (via GlobalStyles)
|
|
73
|
+
* - Any product-specific observers (e.g., JoyIframeObserver)
|
|
74
|
+
*
|
|
75
|
+
* If not provided, defaults to MaterialIframeWrapper (creates Material theme).
|
|
76
|
+
* Pass `null` explicitly to disable iframe wrapping entirely.
|
|
77
|
+
*/
|
|
78
|
+
IframeWrapper?: React.ComponentType<IframeWrapperProps> | null;
|
|
79
|
+
/**
|
|
80
|
+
* Configuration for CodeSandbox/StackBlitz sandbox generation.
|
|
81
|
+
*/
|
|
82
|
+
csb: SandboxConfig;
|
|
83
|
+
}
|
|
84
|
+
declare const DemoContext: React.Context<DemoContextValue | null>;
|
|
85
|
+
export declare function useDemoContext(): DemoContextValue;
|
|
86
|
+
export default DemoContext;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
const DemoContext = /*#__PURE__*/React.createContext(null);
|
|
3
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4
|
+
DemoContext.displayName = 'DemoContext';
|
|
5
|
+
}
|
|
6
|
+
export function useDemoContext() {
|
|
7
|
+
const context = React.useContext(DemoContext);
|
|
8
|
+
if (!context) {
|
|
9
|
+
throw new Error('useDemoContext must be used within a DemoContext.Provider');
|
|
10
|
+
}
|
|
11
|
+
return context;
|
|
12
|
+
}
|
|
13
|
+
export default DemoContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, useDemoContext } from "./DemoContext.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
type ConsentStatus = 'analytics' | 'essential' | null;
|
|
3
|
+
interface AnalyticsContextValue {
|
|
4
|
+
consentStatus: ConsentStatus;
|
|
5
|
+
hasAnalyticsConsent: boolean;
|
|
6
|
+
needsConsent: boolean;
|
|
7
|
+
setAnalyticsConsent: () => void;
|
|
8
|
+
setEssentialOnly: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function useAnalyticsConsent(): AnalyticsContextValue;
|
|
11
|
+
export declare function CookieConsentDialog(): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function AnalyticsProvider({
|
|
13
|
+
children
|
|
14
|
+
}: {
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
var _CookieOutlinedIcon, _BrandingCssThemeProv;
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import Button from '@mui/material/Button';
|
|
4
|
+
import Fade from '@mui/material/Fade';
|
|
5
|
+
import Paper from '@mui/material/Paper';
|
|
6
|
+
import Box from '@mui/material/Box';
|
|
7
|
+
import Stack from '@mui/material/Stack';
|
|
8
|
+
import Typography from '@mui/material/Typography';
|
|
9
|
+
import useLocalStorageState from '@mui/utils/useLocalStorageState';
|
|
10
|
+
import { alpha } from '@mui/system';
|
|
11
|
+
import Portal from '@mui/material/Portal';
|
|
12
|
+
import TrapFocus from '@mui/material/Unstable_TrapFocus';
|
|
13
|
+
import CookieOutlinedIcon from '@mui/icons-material/CookieOutlined';
|
|
14
|
+
import { BrandingCssThemeProvider } from "../branding/BrandingCssVarsProvider.js";
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
const COOKIE_CONSENT_KEY = 'docs-cookie-consent';
|
|
17
|
+
function getDoNotTrack() {
|
|
18
|
+
if (typeof window === 'undefined') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
// Check for Do Not Track (DNT)
|
|
22
|
+
return navigator.doNotTrack === '1' || window.doNotTrack === '1';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// DNT doesn't change during a session, so we can use a simple external store
|
|
26
|
+
const subscribeToNothing = () => () => {};
|
|
27
|
+
const getDoNotTrackSnapshot = () => getDoNotTrack();
|
|
28
|
+
const getDoNotTrackServerSnapshot = () => true; // Assume DNT until we know the actual value
|
|
29
|
+
|
|
30
|
+
function useDoNotTrack() {
|
|
31
|
+
return React.useSyncExternalStore(subscribeToNothing, getDoNotTrackSnapshot, getDoNotTrackServerSnapshot);
|
|
32
|
+
}
|
|
33
|
+
const AnalyticsContext = /*#__PURE__*/React.createContext({
|
|
34
|
+
consentStatus: null,
|
|
35
|
+
hasAnalyticsConsent: false,
|
|
36
|
+
needsConsent: false,
|
|
37
|
+
setAnalyticsConsent: () => {},
|
|
38
|
+
setEssentialOnly: () => {}
|
|
39
|
+
});
|
|
40
|
+
export function useAnalyticsConsent() {
|
|
41
|
+
return React.useContext(AnalyticsContext);
|
|
42
|
+
}
|
|
43
|
+
export function CookieConsentDialog() {
|
|
44
|
+
const {
|
|
45
|
+
needsConsent,
|
|
46
|
+
setAnalyticsConsent,
|
|
47
|
+
setEssentialOnly
|
|
48
|
+
} = useAnalyticsConsent();
|
|
49
|
+
const [show, setShow] = React.useState(false);
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
if (needsConsent) {
|
|
52
|
+
// Double rAF to ensure the initial opacity: 0 state is painted before transitioning
|
|
53
|
+
const frame = requestAnimationFrame(() => {
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
setShow(true);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
return () => cancelAnimationFrame(frame);
|
|
59
|
+
}
|
|
60
|
+
setShow(false);
|
|
61
|
+
return undefined;
|
|
62
|
+
}, [needsConsent]);
|
|
63
|
+
return /*#__PURE__*/_jsx(Portal, {
|
|
64
|
+
children: /*#__PURE__*/_jsx(TrapFocus, {
|
|
65
|
+
open: needsConsent,
|
|
66
|
+
disableAutoFocus: true,
|
|
67
|
+
disableEnforceFocus: true,
|
|
68
|
+
children: /*#__PURE__*/_jsx(Fade, {
|
|
69
|
+
in: show,
|
|
70
|
+
unmountOnExit: true,
|
|
71
|
+
children: /*#__PURE__*/_jsx(Paper, {
|
|
72
|
+
role: "dialog",
|
|
73
|
+
"aria-modal": "false",
|
|
74
|
+
"aria-labelledby": "cookie-consent-dialog-title",
|
|
75
|
+
"aria-describedby": "cookie-consent-dialog-description",
|
|
76
|
+
variant: "outlined",
|
|
77
|
+
tabIndex: -1,
|
|
78
|
+
sx: theme => ({
|
|
79
|
+
position: 'fixed',
|
|
80
|
+
bottom: 0,
|
|
81
|
+
right: 0,
|
|
82
|
+
p: 2,
|
|
83
|
+
m: 2,
|
|
84
|
+
maxWidth: 340,
|
|
85
|
+
pointerEvents: 'auto',
|
|
86
|
+
boxShadow: theme.shadows[2],
|
|
87
|
+
zIndex: theme.zIndex.snackbar,
|
|
88
|
+
...(theme.applyDarkStyles ? theme.applyDarkStyles({
|
|
89
|
+
bgcolor: 'primaryDark.900'
|
|
90
|
+
}) : {
|
|
91
|
+
[theme.getColorSchemeSelector?.('dark') || '&.mode-dark']: {
|
|
92
|
+
bgcolor: 'primaryDark.900'
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
}),
|
|
96
|
+
children: /*#__PURE__*/_jsxs(Stack, {
|
|
97
|
+
direction: "column",
|
|
98
|
+
spacing: 3,
|
|
99
|
+
sx: {
|
|
100
|
+
justifyContent: 'flex-start'
|
|
101
|
+
},
|
|
102
|
+
children: [/*#__PURE__*/_jsxs(Stack, {
|
|
103
|
+
spacing: 1,
|
|
104
|
+
sx: {
|
|
105
|
+
flexShrink: 1,
|
|
106
|
+
alignSelf: {
|
|
107
|
+
xs: 'flex-start',
|
|
108
|
+
sm: 'center'
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
children: [/*#__PURE__*/_jsx(Box, {
|
|
112
|
+
sx: theme => ({
|
|
113
|
+
borderRadius: '50%',
|
|
114
|
+
bgcolor: alpha(theme.palette.primary.main, 0.1),
|
|
115
|
+
p: 1,
|
|
116
|
+
display: 'inline-block',
|
|
117
|
+
width: 40,
|
|
118
|
+
height: 40,
|
|
119
|
+
mb: -1,
|
|
120
|
+
alignSelf: {
|
|
121
|
+
xs: 'center',
|
|
122
|
+
sm: 'flex-start'
|
|
123
|
+
}
|
|
124
|
+
}),
|
|
125
|
+
children: _CookieOutlinedIcon || (_CookieOutlinedIcon = /*#__PURE__*/_jsx(CookieOutlinedIcon, {
|
|
126
|
+
color: "primary",
|
|
127
|
+
strokeWidth: 1.5
|
|
128
|
+
}))
|
|
129
|
+
}), /*#__PURE__*/_jsxs(Stack, {
|
|
130
|
+
spacing: 0.5,
|
|
131
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
132
|
+
variant: "subtitle2",
|
|
133
|
+
id: "cookie-consent-dialog-title",
|
|
134
|
+
textAlign: {
|
|
135
|
+
xs: 'center',
|
|
136
|
+
sm: 'start'
|
|
137
|
+
},
|
|
138
|
+
children: "Cookie Preferences"
|
|
139
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
140
|
+
id: "cookie-consent-dialog-description",
|
|
141
|
+
variant: "body2",
|
|
142
|
+
textAlign: {
|
|
143
|
+
xs: 'center',
|
|
144
|
+
sm: 'start'
|
|
145
|
+
},
|
|
146
|
+
children: "We use cookies to understand site usage and improve our content. This includes third-party analytics."
|
|
147
|
+
})]
|
|
148
|
+
})]
|
|
149
|
+
}), /*#__PURE__*/_jsxs(Stack, {
|
|
150
|
+
direction: "row",
|
|
151
|
+
spacing: 1,
|
|
152
|
+
sx: {
|
|
153
|
+
justifyContent: 'flex-start'
|
|
154
|
+
},
|
|
155
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
156
|
+
onClick: setAnalyticsConsent,
|
|
157
|
+
variant: "contained",
|
|
158
|
+
size: "small",
|
|
159
|
+
children: "Allow analytics"
|
|
160
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
161
|
+
onClick: setEssentialOnly,
|
|
162
|
+
size: "small",
|
|
163
|
+
children: "Essential only"
|
|
164
|
+
})]
|
|
165
|
+
})]
|
|
166
|
+
})
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function updateGoogleConsent(hasAnalytics) {
|
|
173
|
+
if (typeof window !== 'undefined' && typeof window.gtag === 'function') {
|
|
174
|
+
window.gtag('consent', 'update', {
|
|
175
|
+
ad_storage: 'denied',
|
|
176
|
+
ad_user_data: 'denied',
|
|
177
|
+
ad_personalization: 'denied',
|
|
178
|
+
analytics_storage: hasAnalytics ? 'granted' : 'denied'
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Initialize Apollo when analytics consent is granted
|
|
182
|
+
const win = window;
|
|
183
|
+
if (hasAnalytics && typeof win.initApollo === 'function') {
|
|
184
|
+
win.initApollo();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
export function AnalyticsProvider({
|
|
189
|
+
children
|
|
190
|
+
}) {
|
|
191
|
+
const [consentStatus, setConsentStatus] = useLocalStorageState(COOKIE_CONSENT_KEY, null);
|
|
192
|
+
const doNotTrack = useDoNotTrack();
|
|
193
|
+
|
|
194
|
+
// Respect Do Not Track - don't show dialog and treat as essential only
|
|
195
|
+
const needsConsent = consentStatus === null && !doNotTrack;
|
|
196
|
+
|
|
197
|
+
// Update Google consent when status changes or on mount if already set
|
|
198
|
+
React.useEffect(() => {
|
|
199
|
+
if (doNotTrack) {
|
|
200
|
+
// DNT is enabled - always deny analytics
|
|
201
|
+
updateGoogleConsent(false);
|
|
202
|
+
} else if (consentStatus !== null) {
|
|
203
|
+
updateGoogleConsent(consentStatus === 'analytics');
|
|
204
|
+
}
|
|
205
|
+
}, [consentStatus, doNotTrack]);
|
|
206
|
+
const setAnalyticsConsent = React.useCallback(() => {
|
|
207
|
+
setConsentStatus('analytics');
|
|
208
|
+
}, [setConsentStatus]);
|
|
209
|
+
const setEssentialOnly = React.useCallback(() => {
|
|
210
|
+
setConsentStatus('essential');
|
|
211
|
+
}, [setConsentStatus]);
|
|
212
|
+
const contextValue = React.useMemo(() => ({
|
|
213
|
+
consentStatus: doNotTrack ? 'essential' : consentStatus,
|
|
214
|
+
hasAnalyticsConsent: !doNotTrack && consentStatus === 'analytics',
|
|
215
|
+
needsConsent,
|
|
216
|
+
setAnalyticsConsent,
|
|
217
|
+
setEssentialOnly
|
|
218
|
+
}), [consentStatus, doNotTrack, needsConsent, setAnalyticsConsent, setEssentialOnly]);
|
|
219
|
+
return /*#__PURE__*/_jsxs(AnalyticsContext.Provider, {
|
|
220
|
+
value: contextValue,
|
|
221
|
+
children: [children, _BrandingCssThemeProv || (_BrandingCssThemeProv = /*#__PURE__*/_jsx(BrandingCssThemeProvider, {
|
|
222
|
+
children: /*#__PURE__*/_jsx(CookieConsentDialog, {})
|
|
223
|
+
}))]
|
|
224
|
+
});
|
|
225
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { AdConfig } from "../Ad/index.js";
|
|
3
|
+
import type { DemoContextValue } from "../DemoContext/index.js";
|
|
4
|
+
import type { DocsConfig } from "../DocsProvider/index.js";
|
|
5
|
+
import type { MuiPageContext } from "../PageContext/index.js";
|
|
6
|
+
import type { Translations } from "../i18n/index.js";
|
|
7
|
+
import createEmotionCache from "./createEmotionCache.js";
|
|
8
|
+
export interface DocsAppProps {
|
|
9
|
+
/**
|
|
10
|
+
* The Next.js page component.
|
|
11
|
+
*/
|
|
12
|
+
Component: React.ComponentType<any> & {
|
|
13
|
+
getLayout?: (page: React.ReactElement) => React.ReactNode;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The Emotion cache for CSS-in-JS. Falls back to a client-side cache.
|
|
17
|
+
*/
|
|
18
|
+
emotionCache?: ReturnType<typeof createEmotionCache>;
|
|
19
|
+
/**
|
|
20
|
+
* Page props from Next.js, including userLanguage and translations.
|
|
21
|
+
*/
|
|
22
|
+
pageProps: {
|
|
23
|
+
userLanguage: string;
|
|
24
|
+
translations: Translations;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Docs configuration object (from docs/config.ts)
|
|
29
|
+
*/
|
|
30
|
+
docsConfig: DocsConfig;
|
|
31
|
+
/**
|
|
32
|
+
* Path to the service worker file, e.g. '/sw.js'
|
|
33
|
+
*/
|
|
34
|
+
serviceWorkerPath: string;
|
|
35
|
+
/**
|
|
36
|
+
* The currently active page object
|
|
37
|
+
*/
|
|
38
|
+
activePage: MuiPageContext['activePage'];
|
|
39
|
+
/**
|
|
40
|
+
* The parent pages of the active page
|
|
41
|
+
*/
|
|
42
|
+
activePageParents: MuiPageContext['activePageParents'];
|
|
43
|
+
/**
|
|
44
|
+
* List of all pages for the product
|
|
45
|
+
*/
|
|
46
|
+
pageList: MuiPageContext['pages'];
|
|
47
|
+
/**
|
|
48
|
+
* Product metadata and branding info
|
|
49
|
+
*/
|
|
50
|
+
productIdentifier: MuiPageContext['productIdentifier'];
|
|
51
|
+
/**
|
|
52
|
+
* Product identifier string (e.g. 'material-ui')
|
|
53
|
+
*/
|
|
54
|
+
productId: MuiPageContext['productId'];
|
|
55
|
+
/**
|
|
56
|
+
* Product category identifier string (e.g. 'core')
|
|
57
|
+
*/
|
|
58
|
+
productCategoryId: MuiPageContext['productCategoryId'];
|
|
59
|
+
/**
|
|
60
|
+
* Display name for the product (e.g. 'Material UI')
|
|
61
|
+
*/
|
|
62
|
+
demoDisplayName: DemoContextValue['productDisplayName'];
|
|
63
|
+
/**
|
|
64
|
+
* CodeSandbox configuration for demos
|
|
65
|
+
*/
|
|
66
|
+
csbConfig: DemoContextValue['csb'];
|
|
67
|
+
/**
|
|
68
|
+
* Optional ad configuration
|
|
69
|
+
*/
|
|
70
|
+
adConfig?: Partial<AdConfig>;
|
|
71
|
+
/**
|
|
72
|
+
* Optional wrapper component for theming
|
|
73
|
+
*/
|
|
74
|
+
ThemeWrapper?: React.ComponentType<{
|
|
75
|
+
children: React.ReactNode;
|
|
76
|
+
}>;
|
|
77
|
+
}
|
|
78
|
+
declare function DocsApp(props: DocsAppProps): import("react/jsx-runtime").JSX.Element;
|
|
79
|
+
export { DocsApp };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
var _meta, _GoogleAnalytics;
|
|
2
|
+
import NextHead from 'next/head';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { CodeCopyProvider } from "../CodeCopy/index.js";
|
|
5
|
+
import DemoContext from "../DemoContext/index.js";
|
|
6
|
+
import { DocsProvider } from "../DocsProvider/index.js";
|
|
7
|
+
import PageContext from "../PageContext/index.js";
|
|
8
|
+
import { ThemeProvider } from "../ThemeContext/index.js";
|
|
9
|
+
import { CodeStylingProvider } from "../codeStyling/index.js";
|
|
10
|
+
import { CodeVariantProvider } from "../codeVariant/index.js";
|
|
11
|
+
import { AnalyticsProvider } from "./AnalyticsProvider.js";
|
|
12
|
+
import GoogleAnalytics from "./GoogleAnalytics.js";
|
|
13
|
+
import DocsStyledEngineProvider from "./StyledEngineProvider.js";
|
|
14
|
+
import createEmotionCache from "./createEmotionCache.js";
|
|
15
|
+
import { loadDependencies } from "./loadDependencies.js";
|
|
16
|
+
import { registerServiceWorker } from "./serviceWorker.js";
|
|
17
|
+
|
|
18
|
+
// Client-side cache, shared for the whole session of the user in the browser.
|
|
19
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
20
|
+
const clientSideEmotionCache = createEmotionCache();
|
|
21
|
+
function DocsApp(props) {
|
|
22
|
+
const {
|
|
23
|
+
Component,
|
|
24
|
+
emotionCache = clientSideEmotionCache,
|
|
25
|
+
pageProps,
|
|
26
|
+
docsConfig,
|
|
27
|
+
serviceWorkerPath,
|
|
28
|
+
activePage,
|
|
29
|
+
activePageParents,
|
|
30
|
+
pageList,
|
|
31
|
+
productIdentifier,
|
|
32
|
+
productId,
|
|
33
|
+
productCategoryId,
|
|
34
|
+
demoDisplayName,
|
|
35
|
+
csbConfig,
|
|
36
|
+
adConfig,
|
|
37
|
+
ThemeWrapper = ThemeProvider
|
|
38
|
+
} = props;
|
|
39
|
+
const pageContextValue = React.useMemo(() => ({
|
|
40
|
+
activePage,
|
|
41
|
+
activePageParents,
|
|
42
|
+
pages: pageList,
|
|
43
|
+
productIdentifier,
|
|
44
|
+
productId,
|
|
45
|
+
productCategoryId
|
|
46
|
+
}), [activePage, activePageParents, pageList, productIdentifier, productId, productCategoryId]);
|
|
47
|
+
const demoContextValue = React.useMemo(() => ({
|
|
48
|
+
productDisplayName: demoDisplayName,
|
|
49
|
+
csb: csbConfig
|
|
50
|
+
}), [demoDisplayName, csbConfig]);
|
|
51
|
+
const getLayout = Component.getLayout ?? (page => page);
|
|
52
|
+
React.useEffect(() => {
|
|
53
|
+
loadDependencies();
|
|
54
|
+
registerServiceWorker(serviceWorkerPath);
|
|
55
|
+
|
|
56
|
+
// Remove the server-side injected CSS.
|
|
57
|
+
const jssStyles = document.querySelector('#jss-server-side');
|
|
58
|
+
if (jssStyles) {
|
|
59
|
+
jssStyles.parentElement.removeChild(jssStyles);
|
|
60
|
+
}
|
|
61
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
62
|
+
|
|
63
|
+
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
64
|
+
children: [/*#__PURE__*/_jsxs(NextHead, {
|
|
65
|
+
children: [_meta || (_meta = /*#__PURE__*/_jsx("meta", {
|
|
66
|
+
name: "viewport",
|
|
67
|
+
content: "initial-scale=1, width=device-width"
|
|
68
|
+
})), /*#__PURE__*/_jsx("meta", {
|
|
69
|
+
name: "mui:productId",
|
|
70
|
+
content: productId
|
|
71
|
+
}), /*#__PURE__*/_jsx("meta", {
|
|
72
|
+
name: "mui:productCategoryId",
|
|
73
|
+
content: productCategoryId
|
|
74
|
+
})]
|
|
75
|
+
}), /*#__PURE__*/_jsx(DocsProvider, {
|
|
76
|
+
config: docsConfig,
|
|
77
|
+
adConfig: adConfig,
|
|
78
|
+
defaultUserLanguage: pageProps.userLanguage,
|
|
79
|
+
translations: pageProps.translations,
|
|
80
|
+
children: /*#__PURE__*/_jsx(CodeCopyProvider, {
|
|
81
|
+
children: /*#__PURE__*/_jsx(CodeStylingProvider, {
|
|
82
|
+
children: /*#__PURE__*/_jsx(CodeVariantProvider, {
|
|
83
|
+
children: /*#__PURE__*/_jsx(PageContext.Provider, {
|
|
84
|
+
value: pageContextValue,
|
|
85
|
+
children: /*#__PURE__*/_jsx(DemoContext.Provider, {
|
|
86
|
+
value: demoContextValue,
|
|
87
|
+
children: /*#__PURE__*/_jsx(ThemeWrapper, {
|
|
88
|
+
children: /*#__PURE__*/_jsx(DocsStyledEngineProvider, {
|
|
89
|
+
cacheLtr: emotionCache,
|
|
90
|
+
children: /*#__PURE__*/_jsxs(AnalyticsProvider, {
|
|
91
|
+
children: [getLayout(/*#__PURE__*/_jsx(Component, {
|
|
92
|
+
...pageProps
|
|
93
|
+
})), _GoogleAnalytics || (_GoogleAnalytics = /*#__PURE__*/_jsx(GoogleAnalytics, {}))]
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
})]
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
export { DocsApp };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* basically just a `useAnalytics` hook.
|
|
4
|
+
* However, it needs the redux store which is created
|
|
5
|
+
* in the same component this "hook" is used.
|
|
6
|
+
*/
|
|
7
|
+
declare function GoogleAnalytics(): null;
|
|
8
|
+
declare const _default: React.MemoExoticComponent<typeof GoogleAnalytics>;
|
|
9
|
+
export default _default;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import useMediaQuery from '@mui/material/useMediaQuery';
|
|
3
|
+
import { useRouter } from 'next/router';
|
|
4
|
+
import { useNoSsrCodeVariant } from "../codeVariant/index.js";
|
|
5
|
+
import { useUserLanguage } from "../i18n/index.js";
|
|
6
|
+
import { pathnameToLanguage } from "../helpers/index.js";
|
|
7
|
+
import { ThemeOptionsContext } from "../ThemeContext/index.js";
|
|
8
|
+
|
|
9
|
+
// So we can write code like:
|
|
10
|
+
//
|
|
11
|
+
// <Button
|
|
12
|
+
// data-ga-event-category="demo"
|
|
13
|
+
// data-ga-event-action="expand"
|
|
14
|
+
// >
|
|
15
|
+
// Foo
|
|
16
|
+
// </Button>
|
|
17
|
+
function handleClick(event) {
|
|
18
|
+
let el = event.target;
|
|
19
|
+
while (el && el !== document) {
|
|
20
|
+
const element = el;
|
|
21
|
+
const category = element.getAttribute('data-ga-event-category');
|
|
22
|
+
|
|
23
|
+
// We reach a tracking element, no need to look higher in the dom tree.
|
|
24
|
+
if (category) {
|
|
25
|
+
const split = parseFloat(element.getAttribute('data-ga-event-split') || '');
|
|
26
|
+
if (split && split < Math.random()) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
window.gtag('event', category, {
|
|
30
|
+
eventAction: element.getAttribute('data-ga-event-action'),
|
|
31
|
+
eventLabel: element.getAttribute('data-ga-event-label')
|
|
32
|
+
});
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
el = element.parentElement;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
let boundDataGaListener = false;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* basically just a `useAnalytics` hook.
|
|
42
|
+
* However, it needs the redux store which is created
|
|
43
|
+
* in the same component this "hook" is used.
|
|
44
|
+
*/
|
|
45
|
+
function GoogleAnalytics() {
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
if (!boundDataGaListener) {
|
|
48
|
+
boundDataGaListener = true;
|
|
49
|
+
document.addEventListener('click', handleClick);
|
|
50
|
+
}
|
|
51
|
+
}, []);
|
|
52
|
+
const router = useRouter();
|
|
53
|
+
const timeout = React.useRef(null);
|
|
54
|
+
React.useEffect(() => {
|
|
55
|
+
// Wait for the title to be updated.
|
|
56
|
+
// React fires useEffect twice in dev mode
|
|
57
|
+
if (timeout.current) {
|
|
58
|
+
clearTimeout(timeout.current);
|
|
59
|
+
}
|
|
60
|
+
timeout.current = setTimeout(() => {
|
|
61
|
+
const {
|
|
62
|
+
canonicalAsServer
|
|
63
|
+
} = pathnameToLanguage(window.location.pathname);
|
|
64
|
+
|
|
65
|
+
// https://developers.google.com/analytics/devguides/collection/ga4/views?client_type=gtag
|
|
66
|
+
const productIdMeta = document.querySelector('meta[name="mui:productId"]');
|
|
67
|
+
const productCategoryIdMeta = document.querySelector('meta[name="mui:productCategoryId"]');
|
|
68
|
+
window.gtag('event', 'page_view', {
|
|
69
|
+
page_title: document.title,
|
|
70
|
+
page_location: canonicalAsServer,
|
|
71
|
+
productId: productIdMeta?.content,
|
|
72
|
+
productCategoryId: productCategoryIdMeta?.content
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}, [router.route]);
|
|
76
|
+
const codeVariant = useNoSsrCodeVariant();
|
|
77
|
+
React.useEffect(() => {
|
|
78
|
+
window.gtag('set', 'user_properties', {
|
|
79
|
+
codeVariant
|
|
80
|
+
});
|
|
81
|
+
}, [codeVariant]);
|
|
82
|
+
const userLanguage = useUserLanguage();
|
|
83
|
+
React.useEffect(() => {
|
|
84
|
+
window.gtag('set', 'user_properties', {
|
|
85
|
+
userLanguage
|
|
86
|
+
});
|
|
87
|
+
}, [userLanguage]);
|
|
88
|
+
React.useEffect(() => {
|
|
89
|
+
/**
|
|
90
|
+
* Based on https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
|
|
91
|
+
* Adjusted to track 3 or more different ratios
|
|
92
|
+
*/
|
|
93
|
+
function trackDevicePixelRation() {
|
|
94
|
+
const devicePixelRatio = Math.round(window.devicePixelRatio * 10) / 10;
|
|
95
|
+
window.gtag('set', 'user_properties', {
|
|
96
|
+
devicePixelRatio
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
trackDevicePixelRation();
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @type {MediaQueryList}
|
|
103
|
+
*/
|
|
104
|
+
const matchMedia = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
105
|
+
// Intentionally use deprecated listener methods to support iOS & old browsers
|
|
106
|
+
matchMedia.addListener(trackDevicePixelRation);
|
|
107
|
+
return () => {
|
|
108
|
+
matchMedia.removeListener(trackDevicePixelRation);
|
|
109
|
+
};
|
|
110
|
+
}, []);
|
|
111
|
+
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)', {
|
|
112
|
+
noSsr: true
|
|
113
|
+
});
|
|
114
|
+
const colorSchemeOS = prefersDarkMode ? 'dark' : 'light';
|
|
115
|
+
const themeOptions = React.useContext(ThemeOptionsContext);
|
|
116
|
+
const colorScheme = themeOptions.paletteMode;
|
|
117
|
+
React.useEffect(() => {
|
|
118
|
+
window.gtag('set', 'user_properties', {
|
|
119
|
+
colorSchemeOS
|
|
120
|
+
});
|
|
121
|
+
}, [colorSchemeOS]);
|
|
122
|
+
React.useEffect(() => {
|
|
123
|
+
window.gtag('set', 'user_properties', {
|
|
124
|
+
colorScheme
|
|
125
|
+
});
|
|
126
|
+
}, [colorScheme]);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
export default /*#__PURE__*/React.memo(GoogleAnalytics);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createEmotionCache as createCache } from '@mui/material-nextjs/v15-pagesRouter';
|
|
3
|
+
type StyledEngineProviderProps = {
|
|
4
|
+
cacheLtr: ReturnType<typeof createCache>;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
};
|
|
7
|
+
export default function StyledEngineProvider(props: StyledEngineProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|