@docusaurus/theme-classic 0.0.0-4452 → 0.0.0-4458

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.
@@ -151,19 +151,13 @@ declare module '@theme/DocSidebar' {
151
151
  declare module '@theme/DocSidebarItem' {
152
152
  import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
153
153
 
154
- export type DocSidebarPropsBase = {
155
- readonly activePath: string;
156
- readonly onItemClick?: (item: PropSidebarItem) => void;
157
- readonly level: number;
158
- readonly tabIndex?: number;
159
- };
160
-
161
154
  export interface Props {
162
155
  readonly activePath: string;
163
156
  readonly onItemClick?: (item: PropSidebarItem) => void;
164
157
  readonly level: number;
165
158
  readonly tabIndex?: number;
166
159
  readonly item: PropSidebarItem;
160
+ readonly index: number;
167
161
  }
168
162
 
169
163
  export default function DocSidebarItem(props: Props): JSX.Element;
@@ -173,7 +167,7 @@ declare module '@theme/DocSidebarItems' {
173
167
  import type {Props as DocSidebarItemProps} from '@theme/DocSidebarItem';
174
168
  import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
175
169
 
176
- export type Props = Omit<DocSidebarItemProps, 'item'> & {
170
+ export type Props = Omit<DocSidebarItemProps, 'item' | 'index'> & {
177
171
  readonly items: readonly PropSidebarItem[];
178
172
  };
179
173
 
@@ -45,6 +45,7 @@ const DEFAULT_CONFIG = {
45
45
  items: []
46
46
  },
47
47
  hideableSidebar: false,
48
+ autoCollapseSidebarCategories: false,
48
49
  tableOfContents: {
49
50
  minHeadingLevel: 2,
50
51
  maxHeadingLevel: 3
@@ -288,6 +289,7 @@ const ThemeConfigSchema = _utilsValidation.Joi.object({
288
289
  additionalLanguages: _utilsValidation.Joi.array().items(_utilsValidation.Joi.string()).default(DEFAULT_CONFIG.prism.additionalLanguages)
289
290
  }).default(DEFAULT_CONFIG.prism).unknown(),
290
291
  hideableSidebar: _utilsValidation.Joi.bool().default(DEFAULT_CONFIG.hideableSidebar),
292
+ autoCollapseSidebarCategories: _utilsValidation.Joi.bool().default(DEFAULT_CONFIG.autoCollapseSidebarCategories),
291
293
  sidebarCollapsible: _utilsValidation.Joi.forbidden().messages({
292
294
  'any.unknown': 'The themeConfig.sidebarCollapsible has been moved to docs plugin options. See: https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs'
293
295
  }),
@@ -16,10 +16,20 @@ export default function BlogPostAuthors({authors, assets}) {
16
16
  return null;
17
17
  }
18
18
 
19
+ const imageOnly = authors.every(({name}) => !name);
19
20
  return (
20
- <div className="row margin-top--md margin-bottom--sm">
21
+ <div
22
+ className={clsx(
23
+ 'margin-top--md margin-bottom--sm',
24
+ imageOnly ? styles.imageOnlyAuthorRow : 'row',
25
+ )}>
21
26
  {authors.map((author, idx) => (
22
- <div className={clsx('col col--6', styles.authorCol)} key={idx}>
27
+ <div
28
+ className={clsx(
29
+ !imageOnly && 'col col--6',
30
+ imageOnly ? styles.imageOnlyAuthorCol : styles.authorCol,
31
+ )}
32
+ key={idx}>
23
33
  <BlogPostAuthor
24
34
  author={{
25
35
  ...author,
@@ -9,3 +9,14 @@
9
9
  max-width: inherit !important;
10
10
  flex-grow: 1 !important;
11
11
  }
12
+
13
+ .imageOnlyAuthorRow {
14
+ display: flex;
15
+ flex-direction: row;
16
+ flex-wrap: wrap;
17
+ }
18
+
19
+ .imageOnlyAuthorCol {
20
+ margin-left: 0.3rem;
21
+ margin-right: 0.3rem;
22
+ }
@@ -13,6 +13,8 @@ import {
13
13
  useCollapsible,
14
14
  findFirstCategoryLink,
15
15
  ThemeClassNames,
16
+ useThemeConfig,
17
+ useDocSidebarItemsExpandedState,
16
18
  } from '@docusaurus/theme-common';
17
19
  import Link from '@docusaurus/Link';
18
20
  import isInternalUrl from '@docusaurus/isInternalUrl';
@@ -72,12 +74,13 @@ function DocSidebarItemCategory({
72
74
  onItemClick,
73
75
  activePath,
74
76
  level,
77
+ index,
75
78
  ...props
76
79
  }) {
77
80
  const {items, label, collapsible, className, href} = item;
78
81
  const hrefWithSSRFallback = useCategoryHrefWithSSRFallback(item);
79
82
  const isActive = isActiveSidebarItem(item, activePath);
80
- const {collapsed, setCollapsed, toggleCollapsed} = useCollapsible({
83
+ const {collapsed, setCollapsed} = useCollapsible({
81
84
  // active categories are always initialized as expanded
82
85
  // the default (item.collapsed) is only used for non-active categories
83
86
  initialState: () => {
@@ -93,6 +96,30 @@ function DocSidebarItemCategory({
93
96
  collapsed,
94
97
  setCollapsed,
95
98
  });
99
+ const {expandedItem, setExpandedItem} = useDocSidebarItemsExpandedState();
100
+
101
+ function updateCollapsed(toCollapsed = !collapsed) {
102
+ setExpandedItem(toCollapsed ? null : index);
103
+ setCollapsed(toCollapsed);
104
+ }
105
+
106
+ const {autoCollapseSidebarCategories} = useThemeConfig();
107
+ useEffect(() => {
108
+ if (
109
+ collapsible &&
110
+ expandedItem &&
111
+ expandedItem !== index &&
112
+ autoCollapseSidebarCategories
113
+ ) {
114
+ setCollapsed(true);
115
+ }
116
+ }, [
117
+ collapsible,
118
+ expandedItem,
119
+ index,
120
+ setCollapsed,
121
+ autoCollapseSidebarCategories,
122
+ ]);
96
123
  return (
97
124
  <li
98
125
  className={clsx(
@@ -118,16 +145,17 @@ function DocSidebarItemCategory({
118
145
  onItemClick?.(item);
119
146
 
120
147
  if (href) {
121
- setCollapsed(false);
148
+ updateCollapsed(false);
122
149
  } else {
123
150
  e.preventDefault();
124
- toggleCollapsed();
151
+ updateCollapsed();
125
152
  }
126
153
  }
127
154
  : () => {
128
155
  onItemClick?.(item);
129
156
  }
130
157
  }
158
+ aria-current={isActive ? 'page' : undefined}
131
159
  href={collapsible ? hrefWithSSRFallback ?? '#' : hrefWithSSRFallback}
132
160
  {...props}>
133
161
  {label}
@@ -149,7 +177,7 @@ function DocSidebarItemCategory({
149
177
  className="clean-btn menu__caret"
150
178
  onClick={(e) => {
151
179
  e.preventDefault();
152
- toggleCollapsed();
180
+ updateCollapsed();
153
181
  }}
154
182
  />
155
183
  )}
@@ -168,7 +196,14 @@ function DocSidebarItemCategory({
168
196
  );
169
197
  }
170
198
 
171
- function DocSidebarItemLink({item, onItemClick, activePath, level, ...props}) {
199
+ function DocSidebarItemLink({
200
+ item,
201
+ onItemClick,
202
+ activePath,
203
+ level,
204
+ index,
205
+ ...props
206
+ }) {
172
207
  const {href, label, className} = item;
173
208
  const isActive = isActiveSidebarItem(item, activePath);
174
209
  return (
@@ -6,20 +6,22 @@
6
6
  */
7
7
  import React, {memo} from 'react';
8
8
  import DocSidebarItem from '@theme/DocSidebarItem';
9
+ import {DocSidebarItemsExpandedStateProvider} from '@docusaurus/theme-common';
9
10
 
10
11
  // TODO this item should probably not receive the "activePath" props
11
12
  // TODO this triggers whole sidebar re-renders on navigation
12
13
  function DocSidebarItems({items, ...props}) {
13
14
  return (
14
- <>
15
+ <DocSidebarItemsExpandedStateProvider>
15
16
  {items.map((item, index) => (
16
17
  <DocSidebarItem
17
18
  key={index} // sidebar is static, the index does not change
18
19
  item={item}
20
+ index={index}
19
21
  {...props}
20
22
  />
21
23
  ))}
22
- </>
24
+ </DocSidebarItemsExpandedStateProvider>
23
25
  );
24
26
  } // Optimize sidebar at each "level"
25
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/theme-classic",
3
- "version": "0.0.0-4452",
3
+ "version": "0.0.0-4458",
4
4
  "description": "Classic theme for Docusaurus",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/theme-classic.d.ts",
@@ -23,14 +23,14 @@
23
23
  "update-code-translations": "node -e 'require(\"./update-code-translations.js\").run()'"
24
24
  },
25
25
  "dependencies": {
26
- "@docusaurus/core": "0.0.0-4452",
27
- "@docusaurus/plugin-content-blog": "0.0.0-4452",
28
- "@docusaurus/plugin-content-docs": "0.0.0-4452",
29
- "@docusaurus/plugin-content-pages": "0.0.0-4452",
30
- "@docusaurus/theme-common": "0.0.0-4452",
31
- "@docusaurus/theme-translations": "0.0.0-4452",
32
- "@docusaurus/utils": "0.0.0-4452",
33
- "@docusaurus/utils-validation": "0.0.0-4452",
26
+ "@docusaurus/core": "0.0.0-4458",
27
+ "@docusaurus/plugin-content-blog": "0.0.0-4458",
28
+ "@docusaurus/plugin-content-docs": "0.0.0-4458",
29
+ "@docusaurus/plugin-content-pages": "0.0.0-4458",
30
+ "@docusaurus/theme-common": "0.0.0-4458",
31
+ "@docusaurus/theme-translations": "0.0.0-4458",
32
+ "@docusaurus/utils": "0.0.0-4458",
33
+ "@docusaurus/utils-validation": "0.0.0-4458",
34
34
  "@mdx-js/mdx": "^1.6.21",
35
35
  "@mdx-js/react": "^1.6.21",
36
36
  "clsx": "^1.1.1",
@@ -45,8 +45,8 @@
45
45
  "rtlcss": "^3.3.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@docusaurus/module-type-aliases": "0.0.0-4452",
49
- "@docusaurus/types": "0.0.0-4452",
48
+ "@docusaurus/module-type-aliases": "0.0.0-4458",
49
+ "@docusaurus/types": "0.0.0-4458",
50
50
  "@types/mdx-js__react": "^1.5.4",
51
51
  "@types/parse-numeric-range": "^0.0.1",
52
52
  "@types/rtlcss": "^3.1.1",
@@ -61,5 +61,5 @@
61
61
  "engines": {
62
62
  "node": ">=14"
63
63
  },
64
- "gitHead": "48cae5712e0a40d5f7e5c2669edcf2de8ae2533f"
64
+ "gitHead": "38e7bfd3584608cf9d5b3c3d15f431efe755cd28"
65
65
  }
@@ -21,10 +21,20 @@ export default function BlogPostAuthors({
21
21
  if (authorsCount === 0) {
22
22
  return null;
23
23
  }
24
+ const imageOnly = authors.every(({name}) => !name);
24
25
  return (
25
- <div className="row margin-top--md margin-bottom--sm">
26
+ <div
27
+ className={clsx(
28
+ 'margin-top--md margin-bottom--sm',
29
+ imageOnly ? styles.imageOnlyAuthorRow : 'row',
30
+ )}>
26
31
  {authors.map((author, idx) => (
27
- <div className={clsx('col col--6', styles.authorCol)} key={idx}>
32
+ <div
33
+ className={clsx(
34
+ !imageOnly && 'col col--6',
35
+ imageOnly ? styles.imageOnlyAuthorCol : styles.authorCol,
36
+ )}
37
+ key={idx}>
28
38
  <BlogPostAuthor
29
39
  author={{
30
40
  ...author,
@@ -9,3 +9,14 @@
9
9
  max-width: inherit !important;
10
10
  flex-grow: 1 !important;
11
11
  }
12
+
13
+ .imageOnlyAuthorRow {
14
+ display: flex;
15
+ flex-direction: row;
16
+ flex-wrap: wrap;
17
+ }
18
+
19
+ .imageOnlyAuthorCol {
20
+ margin-left: 0.3rem;
21
+ margin-right: 0.3rem;
22
+ }
@@ -14,6 +14,8 @@ import {
14
14
  useCollapsible,
15
15
  findFirstCategoryLink,
16
16
  ThemeClassNames,
17
+ useThemeConfig,
18
+ useDocSidebarItemsExpandedState,
17
19
  } from '@docusaurus/theme-common';
18
20
  import Link from '@docusaurus/Link';
19
21
  import isInternalUrl from '@docusaurus/isInternalUrl';
@@ -92,6 +94,7 @@ function DocSidebarItemCategory({
92
94
  onItemClick,
93
95
  activePath,
94
96
  level,
97
+ index,
95
98
  ...props
96
99
  }: Props & {item: PropSidebarItemCategory}) {
97
100
  const {items, label, collapsible, className, href} = item;
@@ -99,7 +102,7 @@ function DocSidebarItemCategory({
99
102
 
100
103
  const isActive = isActiveSidebarItem(item, activePath);
101
104
 
102
- const {collapsed, setCollapsed, toggleCollapsed} = useCollapsible({
105
+ const {collapsed, setCollapsed} = useCollapsible({
103
106
  // active categories are always initialized as expanded
104
107
  // the default (item.collapsed) is only used for non-active categories
105
108
  initialState: () => {
@@ -111,6 +114,28 @@ function DocSidebarItemCategory({
111
114
  });
112
115
 
113
116
  useAutoExpandActiveCategory({isActive, collapsed, setCollapsed});
117
+ const {expandedItem, setExpandedItem} = useDocSidebarItemsExpandedState();
118
+ function updateCollapsed(toCollapsed: boolean = !collapsed) {
119
+ setExpandedItem(toCollapsed ? null : index);
120
+ setCollapsed(toCollapsed);
121
+ }
122
+ const {autoCollapseSidebarCategories} = useThemeConfig();
123
+ useEffect(() => {
124
+ if (
125
+ collapsible &&
126
+ expandedItem &&
127
+ expandedItem !== index &&
128
+ autoCollapseSidebarCategories
129
+ ) {
130
+ setCollapsed(true);
131
+ }
132
+ }, [
133
+ collapsible,
134
+ expandedItem,
135
+ index,
136
+ setCollapsed,
137
+ autoCollapseSidebarCategories,
138
+ ]);
114
139
 
115
140
  return (
116
141
  <li
@@ -136,16 +161,17 @@ function DocSidebarItemCategory({
136
161
  ? (e) => {
137
162
  onItemClick?.(item);
138
163
  if (href) {
139
- setCollapsed(false);
164
+ updateCollapsed(false);
140
165
  } else {
141
166
  e.preventDefault();
142
- toggleCollapsed();
167
+ updateCollapsed();
143
168
  }
144
169
  }
145
170
  : () => {
146
171
  onItemClick?.(item);
147
172
  }
148
173
  }
174
+ aria-current={isActive ? 'page' : undefined}
149
175
  href={collapsible ? hrefWithSSRFallback ?? '#' : hrefWithSSRFallback}
150
176
  {...props}>
151
177
  {label}
@@ -165,7 +191,7 @@ function DocSidebarItemCategory({
165
191
  className="clean-btn menu__caret"
166
192
  onClick={(e) => {
167
193
  e.preventDefault();
168
- toggleCollapsed();
194
+ updateCollapsed();
169
195
  }}
170
196
  />
171
197
  )}
@@ -189,6 +215,7 @@ function DocSidebarItemLink({
189
215
  onItemClick,
190
216
  activePath,
191
217
  level,
218
+ index,
192
219
  ...props
193
220
  }: Props & {item: PropSidebarItemLink}) {
194
221
  const {href, label, className} = item;
@@ -6,8 +6,8 @@
6
6
  */
7
7
 
8
8
  import React, {memo} from 'react';
9
-
10
9
  import DocSidebarItem from '@theme/DocSidebarItem';
10
+ import {DocSidebarItemsExpandedStateProvider} from '@docusaurus/theme-common';
11
11
 
12
12
  import type {Props} from '@theme/DocSidebarItems';
13
13
 
@@ -15,15 +15,16 @@ import type {Props} from '@theme/DocSidebarItems';
15
15
  // TODO this triggers whole sidebar re-renders on navigation
16
16
  function DocSidebarItems({items, ...props}: Props): JSX.Element {
17
17
  return (
18
- <>
18
+ <DocSidebarItemsExpandedStateProvider>
19
19
  {items.map((item, index) => (
20
20
  <DocSidebarItem
21
21
  key={index} // sidebar is static, the index does not change
22
22
  item={item}
23
+ index={index}
23
24
  {...props}
24
25
  />
25
26
  ))}
26
- </>
27
+ </DocSidebarItemsExpandedStateProvider>
27
28
  );
28
29
  }
29
30
 
@@ -151,19 +151,13 @@ declare module '@theme/DocSidebar' {
151
151
  declare module '@theme/DocSidebarItem' {
152
152
  import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
153
153
 
154
- export type DocSidebarPropsBase = {
155
- readonly activePath: string;
156
- readonly onItemClick?: (item: PropSidebarItem) => void;
157
- readonly level: number;
158
- readonly tabIndex?: number;
159
- };
160
-
161
154
  export interface Props {
162
155
  readonly activePath: string;
163
156
  readonly onItemClick?: (item: PropSidebarItem) => void;
164
157
  readonly level: number;
165
158
  readonly tabIndex?: number;
166
159
  readonly item: PropSidebarItem;
160
+ readonly index: number;
167
161
  }
168
162
 
169
163
  export default function DocSidebarItem(props: Props): JSX.Element;
@@ -173,7 +167,7 @@ declare module '@theme/DocSidebarItems' {
173
167
  import type {Props as DocSidebarItemProps} from '@theme/DocSidebarItem';
174
168
  import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
175
169
 
176
- export type Props = Omit<DocSidebarItemProps, 'item'> & {
170
+ export type Props = Omit<DocSidebarItemProps, 'item' | 'index'> & {
177
171
  readonly items: readonly PropSidebarItem[];
178
172
  };
179
173
 
@@ -41,6 +41,7 @@ const DEFAULT_CONFIG = {
41
41
  items: [],
42
42
  },
43
43
  hideableSidebar: false,
44
+ autoCollapseSidebarCategories: false,
44
45
  tableOfContents: {
45
46
  minHeadingLevel: 2,
46
47
  maxHeadingLevel: 3,
@@ -352,6 +353,9 @@ const ThemeConfigSchema = Joi.object({
352
353
  .default(DEFAULT_CONFIG.prism)
353
354
  .unknown(),
354
355
  hideableSidebar: Joi.bool().default(DEFAULT_CONFIG.hideableSidebar),
356
+ autoCollapseSidebarCategories: Joi.bool().default(
357
+ DEFAULT_CONFIG.autoCollapseSidebarCategories,
358
+ ),
355
359
  sidebarCollapsible: Joi.forbidden().messages({
356
360
  'any.unknown':
357
361
  'The themeConfig.sidebarCollapsible has been moved to docs plugin options. See: https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs',