@docusaurus/theme-common 0.0.0-4523 → 0.0.0-4527

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 (73) hide show
  1. package/lib/components/Collapsible/index.d.ts.map +1 -1
  2. package/lib/components/Collapsible/index.js +9 -5
  3. package/lib/components/Collapsible/index.js.map +1 -1
  4. package/lib/components/Details/index.js +1 -1
  5. package/lib/components/Details/index.js.map +1 -1
  6. package/lib/hooks/useWindowSize.d.ts.map +1 -1
  7. package/lib/hooks/useWindowSize.js +4 -2
  8. package/lib/hooks/useWindowSize.js.map +1 -1
  9. package/lib/utils/ThemeClassNames.d.ts.map +1 -1
  10. package/lib/utils/ThemeClassNames.js +2 -1
  11. package/lib/utils/ThemeClassNames.js.map +1 -1
  12. package/lib/utils/codeBlockUtils.d.ts.map +1 -1
  13. package/lib/utils/codeBlockUtils.js +5 -4
  14. package/lib/utils/codeBlockUtils.js.map +1 -1
  15. package/lib/utils/docsPreferredVersion/DocsPreferredVersionProvider.d.ts.map +1 -1
  16. package/lib/utils/docsPreferredVersion/DocsPreferredVersionProvider.js +3 -7
  17. package/lib/utils/docsPreferredVersion/DocsPreferredVersionProvider.js.map +1 -1
  18. package/lib/utils/docsUtils.d.ts.map +1 -1
  19. package/lib/utils/docsUtils.js +4 -6
  20. package/lib/utils/docsUtils.js.map +1 -1
  21. package/lib/utils/historyUtils.d.ts +11 -0
  22. package/lib/utils/historyUtils.d.ts.map +1 -1
  23. package/lib/utils/historyUtils.js +9 -8
  24. package/lib/utils/historyUtils.js.map +1 -1
  25. package/lib/utils/jsUtils.d.ts +5 -2
  26. package/lib/utils/jsUtils.d.ts.map +1 -1
  27. package/lib/utils/jsUtils.js +5 -2
  28. package/lib/utils/jsUtils.js.map +1 -1
  29. package/lib/utils/mobileSecondaryMenu.d.ts.map +1 -1
  30. package/lib/utils/mobileSecondaryMenu.js.map +1 -1
  31. package/lib/utils/reactUtils.d.ts +18 -0
  32. package/lib/utils/reactUtils.d.ts.map +1 -1
  33. package/lib/utils/reactUtils.js +20 -11
  34. package/lib/utils/reactUtils.js.map +1 -1
  35. package/lib/utils/regexpUtils.d.ts +1 -1
  36. package/lib/utils/regexpUtils.js +1 -1
  37. package/lib/utils/storageUtils.d.ts +4 -4
  38. package/lib/utils/storageUtils.d.ts.map +1 -1
  39. package/lib/utils/storageUtils.js +12 -14
  40. package/lib/utils/storageUtils.js.map +1 -1
  41. package/lib/utils/tocUtils.d.ts.map +1 -1
  42. package/lib/utils/tocUtils.js +1 -3
  43. package/lib/utils/tocUtils.js.map +1 -1
  44. package/lib/utils/useAlternatePageUtils.d.ts.map +1 -1
  45. package/lib/utils/useAlternatePageUtils.js +2 -1
  46. package/lib/utils/useAlternatePageUtils.js.map +1 -1
  47. package/lib/utils/useContextualSearchFilters.js +2 -2
  48. package/lib/utils/useContextualSearchFilters.js.map +1 -1
  49. package/lib/utils/usePluralForm.d.ts.map +1 -1
  50. package/lib/utils/usePluralForm.js +25 -20
  51. package/lib/utils/usePluralForm.js.map +1 -1
  52. package/lib/utils/useTOCHighlight.d.ts.map +1 -1
  53. package/lib/utils/useTOCHighlight.js +20 -17
  54. package/lib/utils/useTOCHighlight.js.map +1 -1
  55. package/package.json +8 -8
  56. package/src/components/Collapsible/index.tsx +14 -9
  57. package/src/components/Details/index.tsx +1 -1
  58. package/src/hooks/useWindowSize.ts +4 -2
  59. package/src/utils/ThemeClassNames.ts +2 -1
  60. package/src/utils/codeBlockUtils.ts +5 -4
  61. package/src/utils/docsPreferredVersion/DocsPreferredVersionProvider.tsx +3 -5
  62. package/src/utils/docsUtils.tsx +5 -6
  63. package/src/utils/historyUtils.ts +9 -8
  64. package/src/utils/jsUtils.ts +5 -2
  65. package/src/utils/mobileSecondaryMenu.tsx +6 -5
  66. package/src/utils/reactUtils.tsx +20 -11
  67. package/src/utils/regexpUtils.ts +1 -1
  68. package/src/utils/storageUtils.ts +12 -13
  69. package/src/utils/tocUtils.ts +1 -2
  70. package/src/utils/useAlternatePageUtils.ts +4 -3
  71. package/src/utils/useContextualSearchFilters.ts +2 -2
  72. package/src/utils/usePluralForm.ts +28 -22
  73. package/src/utils/useTOCHighlight.ts +20 -17
