@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.
- package/Ad/Ad.d.ts +6 -0
- package/Ad/Ad.js +228 -0
- package/Ad/AdCarbon.d.ts +3 -0
- package/Ad/AdCarbon.js +120 -0
- package/Ad/AdDisplay.d.ts +16 -0
- package/Ad/AdDisplay.js +89 -0
- package/Ad/AdGuest.d.ts +10 -0
- package/Ad/AdGuest.js +29 -0
- package/Ad/AdInHouse.d.ts +5 -0
- package/Ad/AdInHouse.js +15 -0
- package/Ad/AdManager.d.ts +16 -0
- package/Ad/AdManager.js +36 -0
- package/Ad/AdProvider.d.ts +15 -0
- package/Ad/AdProvider.js +24 -0
- package/Ad/ad.styles.d.ts +4327 -0
- package/Ad/ad.styles.js +89 -0
- package/Ad/index.d.ts +5 -0
- package/Ad/index.js +7 -0
- package/Ad/package.json +6 -0
- package/CHANGELOG.md +1367 -22
- package/CodeCopy/CodeCopy.js +1 -1
- package/CodeCopy/CodeCopyButton.js +11 -20
- package/CodeCopy/index.js +3 -3
- package/CodeCopy/useClipboardCopy.js +1 -1
- package/ComponentLinkHeader/ComponentLinkHeader.d.ts +9 -0
- package/ComponentLinkHeader/ComponentLinkHeader.js +197 -0
- package/ComponentLinkHeader/index.d.ts +2 -0
- package/ComponentLinkHeader/index.js +2 -0
- package/ComponentLinkHeader/package.json +6 -0
- package/DocsProvider/DocsProvider.d.ts +3 -1
- package/DocsProvider/DocsProvider.js +10 -5
- package/DocsProvider/index.js +1 -1
- package/HighlightedCode/HighlightedCode.d.ts +3 -1
- package/HighlightedCode/HighlightedCode.js +50 -24
- package/HighlightedCode/index.js +1 -1
- package/HighlightedCodeWithTabs/HighlightedCodeWithTabs.d.ts +29 -0
- package/HighlightedCodeWithTabs/HighlightedCodeWithTabs.js +355 -0
- package/HighlightedCodeWithTabs/index.d.ts +2 -0
- package/HighlightedCodeWithTabs/index.js +2 -0
- package/HighlightedCodeWithTabs/package.json +6 -0
- package/InfoCard/InfoCard.d.ts +0 -1
- package/InfoCard/InfoCard.js +46 -45
- package/InfoCard/index.js +1 -1
- package/Link/Link.js +41 -41
- package/Link/index.js +1 -1
- package/MarkdownElement/MarkdownElement.d.ts +1 -0
- package/MarkdownElement/MarkdownElement.js +187 -165
- package/MarkdownElement/index.js +1 -1
- package/NProgressBar/NProgressBar.js +6 -7
- package/NProgressBar/index.js +1 -1
- package/README.md +2 -2
- package/SectionTitle/SectionTitle.d.ts +7 -0
- package/SectionTitle/SectionTitle.js +30 -0
- package/SectionTitle/index.d.ts +1 -0
- package/SectionTitle/index.js +1 -0
- package/SectionTitle/package.json +6 -0
- package/branding/BrandingProvider.d.ts +1 -1
- package/branding/BrandingProvider.js +1 -1
- package/branding/brandingTheme.d.ts +2 -2
- package/branding/brandingTheme.js +657 -369
- package/branding/index.js +2 -2
- package/i18n/i18n.d.ts +2 -1
- package/i18n/i18n.js +19 -9
- package/i18n/index.js +1 -1
- package/node/Ad/Ad.js +238 -0
- package/node/Ad/AdCarbon.js +130 -0
- package/node/Ad/AdDisplay.js +97 -0
- package/node/Ad/AdGuest.js +37 -0
- package/node/Ad/AdInHouse.js +24 -0
- package/node/Ad/AdManager.js +46 -0
- package/node/Ad/AdProvider.js +33 -0
- package/node/Ad/ad.styles.js +97 -0
- package/node/Ad/index.js +63 -0
- package/node/CodeCopy/CodeCopy.js +10 -16
- package/node/CodeCopy/CodeCopyButton.js +10 -19
- package/node/CodeCopy/useClipboardCopy.js +1 -1
- package/node/ComponentLinkHeader/ComponentLinkHeader.js +206 -0
- package/node/ComponentLinkHeader/index.js +24 -0
- package/node/DocsProvider/DocsProvider.js +9 -4
- package/node/HighlightedCode/HighlightedCode.js +48 -22
- package/node/HighlightedCodeWithTabs/HighlightedCodeWithTabs.js +365 -0
- package/node/HighlightedCodeWithTabs/index.js +24 -0
- package/node/InfoCard/InfoCard.js +45 -44
- package/node/Link/Link.js +43 -42
- package/node/MarkdownElement/MarkdownElement.js +642 -623
- package/node/NProgressBar/NProgressBar.js +6 -7
- package/node/SectionTitle/SectionTitle.js +38 -0
- package/node/SectionTitle/index.js +16 -0
- package/node/branding/brandingTheme.js +657 -369
- package/node/i18n/i18n.js +18 -8
- package/node/svgIcons/AdobeXDIcon.js +22 -0
- package/node/svgIcons/BundleSizeIcon.js +22 -0
- package/node/svgIcons/FigmaIcon.js +31 -0
- package/node/svgIcons/FileDownload.js +3 -3
- package/node/svgIcons/JavaScript.js +3 -3
- package/node/svgIcons/MaterialDesignIcon.js +27 -0
- package/node/svgIcons/SketchIcon.js +36 -0
- package/node/svgIcons/TypeScript.js +3 -3
- package/node/svgIcons/W3CIcon.js +24 -0
- package/node/translations/translations.json +9 -4
- package/node/utils/loadScript.js +15 -0
- package/package.json +12 -10
- package/svgIcons/AdobeXDIcon.d.ts +4 -0
- package/svgIcons/AdobeXDIcon.js +14 -0
- package/svgIcons/BundleSizeIcon.d.ts +4 -0
- package/svgIcons/BundleSizeIcon.js +14 -0
- package/svgIcons/FigmaIcon.d.ts +4 -0
- package/svgIcons/FigmaIcon.js +23 -0
- package/svgIcons/FileDownload.d.ts +7 -0
- package/svgIcons/FileDownload.js +3 -3
- package/svgIcons/JavaScript.d.ts +7 -0
- package/svgIcons/JavaScript.js +3 -3
- package/svgIcons/MaterialDesignIcon.d.ts +4 -0
- package/svgIcons/MaterialDesignIcon.js +19 -0
- package/svgIcons/SketchIcon.d.ts +4 -0
- package/svgIcons/SketchIcon.js +28 -0
- package/svgIcons/TypeScript.d.ts +7 -0
- package/svgIcons/TypeScript.js +3 -3
- package/svgIcons/W3CIcon.d.ts +4 -0
- package/svgIcons/W3CIcon.js +16 -0
- package/translations/index.js +1 -1
- package/translations/translations.json +9 -4
- package/tsconfig.build.tsbuildinfo +1 -1
- package/utils/loadScript.d.ts +1 -0
- package/utils/loadScript.js +9 -0
package/Ad/Ad.d.ts
ADDED
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
|
+
}
|
package/Ad/AdCarbon.d.ts
ADDED
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 {};
|
package/Ad/AdDisplay.js
ADDED
|
@@ -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
|
+
}
|
package/Ad/AdGuest.d.ts
ADDED
|
@@ -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 };
|
package/Ad/AdInHouse.js
ADDED
|
@@ -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 {};
|
package/Ad/AdManager.js
ADDED
|
@@ -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;
|
package/Ad/AdProvider.js
ADDED
|
@@ -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
|
+
}
|