@docusaurus/theme-common 2.0.0-beta.18 → 2.0.0-beta.19

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 (128) hide show
  1. package/Details.d.ts +14 -0
  2. package/lib/components/Collapsible/index.js +2 -2
  3. package/lib/components/Collapsible/index.js.map +1 -1
  4. package/lib/components/Details/index.d.ts.map +1 -1
  5. package/lib/components/Details/index.js +3 -2
  6. package/lib/components/Details/index.js.map +1 -1
  7. package/lib/components/Details/styles.module.css +4 -0
  8. package/lib/contexts/announcementBar.js +1 -1
  9. package/lib/contexts/colorMode.d.ts.map +1 -1
  10. package/lib/contexts/colorMode.js +34 -16
  11. package/lib/contexts/colorMode.js.map +1 -1
  12. package/lib/contexts/docsPreferredVersion.d.ts +5 -2
  13. package/lib/contexts/docsPreferredVersion.d.ts.map +1 -1
  14. package/lib/contexts/docsPreferredVersion.js +5 -2
  15. package/lib/contexts/docsPreferredVersion.js.map +1 -1
  16. package/lib/contexts/docsSidebar.d.ts +9 -3
  17. package/lib/contexts/docsSidebar.d.ts.map +1 -1
  18. package/lib/contexts/docsSidebar.js +7 -6
  19. package/lib/contexts/docsSidebar.js.map +1 -1
  20. package/lib/contexts/navbarMobileSidebar.js +5 -5
  21. package/lib/contexts/navbarMobileSidebar.js.map +1 -1
  22. package/lib/contexts/{navbarSecondaryMenu.d.ts → navbarSecondaryMenu/content.d.ts} +13 -14
  23. package/lib/contexts/navbarSecondaryMenu/content.d.ts.map +1 -0
  24. package/lib/contexts/navbarSecondaryMenu/content.js +56 -0
  25. package/lib/contexts/navbarSecondaryMenu/content.js.map +1 -0
  26. package/lib/contexts/navbarSecondaryMenu/display.d.ts +24 -0
  27. package/lib/contexts/navbarSecondaryMenu/display.d.ts.map +1 -0
  28. package/lib/contexts/navbarSecondaryMenu/display.js +62 -0
  29. package/lib/contexts/navbarSecondaryMenu/display.js.map +1 -0
  30. package/lib/contexts/tabGroupChoice.d.ts.map +1 -1
  31. package/lib/contexts/tabGroupChoice.js.map +1 -1
  32. package/lib/hooks/useBackToTopButton.d.ts +27 -0
  33. package/lib/hooks/useBackToTopButton.d.ts.map +1 -0
  34. package/lib/hooks/useBackToTopButton.js +50 -0
  35. package/lib/hooks/useBackToTopButton.js.map +1 -0
  36. package/lib/hooks/useCodeWordWrap.d.ts +14 -0
  37. package/lib/hooks/useCodeWordWrap.d.ts.map +1 -0
  38. package/lib/hooks/useCodeWordWrap.js +41 -0
  39. package/lib/hooks/useCodeWordWrap.js.map +1 -0
  40. package/lib/hooks/useHideableNavbar.d.ts.map +1 -1
  41. package/lib/hooks/useHideableNavbar.js +1 -2
  42. package/lib/hooks/useHideableNavbar.js.map +1 -1
  43. package/lib/hooks/usePrismTheme.d.ts +2 -2
  44. package/lib/hooks/usePrismTheme.d.ts.map +1 -1
  45. package/lib/hooks/usePrismTheme.js +1 -2
  46. package/lib/hooks/usePrismTheme.js.map +1 -1
  47. package/lib/hooks/useSkipToContent.d.ts +25 -0
  48. package/lib/hooks/useSkipToContent.d.ts.map +1 -0
  49. package/lib/hooks/useSkipToContent.js +35 -0
  50. package/lib/hooks/useSkipToContent.js.map +1 -0
  51. package/lib/hooks/useTOCHighlight.js +3 -3
  52. package/lib/hooks/useTOCHighlight.js.map +1 -1
  53. package/lib/index.d.ts +9 -6
  54. package/lib/index.d.ts.map +1 -1
  55. package/lib/index.js +8 -5
  56. package/lib/index.js.map +1 -1
  57. package/lib/utils/codeBlockUtils.d.ts +42 -12
  58. package/lib/utils/codeBlockUtils.d.ts.map +1 -1
  59. package/lib/utils/codeBlockUtils.js +89 -58
  60. package/lib/utils/codeBlockUtils.js.map +1 -1
  61. package/lib/utils/docsUtils.d.ts +58 -0
  62. package/lib/utils/docsUtils.d.ts.map +1 -1
  63. package/lib/utils/docsUtils.js +109 -10
  64. package/lib/utils/docsUtils.js.map +1 -1
  65. package/lib/utils/metadataUtils.d.ts +2 -2
  66. package/lib/utils/metadataUtils.d.ts.map +1 -1
  67. package/lib/utils/navbarUtils.d.ts +2 -2
  68. package/lib/utils/navbarUtils.d.ts.map +1 -1
  69. package/lib/utils/navbarUtils.js +7 -5
  70. package/lib/utils/navbarUtils.js.map +1 -1
  71. package/lib/utils/routesUtils.d.ts +4 -4
  72. package/lib/utils/routesUtils.d.ts.map +1 -1
  73. package/lib/utils/routesUtils.js.map +1 -1
  74. package/lib/utils/scrollUtils.d.ts +24 -0
  75. package/lib/utils/scrollUtils.d.ts.map +1 -1
  76. package/lib/utils/scrollUtils.js +52 -0
  77. package/lib/utils/scrollUtils.js.map +1 -1
  78. package/lib/utils/searchUtils.d.ts.map +1 -1
  79. package/lib/utils/searchUtils.js +2 -0
  80. package/lib/utils/searchUtils.js.map +1 -1
  81. package/lib/utils/storageUtils.d.ts +2 -2
  82. package/lib/utils/storageUtils.d.ts.map +1 -1
  83. package/lib/utils/tagsUtils.d.ts +3 -7
  84. package/lib/utils/tagsUtils.d.ts.map +1 -1
  85. package/lib/utils/tagsUtils.js +2 -2
  86. package/lib/utils/tagsUtils.js.map +1 -1
  87. package/lib/utils/tocUtils.d.ts +2 -2
  88. package/lib/utils/tocUtils.d.ts.map +1 -1
  89. package/lib/utils/tocUtils.js +4 -4
  90. package/lib/utils/tocUtils.js.map +1 -1
  91. package/lib/utils/useThemeConfig.d.ts +7 -4
  92. package/lib/utils/useThemeConfig.d.ts.map +1 -1
  93. package/lib/utils/useThemeConfig.js.map +1 -1
  94. package/package.json +18 -10
  95. package/src/components/Collapsible/index.tsx +2 -2
  96. package/src/components/Details/index.tsx +4 -2
  97. package/src/components/Details/styles.module.css +4 -0
  98. package/src/contexts/announcementBar.tsx +1 -1
  99. package/src/contexts/colorMode.tsx +38 -15
  100. package/src/contexts/docsPreferredVersion.tsx +5 -2
  101. package/src/contexts/docsSidebar.tsx +17 -9
  102. package/src/contexts/navbarMobileSidebar.tsx +5 -5
  103. package/src/contexts/navbarSecondaryMenu/content.tsx +110 -0
  104. package/src/contexts/navbarSecondaryMenu/display.tsx +102 -0
  105. package/src/contexts/tabGroupChoice.tsx +6 -3
  106. package/src/hooks/useBackToTopButton.ts +73 -0
  107. package/src/hooks/useCodeWordWrap.ts +56 -0
  108. package/src/hooks/useHideableNavbar.ts +1 -3
  109. package/src/hooks/usePrismTheme.ts +3 -3
  110. package/src/hooks/useSkipToContent.ts +58 -0
  111. package/src/hooks/useTOCHighlight.ts +3 -3
  112. package/src/index.ts +12 -5
  113. package/src/utils/codeBlockUtils.ts +150 -66
  114. package/src/utils/docsUtils.tsx +163 -9
  115. package/src/utils/metadataUtils.tsx +2 -2
  116. package/src/utils/navbarUtils.tsx +11 -6
  117. package/src/utils/routesUtils.ts +7 -7
  118. package/src/utils/scrollUtils.tsx +74 -0
  119. package/src/utils/searchUtils.ts +2 -0
  120. package/src/utils/storageUtils.ts +2 -2
  121. package/src/utils/tagsUtils.ts +4 -9
  122. package/src/utils/tocUtils.ts +5 -5
  123. package/src/utils/useThemeConfig.ts +7 -4
  124. package/yarn-error.log +20199 -0
  125. package/lib/contexts/navbarSecondaryMenu.d.ts.map +0 -1
  126. package/lib/contexts/navbarSecondaryMenu.js +0 -93
  127. package/lib/contexts/navbarSecondaryMenu.js.map +0 -1
  128. package/src/contexts/navbarSecondaryMenu.tsx +0 -170