@@ -7,19 +7,27 @@
7
7
 
8
8
  import {useCallback, useEffect, useLayoutEffect, useRef} from 'react';
9
9
 
10
- // This hook is like useLayoutEffect, but without the SSR warning
11
- // It seems hacky but it's used in many React libs (Redux, Formik...)
12
- // Also mentioned here: https://github.com/facebook/react/issues/16956
13
- // It is useful when you need to update a ref as soon as possible after a React render (before useEffect)
10
+ /**
11
+ * This hook is like useLayoutEffect, but without the SSR warning
12
+ * It seems hacky but it's used in many React libs (Redux, Formik...)
13
+ * Also mentioned here: https://github.com/facebook/react/issues/16956
14
+ * It is useful when you need to update a ref as soon as possible after a React
15
+ * render (before `useEffect`)
16
+ */
14
17
  export const useIsomorphicLayoutEffect =
15
18
  typeof window !== 'undefined' ? useLayoutEffect : useEffect;
16
19
 
17
- // Permits to transform an unstable callback (like an arrow function provided as props)
18
- // to a "stable" callback that is safe to use in a useEffect dependency array
19
- // Useful to avoid React stale closure problems + avoid useless effect re-executions
20
- //
21
- // Workaround until the React team recommends a good solution, see https://github.com/facebook/react/issues/16956
22
- // This generally works has some potential drawbacks, such as https://github.com/facebook/react/issues/16956#issuecomment-536636418
20
+ /**
21
+ * Permits to transform an unstable callback (like an arrow function provided as
22
+ * props) to a "stable" callback that is safe to use in a useEffect dependency
23
+ * array. Useful to avoid React stale closure problems + avoid useless effect
24
+ * re-executions
25
+ *
26
+ * Workaround until the React team recommends a good solution, see
27
+ * https://github.com/facebook/react/issues/16956
28
+ * This generally works but has some potential drawbacks, such as
29
+ * https://github.com/facebook/react/issues/16956#issuecomment-536636418
30
+ */
23
31
  export function useDynamicCallback<T extends (...args: never[]) => unknown>(
24
32
  callback: T,
25
33
  ): T {
@@ -29,6 +37,7 @@ export function useDynamicCallback<T extends (...args: never[]) => unknown>(
29
37
  ref.current = callback;
30
38
  }, [callback]);
31
39
 
32
- // @ts-expect-error: TS is right that this callback may be a supertype of T, but good enough for our use
40
+ // @ts-expect-error: TS is right that this callback may be a supertype of T,
41
+ // but good enough for our use
33
42
  return useCallback<T>((...args) => ref.current(...args), []);
34
43
  }
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  /**
9
- * Utility to convert an optional string into a Regex case insensitive and global
9
+ * Converts an optional string into a Regex case insensitive and global
10
10
  */
