@docusaurus/theme-classic 0.0.0-4707 → 0.0.0-4710
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/lib/getSwizzleConfig.js +50 -2
- package/lib/theme-classic.d.ts +72 -1
- package/lib-next/theme/Footer/Copyright/index.js +18 -0
- package/lib-next/theme/Footer/Layout/index.js +26 -0
- package/lib-next/theme/Footer/LinkItem/index.js +35 -0
- package/lib-next/theme/Footer/Links/MultiColumn/index.js +47 -0
- package/lib-next/theme/Footer/Links/Simple/index.js +41 -0
- package/lib-next/theme/Footer/Links/index.js +17 -0
- package/lib-next/theme/Footer/Logo/index.js +38 -0
- package/lib-next/theme/Footer/{styles.module.css → Logo/styles.module.css} +0 -0
- package/lib-next/theme/Footer/index.js +11 -156
- package/lib-next/theme/MDXComponents/index.js +1 -1
- package/lib-next/theme/Tabs/__tests__/index.test.js +5 -5
- package/lib-next/theme/Tabs/index.js +2 -2
- package/package.json +13 -13
- package/src/getSwizzleConfig.ts +52 -1
- package/src/theme/Footer/Copyright/index.tsx +22 -0
- package/src/theme/Footer/Layout/index.tsx +34 -0
- package/src/theme/Footer/LinkItem/index.tsx +38 -0
- package/src/theme/Footer/Links/MultiColumn/index.tsx +53 -0
- package/src/theme/Footer/Links/Simple/index.tsx +44 -0
- package/src/theme/Footer/Links/index.tsx +21 -0
- package/src/theme/Footer/Logo/index.tsx +41 -0
- package/src/theme/Footer/{styles.module.css → Logo/styles.module.css} +0 -0
- package/src/theme/Footer/index.tsx +12 -170
- package/src/theme/MDXComponents/index.tsx +2 -2
- package/src/theme/Tabs/index.tsx +1 -2
- package/src/theme-classic.d.ts +72 -1
package/lib/getSwizzleConfig.js
CHANGED
|
@@ -40,12 +40,60 @@ function getSwizzleConfig() {
|
|
|
40
40
|
},
|
|
41
41
|
Footer: {
|
|
42
42
|
actions: {
|
|
43
|
-
eject: '
|
|
44
|
-
// TODO split footer into smaller parts
|
|
43
|
+
eject: 'safe',
|
|
45
44
|
wrap: 'safe'
|
|
46
45
|
},
|
|
47
46
|
description: "The footer component of you site's layout"
|
|
48
47
|
},
|
|
48
|
+
'Footer/Copyright': {
|
|
49
|
+
actions: {
|
|
50
|
+
eject: 'safe',
|
|
51
|
+
wrap: 'safe'
|
|
52
|
+
},
|
|
53
|
+
description: 'The footer copyright'
|
|
54
|
+
},
|
|
55
|
+
'Footer/Layout': {
|
|
56
|
+
actions: {
|
|
57
|
+
eject: 'safe',
|
|
58
|
+
wrap: 'safe'
|
|
59
|
+
},
|
|
60
|
+
description: 'The footer main layout component'
|
|
61
|
+
},
|
|
62
|
+
'Footer/LinkItem': {
|
|
63
|
+
actions: {
|
|
64
|
+
eject: 'safe',
|
|
65
|
+
wrap: 'safe'
|
|
66
|
+
},
|
|
67
|
+
description: 'The footer link item component'
|
|
68
|
+
},
|
|
69
|
+
'Footer/Links': {
|
|
70
|
+
actions: {
|
|
71
|
+
eject: 'safe',
|
|
72
|
+
wrap: 'safe'
|
|
73
|
+
},
|
|
74
|
+
description: 'The footer component rendering the footer links'
|
|
75
|
+
},
|
|
76
|
+
'Footer/Links/MultiColumn': {
|
|
77
|
+
actions: {
|
|
78
|
+
eject: 'safe',
|
|
79
|
+
wrap: 'safe'
|
|
80
|
+
},
|
|
81
|
+
description: 'The footer component rendering the footer links with a multi-column layout'
|
|
82
|
+
},
|
|
83
|
+
'Footer/Links/Simple': {
|
|
84
|
+
actions: {
|
|
85
|
+
eject: 'safe',
|
|
86
|
+
wrap: 'safe'
|
|
87
|
+
},
|
|
88
|
+
description: 'The footer component rendering the footer links with a simple layout (single row)'
|
|
89
|
+
},
|
|
90
|
+
'Footer/Logo': {
|
|
91
|
+
actions: {
|
|
92
|
+
eject: 'safe',
|
|
93
|
+
wrap: 'safe'
|
|
94
|
+
},
|
|
95
|
+
description: 'The footer logo'
|
|
96
|
+
},
|
|
49
97
|
IconArrow: {
|
|
50
98
|
actions: {
|
|
51
99
|
eject: 'safe',
|
package/lib/theme-classic.d.ts
CHANGED
|
@@ -205,7 +205,7 @@ declare module '@theme/DocSidebar/Desktop/Content' {
|
|
|
205
205
|
readonly sidebar: readonly PropSidebarItem[];
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
export default function
|
|
208
|
+
export default function Content(props: Props): JSX.Element;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
declare module '@theme/DocSidebar/Desktop/CollapseButton' {
|
|
@@ -280,6 +280,77 @@ declare module '@theme/Footer' {
|
|
|
280
280
|
export default function Footer(): JSX.Element | null;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
+
declare module '@theme/Footer/Logo' {
|
|
284
|
+
import type {FooterLogo} from '@docusaurus/theme-common';
|
|
285
|
+
|
|
286
|
+
export interface Props {
|
|
287
|
+
logo: FooterLogo;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export default function FooterLogo(props: Props): JSX.Element;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
declare module '@theme/Footer/Copyright' {
|
|
294
|
+
export interface Props {
|
|
295
|
+
copyright: string;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export default function FooterCopyright(props: Props): JSX.Element;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
declare module '@theme/Footer/LinkItem' {
|
|
302
|
+
import type {FooterLinkItem} from '@docusaurus/theme-common';
|
|
303
|
+
|
|
304
|
+
export interface Props {
|
|
305
|
+
item: FooterLinkItem;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export default function FooterLinkItem(props: Props): JSX.Element;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
declare module '@theme/Footer/Layout' {
|
|
312
|
+
import type {ReactNode} from 'react';
|
|
313
|
+
|
|
314
|
+
export interface Props {
|
|
315
|
+
style: 'light' | 'dark';
|
|
316
|
+
links: ReactNode;
|
|
317
|
+
logo: ReactNode;
|
|
318
|
+
copyright: ReactNode;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export default function FooterLayout(props: Props): JSX.Element;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
declare module '@theme/Footer/Links' {
|
|
325
|
+
import type {Footer} from '@docusaurus/theme-common';
|
|
326
|
+
|
|
327
|
+
export interface Props {
|
|
328
|
+
links: Footer['links'];
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export default function FooterLinks(props: Props): JSX.Element;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
declare module '@theme/Footer/Links/MultiColumn' {
|
|
335
|
+
import type {MultiColumnFooter} from '@docusaurus/theme-common';
|
|
336
|
+
|
|
337
|
+
export interface Props {
|
|
338
|
+
columns: MultiColumnFooter['links'];
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export default function FooterLinksMultiColumn(props: Props): JSX.Element;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
declare module '@theme/Footer/Links/Simple' {
|
|
345
|
+
import type {SimpleFooter} from '@docusaurus/theme-common';
|
|
346
|
+
|
|
347
|
+
export interface Props {
|
|
348
|
+
links: SimpleFooter['links'];
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export default function FooterLinksSimple(props: Props): JSX.Element;
|
|
352
|
+
}
|
|
353
|
+
|
|
283
354
|
declare module '@theme/Heading' {
|
|
284
355
|
import type {ComponentProps} from 'react';
|
|
285
356
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
export default function FooterCopyright({copyright}) {
|
|
9
|
+
return (
|
|
10
|
+
<div
|
|
11
|
+
className="footer__copyright" // Developer provided the HTML, so assume it's safe.
|
|
12
|
+
// eslint-disable-next-line react/no-danger
|
|
13
|
+
dangerouslySetInnerHTML={{
|
|
14
|
+
__html: copyright,
|
|
15
|
+
}}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
export default function FooterLayout({style, links, logo, copyright}) {
|
|
10
|
+
return (
|
|
11
|
+
<footer
|
|
12
|
+
className={clsx('footer', {
|
|
13
|
+
'footer--dark': style === 'dark',
|
|
14
|
+
})}>
|
|
15
|
+
<div className="container container-fluid">
|
|
16
|
+
{links}
|
|
17
|
+
{(logo || copyright) && (
|
|
18
|
+
<div className="footer__bottom text--center">
|
|
19
|
+
{logo && <div className="margin-bottom--sm">{logo}</div>}
|
|
20
|
+
{copyright}
|
|
21
|
+
</div>
|
|
22
|
+
)}
|
|
23
|
+
</div>
|
|
24
|
+
</footer>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import Link from '@docusaurus/Link';
|
|
9
|
+
import useBaseUrl from '@docusaurus/useBaseUrl';
|
|
10
|
+
import isInternalUrl from '@docusaurus/isInternalUrl';
|
|
11
|
+
import IconExternalLink from '@theme/IconExternalLink';
|
|
12
|
+
export default function FooterLinkItem({item}) {
|
|
13
|
+
const {to, href, label, prependBaseUrlToHref, ...props} = item;
|
|
14
|
+
const toUrl = useBaseUrl(to);
|
|
15
|
+
const normalizedHref = useBaseUrl(href, {
|
|
16
|
+
forcePrependBaseUrl: true,
|
|
17
|
+
});
|
|
18
|
+
return (
|
|
19
|
+
<Link
|
|
20
|
+
className="footer__link-item"
|
|
21
|
+
{...(href
|
|
22
|
+
? {
|
|
23
|
+
href: prependBaseUrlToHref ? normalizedHref : href,
|
|
24
|
+
}
|
|
25
|
+
: {
|
|
26
|
+
to: toUrl,
|
|
27
|
+
})}
|
|
28
|
+
{...props}>
|
|
29
|
+
<span>
|
|
30
|
+
{label}
|
|
31
|
+
{href && !isInternalUrl(href) && <IconExternalLink />}
|
|
32
|
+
</span>
|
|
33
|
+
</Link>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import LinkItem from '@theme/Footer/LinkItem';
|
|
9
|
+
|
|
10
|
+
function ColumnLinkItem({item}) {
|
|
11
|
+
return item.html ? (
|
|
12
|
+
<li
|
|
13
|
+
className="footer__item" // Developer provided the HTML, so assume it's safe.
|
|
14
|
+
// eslint-disable-next-line react/no-danger
|
|
15
|
+
dangerouslySetInnerHTML={{
|
|
16
|
+
__html: item.html,
|
|
17
|
+
}}
|
|
18
|
+
/>
|
|
19
|
+
) : (
|
|
20
|
+
<li key={item.href || item.to} className="footer__item">
|
|
21
|
+
<LinkItem item={item} />
|
|
22
|
+
</li>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function Column({column}) {
|
|
27
|
+
return (
|
|
28
|
+
<div className="col footer__col">
|
|
29
|
+
<div className="footer__title">{column.title}</div>
|
|
30
|
+
<ul className="footer__items">
|
|
31
|
+
{column.items.map((item, i) => (
|
|
32
|
+
<ColumnLinkItem key={i} item={item} />
|
|
33
|
+
))}
|
|
34
|
+
</ul>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default function FooterLinksMultiColumn({columns}) {
|
|
40
|
+
return (
|
|
41
|
+
<div className="row footer__links">
|
|
42
|
+
{columns.map((column, i) => (
|
|
43
|
+
<Column key={i} column={column} />
|
|
44
|
+
))}
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import LinkItem from '@theme/Footer/LinkItem';
|
|
9
|
+
|
|
10
|
+
function Separator() {
|
|
11
|
+
return <span className="footer__link-separator">·</span>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function SimpleLinkItem({item}) {
|
|
15
|
+
return item.html ? (
|
|
16
|
+
<span
|
|
17
|
+
className="footer__link-item" // Developer provided the HTML, so assume it's safe.
|
|
18
|
+
// eslint-disable-next-line react/no-danger
|
|
19
|
+
dangerouslySetInnerHTML={{
|
|
20
|
+
__html: item.html,
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
23
|
+
) : (
|
|
24
|
+
<LinkItem item={item} />
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default function FooterLinksSimple({links}) {
|
|
29
|
+
return (
|
|
30
|
+
<div className="footer__links text--center">
|
|
31
|
+
<div className="footer__links">
|
|
32
|
+
{links.map((item, i) => (
|
|
33
|
+
<React.Fragment key={i}>
|
|
34
|
+
<SimpleLinkItem item={item} />
|
|
35
|
+
{links.length !== i + 1 && <Separator />}
|
|
36
|
+
</React.Fragment>
|
|
37
|
+
))}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import {isMultiColumnFooterLinks} from '@docusaurus/theme-common';
|
|
9
|
+
import FooterLinksMultiColumn from '@theme/Footer/Links/MultiColumn';
|
|
10
|
+
import FooterLinksSimple from '@theme/Footer/Links/Simple';
|
|
11
|
+
export default function FooterLinks({links}) {
|
|
12
|
+
return isMultiColumnFooterLinks(links) ? (
|
|
13
|
+
<FooterLinksMultiColumn columns={links} />
|
|
14
|
+
) : (
|
|
15
|
+
<FooterLinksSimple links={links} />
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import Link from '@docusaurus/Link';
|
|
9
|
+
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
|
|
10
|
+
import styles from './styles.module.css';
|
|
11
|
+
import ThemedImage from '@theme/ThemedImage';
|
|
12
|
+
|
|
13
|
+
function LogoImage({logo}) {
|
|
14
|
+
const {withBaseUrl} = useBaseUrlUtils();
|
|
15
|
+
const sources = {
|
|
16
|
+
light: withBaseUrl(logo.src),
|
|
17
|
+
dark: withBaseUrl(logo.srcDark ?? logo.src),
|
|
18
|
+
};
|
|
19
|
+
return (
|
|
20
|
+
<ThemedImage
|
|
21
|
+
className="footer__logo"
|
|
22
|
+
alt={logo.alt}
|
|
23
|
+
sources={sources}
|
|
24
|
+
width={logo.width}
|
|
25
|
+
height={logo.height}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default function FooterLogo({logo}) {
|
|
31
|
+
return logo.href ? (
|
|
32
|
+
<Link href={logo.href} className={styles.footerLogoLink}>
|
|
33
|
+
<LogoImage logo={logo} />
|
|
34
|
+
</Link>
|
|
35
|
+
) : (
|
|
36
|
+
<LogoImage logo={logo} />
|
|
37
|
+
);
|
|
38
|
+
}
|
|
File without changes
|
|
@@ -5,130 +5,11 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
-
import clsx from 'clsx';
|
|
9
|
-
import Link from '@docusaurus/Link';
|
|
10
8
|
import {useThemeConfig} from '@docusaurus/theme-common';
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import IconExternalLink from '@theme/IconExternalLink';
|
|
16
|
-
|
|
17
|
-
function FooterLink({to, href, label, prependBaseUrlToHref, ...props}) {
|
|
18
|
-
const toUrl = useBaseUrl(to);
|
|
19
|
-
const normalizedHref = useBaseUrl(href, {
|
|
20
|
-
forcePrependBaseUrl: true,
|
|
21
|
-
});
|
|
22
|
-
return (
|
|
23
|
-
<Link
|
|
24
|
-
className="footer__link-item"
|
|
25
|
-
{...(href
|
|
26
|
-
? {
|
|
27
|
-
href: prependBaseUrlToHref ? normalizedHref : href,
|
|
28
|
-
}
|
|
29
|
-
: {
|
|
30
|
-
to: toUrl,
|
|
31
|
-
})}
|
|
32
|
-
{...props}>
|
|
33
|
-
<span>
|
|
34
|
-
{label}
|
|
35
|
-
{href && !isInternalUrl(href) && <IconExternalLink />}
|
|
36
|
-
</span>
|
|
37
|
-
</Link>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function FooterLogo({logo}) {
|
|
42
|
-
const {withBaseUrl} = useBaseUrlUtils();
|
|
43
|
-
|
|
44
|
-
if (!logo?.src) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const sources = {
|
|
49
|
-
light: withBaseUrl(logo.src),
|
|
50
|
-
dark: withBaseUrl(logo.srcDark ?? logo.src),
|
|
51
|
-
};
|
|
52
|
-
const image = (
|
|
53
|
-
<ThemedImage
|
|
54
|
-
className="footer__logo"
|
|
55
|
-
alt={logo.alt}
|
|
56
|
-
sources={sources}
|
|
57
|
-
width={logo.width}
|
|
58
|
-
height={logo.height}
|
|
59
|
-
/>
|
|
60
|
-
);
|
|
61
|
-
return (
|
|
62
|
-
<div className="margin-bottom--sm">
|
|
63
|
-
{logo.href ? (
|
|
64
|
-
<Link href={logo.href} className={styles.footerLogoLink}>
|
|
65
|
-
{image}
|
|
66
|
-
</Link>
|
|
67
|
-
) : (
|
|
68
|
-
image
|
|
69
|
-
)}
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function MultiColumnLinks({links}) {
|
|
75
|
-
return (
|
|
76
|
-
<>
|
|
77
|
-
{links.map((linkItem, i) => (
|
|
78
|
-
<div key={i} className="col footer__col">
|
|
79
|
-
<div className="footer__title">{linkItem.title}</div>
|
|
80
|
-
<ul className="footer__items">
|
|
81
|
-
{linkItem.items.map((item, key) =>
|
|
82
|
-
item.html ? (
|
|
83
|
-
<li
|
|
84
|
-
key={key}
|
|
85
|
-
className="footer__item" // Developer provided the HTML, so assume it's safe.
|
|
86
|
-
// eslint-disable-next-line react/no-danger
|
|
87
|
-
dangerouslySetInnerHTML={{
|
|
88
|
-
__html: item.html,
|
|
89
|
-
}}
|
|
90
|
-
/>
|
|
91
|
-
) : (
|
|
92
|
-
<li key={item.href || item.to} className="footer__item">
|
|
93
|
-
<FooterLink {...item} />
|
|
94
|
-
</li>
|
|
95
|
-
),
|
|
96
|
-
)}
|
|
97
|
-
</ul>
|
|
98
|
-
</div>
|
|
99
|
-
))}
|
|
100
|
-
</>
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function SimpleLinks({links}) {
|
|
105
|
-
return (
|
|
106
|
-
<div className="footer__links">
|
|
107
|
-
{links.map((item, key) => (
|
|
108
|
-
<React.Fragment key={key}>
|
|
109
|
-
{item.html ? (
|
|
110
|
-
<span
|
|
111
|
-
className="footer__link-item" // Developer provided the HTML, so assume it's safe.
|
|
112
|
-
// eslint-disable-next-line react/no-danger
|
|
113
|
-
dangerouslySetInnerHTML={{
|
|
114
|
-
__html: item.html,
|
|
115
|
-
}}
|
|
116
|
-
/>
|
|
117
|
-
) : (
|
|
118
|
-
<FooterLink {...item} />
|
|
119
|
-
)}
|
|
120
|
-
{links.length !== key + 1 && (
|
|
121
|
-
<span className="footer__link-separator">·</span>
|
|
122
|
-
)}
|
|
123
|
-
</React.Fragment>
|
|
124
|
-
))}
|
|
125
|
-
</div>
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function isMultiColumnFooterLinks(links) {
|
|
130
|
-
return 'title' in links[0];
|
|
131
|
-
}
|
|
9
|
+
import FooterLinks from '@theme/Footer/Links';
|
|
10
|
+
import FooterLogo from '@theme/Footer/Logo';
|
|
11
|
+
import FooterCopyright from '@theme/Footer/Copyright';
|
|
12
|
+
import FooterLayout from '@theme/Footer/Layout';
|
|
132
13
|
|
|
133
14
|
function Footer() {
|
|
134
15
|
const {footer} = useThemeConfig();
|
|
@@ -137,40 +18,14 @@ function Footer() {
|
|
|
137
18
|
return null;
|
|
138
19
|
}
|
|
139
20
|
|
|
140
|
-
const {copyright, links, logo} = footer;
|
|
21
|
+
const {copyright, links, logo, style} = footer;
|
|
141
22
|
return (
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
<
|
|
147
|
-
|
|
148
|
-
links.length > 0 &&
|
|
149
|
-
(isMultiColumnFooterLinks(links) ? (
|
|
150
|
-
<div className="row footer__links">
|
|
151
|
-
<MultiColumnLinks links={links} />
|
|
152
|
-
</div>
|
|
153
|
-
) : (
|
|
154
|
-
<div className="footer__links text--center">
|
|
155
|
-
<SimpleLinks links={links} />
|
|
156
|
-
</div>
|
|
157
|
-
))}
|
|
158
|
-
{(logo || copyright) && (
|
|
159
|
-
<div className="footer__bottom text--center">
|
|
160
|
-
<FooterLogo logo={logo} />
|
|
161
|
-
{copyright && (
|
|
162
|
-
<div
|
|
163
|
-
className="footer__copyright" // Developer provided the HTML, so assume it's safe.
|
|
164
|
-
// eslint-disable-next-line react/no-danger
|
|
165
|
-
dangerouslySetInnerHTML={{
|
|
166
|
-
__html: copyright,
|
|
167
|
-
}}
|
|
168
|
-
/>
|
|
169
|
-
)}
|
|
170
|
-
</div>
|
|
171
|
-
)}
|
|
172
|
-
</div>
|
|
173
|
-
</footer>
|
|
23
|
+
<FooterLayout
|
|
24
|
+
style={style}
|
|
25
|
+
links={links && links.length > 0 && <FooterLinks links={links} />}
|
|
26
|
+
logo={logo && <FooterLogo logo={logo} />}
|
|
27
|
+
copyright={copyright && <FooterCopyright copyright={copyright} />}
|
|
28
|
+
/>
|
|
174
29
|
);
|
|
175
30
|
}
|
|
176
31
|
|
|
@@ -45,7 +45,7 @@ const MDXComponents = {
|
|
|
45
45
|
const shouldBeInline = React.Children.toArray(props.children).every(
|
|
46
46
|
(el) =>
|
|
47
47
|
(typeof el === 'string' && !el.includes('\n')) ||
|
|
48
|
-
(
|
|
48
|
+
(isValidElement(el) && inlineElements.includes(el.props.mdxType)),
|
|
49
49
|
);
|
|
50
50
|
return shouldBeInline ? <code {...props} /> : <CodeBlock {...props} />;
|
|
51
51
|
},
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
ScrollControllerProvider,
|
|
14
14
|
} from '@docusaurus/theme-common';
|
|
15
15
|
describe('Tabs', () => {
|
|
16
|
-
|
|
16
|
+
it('rejects bad Tabs child', () => {
|
|
17
17
|
expect(() => {
|
|
18
18
|
renderer.create(
|
|
19
19
|
<Tabs>
|
|
@@ -25,7 +25,7 @@ describe('Tabs', () => {
|
|
|
25
25
|
`"Docusaurus error: Bad <Tabs> child <div>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique \\"value\\" prop."`,
|
|
26
26
|
);
|
|
27
27
|
});
|
|
28
|
-
|
|
28
|
+
it('rejects bad Tabs defaultValue', () => {
|
|
29
29
|
expect(() => {
|
|
30
30
|
renderer.create(
|
|
31
31
|
<Tabs defaultValue="bad">
|
|
@@ -37,7 +37,7 @@ describe('Tabs', () => {
|
|
|
37
37
|
`"Docusaurus error: The <Tabs> has a defaultValue \\"bad\\" but none of its children has the corresponding value. Available values are: v1, v2. If you intend to show no default tab, use defaultValue={null} instead."`,
|
|
38
38
|
);
|
|
39
39
|
});
|
|
40
|
-
|
|
40
|
+
it('rejects duplicate values', () => {
|
|
41
41
|
expect(() => {
|
|
42
42
|
renderer.create(
|
|
43
43
|
<Tabs>
|
|
@@ -53,7 +53,7 @@ describe('Tabs', () => {
|
|
|
53
53
|
`"Docusaurus error: Duplicate values \\"v1, v2\\" found in <Tabs>. Every value needs to be unique."`,
|
|
54
54
|
);
|
|
55
55
|
});
|
|
56
|
-
|
|
56
|
+
it('accepts valid Tabs config', () => {
|
|
57
57
|
expect(() => {
|
|
58
58
|
renderer.create(
|
|
59
59
|
<ScrollControllerProvider>
|
|
@@ -120,7 +120,7 @@ describe('Tabs', () => {
|
|
|
120
120
|
}).not.toThrow(); // TODO Better Jest infrastructure to mock the Layout
|
|
121
121
|
}); // https://github.com/facebook/docusaurus/issues/5729
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
it('accepts dynamic Tabs with number values', () => {
|
|
124
124
|
expect(() => {
|
|
125
125
|
const tabs = ['Apple', 'Banana', 'Carrot'];
|
|
126
126
|
renderer.create(
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React, {useState, cloneElement,
|
|
7
|
+
import React, {useState, cloneElement, isValidElement} from 'react';
|
|
8
8
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
9
9
|
import {
|
|
10
10
|
useScrollPositionBlocker,
|
|
@@ -28,7 +28,7 @@ function TabsComponent(props) {
|
|
|
28
28
|
groupId,
|
|
29
29
|
className,
|
|
30
30
|
} = props;
|
|
31
|
-
const children = Children.map(props.children, (child) => {
|
|
31
|
+
const children = React.Children.map(props.children, (child) => {
|
|
32
32
|
if (isValidElement(child) && isTabItem(child)) {
|
|
33
33
|
return child;
|
|
34
34
|
} // child.type.name will give non-sensical values in prod because of
|