@@ -1 +0,0 @@
1
- {"version":3,"file":"navbarSecondaryMenu.d.ts","sourceRoot":"","sources":["../../src/contexts/navbarSecondaryMenu.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAMZ,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAIf,oBAAY,4BAA4B,CAAC,KAAK,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;AA0DvE,wBAAgB,2BAA2B,CAAC,EAC1C,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CAGd;AAmBD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,MAAM,EAAE,EAC1D,SAAS,EACT,KAAK,GACN,EAAE;IACD,SAAS,EAAE,4BAA4B,CAAC,CAAC,CAAC,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC;CACV,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAiBrB;AAUD,sEAAsE;AACtE,wBAAgB,sBAAsB,IAAI;IACxC,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,mEAAmE;IACnE,OAAO,EAAE,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC;CAClC,CAYA"}
@@ -1,93 +0,0 @@
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, { useState, useContext, useEffect, useMemo, useCallback, } from 'react';
8
- import { ReactContextError, usePrevious } from '../utils/reactUtils';
9
- import { useNavbarMobileSidebar } from './navbarMobileSidebar';
10
- const InitialState = {
11
- shown: false,
12
- content: { component: null, props: null },
13
- };
14
- const Context = React.createContext(null);
15
- function useContextValue() {
16
- const mobileSidebar = useNavbarMobileSidebar();
17
- const [state, setState] = useState(InitialState);
18
- const setShown = (shown) => setState((s) => ({ ...s, shown }));
19
- const hasContent = state.content?.component !== null;
20
- const previousHasContent = usePrevious(state.content?.component !== null);
21
- // When content is become available for the first time (set in useEffect)
22
- // we set this content to be shown!
23
- useEffect(() => {
24
- const contentBecameAvailable = hasContent && !previousHasContent;
25
- if (contentBecameAvailable) {
26
- setShown(true);
27
- }
28
- }, [hasContent, previousHasContent]);
29
- // On sidebar close, secondary menu is set to be shown on next re-opening
30
- // (if any secondary menu content available)
31
- useEffect(() => {
32
- if (!hasContent) {
33
- setShown(false);
34
- return;
35
- }
36
- if (!mobileSidebar.shown) {
37
- setShown(true);
38
- }
39
- }, [mobileSidebar.shown, hasContent]);
40
- return [state, setState];
41
- }
42
- export function NavbarSecondaryMenuProvider({ children, }) {
43
- const value = useContextValue();
44
- return React.createElement(Context.Provider, { value: value }, children);
45
- }
46
- function useNavbarSecondaryMenuContext() {
47
- const value = useContext(Context);
48
- if (value === null) {
49
- throw new ReactContextError('MobileSecondaryMenuProvider');
50
- }
51
- return value;
52
- }
53
- function useShallowMemoizedObject(obj) {
54
- return useMemo(() => obj,
55
- // Is this safe?
56
- // eslint-disable-next-line react-hooks/exhaustive-deps
57
- [...Object.keys(obj), ...Object.values(obj)]);
58
- }
59
- /**
60
- * This component renders nothing by itself, but it fills the placeholder in the
61
- * generic secondary menu layout. This reduces coupling between the main layout
62
- * and the specific page.
63
- *
64
- * This kind of feature is often called portal/teleport/gateway/outlet...
65
- * Various unmaintained React libs exist. Most up-to-date one:
66
- * https://github.com/gregberge/react-teleporter
67
- * Not sure any of those is safe regarding concurrent mode.
68
- */
69
- export function NavbarSecondaryMenuFiller({ component, props, }) {
70
- const [, setState] = useNavbarSecondaryMenuContext();
71
- // To avoid useless context re-renders, props are memoized shallowly
72
- const memoizedProps = useShallowMemoizedObject(props);
73
- useEffect(() => {
74
- // @ts-expect-error: context is not 100% type-safe but it's ok
75
- setState((s) => ({ ...s, content: { component, props: memoizedProps } }));
76
- }, [setState, component, memoizedProps]);
77
- useEffect(() => () => setState((s) => ({ ...s, component: null, props: null })), [setState]);
78
- return null;
79
- }
80
- function renderElement(state) {
81
- if (state.content?.component) {
82
- const Comp = state.content.component;
83
- return React.createElement(Comp, { ...state.content.props });
84
- }
85
- return undefined;
86
- }
87
- /** Wires the logic for rendering the mobile navbar secondary menu. */
88
- export function useNavbarSecondaryMenu() {
89
- const [state, setState] = useNavbarSecondaryMenuContext();
90
- const hide = useCallback(() => setState((s) => ({ ...s, shown: false })), [setState]);
91
- return useMemo(() => ({ shown: state.shown, hide, content: renderElement(state) }), [hide, state]);
92
- }
93
- //# sourceMappingURL=navbarSecondaryMenu.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navbarSecondaryMenu.js","sourceRoot":"","sources":["../../src/contexts/navbarSecondaryMenu.tsx"],"names":[],"mappings":"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"}
@@ -1,170 +0,0 @@
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
-
8
- import React, {
9
- useState,
10
- useContext,
11
- useEffect,
12
- useMemo,
13
- useCallback,
14
- type ReactNode,
15
- type ComponentType,
16
- } from 'react';
17
- import {ReactContextError, usePrevious} from '../utils/reactUtils';
18
- import {useNavbarMobileSidebar} from './navbarMobileSidebar';
19
-
20
- export type NavbarSecondaryMenuComponent<Props> = ComponentType<Props>;
21
-
22
- type State = {
23
- shown: boolean;
24
- content:
25
- | {
26
- component: NavbarSecondaryMenuComponent<object>;
27
- props: object;
28
- }
29
- | {component: null; props: null};
30
- };
31
-
32
- const InitialState: State = {
33
- shown: false,
34
- content: {component: null, props: null},
35
- };
36
-
37
- type ContextValue = [
38
- state: State,
39
- setState: React.Dispatch<React.SetStateAction<State>>,
40
- ];
41
-
42
- const Context = React.createContext<ContextValue | null>(null);
43
-
44
- function useContextValue(): ContextValue {
45
- const mobileSidebar = useNavbarMobileSidebar();
46
-
47
- const [state, setState] = useState<State>(InitialState);
48
-
49
- const setShown = (shown: boolean) => setState((s) => ({...s, shown}));
50
-
51
- const hasContent = state.content?.component !== null;
52
- const previousHasContent = usePrevious(state.content?.component !== null);
53
-
54
- // When content is become available for the first time (set in useEffect)
55
- // we set this content to be shown!
56
- useEffect(() => {
57
- const contentBecameAvailable = hasContent && !previousHasContent;
58
- if (contentBecameAvailable) {
59
- setShown(true);
60
- }
61
- }, [hasContent, previousHasContent]);
62
-
63
- // On sidebar close, secondary menu is set to be shown on next re-opening
64
- // (if any secondary menu content available)
65
- useEffect(() => {
66
- if (!hasContent) {
67
- setShown(false);
68
- return;
69
- }
70
- if (!mobileSidebar.shown) {
71
- setShown(true);
72
- }
73
- }, [mobileSidebar.shown, hasContent]);
74
-
75
- return [state, setState];
76
- }
77
-
78
- export function NavbarSecondaryMenuProvider({
79
- children,
80
- }: {
81
- children: ReactNode;
82
- }): JSX.Element {
83
- const value = useContextValue();
84
- return <Context.Provider value={value}>{children}</Context.Provider>;
85
- }
86
-
87
- function useNavbarSecondaryMenuContext(): ContextValue {
88
- const value = useContext(Context);
89
- if (value === null) {
90
- throw new ReactContextError('MobileSecondaryMenuProvider');
91
- }
92
- return value;
93
- }
94
-
95
- function useShallowMemoizedObject<O>(obj: O) {
96
- return useMemo(
97
- () => obj,
98
- // Is this safe?
99
- // eslint-disable-next-line react-hooks/exhaustive-deps
100
- [...Object.keys(obj), ...Object.values(obj)],
101
- );
102
- }
103
-
104
- /**
105
- * This component renders nothing by itself, but it fills the placeholder in the
106
- * generic secondary menu layout. This reduces coupling between the main layout
107
- * and the specific page.
108
- *
109
- * This kind of feature is often called portal/teleport/gateway/outlet...
110
- * Various unmaintained React libs exist. Most up-to-date one:
111
- * https://github.com/gregberge/react-teleporter
112
- * Not sure any of those is safe regarding concurrent mode.
113
- */
114
- export function NavbarSecondaryMenuFiller<P extends object>({
115
- component,
116
- props,
117
- }: {
118
- component: NavbarSecondaryMenuComponent<P>;
119
- props: P;
120
- }): JSX.Element | null {
121
- const [, setState] = useNavbarSecondaryMenuContext();
122
-
123
- // To avoid useless context re-renders, props are memoized shallowly
124
- const memoizedProps = useShallowMemoizedObject(props);
125
-
126
- useEffect(() => {
127
- // @ts-expect-error: context is not 100% type-safe but it's ok
128
- setState((s) => ({...s, content: {component, props: memoizedProps}}));
129
- }, [setState, component, memoizedProps]);
130
-
131
- useEffect(
132
- () => () => setState((s) => ({...s, component: null, props: null})),
133
- [setState],
134
- );
135
-
136
- return null;
137
- }
138
-
139
- function renderElement(state: State): JSX.Element | undefined {
140
- if (state.content?.component) {
141
- const Comp = state.content.component;
142
- return <Comp {...state.content.props} />;
143
- }
144
- return undefined;
145
- }
146
-
147
- /** Wires the logic for rendering the mobile navbar secondary menu. */
148
- export function useNavbarSecondaryMenu(): {
149
- /** Whether secondary menu is displayed. */
150
- shown: boolean;
151
- /**
152
- * Hide the secondary menu; fired either when hiding the entire sidebar, or
153
- * when going back to the primary menu.
154
- */
155
- hide: () => void;
156
- /** The content returned from the current secondary menu filler. */
157
- content: JSX.Element | undefined;
158
- } {
159
- const [state, setState] = useNavbarSecondaryMenuContext();
160
-
161
- const hide = useCallback(
162
- () => setState((s) => ({...s, shown: false})),
163
- [setState],
164
- );
165
-
166
- return useMemo(
167
- () => ({shown: state.shown, hide, content: renderElement(state)}),
168
- [hide, state],
169
- );
170
- }