11
11
  export function isRegexpStringMatch(
12
12
  regexAsString?: string,
@@ -11,8 +11,8 @@ export type StorageType = typeof StorageTypes[number];
11
11
 
12
12
  const DefaultStorageType: StorageType = 'localStorage';
13
13
 
14
- // Will return null browser storage is unavailable (like running Docusaurus in iframe)
15
- // See https://github.com/facebook/docusaurus/pull/4501
14
+ // Will return null browser storage is unavailable (like running Docusaurus in
15
+ // iframe) See https://github.com/facebook/docusaurus/pull/4501
16
16
  function getBrowserStorage(
17
17
  storageType: StorageType = DefaultStorageType,
18
18
  ): Storage | null {
@@ -23,13 +23,12 @@ function getBrowserStorage(
23
23
  }
24
24
  if (storageType === 'none') {
25
25
  return null;
26
- } else {
27
- try {
28
- return window[storageType];
29
- } catch (e) {
30
- logOnceBrowserStorageNotAvailableWarning(e as Error);
31
- return null;
32
- }
26
+ }
27
+ try {
28
+ return window[storageType];
29
+ } catch (e) {
30
+ logOnceBrowserStorageNotAvailableWarning(e as Error);
31
+ return null;
33
32
  }
34
33
  }
35
34
 
@@ -79,10 +78,10 @@ Please only call storage APIs in effects and event handlers.`);
79
78
 
80
79
  /**
81
80
  * Creates an object for accessing a particular key in localStorage.
82
- * The API is fail-safe, and usage of browser storage should be considered unreliable
83
- * Local storage might simply be unavailable (iframe + browser security) or operations might fail individually
84
- * Please assume that using this API can be a NO-OP
85
- * See also https://github.com/facebook/docusaurus/issues/6036
81
+ * The API is fail-safe, and usage of browser storage should be considered
82
+ * unreliable. Local storage might simply be unavailable (iframe + browser
83
+ * security) or operations might fail individually. Please assume that using
84
+ * this API can be a NO-OP. See also https://github.com/facebook/docusaurus/issues/6036
86
85
  */
87
86
  export const createStorageSlot = (
88
87
  key: string,
@@ -36,9 +36,8 @@ export function filterTOC({
36
36
  children: filteredChildren,
37
37
  },
38
38
  ];
39
- } else {
40
- return filteredChildren;
41
39
  }
40
+ return filteredChildren;
42
41
  });
43
42
  }
44
43
 
@@ -39,14 +39,15 @@ export function useAlternatePageUtils(): {
39
39
  : `${baseUrlUnlocalized}${locale}/`;
40
40
  }
41
41
 
42
- // TODO support correct alternate url when localized site is deployed on another domain
42
+ // TODO support correct alternate url when localized site is deployed on
43
+ // another domain
43
44
  function createUrl({
44
45
  locale,
45
46
  fullyQualified,
46
47
  }: {
47
48
  locale: string;
48
- // For hreflang SEO headers, we need it to be fully qualified (full protocol/domain/path...)
49
- // For locale dropdown, using a path is good enough
49
+ // For hreflang SEO headers, we need it to be fully qualified (full
50
+ // protocol/domain/path...) or locale dropdown, using a path is good enough
50
51
  fullyQualified: boolean;
51
52
  }) {
52
53
  return `${fullyQualified ? url : ''}${getLocalizedBaseUrl(
@@ -18,8 +18,8 @@ export type useContextualSearchFiltersReturns = {
18
18
  tags: string[];
19
19
  };
20
20
 
21
- // We may want to support multiple search engines, don't couple that to Algolia/DocSearch
22
- // Maybe users will want to use its own search engine solution
21
+ // We may want to support multiple search engines, don't couple that to
22
+ // Algolia/DocSearch. Maybe users want to use their own search engine solution
23
23
  export function useContextualSearchFilters(): useContextualSearchFiltersReturns {
24
24
  const {i18n} = useDocusaurusContext();
25
25
  const allDocsData = useAllDocsData();
@@ -49,23 +49,29 @@ function createLocalePluralForms(locale: string): LocalePluralForms {
49
49
  };
50
50
  }
51
51
 
52
- // Poor man's PluralSelector implementation, using an english fallback.
53
- // We want a lightweight, future-proof and good-enough solution.
54
- // We don't want a perfect and heavy solution.
55
- //
56
- // Docusaurus classic theme has only 2 deeply nested labels requiring complex plural rules
57
- // We don't want to use Intl + PluralRules polyfills + full ICU syntax (react-intl) just for that.
58
- //
59
- // Notes:
60
- // - 2021: 92+% Browsers support Intl.PluralRules, and support will increase in the future
61
- // - NodeJS >= 13 has full ICU support by default
62
- // - In case of "mismatch" between SSR and Browser ICU support, React keeps working!
52
+ /**
53
+ * Poor man's PluralSelector implementation, using an english fallback. We want
54
+ * a lightweight, future-proof and good-enough solution. We don't want a perfect
55
+ * and heavy solution.
56
+ *
57
+ * Docusaurus classic theme has only 2 deeply nested labels requiring complex
58
+ * plural rules. We don't want to use Intl + PluralRules polyfills + full ICU
59
+ * syntax (react-intl) just for that.
60
+ *
61
+ * Notes:
62
+ * - 2021: 92+% Browsers support Intl.PluralRules, and support will increase in
63
+ * the future
64
+ * - NodeJS >= 13 has full ICU support by default
65
+ * - In case of "mismatch" between SSR and Browser ICU support, React keeps
66
+ * working!
67
+ */
63
68
  function useLocalePluralForms(): LocalePluralForms {
64
69
  const {
65
70
  i18n: {currentLocale},
66
71
  } = useDocusaurusContext();
67
72
  return useMemo(() => {
68
- // @ts-expect-error checking Intl.PluralRules in case browser doesn't have it (e.g Safari 12-)
73
+ // @ts-expect-error checking Intl.PluralRules in case browser doesn't
74
+ // have it (e.g Safari 12-)
69
75
  if (Intl.PluralRules) {
70
76
  try {
71
77
  return createLocalePluralForms(currentLocale);
@@ -94,17 +100,17 @@ function selectPluralMessage(
94
100
 
95
101
  if (parts.length === 1) {
96
102
  return parts[0];
97
- } else {
98
- if (parts.length > localePluralForms.pluralForms.length) {
99
- console.error(
100
- `For locale=${localePluralForms.locale}, a maximum of ${localePluralForms.pluralForms.length} plural forms are expected (${localePluralForms.pluralForms}), but the message contains ${parts.length} plural forms: ${pluralMessages} `,
101
- );
102
- }
103
- const pluralForm = localePluralForms.select(count);
104
- const pluralFormIndex = localePluralForms.pluralForms.indexOf(pluralForm);
105
- // In case of not enough plural form messages, we take the last one (other) instead of returning undefined
106
- return parts[Math.min(pluralFormIndex, parts.length - 1)];
107
103
  }
104
+ if (parts.length > localePluralForms.pluralForms.length) {
105
+ console.error(
106
+ `For locale=${localePluralForms.locale}, a maximum of ${localePluralForms.pluralForms.length} plural forms are expected (${localePluralForms.pluralForms}), but the message contains ${parts.length} plural forms: ${pluralMessages} `,
107
+ );
108
+ }
109
+ const pluralForm = localePluralForms.select(count);
110
+ const pluralFormIndex = localePluralForms.pluralForms.indexOf(pluralForm);
111
+ // In case of not enough plural form messages, we take the last one (other)
112
+ // instead of returning undefined
113
+ return parts[Math.min(pluralFormIndex, parts.length - 1)];
108
114
  }
109
115
 
110
116
  export function usePluralForm(): {
@@ -13,7 +13,8 @@ TODO make the hardcoded theme-classic classnames configurable
13
13
  (or add them to ThemeClassNames?)
14
14
  */
15
15
 
16
- // If the anchor has no height and is just a "marker" in the dom; we'll use the parent (normally the link text) rect boundaries instead
16
+ // If the anchor has no height and is just a "marker" in the dom; we'll use the
17
+ // parent (normally the link text) rect boundaries instead
17
18
  function getVisibleBoundingClientRect(element: HTMLElement): DOMRect {
18
19
  const rect = element.getBoundingClientRect();
19
20
  const hasNoHeight = rect.top === rect.bottom;
@@ -23,8 +24,10 @@ function getVisibleBoundingClientRect(element: HTMLElement): DOMRect {
23
24
  return rect;
24
25
  }
25
26
 
26
- // Considering we divide viewport into 2 zones of each 50vh
27
- // This returns true if an element is in the first zone (ie, appear in viewport, near the top)
27
+ /**
28
+ * Considering we divide viewport into 2 zones of each 50vh, this returns true
29
+ * if an element is in the first zone (ie, appear in viewport, near the top)
30
+ */
28
31
  function isInViewportTopHalf(boundingRect: DOMRect) {
29
32
  return boundingRect.top > 0 && boundingRect.bottom < window.innerHeight / 2;
30
33
  }
@@ -54,9 +57,10 @@ function getActiveAnchor(
54
57
  anchorTopOffset: number;
55
58
  },
56
59
  ): Element | null {
57
- // Naming is hard
58
- // The "nextVisibleAnchor" is the first anchor that appear under the viewport top boundary
59
- // Note: it does not mean this anchor is visible yet, but if user continues scrolling down, it will be the first to become visible
60
+ // Naming is hard: The "nextVisibleAnchor" is the first anchor that appear
61
+ // under the viewport top boundary. It does not mean this anchor is visible
62
+ // yet, but if user continues scrolling down, it will be the first to become
63
+ // visible
60
64
  const nextVisibleAnchor = anchors.find((anchor) => {
61
65
  const boundingRect = getVisibleBoundingClientRect(anchor);
62
66
  return boundingRect.top >= anchorTopOffset;
@@ -64,23 +68,22 @@ function getActiveAnchor(
64
68
 
65
69
  if (nextVisibleAnchor) {
66
70
  const boundingRect = getVisibleBoundingClientRect(nextVisibleAnchor);
67
- // If anchor is in the top half of the viewport: it is the one we consider "active"
68
- // (unless it's too close to the top and and soon to be scrolled outside viewport)
71
+ // If anchor is in the top half of the viewport: it is the one we consider
72
+ // "active" (unless it's too close to the top and and soon to be scrolled
73
+ // outside viewport)
69
74
  if (isInViewportTopHalf(boundingRect)) {
70
75
  return nextVisibleAnchor;
71
76
  }
72
- // If anchor is in the bottom half of the viewport, or under the viewport, we consider the active anchor is the previous one
73
- // This is because the main text appearing in the user screen mostly belong to the previous anchor
74
- else {
75
- // Returns null for the first anchor, see https://github.com/facebook/docusaurus/issues/5318
76
- return anchors[anchors.indexOf(nextVisibleAnchor) - 1] ?? null;
77
- }
77
+ // If anchor is in the bottom half of the viewport, or under the viewport,
78
+ // we consider the active anchor is the previous one. This is because the
79
+ // main text appearing in the user screen mostly belong to the previous
80
+ // anchor. Returns null for the first anchor, see
81
+ // https://github.com/facebook/docusaurus/issues/5318
82
+ return anchors[anchors.indexOf(nextVisibleAnchor) - 1] ?? null;
78
83
  }
79
84
  // no anchor under viewport top? (ie we are at the bottom of the page)
80
85
  // => highlight the last anchor found
81
- else {
82
- return anchors[anchors.length - 1];
83
- }
86
+ return anchors[anchors.length - 1];
84
87
  }
85
88
 
86
89
  function getLinkAnchorValue(link: HTMLAnchorElement): string {