@mui/internal-docs-infra 0.2.3-canary.9 → 0.3.1-canary.0

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 (144) hide show
  1. package/README.md +3 -2
  2. package/esm/CodeHighlighter/CodeHighlighter.js +16 -16
  3. package/esm/CodeHighlighter/CodeHighlighterClient.js +33 -33
  4. package/esm/CodeHighlighter/errors.js +3 -3
  5. package/esm/CodeHighlighter/types.d.ts +1 -1
  6. package/esm/CodeProvider/CodeContext.d.ts +4 -4
  7. package/esm/CodeProvider/CodeProvider.js +7 -7
  8. package/esm/cli/index.d.ts +1 -0
  9. package/esm/cli/index.js +6 -0
  10. package/esm/cli/runValidate.d.ts +8 -0
  11. package/esm/cli/runValidate.js +297 -0
  12. package/esm/createSitemap/createSitemap.d.ts +23 -0
  13. package/esm/createSitemap/createSitemap.js +45 -0
  14. package/esm/createSitemap/index.d.ts +1 -0
  15. package/esm/createSitemap/index.js +1 -0
  16. package/esm/createSitemap/types.d.ts +68 -0
  17. package/esm/createSitemap/types.js +1 -0
  18. package/esm/pipeline/getFileConventions/fileConventions.d.ts +4 -0
  19. package/esm/pipeline/getFileConventions/fileConventions.js +4 -0
  20. package/esm/pipeline/getFileConventions/getFileConventions.d.ts +4 -0
  21. package/esm/pipeline/getFileConventions/getFileConventions.js +17 -0
  22. package/esm/pipeline/getFileConventions/index.d.ts +1 -0
  23. package/esm/pipeline/getFileConventions/index.js +1 -0
  24. package/esm/{CodeHighlighter/addPathsToVariant.d.ts → pipeline/loadCodeVariant/addCodeVariantPaths.d.ts} +1 -1
  25. package/esm/{CodeHighlighter/applyTransform.d.ts → pipeline/loadCodeVariant/applyCodeTransform.d.ts} +3 -3
  26. package/esm/{CodeHighlighter/applyTransform.js → pipeline/loadCodeVariant/applyCodeTransform.js} +4 -4
  27. package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/calculateMainFilePath.js +1 -1
  28. package/esm/{CodeHighlighter/transformCode.d.ts → pipeline/loadCodeVariant/computeHastDeltas.d.ts} +9 -5
  29. package/esm/{CodeHighlighter/transformCode.js → pipeline/loadCodeVariant/computeHastDeltas.js} +20 -16
  30. package/esm/pipeline/loadCodeVariant/diffHast.d.ts +3 -0
  31. package/esm/{CodeHighlighter/transformParsedSource.js → pipeline/loadCodeVariant/diffHast.js} +5 -5
  32. package/esm/{CodeHighlighter/examineVariant.d.ts → pipeline/loadCodeVariant/examineCodeVariant.d.ts} +2 -2
  33. package/esm/{CodeHighlighter/examineVariant.js → pipeline/loadCodeVariant/examineCodeVariant.js} +1 -1
  34. package/esm/{useDemo/flattenVariant.d.ts → pipeline/loadCodeVariant/flattenCodeVariant.d.ts} +2 -2
  35. package/esm/{useDemo/flattenVariant.js → pipeline/loadCodeVariant/flattenCodeVariant.js} +3 -3
  36. package/esm/{CodeHighlighter/hasAllVariants.d.ts → pipeline/loadCodeVariant/hasAllCodeVariants.d.ts} +1 -1
  37. package/esm/pipeline/loadCodeVariant/index.d.ts +10 -0
  38. package/esm/pipeline/loadCodeVariant/index.js +17 -0
  39. package/esm/{CodeHighlighter/loadFallbackCode.d.ts → pipeline/loadCodeVariant/loadCodeFallback.d.ts} +2 -2
  40. package/esm/{CodeHighlighter/loadFallbackCode.js → pipeline/loadCodeVariant/loadCodeFallback.js} +180 -106
  41. package/esm/{CodeHighlighter/loadVariant.d.ts → pipeline/loadCodeVariant/loadCodeVariant.d.ts} +2 -2
  42. package/esm/{CodeHighlighter/loadVariant.js → pipeline/loadCodeVariant/loadCodeVariant.js} +122 -49
  43. package/esm/{CodeHighlighter/maybeInitialData.d.ts → pipeline/loadCodeVariant/maybeCodeInitialData.d.ts} +6 -6
  44. package/esm/{CodeHighlighter/maybeInitialData.js → pipeline/loadCodeVariant/maybeCodeInitialData.js} +6 -6
  45. package/esm/{CodeHighlighter/mergeMetadata.d.ts → pipeline/loadCodeVariant/mergeCodeMetadata.d.ts} +3 -3
  46. package/esm/{CodeHighlighter/mergeMetadata.js → pipeline/loadCodeVariant/mergeCodeMetadata.js} +3 -3
  47. package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/parseCode.d.ts +1 -1
  48. package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/transformSource.d.ts +1 -1
  49. package/esm/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.d.ts +5 -0
  50. package/esm/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.js +86 -13
  51. package/esm/pipeline/loadPrecomputedCodeHighlighter/performanceLogger.d.ts +30 -0
  52. package/esm/pipeline/loadPrecomputedCodeHighlighter/performanceLogger.js +77 -0
  53. package/esm/pipeline/loadPrecomputedCodeHighlighterClient/loadPrecomputedCodeHighlighterClient.js +7 -7
  54. package/esm/pipeline/loadPrecomputedSitemap/index.d.ts +2 -0
  55. package/esm/pipeline/loadPrecomputedSitemap/index.js +4 -0
  56. package/esm/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.d.ts +10 -0
  57. package/esm/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.js +213 -0
  58. package/esm/pipeline/loadServerCodeMeta/index.d.ts +2 -1
  59. package/esm/pipeline/loadServerCodeMeta/index.js +2 -1
  60. package/esm/pipeline/loadServerCodeMeta/loadServerCodeMeta.d.ts +1 -1
  61. package/esm/pipeline/loadServerCodeMeta/loadServerCodeMeta.js +2 -2
  62. package/esm/pipeline/{loaderUtils → loadServerCodeMeta}/resolveModulePathWithFs.d.ts +1 -1
  63. package/esm/pipeline/{loaderUtils → loadServerCodeMeta}/resolveModulePathWithFs.js +1 -1
  64. package/esm/pipeline/loadServerPageIndex/index.d.ts +2 -0
  65. package/esm/pipeline/loadServerPageIndex/index.js +1 -0
  66. package/esm/pipeline/loadServerPageIndex/loadServerPageIndex.d.ts +51 -0
  67. package/esm/pipeline/loadServerPageIndex/loadServerPageIndex.js +174 -0
  68. package/esm/pipeline/loadServerSitemap/index.d.ts +2 -0
  69. package/esm/pipeline/loadServerSitemap/index.js +1 -0
  70. package/esm/pipeline/loadServerSitemap/loadServerSitemap.d.ts +39 -0
  71. package/esm/pipeline/loadServerSitemap/loadServerSitemap.js +168 -0
  72. package/esm/pipeline/loadServerSource/loadServerSource.js +1 -1
  73. package/esm/pipeline/loaderUtils/externalsToPackages.js +1 -1
  74. package/esm/pipeline/loaderUtils/processRelativeImports.js +16 -3
  75. package/esm/pipeline/loaderUtils/rewriteImports.d.ts +36 -0
  76. package/esm/pipeline/loaderUtils/rewriteImports.js +139 -8
  77. package/esm/pipeline/syncPageIndex/createMarkdownNodes.d.ts +76 -0
  78. package/esm/pipeline/syncPageIndex/createMarkdownNodes.js +305 -0
  79. package/esm/pipeline/syncPageIndex/index.d.ts +1 -0
  80. package/esm/pipeline/syncPageIndex/index.js +1 -0
  81. package/esm/pipeline/syncPageIndex/mergeMetadataMarkdown.d.ts +58 -0
  82. package/esm/pipeline/syncPageIndex/mergeMetadataMarkdown.js +214 -0
  83. package/esm/pipeline/syncPageIndex/metadataToMarkdown.d.ts +67 -0
  84. package/esm/pipeline/syncPageIndex/metadataToMarkdown.js +1486 -0
  85. package/esm/pipeline/syncPageIndex/syncPageIndex.d.ts +108 -0
  86. package/esm/pipeline/syncPageIndex/syncPageIndex.js +540 -0
  87. package/esm/pipeline/transformHtmlCodePrecomputed/transformHtmlCodePrecomputed.d.ts +2 -2
  88. package/esm/pipeline/transformHtmlCodePrecomputed/transformHtmlCodePrecomputed.js +5 -5
  89. package/esm/pipeline/transformMarkdownBlockquoteCallouts/index.d.ts +2 -0
  90. package/esm/pipeline/transformMarkdownBlockquoteCallouts/index.js +4 -0
  91. package/esm/pipeline/transformMarkdownBlockquoteCallouts/transformMarkdownBlockquoteCallouts.d.ts +16 -0
  92. package/esm/pipeline/transformMarkdownBlockquoteCallouts/transformMarkdownBlockquoteCallouts.js +58 -0
  93. package/esm/pipeline/transformMarkdownDemoLinks/index.d.ts +2 -0
  94. package/esm/pipeline/transformMarkdownDemoLinks/index.js +4 -0
  95. package/esm/pipeline/transformMarkdownDemoLinks/transformMarkdownDemoLinks.d.ts +26 -0
  96. package/esm/pipeline/transformMarkdownDemoLinks/transformMarkdownDemoLinks.js +107 -0
  97. package/esm/pipeline/transformMarkdownMetadata/index.d.ts +2 -0
  98. package/esm/pipeline/transformMarkdownMetadata/index.js +4 -0
  99. package/esm/pipeline/transformMarkdownMetadata/transformMarkdownMetadata.d.ts +3 -0
  100. package/esm/pipeline/transformMarkdownMetadata/transformMarkdownMetadata.js +1010 -0
  101. package/esm/pipeline/transformMarkdownMetadata/types.d.ts +110 -0
  102. package/esm/pipeline/transformMarkdownMetadata/types.js +1 -0
  103. package/esm/pipeline/transformMarkdownRelativePaths/index.d.ts +2 -0
  104. package/esm/pipeline/transformMarkdownRelativePaths/index.js +4 -0
  105. package/esm/pipeline/transformMarkdownRelativePaths/transformMarkdownRelativePaths.d.ts +15 -0
  106. package/esm/pipeline/transformMarkdownRelativePaths/transformMarkdownRelativePaths.js +40 -0
  107. package/esm/useCode/Pre.js +15 -2
  108. package/esm/useCode/useCode.d.ts +15 -2
  109. package/esm/useCode/useCode.js +15 -6
  110. package/esm/useCode/useCodeUtils.js +3 -3
  111. package/esm/useCode/useFileNavigation.d.ts +9 -3
  112. package/esm/useCode/useFileNavigation.js +124 -81
  113. package/esm/useCode/useUIState.d.ts +4 -1
  114. package/esm/useCode/useUIState.js +17 -2
  115. package/esm/useCode/useVariantSelection.d.ts +8 -3
  116. package/esm/useCode/useVariantSelection.js +144 -52
  117. package/esm/useCopier/index.js +5 -4
  118. package/esm/useDemo/createCodeSandbox.d.ts +1 -1
  119. package/esm/useDemo/createStackBlitz.d.ts +1 -1
  120. package/esm/useDemo/exportVariant.js +13 -11
  121. package/esm/useDemo/index.d.ts +1 -1
  122. package/esm/useDemo/index.js +1 -1
  123. package/esm/useDemo/useDemo.d.ts +5 -5
  124. package/esm/useDemo/useDemo.js +6 -6
  125. package/esm/useErrors/useErrors.d.ts +1 -1
  126. package/esm/useErrors/useErrors.js +6 -2
  127. package/esm/useSearch/index.d.ts +1 -0
  128. package/esm/useSearch/index.js +1 -0
  129. package/esm/useSearch/types.d.ts +165 -0
  130. package/esm/useSearch/types.js +1 -0
  131. package/esm/useSearch/useSearch.d.ts +56 -0
  132. package/esm/useSearch/useSearch.js +647 -0
  133. package/esm/withDocsInfra/withDeploymentConfig.js +4 -2
  134. package/esm/withDocsInfra/withDocsInfra.d.ts +39 -0
  135. package/esm/withDocsInfra/withDocsInfra.js +79 -7
  136. package/package.json +105 -5
  137. package/esm/CodeHighlighter/transformParsedSource.d.ts +0 -3
  138. /package/esm/{CodeHighlighter/addPathsToVariant.js → pipeline/loadCodeVariant/addCodeVariantPaths.js} +0 -0
  139. /package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/calculateMainFilePath.d.ts +0 -0
  140. /package/esm/{CodeHighlighter/hasAllVariants.js → pipeline/loadCodeVariant/hasAllCodeVariants.js} +0 -0
  141. /package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/parseCode.js +0 -0
  142. /package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/pathUtils.d.ts +0 -0
  143. /package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/pathUtils.js +0 -0
  144. /package/esm/{CodeHighlighter → pipeline/loadCodeVariant}/transformSource.js +0 -0
