@mui/docs 6.0.0-dev.240424162023-9968b4889d → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/Ad/Ad.d.ts +6 -0
  2. package/Ad/Ad.js +228 -0
  3. package/Ad/AdCarbon.d.ts +3 -0
  4. package/Ad/AdCarbon.js +120 -0
  5. package/Ad/AdDisplay.d.ts +16 -0
  6. package/Ad/AdDisplay.js +89 -0
  7. package/Ad/AdGuest.d.ts +10 -0
  8. package/Ad/AdGuest.js +29 -0
  9. package/Ad/AdInHouse.d.ts +5 -0
  10. package/Ad/AdInHouse.js +15 -0
  11. package/Ad/AdManager.d.ts +16 -0
  12. package/Ad/AdManager.js +36 -0
  13. package/Ad/AdProvider.d.ts +15 -0
  14. package/Ad/AdProvider.js +24 -0
  15. package/Ad/ad.styles.d.ts +4327 -0
  16. package/Ad/ad.styles.js +89 -0
  17. package/Ad/index.d.ts +5 -0
  18. package/Ad/index.js +7 -0
  19. package/Ad/package.json +6 -0
  20. package/CHANGELOG.md +1367 -22
  21. package/CodeCopy/CodeCopy.js +1 -1
  22. package/CodeCopy/CodeCopyButton.js +11 -20
  23. package/CodeCopy/index.js +3 -3
  24. package/CodeCopy/useClipboardCopy.js +1 -1
  25. package/ComponentLinkHeader/ComponentLinkHeader.d.ts +9 -0
  26. package/ComponentLinkHeader/ComponentLinkHeader.js +197 -0
  27. package/ComponentLinkHeader/index.d.ts +2 -0
  28. package/ComponentLinkHeader/index.js +2 -0
  29. package/ComponentLinkHeader/package.json +6 -0
  30. package/DocsProvider/DocsProvider.d.ts +3 -1
  31. package/DocsProvider/DocsProvider.js +10 -5
  32. package/DocsProvider/index.js +1 -1
  33. package/HighlightedCode/HighlightedCode.d.ts +3 -1
  34. package/HighlightedCode/HighlightedCode.js +50 -24
  35. package/HighlightedCode/index.js +1 -1
  36. package/HighlightedCodeWithTabs/HighlightedCodeWithTabs.d.ts +29 -0
  37. package/HighlightedCodeWithTabs/HighlightedCodeWithTabs.js +355 -0
  38. package/HighlightedCodeWithTabs/index.d.ts +2 -0
  39. package/HighlightedCodeWithTabs/index.js +2 -0
  40. package/HighlightedCodeWithTabs/package.json +6 -0
  41. package/InfoCard/InfoCard.d.ts +0 -1
  42. package/InfoCard/InfoCard.js +46 -45
  43. package/InfoCard/index.js +1 -1
  44. package/Link/Link.js +41 -41
  45. package/Link/index.js +1 -1
  46. package/MarkdownElement/MarkdownElement.d.ts +1 -0
  47. package/MarkdownElement/MarkdownElement.js +187 -165
  48. package/MarkdownElement/index.js +1 -1
  49. package/NProgressBar/NProgressBar.js +6 -7
  50. package/NProgressBar/index.js +1 -1
  51. package/README.md +2 -2
  52. package/SectionTitle/SectionTitle.d.ts +7 -0
  53. package/SectionTitle/SectionTitle.js +30 -0
  54. package/SectionTitle/index.d.ts +1 -0
  55. package/SectionTitle/index.js +1 -0
  56. package/SectionTitle/package.json +6 -0
  57. package/branding/BrandingProvider.d.ts +1 -1
  58. package/branding/BrandingProvider.js +1 -1
  59. package/branding/brandingTheme.d.ts +2 -2
  60. package/branding/brandingTheme.js +657 -369
  61. package/branding/index.js +2 -2
  62. package/i18n/i18n.d.ts +2 -1
  63. package/i18n/i18n.js +19 -9
  64. package/i18n/index.js +1 -1
  65. package/node/Ad/Ad.js +238 -0
  66. package/node/Ad/AdCarbon.js +130 -0
  67. package/node/Ad/AdDisplay.js +97 -0
  68. package/node/Ad/AdGuest.js +37 -0
  69. package/node/Ad/AdInHouse.js +24 -0
  70. package/node/Ad/AdManager.js +46 -0
  71. package/node/Ad/AdProvider.js +33 -0
  72. package/node/Ad/ad.styles.js +97 -0
  73. package/node/Ad/index.js +63 -0
  74. package/node/CodeCopy/CodeCopy.js +10 -16
  75. package/node/CodeCopy/CodeCopyButton.js +10 -19
  76. package/node/CodeCopy/useClipboardCopy.js +1 -1
  77. package/node/ComponentLinkHeader/ComponentLinkHeader.js +206 -0
  78. package/node/ComponentLinkHeader/index.js +24 -0
  79. package/node/DocsProvider/DocsProvider.js +9 -4
  80. package/node/HighlightedCode/HighlightedCode.js +48 -22
  81. package/node/HighlightedCodeWithTabs/HighlightedCodeWithTabs.js +365 -0
  82. package/node/HighlightedCodeWithTabs/index.js +24 -0
  83. package/node/InfoCard/InfoCard.js +45 -44
  84. package/node/Link/Link.js +43 -42
  85. package/node/MarkdownElement/MarkdownElement.js +642 -623
  86. package/node/NProgressBar/NProgressBar.js +6 -7
  87. package/node/SectionTitle/SectionTitle.js +38 -0
  88. package/node/SectionTitle/index.js +16 -0
  89. package/node/branding/brandingTheme.js +657 -369
  90. package/node/i18n/i18n.js +18 -8
  91. package/node/svgIcons/AdobeXDIcon.js +22 -0
  92. package/node/svgIcons/BundleSizeIcon.js +22 -0
  93. package/node/svgIcons/FigmaIcon.js +31 -0
  94. package/node/svgIcons/FileDownload.js +3 -3
  95. package/node/svgIcons/JavaScript.js +3 -3
  96. package/node/svgIcons/MaterialDesignIcon.js +27 -0
  97. package/node/svgIcons/SketchIcon.js +36 -0
  98. package/node/svgIcons/TypeScript.js +3 -3
  99. package/node/svgIcons/W3CIcon.js +24 -0
  100. package/node/translations/translations.json +9 -4
  101. package/node/utils/loadScript.js +15 -0
  102. package/package.json +12 -10
  103. package/svgIcons/AdobeXDIcon.d.ts +4 -0
  104. package/svgIcons/AdobeXDIcon.js +14 -0
  105. package/svgIcons/BundleSizeIcon.d.ts +4 -0
  106. package/svgIcons/BundleSizeIcon.js +14 -0
  107. package/svgIcons/FigmaIcon.d.ts +4 -0
  108. package/svgIcons/FigmaIcon.js +23 -0
  109. package/svgIcons/FileDownload.d.ts +7 -0
  110. package/svgIcons/FileDownload.js +3 -3
  111. package/svgIcons/JavaScript.d.ts +7 -0
  112. package/svgIcons/JavaScript.js +3 -3
  113. package/svgIcons/MaterialDesignIcon.d.ts +4 -0
  114. package/svgIcons/MaterialDesignIcon.js +19 -0
  115. package/svgIcons/SketchIcon.d.ts +4 -0
  116. package/svgIcons/SketchIcon.js +28 -0
  117. package/svgIcons/TypeScript.d.ts +7 -0
  118. package/svgIcons/TypeScript.js +3 -3
  119. package/svgIcons/W3CIcon.d.ts +4 -0
  120. package/svgIcons/W3CIcon.js +16 -0
  121. package/translations/index.js +1 -1
  122. package/translations/translations.json +9 -4
  123. package/tsconfig.build.tsbuildinfo +1 -1
  124. package/utils/loadScript.d.ts +1 -0
  125. package/utils/loadScript.js +9 -0
