@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.
@@ -40,12 +40,60 @@ function getSwizzleConfig() {
40
40
  },
41
41
  Footer: {
42
42
  actions: {
43
- eject: 'unsafe',
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',
@@ -205,7 +205,7 @@ declare module '@theme/DocSidebar/Desktop/Content' {
205
205
  readonly sidebar: readonly PropSidebarItem[];
206
206
  }
207
207
 
208
- export default function CollapseButton(props: Props): JSX.Element;
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
+ }
@@ -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 useBaseUrl, {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
12
- import isInternalUrl from '@docusaurus/isInternalUrl';
13
- import styles from './styles.module.css';
14
- import ThemedImage from '@theme/ThemedImage';
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
- <footer
143
- className={clsx('footer', {
144
- 'footer--dark': footer.style === 'dark',
145
- })}>
146
- <div className="container container-fluid">
147
- {links &&
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
- (React.isValidElement(el) && inlineElements.includes(el.props.mdxType)),
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
- test('Should reject bad Tabs child', () => {
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
- test('Should reject bad Tabs defaultValue', () => {
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
- test('Should reject duplicate values', () => {
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
- test('Should accept valid Tabs config', () => {
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
- test('Should accept dynamic Tabs with number values', () => {
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, Children, isValidElement} from 'react';
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