@@ -3,16 +3,69 @@ import _typeof from "@babel/runtime/helpers/esm/typeof";
3
3
  import * as React from 'react';
4
4
  import { usePreference } from "../usePreference/index.js";
5
5
  import { useUrlHashState } from "../useUrlHashState/index.js";
6
- import { isHashRelevantToDemo } from "./useFileNavigation.js";
6
+ import { isHashRelevantToDemo, toKebabCase } from "./useFileNavigation.js";
7
+
8
+ /**
9
+ * Parses the variant name from a URL hash
10
+ * Hash formats:
11
+ * - slug:file.tsx -> "Default"
12
+ * - slug:variant:file.tsx -> "variant"
13
+ * - slug:variant -> "variant"
14
+ * @param urlHash - The URL hash (without '#')
15
+ * @param mainSlug - The main slug for the demo (optional, used to determine if hash is relevant for file selection)
16
+ * @param variantKeys - Available variant keys
17
+ * @returns The variant name or null if not found/parseable
18
+ */
19
+ function parseVariantFromHash(urlHash, mainSlug, variantKeys) {
20
+ if (!urlHash) {
21
+ return null;
22
+ }
23
+ var parts = urlHash.split(':');
24
+
25
+ // If there are 3 parts (slug:variant:file), the variant is in the middle
26
+ if (parts.length === 3) {
27
+ var variantPart = parts[1];
28
+ // Find matching variant key (case-insensitive kebab match)
29
+ var matchingVariant = variantKeys.find(function (key) {
30
+ return toKebabCase(key) === variantPart.toLowerCase();
31
+ });
32
+ return matchingVariant || null;
33
+ }
34
+
35
+ // If there are 2 parts, could be slug:variant or slug:file
36
+ if (parts.length === 2) {
37
+ var secondPart = parts[1];
38
+ // Try to match as a variant first
39
+ var _matchingVariant = variantKeys.find(function (key) {
40
+ return toKebabCase(key) === secondPart.toLowerCase();
41
+ });
42
+ if (_matchingVariant) {
43
+ return _matchingVariant;
44
+ }
45
+ // If no matching variant and it looks like a filename, assume Default
46
+ if (secondPart.includes('.')) {
47
+ return 'Default';
48
+ }
49
+ }
50
+
51
+ // Just the slug with no other parts, assume Default
52
+ if (parts.length === 1) {
53
+ return 'Default';
54
+ }
55
+ return null;
56
+ }
7
57
  /**
8
58
  * Hook for managing variant selection and providing variant-related data
9
- * Uses React state as source of truth, with localStorage for persistence
59
+ * Priority: URL hash > localStorage > initialVariant > first variant
60
+ * When hash has a variant, it overrides localStorage and is saved to localStorage
10
61
  */