package/Ad/Ad.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export declare const AD_MARGIN_TOP = 3;
3
+ export declare const AD_MARGIN_BOTTOM = 3;
4
+ export declare const AD_HEIGHT = 126;
5
+ export declare const AD_HEIGHT_MOBILE: number;
6
+ export declare function Ad(): React.JSX.Element;
package/Ad/Ad.js ADDED
@@ -0,0 +1,228 @@
1
+ var _span, _PleaseDisableAdblock, _AdCarbon;
2
+ import * as React from 'react';
3
+ import Typography from '@mui/material/Typography';
4
+ import Box from '@mui/material/Box';
5
+ import Paper from '@mui/material/Paper';
6
+ import { useTranslate } from "../i18n/index.js";
7
+ import AdCarbon from "./AdCarbon.js";
8
+ import AdInHouse from "./AdInHouse.js";
9
+ import { AdContext, adShape } from "./AdManager.js";
10
+ import { useAdConfig } from "./AdProvider.js";
11
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ function PleaseDisableAdblock() {
13
+ const t = useTranslate();
14
+ return /*#__PURE__*/_jsxs(Paper, {
15
+ component: "span",
16
+ elevation: 0,
17
+ sx: {
18
+ display: 'block',
19
+ p: 1.5,
20
+ border: '2px solid',
21
+ borderColor: 'primary.main'
22
+ },
23
+ children: [/*#__PURE__*/_jsx(Typography, {
24
+ variant: "body2",
25
+ component: "span",
26
+ gutterBottom: true,
27
+ sx: {
28
+ display: 'block'
29
+ },
30
+ children: t('likeMui')
31
+ }), /*#__PURE__*/_jsx(Typography, {
32
+ variant: "body2",
33
+ component: "span",
34
+ gutterBottom: true,
35
+ sx: {
36
+ display: 'block'
37
+ },
38
+ children: t('adblock')
39
+ }), /*#__PURE__*/_jsxs(Typography, {
40
+ variant: "body2",
41
+ component: "span",
42
+ sx: {
43
+ display: 'block'
44
+ },
45
+ children: [t('thanks'), ' ', /*#__PURE__*/_jsx("span", {
46
+ role: "img",
47
+ "aria-label": t('emojiLove'),
48
+ children: "\u2764\uFE0F"
49
+ })]
50
+ })]
51
+ });
52
+ }
53
+ const disableAd = process.env.NODE_ENV !== 'production' && process.env.ENABLE_AD_IN_DEV_MODE !== 'true';
54
+ const inHouseAds = [{
55
+ name: 'scaffoldhub',
56
+ link: 'https://v2.scaffoldhub.io/scaffolds/react-material-ui?partner=1',
57
+ img: '/static/ads-in-house/scaffoldhub.png',
58
+ description: '<b>ScaffoldHub</b>. Automate building your full-stack Material UI web-app.'
59
+ }, {
60
+ name: 'templates',
61
+ link: 'https://mui.com/store/?utm_source=docs&utm_medium=referral&utm_campaign=in-house-templates',
62
+ img: '/static/ads-in-house/themes-2.jpg',
63
+ description: '<b>Premium Templates</b>. Start your project with the best templates for admins, dashboards, and more.'
64
+ }, {
65
+ name: 'themes',
66
+ link: 'https://mui.com/store/?utm_source=docs&utm_medium=referral&utm_campaign=in-house-themes',
67
+ img: '/static/ads-in-house/themes.png',
68
+ description: '<b>Premium Themes</b>. Kickstart your application development with a ready-made theme.'
69
+ }, {
70
+ name: 'tidelift',
71
+ link: 'https://tidelift.com/subscription/pkg/npm-material-ui?utm_source=npm-material-ui&utm_medium=referral&utm_campaign=enterprise&utm_content=ad',
72
+ img: '/static/ads-in-house/tidelift.png',
73
+ description: '<b>MUI for enterprise</b>. Save time and reduce risk. Managed open source — backed by maintainers.'
74
+ }, {
75
+ name: 'figma',
76
+ link: 'https://mui.com/store/items/figma-react/?utm_source=docs&utm_medium=referral&utm_campaign=in-house-figma',
77
+ img: '/static/ads-in-house/figma.png',
78
+ description: '<b>For Figma</b>. A large UI kit with over 600 handcrafted Material UI, MUI X, Joy UI components 🎨.'
79
+ }];
80
+ class AdErrorBoundary extends React.Component {
81
+ state = {
82
+ didError: false
83
+ };
84
+ static getDerivedStateFromError() {
85
+ return {
86
+ didError: true
87
+ };
88
+ }
89
+ componentDidCatch() {
90
+ // send explicit `'null'`
91
+ const eventLabel = String(this.props.eventLabel);
92
+ // TODO: Use proper error monitoring service (for example Sentry) instead
93
+
94
+ window.gtag('event', 'ad', {
95
+ eventAction: 'crash',
96
+ eventLabel
97
+ });
98
+ }
99
+ render() {
100
+ const {
101
+ didError
102
+ } = this.state;
103
+ const {
104
+ children
105
+ } = this.props;
106
+ if (didError) {
107
+ return null;
108
+ }
109
+ return children;
110
+ }
111
+ }
112
+ export const AD_MARGIN_TOP = 3;
113
+ export const AD_MARGIN_BOTTOM = 3;
114
+ export const AD_HEIGHT = 126;
115
+ // Add more height on mobile as the text tends to wrap beyond the image height.
116
+ export const AD_HEIGHT_MOBILE = 126 + 16;
117
+
118
+ // https://stackoverflow.com/a/20084661
119
+ function isBot() {
120
+ return /bot|googlebot|crawler|spider|robot|crawling/i.test(navigator.userAgent);
121
+ }
122
+ export function Ad() {
123
+ const [adblock, setAdblock] = React.useState(null);
124
+ const [carbonOut, setCarbonOut] = React.useState(null);
125
+ const {
126
+ current: randomAdblock
127
+ } = React.useRef(Math.random());
128
+ const {
129
+ current: randomInHouse
130
+ } = React.useRef(Math.random());
131
+ let children;
132
+ let label;
133
+ // Hide the content to google bot to avoid its indexation.
134
+ if (typeof window !== 'undefined' && isBot() || disableAd) {
135
+ children = _span || (_span = /*#__PURE__*/_jsx("span", {}));
136
+ } else if (adblock) {
137
+ if (randomAdblock < 0.2) {
138
+ children = _PleaseDisableAdblock || (_PleaseDisableAdblock = /*#__PURE__*/_jsx(PleaseDisableAdblock, {}));
139
+ label = 'in-house-adblock';
140
+ } else {
141
+ children = /*#__PURE__*/_jsx(AdInHouse, {
142
+ ad: inHouseAds[Math.floor(inHouseAds.length * randomInHouse)]
143
+ });
144
+ label = 'in-house';
145
+ }
146
+ } else if (carbonOut) {
147
+ children = /*#__PURE__*/_jsx(AdInHouse, {
148
+ ad: inHouseAds[Math.floor(inHouseAds.length * randomInHouse)]
149
+ });
150
+ label = 'in-house-carbon';
151
+ } else {
152
+ children = _AdCarbon || (_AdCarbon = /*#__PURE__*/_jsx(AdCarbon, {}));
153
+ label = 'carbon';
154
+ }
155
+ const ad = React.useContext(AdContext);
156
+ const eventLabel = label ? `${label}-${ad.placement}-${adShape}` : null;
157
+ const timerAdblock = React.useRef(undefined);
158
+ const checkAdblock = React.useCallback((attempt = 1) => {
159
+ if (document.querySelector('.ea-placement') || document.querySelector('#carbonads') || document.querySelector('.carbonads') || carbonOut) {
160
+ if (document.querySelector('#carbonads a') && document.querySelector('#carbonads a')?.getAttribute('href') === 'https://material-ui-next.com/discover-more/backers') {
161
+ setCarbonOut(true);
162
+ }
163
+ setAdblock(false);
164
+ return;
165
+ }
166
+ if (attempt < 30) {
167
+ timerAdblock.current = setTimeout(() => {
168
+ checkAdblock(attempt + 1);
169
+ }, 500);
170
+ }
171
+ if (attempt > 6) {
172
+ setAdblock(true);
173
+ }
174
+ }, [carbonOut]);
175
+ React.useEffect(() => {
176
+ if (disableAd) {
177
+ return undefined;
178
+ }
179
+ checkAdblock();
180
+ return () => {
181
+ clearTimeout(timerAdblock.current);
182
+ };
183
+ }, [checkAdblock]);
184
+ const {
185
+ GADisplayRatio
186
+ } = useAdConfig();
187
+ React.useEffect(() => {
188
+ // Avoid an exceed on the Google Analytics quotas.
189
+ if (Math.random() > (GADisplayRatio ?? 0.1) || !eventLabel) {
190
+ return undefined;
191
+ }
192
+ const delay = setTimeout(() => {
193
+ window.gtag('event', 'ad', {
194
+ eventAction: 'display',
195
+ eventLabel
196
+ });
197
+ }, 2500);
198
+ return () => {
199
+ clearTimeout(delay);
200
+ };
201
+ }, [GADisplayRatio, eventLabel]);
202
+ return /*#__PURE__*/_jsx(Box, {
203
+ component: "span",
204
+ sx: theme => ({
205
+ position: 'relative',
206
+ display: 'block',
207
+ mt: AD_MARGIN_TOP,
208
+ mb: AD_MARGIN_BOTTOM,
209
+ minHeight: AD_HEIGHT_MOBILE,
210
+ [theme.breakpoints.up('sm')]: {
211
+ minHeight: AD_HEIGHT
212
+ },
213
+ ...(adShape === 'image' && {}),
214
+ ...(adShape === 'inline' && {
215
+ display: 'flex',
216
+ alignItems: 'flex-end'
217
+ })
218
+ }),
219
+ "data-ga-event-category": "ad",
220
+ "data-ga-event-action": "click",
221
+ "data-ga-event-label": eventLabel,
222
+ className: "Ad-root",
223
+ children: /*#__PURE__*/_jsx(AdErrorBoundary, {
224
+ eventLabel: eventLabel,
225
+ children: children
226
+ })
227
+ });
228
+ }
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ export declare function AdCarbonInline(): React.JSX.Element;
3
+ export default function AdCarbon(): React.JSX.Element;
package/Ad/AdCarbon.js ADDED
@@ -0,0 +1,120 @@
1
+ var _AdCarbonImage;
2
+ import * as React from 'react';
3
+ import { styled } from '@mui/material/styles';
4
+ import loadScript from "../utils/loadScript.js";
5
+ import AdDisplay from "./AdDisplay.js";
6
+ import { adBodyImageStyles } from "./ad.styles.js";
7
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ const CarbonRoot = styled('span')(({
9
+ theme
10
+ }) => {
11
+ const styles = adBodyImageStyles(theme);
12
+ return {
13
+ width: '100%',
14
+ '& > div': {
15
+ // The isolation logic of carbonads is broken.
16
+ // Once the script starts loading, it will asynchronous resolve, with no way to stop it.
17
+ // This leads to duplication of the ad.
18
+ //
19
+ // To solve the issue, we only display the #carbonads div
20
+ display: 'none'
21
+ },
22
+ '& #carbonads': {
23
+ ...styles.root,
24
+ '& .carbon-img': styles.imgWrapper,
25
+ '& img': styles.img,
26
+ '& a, & a:hover': styles.a,
27
+ '& .carbon-text': styles.description,
28
+ '& .carbon-poweredby': styles.poweredby
29
+ }
30
+ };
31
+ });
32
+ function AdCarbonImage() {
33
+ const ref = React.useRef(null);
34
+ React.useEffect(() => {
35
+ // The isolation logic of carbonads is broken.
36
+ // Once the script starts loading, it will asynchronous resolve, with no way to stop it.
37
+ // This leads to duplication of the ad.
38
+ //
39
+ // To solve the issue, for example StrictModel double effect execution, we debounce the load action.
40
+ const load = setTimeout(() => {
41
+ const script = loadScript('https://cdn.carbonads.com/carbon.js?serve=CKYIL27L&placement=material-uicom', ref.current);
42
+ script.id = '_carbonads_js';
43
+ });
44
+ return () => {
45
+ clearTimeout(load);
46
+ };
47
+ }, []);
48
+ return /*#__PURE__*/_jsx(CarbonRoot, {
49
+ ref: ref
50
+ });
51
+ }
52
+ export function AdCarbonInline() {
53
+ const [ad, setAd] = React.useState(null);
54
+ React.useEffect(() => {
55
+ let active = true;
56
+ let attempt = 0;
57
+ (async () => {
58
+ async function tryFetch() {
59
+ if (attempt >= 10 || !active) {
60
+ return null;
61
+ }
62
+ attempt += 1;
63
+ let response;
64
+ try {
65
+ response = await fetch('https://srv.buysellads.com/ads/CE7DC23W.json');
66
+ } catch (err) {
67
+ // Ad blocker crashes this request
68
+ return null;
69
+ }
70
+ const data = await response.json();
71
+ // Inspired by https://github.com/Semantic-Org/Semantic-UI-React/blob/2c7134128925dd831de85011e3eb0ec382ba7f73/docs/src/components/CarbonAd/CarbonAdNative.js#L9
72
+ const sanitizedAd = data.ads.filter(item => Object.keys(item).length > 0).filter(item => item.statlink).filter(Boolean)[0];
73
+ if (!sanitizedAd) {
74
+ return tryFetch();
75
+ }
76
+ return sanitizedAd;
77
+ }
78
+ const sanitizedAd = await tryFetch();
79
+ if (active) {
80
+ setAd(sanitizedAd);
81
+ }
82
+ })();
83
+ return () => {
84
+ active = false;
85
+ };
86
+ }, []);
87
+ return ad ? /*#__PURE__*/_jsxs(React.Fragment, {
88
+ children: [/*#__PURE__*/_jsx("img", {
89
+ src: ad.statimp,
90
+ alt: "",
91
+ style: {
92
+ display: 'none'
93
+ }
94
+ }), ad.pixel && ad.pixel.split('||').map((pixel, i) => /*#__PURE__*/_jsx("img", {
95
+ src: `${pixel.replace('[timestamp]', ad.timestamp)}`,
96
+ style: {
97
+ display: 'none'
98
+ },
99
+ alt: ""
100
+ }, i)), /*#__PURE__*/_jsx(AdDisplay, {
101
+ className: "carbonads",
102
+ shape: "inline",
103
+ ad: {
104
+ link: ad.statlink,
105
+ img: ad.image,
106
+ name: ad.company,
107
+ description: `<strong>${ad.company}</strong> - ${ad.description}`,
108
+ poweredby: 'Carbon',
109
+ label: 'carbon-demo-inline'
110
+ }
111
+ })]
112
+ }) : /*#__PURE__*/_jsx("div", {
113
+ style: {
114
+ minHeight: 52
115
+ }
116
+ });
117
+ }
118
+ export default function AdCarbon() {
119
+ return _AdCarbonImage || (_AdCarbonImage = /*#__PURE__*/_jsx(AdCarbonImage, {}));
120
+ }
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ export interface AdParameters {
3
+ name: string;
4
+ link: string;
5
+ img?: string;
6
+ description: string;
7
+ poweredby: string;
8
+ label: string;
9
+ }
10
+ interface AdDisplayProps {
11
+ ad: AdParameters;
12
+ className?: string;
13
+ shape?: 'auto' | 'inline' | 'image';
14
+ }
15
+ export default function AdDisplay(props: AdDisplayProps): React.JSX.Element;
16
+ export {};
@@ -0,0 +1,89 @@
1
+ import * as React from 'react';
2
+ import { styled } from '@mui/material/styles';
3
+ import { useTranslate } from "../i18n/index.js";
4
+ import { adShape } from "./AdManager.js";
5
+ import { adBodyImageStyles, adBodyInlineStyles } from "./ad.styles.js";
6
+ import { useAdConfig } from "./AdProvider.js";
7
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ const InlineShape = styled('span')(({
9
+ theme
10
+ }) => {
11
+ const styles = adBodyInlineStyles(theme);
12
+ return {
13
+ ...styles.root,
14
+ '& img': styles.img,
15
+ '& a, & a:hover': styles.a,
16
+ '& .AdDisplay-imageWrapper': styles.imgWrapper,
17
+ '& .AdDisplay-description': styles.description,
18
+ '& .AdDisplay-poweredby': styles.poweredby
19
+ };
20
+ });
21
+ const ImageShape = styled('span')(({
22
+ theme
23
+ }) => {
24
+ const styles = adBodyImageStyles(theme);
25
+ return {
26
+ ...styles.root,
27
+ '& img': styles.img,
28
+ '& a, & a:hover': styles.a,
29
+ '& .AdDisplay-imageWrapper': styles.imgWrapper,
30
+ '& .AdDisplay-description': styles.description,
31
+ '& .AdDisplay-poweredby': styles.poweredby
32
+ };
33
+ });
34
+ export default function AdDisplay(props) {
35
+ const {
36
+ ad,
37
+ className,
38
+ shape: shapeProp = 'auto'
39
+ } = props;
40
+ const t = useTranslate();
41
+ const {
42
+ GADisplayRatio
43
+ } = useAdConfig();
44
+ React.useEffect(() => {
45
+ // Avoid an exceed on the Google Analytics quotas.
46
+ if (Math.random() > (GADisplayRatio ?? 0.1) || !ad.label) {
47
+ return;
48
+ }
49
+ window.gtag('event', 'ad', {
50
+ eventAction: 'display',
51
+ eventLabel: ad.label
52
+ });
53
+ }, [GADisplayRatio, ad.label]);
54
+ const shape = shapeProp === 'auto' ? adShape : shapeProp;
55
+ const Root = shape === 'image' ? ImageShape : InlineShape;
56
+
57
+ /* eslint-disable react/no-danger */
58
+ return /*#__PURE__*/_jsxs(Root, {
59
+ className: className,
60
+ children: [/*#__PURE__*/_jsxs("a", {
61
+ href: ad.link,
62
+ target: "_blank",
63
+ rel: "noopener sponsored",
64
+ ...(ad.label ? {
65
+ 'data-ga-event-category': 'ad',
66
+ 'data-ga-event-action': 'click',
67
+ 'data-ga-event-label': ad.label
68
+ } : {}),
69
+ children: [/*#__PURE__*/_jsx("span", {
70
+ className: "AdDisplay-imageWrapper",
71
+ children: /*#__PURE__*/_jsx("img", {
72
+ height: "100",
73
+ width: "130",
74
+ src: ad.img,
75
+ alt: ad.name
76
+ })
77
+ }), /*#__PURE__*/_jsx("span", {
78
+ className: "AdDisplay-description",
79
+ dangerouslySetInnerHTML: {
80
+ __html: ad.description
81
+ }
82
+ })]
83
+ }), /*#__PURE__*/_jsx("span", {
84
+ className: "AdDisplay-poweredby",
85
+ children: t('adPublisher').replace('{{publisher}}', ad.poweredby)
86
+ })]
87
+ });
88
+ /* eslint-enable react/no-danger */
89
+ }
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ export interface AdGuestProps {
3
+ /**
4
+ * The querySelector use to target the element which will include the ad.
5
+ */
6
+ classSelector?: string;
7
+ children?: React.ReactNode | undefined;
8
+ }
9
+ declare function AdGuest(props: AdGuestProps): React.JSX.Element | null;
10
+ export { AdGuest };
package/Ad/AdGuest.js ADDED
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import Portal from '@mui/material/Portal';
3
+ import { AdContext } from "./AdManager.js";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ function AdGuest(props) {
6
+ const {
7
+ classSelector = '.description',
8
+ children
9
+ } = props;
10
+ const ad = React.useContext(AdContext);
11
+ if (!ad.element) {
12
+ return null;
13
+ }
14
+ return /*#__PURE__*/_jsx(Portal, {
15
+ container: () => {
16
+ const element = document.querySelector(classSelector);
17
+ if (element) {
18
+ if (ad.element === element) {
19
+ element.classList.add('ad');
20
+ } else {
21
+ element.classList.remove('ad');
22
+ }
23
+ }
24
+ return ad.element;
25
+ },
26
+ children: children
27
+ });
28
+ }
29
+ export { AdGuest };
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ import { AdParameters } from './AdDisplay';
3
+ export default function AdInHouse(props: {
4
+ ad: Omit<AdParameters, 'poweredby' | 'label'>;
5
+ }): React.JSX.Element;
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+ import AdDisplay from "./AdDisplay.js";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ export default function AdInHouse(props) {
5
+ const {
6
+ ad
7
+ } = props;
8
+ return /*#__PURE__*/_jsx(AdDisplay, {
9
+ ad: {
10
+ poweredby: 'MUI',
11
+ label: `in-house-${ad.name}`,
12
+ ...ad
13
+ }
14
+ });
15
+ }
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ type AdPortal = {
3
+ placement: 'body-top';
4
+ element: Element | null;
5
+ };
6
+ interface AdManagerProps {
7
+ /**
8
+ * The querySelector use to target the element which will include the ad.
9
+ */
10
+ classSelector?: string;
11
+ children?: React.ReactNode | undefined;
12
+ }
13
+ export declare const AdContext: React.Context<AdPortal>;
14
+ export declare const adShape: string;
15
+ export declare function AdManager({ classSelector, children }: AdManagerProps): React.JSX.Element;
16
+ export {};
@@ -0,0 +1,36 @@
1
+ import * as React from 'react';
2
+ import { unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/material/utils';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ export const AdContext = /*#__PURE__*/React.createContext({
5
+ placement: 'body-top',
6
+ element: null
7
+ });
8
+
9
+ // Persisted for the whole session.
10
+ // The state is used to use different ad placements.
11
+ const randomSession = Math.random();
12
+
13
+ // Distribution profile:
14
+ // 20% body-inline
15
+ // 80% body-image
16
+ export const adShape = randomSession < 0.2 ? 'inline' : 'image';
17
+ export function AdManager({
18
+ classSelector = '.description',
19
+ children
20
+ }) {
21
+ const [portal, setPortal] = React.useState({
22
+ placement: 'body-top',
23
+ element: null
24
+ });
25
+ useEnhancedEffect(() => {
26
+ const container = document.querySelector(classSelector);
27
+ setPortal({
28
+ placement: 'body-top',
29
+ element: container
30
+ });
31
+ }, [classSelector]);
32
+ return /*#__PURE__*/_jsx(AdContext.Provider, {
33
+ value: portal,
34
+ children: children
35
+ });
36
+ }
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+ export interface AdConfig {
3
+ /**
4
+ * The ratio of "ad display" event sent to Google Analytics.
5
+ * Used to avoid an exceed on the Google Analytics quotas.
6
+ * @default 0.1
7
+ */
8
+ GADisplayRatio: number;
9
+ }
10
+ export interface AdProviderProps {
11
+ children: React.ReactNode;
12
+ config?: Partial<AdConfig>;
13
+ }
14
+ export declare function AdProvider(props: AdProviderProps): React.JSX.Element;
15
+ export declare function useAdConfig(): AdConfig;
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ const AdConfigContext = /*#__PURE__*/React.createContext(null);
4
+ export function AdProvider(props) {
5
+ const {
6
+ children,
7
+ config
8
+ } = props;
9
+ const value = React.useMemo(() => ({
10
+ GADisplayRatio: 0.1,
11
+ ...config
12
+ }), [config]);
13
+ return /*#__PURE__*/_jsx(AdConfigContext.Provider, {
14
+ value: value,
15
+ children: children
16
+ });
17
+ }
18
+ export function useAdConfig() {
19
+ const config = React.useContext(AdConfigContext);
20
+ if (!config) {
21
+ throw new Error('Could not find docs ad config context value; please ensure the component is wrapped in a <AdProvider>');
22
+ }
23
+ return config;
24
+ }