11
62
  export function useVariantSelection(_ref) {
12
63
  var effectiveCode = _ref.effectiveCode,
13
64
  initialVariant = _ref.initialVariant,
14
65
  variantType = _ref.variantType,
15
- mainSlug = _ref.mainSlug;
66
+ mainSlug = _ref.mainSlug,
67
+ _ref$saveHashVariantT = _ref.saveHashVariantToLocalStorage,
68
+ saveHashVariantToLocalStorage = _ref$saveHashVariantT === void 0 ? 'on-interaction' : _ref$saveHashVariantT;
16
69
  // Get variant keys from effective code
17
70
  var variantKeys = React.useMemo(function () {
18
71
  return Object.keys(effectiveCode).filter(function (key) {
@@ -21,14 +74,14 @@ export function useVariantSelection(_ref) {
21
74
  });
22
75
  }, [effectiveCode]);
23
76
 
24
- // Check if there's a URL hash present that's relevant to this demo
25
- // Only override localStorage if hash starts with this demo's slug
77
+ // Get URL hash and parse variant from it
26
78
  var _useUrlHashState = useUrlHashState(),
27
- _useUrlHashState2 = _slicedToArray(_useUrlHashState, 1),
28
- urlHash = _useUrlHashState2[0];
29
- var hasRelevantUrlHash = React.useMemo(function () {
30
- return isHashRelevantToDemo(urlHash, mainSlug);
31
- }, [urlHash, mainSlug]);
79
+ _useUrlHashState2 = _slicedToArray(_useUrlHashState, 2),
80
+ urlHash = _useUrlHashState2[0],
81
+ setUrlHash = _useUrlHashState2[1];
82
+ var hashVariant = React.useMemo(function () {
83
+ return parseVariantFromHash(urlHash, mainSlug, variantKeys);
84
+ }, [urlHash, mainSlug, variantKeys]);
32
85
 
33
86
  // Use localStorage hook for variant persistence
34
87
  var _usePreference = usePreference('variant', variantType || variantKeys, function () {
@@ -38,73 +91,105 @@ export function useVariantSelection(_ref) {
38
91
  storedValue = _usePreference2[0],
39
92
  setStoredValue = _usePreference2[1];
40
93
 
41
- // Initialize state - will be updated by effect if localStorage should be used
94
+ // Track if the last change was user-initiated (to prevent hash from overriding)
95
+ var isUserInitiatedChange = React.useRef(false);
96
+ // Track previous hash variant to detect hash changes
97
+ var prevHashVariant = React.useRef(hashVariant);
98
+ // Track previous storedValue to detect localStorage changes
99
+ var prevStoredValue = React.useRef(storedValue);
100
+
101
+ // Determine initial variant: hash > localStorage > initialVariant > first variant
42
102
  var _React$useState = React.useState(function () {
43
- // Use initial variant if provided and valid
103
+ // Priority 1: Hash variant
104
+ if (hashVariant && variantKeys.includes(hashVariant)) {
105
+ return hashVariant;
106
+ }
107
+ // Priority 2: localStorage
108
+ if (storedValue && variantKeys.includes(storedValue)) {
109
+ return storedValue;
110
+ }
111
+ // Priority 3: initialVariant prop
44
112
  if (initialVariant && variantKeys.includes(initialVariant)) {
45
113
  return initialVariant;
46
114
  }
47
-
48
- // Final fallback: use first available variant
115
+ // Priority 4: First available variant
49
116
  return variantKeys[0] || '';
50
117
  }),
51
118
  _React$useState2 = _slicedToArray(_React$useState, 2),
52
119
  selectedVariantKey = _React$useState2[0],
53
120
  setSelectedVariantKeyState = _React$useState2[1];
54
121
 
55
- // On mount, check if we should restore from localStorage
56
- // This needs to be in an effect because we need to check hasRelevantUrlHash which depends on urlHash
57
- var _React$useState3 = React.useState(false),
58
- _React$useState4 = _slicedToArray(_React$useState3, 2),
59
- hasInitialized = _React$useState4[0],
60
- setHasInitialized = _React$useState4[1];
122
+ // Track selected variant key in a ref for use in effect without causing re-runs
123
+ var selectedVariantKeyRef = React.useRef(selectedVariantKey);
61
124
  React.useEffect(function () {
62
- if (hasInitialized) {
63
- return;
64
- }
65
- setHasInitialized(true);
125
+ selectedVariantKeyRef.current = selectedVariantKey;
126
+ });
66
127
 
67
- // If there's a relevant URL hash, don't use localStorage - hash takes priority
68
- if (hasRelevantUrlHash) {
128
+ // When hash changes and has a variant, override current selection
129
+ // When hash is removed, fall back to localStorage
130
+ React.useEffect(function () {
131
+ // Skip if this was a user-initiated change
132
+ if (isUserInitiatedChange.current) {
133
+ // Only reset the flag once the hash has actually been cleared
134
+ if (hashVariant === null && urlHash === null) {
135
+ isUserInitiatedChange.current = false;
136
+ }
137
+ prevHashVariant.current = hashVariant;
69
138
  return;
70
139
  }
71
140
 
72
- // If we have a stored value, use it (localStorage takes priority over initialVariant)
73
- if (storedValue && variantKeys.includes(storedValue)) {
74
- setSelectedVariantKeyState(storedValue);
75
- }
76
- }, [hasInitialized, hasRelevantUrlHash, storedValue, variantKeys]);
77
-
78
- // Sync with localStorage changes (but don't override programmatic changes or when hash is present)
79
- // Only sync when storedValue changes, not when selectedVariantKey changes
80
- var prevStoredValue = React.useRef(storedValue);
81
- React.useEffect(function () {
82
- // Don't sync from localStorage when a relevant URL hash is present - hash takes absolute priority
83
- if (hasRelevantUrlHash) {
141
+ // Only apply hash if it actually changed (not just a re-render with same hash)
142
+ var hashChanged = prevHashVariant.current !== hashVariant;
143
+ var storedValueChanged = prevStoredValue.current !== storedValue;
144
+ prevHashVariant.current = hashVariant;
145
+ prevStoredValue.current = storedValue;
146
+ if (!hashChanged && !storedValueChanged) {
84
147
  return;
85
148
  }
86
- if (storedValue !== prevStoredValue.current) {
87
- prevStoredValue.current = storedValue;
88
- if (storedValue && variantKeys.includes(storedValue) && storedValue !== selectedVariantKey) {
89
- setSelectedVariantKeyState(storedValue);
149
+ if (hashVariant && variantKeys.includes(hashVariant) && hashVariant !== selectedVariantKeyRef.current) {
150
+ // Hash has a variant - use it
151
+ setSelectedVariantKeyState(hashVariant);
152
+ // Save hash variant to localStorage based on configuration
153
+ if (saveHashVariantToLocalStorage === 'on-load' && hashVariant !== storedValue) {
154
+ setStoredValue(hashVariant);
90
155
  }
156
+ } else if (!hashVariant && !urlHash &&
157
+ // Only fall back to localStorage when hash is truly empty
158
+ storedValue && variantKeys.includes(storedValue) && storedValue !== selectedVariantKeyRef.current) {
159
+ // Hash is empty but localStorage has a variant - use it
160
+ setSelectedVariantKeyState(storedValue);
91
161
  }
92
- }, [storedValue, variantKeys, selectedVariantKey, hasRelevantUrlHash]);
162
+ }, [hashVariant, urlHash, variantKeys,
163
+ // Note: selectedVariantKey is intentionally NOT in dependencies
164
+ // to avoid effect running when user manually changes variant
165
+ storedValue, setStoredValue, saveHashVariantToLocalStorage]);
166
+
167
+ // Programmatic setter: doesn't save to localStorage (used for hash-driven changes)
93
168
  var setSelectedVariantKeyProgrammatic = React.useCallback(function (value) {
94
169
  var resolvedValue = typeof value === 'function' ? value(selectedVariantKey) : value;
95
170
  if (variantKeys.includes(resolvedValue)) {
96
- // Only update React state, not localStorage
97
- // This prevents conflicts with hash-driven navigation
98
171
  setSelectedVariantKeyState(resolvedValue);
99
172
  }
100
173
  }, [selectedVariantKey, variantKeys]);
174
+
175
+ // User setter: saves to localStorage (used for user-initiated changes like dropdown)
101
176
  var setSelectedVariantKeyAsUser = React.useCallback(function (value) {
102
177
  var resolvedValue = typeof value === 'function' ? value(selectedVariantKey) : value;
103
- if (variantKeys.includes(resolvedValue)) {
104
- setSelectedVariantKeyState(resolvedValue);
105
- setStoredValue(resolvedValue);
178
+ // If value is null, select the first variant (default)
179
+ var effectiveValue = resolvedValue != null ? resolvedValue : variantKeys[0];
180
+ if (effectiveValue && variantKeys.includes(effectiveValue)) {
181
+ // Mark as user-initiated to prevent hash effect from overriding
182
+ isUserInitiatedChange.current = true;
183
+ // Clear hash if it exists and is relevant to this demo
184
+ if (urlHash && mainSlug && isHashRelevantToDemo(urlHash, mainSlug)) {
185
+ setUrlHash(null);
186
+ // Update prevHashVariant to reflect that hash is now null
187
+ prevHashVariant.current = null;
188
+ }
189
+ setSelectedVariantKeyState(effectiveValue);
190
+ setStoredValue(effectiveValue);
106
191
  }
107
- }, [setStoredValue, selectedVariantKey, variantKeys]);
192
+ }, [setStoredValue, selectedVariantKey, variantKeys, urlHash, mainSlug, setUrlHash]);
108
193
  var selectedVariant = React.useMemo(function () {
109
194
  var variant = effectiveCode[selectedVariantKey];
110
195
  if (variant && _typeof(variant) === 'object' && 'source' in variant) {
@@ -116,16 +201,23 @@ export function useVariantSelection(_ref) {
116
201
  // Safety check: if selectedVariant doesn't exist, fall back to first variant
117
202
  React.useEffect(function () {
118
203
  if (!selectedVariant && variantKeys.length > 0) {
119
- // Don't mark this as a user selection - it's just a fallback
120
- // Use programmatic setter to avoid localStorage save
121
204
  setSelectedVariantKeyProgrammatic(variantKeys[0]);
122
205
  }
123
206
  }, [selectedVariant, variantKeys, setSelectedVariantKeyProgrammatic]);
207
+
208
+ // Function to save variant to localStorage (used for on-interaction mode)
209
+ var saveVariantToLocalStorage = React.useCallback(function (variant) {
210
+ if (saveHashVariantToLocalStorage === 'on-interaction' && variant !== storedValue) {
211
+ setStoredValue(variant);
212
+ }
213
+ }, [saveHashVariantToLocalStorage, storedValue, setStoredValue]);
124
214
  return {
125
215
  variantKeys: variantKeys,
126
216
  selectedVariantKey: selectedVariantKey,
127
217
  selectedVariant: selectedVariant,
128
218
  selectVariant: setSelectedVariantKeyAsUser,
129
- selectVariantProgrammatic: setSelectedVariantKeyProgrammatic
219
+ selectVariantProgrammatic: setSelectedVariantKeyProgrammatic,
220
+ saveVariantToLocalStorage: saveVariantToLocalStorage,
221
+ hashVariant: hashVariant
130
222
  };
131
223
  }
@@ -32,7 +32,12 @@ export function useCopier(contents, opts) {
32
32
  _context.n = 2;
33
33
  return copyToClipboard(content);
34
34
  case 2:
35
+ setRecentlySuccessful(true);
35
36
  onCopied == null || onCopied();
37
+ copyTimeoutRef.current = setTimeout(function () {
38
+ clearTimeout(copyTimeoutRef.current);
39
+ setRecentlySuccessful(false);
40
+ }, timeout);
36
41
  _context.n = 4;
37
42
  break;
38
43
  case 3:
@@ -41,10 +46,6 @@ export function useCopier(contents, opts) {
41
46
  onError == null || onError(_t);
42
47
  case 4:
43
48
  onClick == null || onClick(event);
44
- copyTimeoutRef.current = setTimeout(function () {
45
- clearTimeout(copyTimeoutRef.current);
46
- setRecentlySuccessful(false);
47
- }, timeout);
48
49
  case 5:
49
50
  return _context.a(2);
50
51
  }
@@ -1,4 +1,4 @@
1
- import type { FlattenedFiles } from "./flattenVariant.js";
1
+ import type { FlattenedFiles } from "../pipeline/loadCodeVariant/flattenCodeVariant.js";
2
2
  /**
3
3
  * Utility function for creating CodeSandbox demos
4
4
  * Returns the configuration that can be used with openWithForm
@@ -2,7 +2,7 @@
2
2
  * Utility function for creating StackBlitz demos
3
3
  * Returns the configuration that can be used with openWithForm
4
4
  */
5
- import type { FlattenedFiles } from "./flattenVariant.js";
5
+ import type { FlattenedFiles } from "../pipeline/loadCodeVariant/flattenCodeVariant.js";
6
6
  /**
7
7
  * Create StackBlitz configuration for use with openWithForm
8
8
  */
@@ -7,8 +7,8 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
7
7
 
8
8
  import { externalsToPackages } from "../pipeline/loaderUtils/index.js";
9
9
  import { getFileNameFromUrl } from "../pipeline/loaderUtils/getFileNameFromUrl.js";
10
- import { createPathContext } from "../CodeHighlighter/examineVariant.js";
11
- import { mergeMetadata, extractMetadata } from "../CodeHighlighter/mergeMetadata.js";
10
+ import { examineCodeVariant } from "../pipeline/loadCodeVariant/examineCodeVariant.js";
11
+ import { mergeCodeMetadata, extractCodeMetadata } from "../pipeline/loadCodeVariant/mergeCodeMetadata.js";
12
12
 
13
13
  /**
14
14
  * Merges multiple file objects into a single object.
@@ -162,15 +162,17 @@ export function exportVariant(variantCode) {
162
162
  var finalTitle = [titlePrefix, title, titleSuffix].filter(Boolean).join('');
163
163
  var finalDescription = [descriptionPrefix, description, descriptionSuffix].filter(Boolean).join('');
164
164
 
165
- // Use extractMetadata to properly separate metadata and non-metadata files
166
- var _extractMetadata = extractMetadata(variantCode),
167
- processedVariantCode = _extractMetadata.variant,
168
- processedGlobals = _extractMetadata.metadata;
165
+ // Use extractCodeMetadata to properly separate metadata and non-metadata files
166
+ var _extractCodeMetadata = extractCodeMetadata(variantCode),
167
+ processedVariantCode = _extractCodeMetadata.variant,
168
+ processedGlobals = _extractCodeMetadata.metadata;
169
+
170
+ // Run optional transform hook to modify variant and globals before processing
169
171
  if (transformVariant) {
170
172
  var transformed = transformVariant(processedVariantCode, variantName, processedGlobals);
171
173
  if (transformed) {
172
174
  // Re-extract metadata after transformation
173
- var result = transformed.variant && extractMetadata(transformed.variant);
175
+ var result = transformed.variant && extractCodeMetadata(transformed.variant);
174
176
  processedVariantCode = (result == null ? void 0 : result.variant) || processedVariantCode;
175
177
 
176
178
  // Start fresh with only the new metadata and explicitly transformed globals
@@ -191,7 +193,7 @@ export function exportVariant(variantCode) {
191
193
  var sourceFilename = getFilenameFromVariant(processedVariantCode);
192
194
 
193
195
  // Get path context to understand navigation
194
- var pathContext = createPathContext(variantCode);
196
+ var pathContext = examineCodeVariant(variantCode);
195
197
 
196
198
  // Determine if we need to rename the source file
197
199
  var ext = useTypescript ? 'tsx' : 'jsx';
@@ -401,7 +403,7 @@ export function exportVariant(variantCode) {
401
403
  // Merge all metadata files including framework metadata and globals
402
404
  var allMetadataFiles = mergeFiles(processedGlobals || {}, metadataFiles, extraMetadataFiles, frameworkFiles.globals || {});
403
405
 
404
- // Merge all files using mergeMetadata to properly position everything with 'src/' (sourcePrefix opt) prefix
406
+ // Merge all files using mergeCodeMetadata to properly position everything with 'src/' (sourcePrefix opt) prefix
405
407
  var allSourceFilesWithFramework = mergeFiles(processedVariantCode.extraFiles || {}, generatedFiles, ((_frameworkFiles$varia = frameworkFiles.variant) == null ? void 0 : _frameworkFiles$varia.extraFiles) || {});
406
408
 
407
409
  // Update the variant with all source files including framework source files
@@ -409,8 +411,8 @@ export function exportVariant(variantCode) {
409
411
  extraFiles: allSourceFilesWithFramework
410
412
  });
411
413
 
412
- // Use mergeMetadata to position everything correctly
413
- var finalVariant = mergeMetadata(finalVariantWithSources, allMetadataFiles, {
414
+ // Use mergeCodeMetadata to position everything correctly
415
+ var finalVariant = mergeCodeMetadata(finalVariantWithSources, allMetadataFiles, {
414
416
  metadataPrefix: sourcePrefix
415
417
  });
416
418
 
@@ -1,6 +1,6 @@
1
1
  export * from "./useDemo.js";
2
2
  export * from "./createStackBlitz.js";
3
3
  export * from "./createCodeSandbox.js";
4
- export * from "./flattenVariant.js";
4
+ export * from "../pipeline/loadCodeVariant/flattenCodeVariant.js";
5
5
  export * from "./exportVariant.js";
6
6
  export * from "./exportVariantAsCra.js";
@@ -1,6 +1,6 @@
1
1
  export * from "./useDemo.js";
2
2
  export * from "./createStackBlitz.js";
3
3
  export * from "./createCodeSandbox.js";
4
- export * from "./flattenVariant.js";
4
+ export * from "../pipeline/loadCodeVariant/flattenCodeVariant.js";
5
5
  export * from "./exportVariant.js";
6
6
  export * from "./exportVariantAsCra.js";
@@ -3,16 +3,16 @@ import type { UseCodeOpts } from "../useCode/index.js";
3
3
  import type { ContentProps } from "../CodeHighlighter/types.js";
4
4
  import { type ExportConfig } from "./exportVariant.js";
5
5
  /**
6
- * Demo templates use the exportVariant/exportVariantAsCra with flattenVariant pattern:
6
+ * Demo templates use the exportVariant/exportVariantAsCra with flattenCodeVariant pattern:
7
7
  *
8
8
  * For StackBlitz:
9
9
  * const { exported: exportedVariant, entrypoint } = exportVariant(variantCode);
10
- * const flattenedFiles = flattenVariant(exportedVariant);
10
+ * const flattenedFiles = flattenCodeVariant(exportedVariant);
11
11
  * createStackBlitzDemo({ title, description, flattenedFiles, useTypescript, initialFile: entrypoint })
12
12
  *
13
13
  * For CodeSandbox:
14
14
  * const { exported: craExport, entrypoint } = exportVariantAsCra(variantCode, { title, description, useTypescript });
15
- * const flattenedFiles = flattenVariant(craExport);
15
+ * const flattenedFiles = flattenCodeVariant(craExport);
16
16
  * createCodeSandboxDemo({ title, description, flattenedFiles, useTypescript, initialFile: entrypoint })
17
17
  * createCodeSandboxDemo({ title, description, flattenedFiles, useTypescript })
18
18
  */
@@ -55,7 +55,7 @@ export declare function useDemo<T extends {} = {}>(contentProps: ContentProps<T>
55
55
  slug: string | undefined;
56
56
  variants: string[];
57
57
  selectedVariant: string;
58
- selectVariant: React.Dispatch<React.SetStateAction<string>>;
58
+ selectVariant: (variant: string | null) => void;
59
59
  files: Array<{
60
60
  name: string;
61
61
  slug?: string;
@@ -72,7 +72,7 @@ export declare function useDemo<T extends {} = {}>(contentProps: ContentProps<T>
72
72
  }>;
73
73
  expanded: boolean;
74
74
  expand: () => void;
75
- setExpanded: React.Dispatch<React.SetStateAction<boolean>>;
75
+ setExpanded: (expanded: boolean) => void;
76
76
  copy: (event: React.MouseEvent<HTMLButtonElement>) => Promise<void>;
77
77
  availableTransforms: string[];
78
78
  selectedTransform: string | null | undefined;
@@ -8,19 +8,19 @@ import { createStackBlitz } from "./createStackBlitz.js";
8
8
  import { createCodeSandbox } from "./createCodeSandbox.js";
9
9
  import { exportVariant } from "./exportVariant.js";
10
10
  import { exportVariantAsCra } from "./exportVariantAsCra.js";
11
- import { flattenVariant } from "./flattenVariant.js";
11
+ import { flattenCodeVariant } from "../pipeline/loadCodeVariant/flattenCodeVariant.js";
12
12
 
13
13
  /**
14
- * Demo templates use the exportVariant/exportVariantAsCra with flattenVariant pattern:
14
+ * Demo templates use the exportVariant/exportVariantAsCra with flattenCodeVariant pattern:
15
15
  *
16
16
  * For StackBlitz:
17
17
  * const { exported: exportedVariant, entrypoint } = exportVariant(variantCode);
18
- * const flattenedFiles = flattenVariant(exportedVariant);
18
+ * const flattenedFiles = flattenCodeVariant(exportedVariant);
19
19
  * createStackBlitzDemo({ title, description, flattenedFiles, useTypescript, initialFile: entrypoint })
20
20
  *
21
21
  * For CodeSandbox:
22
22
  * const { exported: craExport, entrypoint } = exportVariantAsCra(variantCode, { title, description, useTypescript });
23
- * const flattenedFiles = flattenVariant(craExport);
23
+ * const flattenedFiles = flattenCodeVariant(craExport);
24
24
  * createCodeSandboxDemo({ title, description, flattenedFiles, useTypescript, initialFile: entrypoint })
25
25
  * createCodeSandboxDemo({ title, description, flattenedFiles, useTypescript })
26
26
  */
@@ -133,7 +133,7 @@ export function useDemo(contentProps, opts) {
133
133
  rootFile = _exportFunction.rootFile;
134
134
 
135
135
  // Flatten the variant to get a flat file structure
136
- var flattenedFiles = flattenVariant(exported);
136
+ var flattenedFiles = flattenCodeVariant(exported);
137
137
  var stackBlitzDemo = createStackBlitz({
138
138
  title: title,
139
139
  description: description,
@@ -173,7 +173,7 @@ export function useDemo(contentProps, opts) {
173
173
  rootFile = _exportFunction2.rootFile;
174
174
 
175
175
  // Flatten the variant to get a flat file structure
176
- var flattenedFiles = flattenVariant(craExport);
176
+ var flattenedFiles = flattenCodeVariant(craExport);
177
177
  var codeSandboxDemo = createCodeSandbox({
178
178
  flattenedFiles: flattenedFiles,
179
179
  rootFile: rootFile
@@ -1,5 +1,5 @@
1
1
  type Errors = {
2
2
  errors?: Error[];
3
3
  };
4
- export declare function useErrors(): Errors;
4
+ export declare function useErrors(props?: Errors): Errors;
5
5
  export {};
@@ -1,7 +1,11 @@
1
1
  import { useErrorsContext } from "./ErrorsContext.js";
2
- export function useErrors() {
2
+ export function useErrors(props) {
3
3
  var context = useErrorsContext();
4
+
5
+ // Context errors take precedence over prop errors
6
+ // This ensures client-side errors override server-side errors
7
+ var errors = (context == null ? void 0 : context.errors) || (props == null ? void 0 : props.errors);
4
8
  return {
5
- errors: context == null ? void 0 : context.errors
9
+ errors: errors
6
10
  };
7
11
  }
@@ -0,0 +1 @@
1
+ export * from "./useSearch.js";
@@ -0,0 +1 @@
1
+ export * from "./useSearch.js";
@@ -0,0 +1,165 @@
1
+ import { ElapsedTime, Orama, SearchParams } from '@orama/orama';
2
+ import type { Sitemap, SitemapPage, SitemapSection, SitemapPart, SitemapExport, SitemapSectionData } from "../createSitemap/types.js";
3
+ /**
4
+ * Base search result structure that can be extended by consumers
5
+ */
6
+ export interface BaseSearchResult {
7
+ id?: string;
8
+ title?: string;
9
+ description?: string;
10
+ slug: string;
11
+ path: string;
12
+ sectionTitle: string;
13
+ prefix: string;
14
+ keywords?: string;
15
+ score?: number;
16
+ group?: string;
17
+ }
18
+ /**
19
+ * Page search result (top-level documentation page)
20
+ */
21
+ export interface PageSearchResult extends BaseSearchResult {
22
+ type: 'page';
23
+ page?: string;
24
+ pageKeywords?: string;
25
+ sections?: string;
26
+ subsections?: string;
27
+ }
28
+ /**
29
+ * Part search result (component part with API documentation)
30
+ */
31
+ export interface PartSearchResult extends BaseSearchResult {
32
+ type: 'part';
33
+ part: string;
34
+ export: string;
35
+ props?: string;
36
+ dataAttributes?: string;
37
+ cssVariables?: string;
38
+ }
39
+ /**
40
+ * Export search result (exported function/component with API documentation)
41
+ */
42
+ export interface ExportSearchResult extends BaseSearchResult {
43
+ type: 'export';
44
+ export: string;
45
+ props?: string;
46
+ dataAttributes?: string;
47
+ cssVariables?: string;
48
+ }
49
+ /**
50
+ * Section search result (top-level heading within a page)
51
+ */
52
+ export interface SectionSearchResult extends BaseSearchResult {
53
+ type: 'section';
54
+ section: string;
55
+ }
56
+ /**
57
+ * Subsection search result (nested heading within a page)
58
+ */
59
+ export interface SubsectionSearchResult extends BaseSearchResult {
60
+ type: 'subsection';
61
+ subsection: string;
62
+ }
63
+ /**
64
+ * Union type of all common search result variants
65
+ */
66
+ export type SearchResult = PageSearchResult | PartSearchResult | ExportSearchResult | SectionSearchResult | SubsectionSearchResult;
67
+ export type { SitemapPage, SitemapSection, SitemapPart, SitemapExport, SitemapSectionData, Sitemap };
68
+ export type SearchResults = {
69
+ group: string;
70
+ items: SearchResult[];
71
+ }[];
72
+ /**
73
+ * Options for configuring search behavior
74
+ */
75
+ export interface UseSearchOptions {
76
+ /** Function that returns a promise resolving to sitemap data */
77
+ sitemap: () => Promise<{
78
+ sitemap?: Sitemap;
79
+ }>;
80
+ /** Maximum number of default results to show */
81
+ maxDefaultResults?: number;
82
+ /** Search tolerance for fuzzy matching */
83
+ tolerance?: number;
84
+ /** Maximum number of search results */
85
+ limit?: number;
86
+ /** Enable stemming and stopwords (uses English by default) */
87
+ enableStemming?: boolean;
88
+ /** Boost values for different result types and fields */
89
+ boost?: Partial<Record<string, number>>;
90
+ /** Include page categories in groups: "Overview Pages" vs "Pages" */
91
+ includeCategoryInGroup?: boolean;
92
+ /**
93
+ * When true, excludes `sections` and `subsections` fields from page-type results.
94
+ * The individual section and subsection entries are still created.
95
+ * @default false
96
+ */
97
+ excludeSections?: boolean;
98
+ /**
99
+ * Custom function to convert heading text to URL-friendly slugs.
100
+ * Use this to match your site's slug generation (e.g., rehype-slug).
101
+ * Only applied to section/subsection slugs from the sitemap.
102
+ *
103
+ * If not provided, the original slugs from the sitemap are used as-is.
104
+ *
105
+ * The second parameter `parentTitles` contains the original text of parent headings,
106
+ * useful for pages that concatenate parent context into child heading IDs
107
+ * (e.g., Releases pages: `v1.0.0-rc.0-autocomplete` where the version is prepended).
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * // Simple generateSlug (ignores parent context)
112
+ * generateSlug: (text) => text.toLowerCase().replace(/[^a-z0-9]+/g, '-')
113
+ *
114
+ * // generateSlug with parent concatenation for subsections (e.g., Releases page)
115
+ * generateSlug: (text, parentTitles) => {
116
+ * const slug = stringToUrl(text);
117
+ * // If parent is a semver version, prepend it to match rehypeConcatHeadings
118
+ * if (parentTitles?.[0]?.match(/^v\d+\.\d+\.\d+/)) {
119
+ * return `${parentTitles[0]}-${slug}`;
120
+ * }
121
+ * return slug;
122
+ * }
123
+ * ```
124
+ */
125
+ generateSlug?: (text: string, parentTitles?: string[]) => string;
126
+ /** Custom function to flatten sitemap pages into search results */
127
+ flattenPage?: (page: SitemapPage, sectionData: SitemapSectionData) => SearchResult[];
128
+ /** Custom function to format Orama search hits into typed results */
129
+ formatResult?: <TDocument = unknown>(hit: import('@orama/orama').Result<TDocument>) => SearchResult;
130
+ }
131
+ export type SearchBy<T> = Pick<SearchParams<Orama<T>>, 'facets' | 'groupBy' | 'limit' | 'offset' | 'where'>;
132
+ /**
133
+ * Return value from useSearch hook
134
+ */
135
+ export interface UseSearchResult<T> {
136
+ /**
137
+ * Current search results
138
+ */
139
+ results: {
140
+ results: SearchResults;
141
+ count: number;
142
+ elapsed: ElapsedTime;
143
+ };
144
+ /**
145
+ * Whether the search index is ready
146
+ */
147
+ isReady: boolean;
148
+ /**
149
+ * Function to update search value and get new results
150
+ */
151
+ search: (value: string, by?: SearchBy<T>) => Promise<void>;
152
+ /**
153
+ * Default results shown when search is empty
154
+ */
155
+ defaultResults: {
156
+ results: SearchResults;
157
+ count: number;
158
+ elapsed: ElapsedTime;
159
+ };
160
+ /**
161
+ * Build a URL from a search result
162
+ * Handles path normalization and hash fragments for different result types
163
+ */
164
+ buildResultUrl: (result: SearchResult) => string;
165
+ }