@mui/internal-docs-infra 0.3.1-canary.3 → 0.3.1-canary.5
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.
- package/esm/CodeControllerContext/CodeControllerContext.js +2 -2
- package/esm/CodeExternalsContext/CodeExternalsContext.js +1 -1
- package/esm/CodeHighlighter/CodeHighlighter.js +247 -329
- package/esm/CodeHighlighter/CodeHighlighterClient.js +447 -653
- package/esm/CodeHighlighter/CodeHighlighterContext.js +2 -2
- package/esm/CodeHighlighter/CodeHighlighterFallbackContext.js +2 -2
- package/esm/CodeHighlighter/codeToFallbackProps.js +21 -37
- package/esm/CodeHighlighter/errors.js +248 -400
- package/esm/CodeHighlighter/parseControlledCode.js +12 -20
- package/esm/CodeProvider/CodeContext.js +3 -3
- package/esm/CodeProvider/CodeProvider.js +31 -40
- package/esm/abstractCreateDemo/abstractCreateDemo.js +13 -17
- package/esm/abstractCreateDemoClient/abstractCreateDemoClient.js +12 -12
- package/esm/cli/index.js +1 -1
- package/esm/cli/runValidate.js +160 -264
- package/esm/createDemoData/createDemoData.js +11 -12
- package/esm/createSitemap/createSitemap.js +2 -2
- package/esm/pipeline/getFileConventions/fileConventions.js +1 -1
- package/esm/pipeline/getFileConventions/getFileConventions.js +2 -15
- package/esm/pipeline/hastUtils/hastUtils.js +16 -17
- package/esm/pipeline/loadCodeVariant/addCodeVariantPaths.js +24 -24
- package/esm/pipeline/loadCodeVariant/applyCodeTransform.js +12 -22
- package/esm/pipeline/loadCodeVariant/calculateMainFilePath.js +30 -37
- package/esm/pipeline/loadCodeVariant/computeHastDeltas.js +107 -185
- package/esm/pipeline/loadCodeVariant/diffHast.js +18 -53
- package/esm/pipeline/loadCodeVariant/examineCodeVariant.js +24 -27
- package/esm/pipeline/loadCodeVariant/flattenCodeVariant.js +9 -10
- package/esm/pipeline/loadCodeVariant/hasAllCodeVariants.js +5 -5
- package/esm/pipeline/loadCodeVariant/loadCodeFallback.js +516 -731
- package/esm/pipeline/loadCodeVariant/loadCodeVariant.js +679 -1079
- package/esm/pipeline/loadCodeVariant/maybeCodeInitialData.js +14 -20
- package/esm/pipeline/loadCodeVariant/mergeCodeMetadata.js +53 -63
- package/esm/pipeline/loadCodeVariant/parseCode.js +40 -48
- package/esm/pipeline/loadCodeVariant/pathUtils.js +43 -64
- package/esm/pipeline/loadCodeVariant/transformSource.js +55 -125
- package/esm/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.js +160 -221
- package/esm/pipeline/loadPrecomputedCodeHighlighter/parseCreateFactoryCall.js +377 -479
- package/esm/pipeline/loadPrecomputedCodeHighlighter/parseFunctionArguments.js +171 -173
- package/esm/pipeline/loadPrecomputedCodeHighlighter/performanceLogger.js +14 -30
- package/esm/pipeline/loadPrecomputedCodeHighlighter/replacePrecomputeValue.js +19 -21
- package/esm/pipeline/loadPrecomputedCodeHighlighter/serializeFunctionArguments.js +37 -71
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/filterRuntimeExternals.js +3 -9
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/generateImportStatements.js +54 -80
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/generateResolvedExternals.js +71 -98
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/injectImportsIntoSource.js +5 -5
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/loadPrecomputedCodeHighlighterClient.js +161 -211
- package/esm/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.js +159 -207
- package/esm/pipeline/loadServerCodeMeta/loadServerCodeMeta.js +42 -64
- package/esm/pipeline/loadServerCodeMeta/resolveModulePathWithFs.js +20 -96
- package/esm/pipeline/loadServerPageIndex/loadServerPageIndex.js +66 -85
- package/esm/pipeline/loadServerSitemap/loadServerSitemap.js +71 -118
- package/esm/pipeline/loadServerSource/loadServerSource.js +121 -148
- package/esm/pipeline/loaderUtils/externalsToPackages.js +7 -7
- package/esm/pipeline/loaderUtils/extractNameAndSlugFromUrl.js +8 -12
- package/esm/pipeline/loaderUtils/fileUrlToPortablePath.js +5 -5
- package/esm/pipeline/loaderUtils/getFileNameFromUrl.js +19 -29
- package/esm/pipeline/loaderUtils/getLanguageFromExtension.js +3 -4
- package/esm/pipeline/loaderUtils/mergeExternals.js +15 -35
- package/esm/pipeline/loaderUtils/parseImportsAndComments.js +413 -433
- package/esm/pipeline/loaderUtils/processRelativeImports.js +153 -239
- package/esm/pipeline/loaderUtils/resolveModulePath.js +544 -1303
- package/esm/pipeline/loaderUtils/rewriteImports.js +73 -111
- package/esm/pipeline/parseSource/addLineGutters.js +33 -45
- package/esm/pipeline/parseSource/grammars.js +3 -3
- package/esm/pipeline/parseSource/parseSource.js +13 -31
- package/esm/pipeline/syncPageIndex/createMarkdownNodes.js +32 -55
- package/esm/pipeline/syncPageIndex/mergeMetadataMarkdown.js +107 -160
- package/esm/pipeline/syncPageIndex/metadataToMarkdown.js +846 -1033
- package/esm/pipeline/syncPageIndex/syncPageIndex.js +291 -438
- package/esm/pipeline/transformHtmlCodePrecomputed/transformHtmlCodePrecomputed.js +213 -311
- package/esm/pipeline/transformMarkdownBlockquoteCallouts/transformMarkdownBlockquoteCallouts.js +10 -10
- package/esm/pipeline/transformMarkdownCode/transformMarkdownCode.js +133 -193
- package/esm/pipeline/transformMarkdownDemoLinks/transformMarkdownDemoLinks.js +25 -27
- package/esm/pipeline/transformMarkdownMetadata/transformMarkdownMetadata.js +572 -717
- package/esm/pipeline/transformMarkdownRelativePaths/transformMarkdownRelativePaths.js +8 -8
- package/esm/pipeline/transformTypescriptToJavascript/removeTypes.js +84 -113
- package/esm/pipeline/transformTypescriptToJavascript/transformTypescriptToJavascript.js +10 -26
- package/esm/useCode/Pre.js +58 -62
- package/esm/useCode/useCode.js +59 -61
- package/esm/useCode/useCodeUtils.js +54 -63
- package/esm/useCode/useCopyFunctionality.js +10 -9
- package/esm/useCode/useFileNavigation.js +150 -212
- package/esm/useCode/useSourceEditing.js +17 -14
- package/esm/useCode/useTransformManagement.js +23 -26
- package/esm/useCode/useUIState.js +12 -20
- package/esm/useCode/useVariantSelection.js +62 -79
- package/esm/useCopier/index.js +29 -56
- package/esm/useDemo/createCodeSandbox.js +12 -15
- package/esm/useDemo/createStackBlitz.js +14 -20
- package/esm/useDemo/exportVariant.js +200 -180
- package/esm/useDemo/exportVariantAsCra.js +22 -25
- package/esm/useDemo/useDemo.js +80 -84
- package/esm/useErrors/ErrorsContext.js +1 -1
- package/esm/useErrors/useErrors.js +3 -3
- package/esm/useLocalStorageState/useLocalStorageState.js +23 -39
- package/esm/usePreference/PreferencesProvider.js +1 -1
- package/esm/usePreference/usePreference.js +9 -11
- package/esm/useSearch/useSearch.js +290 -387
- package/esm/useUrlHashState/useUrlHashState.js +11 -14
- package/esm/withDocsInfra/withDeploymentConfig.js +26 -21
- package/esm/withDocsInfra/withDocsInfra.js +99 -101
- package/package.json +7 -4
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
/**
|
|
4
3
|
* Hook for managing source code editing functionality
|
|
5
4
|
*/
|
|
6
|
-
export function useSourceEditing(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
export function useSourceEditing({
|
|
6
|
+
context,
|
|
7
|
+
selectedVariantKey,
|
|
8
|
+
effectiveCode,
|
|
9
|
+
selectedVariant
|
|
10
|
+
}) {
|
|
11
|
+
const contextSetCode = context?.setCode;
|
|
12
|
+
const setSource = React.useCallback(source => {
|
|
13
13
|
if (contextSetCode) {
|
|
14
|
-
contextSetCode(
|
|
15
|
-
|
|
14
|
+
contextSetCode(currentCode => {
|
|
15
|
+
let newCode = {};
|
|
16
16
|
if (!currentCode) {
|
|
17
|
-
newCode =
|
|
17
|
+
newCode = {
|
|
18
|
+
...effectiveCode
|
|
19
|
+
}; // TODO: ensure all source are strings
|
|
18
20
|
}
|
|
19
|
-
newCode[selectedVariantKey] =
|
|
20
|
-
|
|
21
|
+
newCode[selectedVariantKey] = {
|
|
22
|
+
...(newCode[selectedVariantKey] || selectedVariant),
|
|
23
|
+
source,
|
|
21
24
|
extraFiles: {}
|
|
22
|
-
}
|
|
25
|
+
};
|
|
23
26
|
return newCode;
|
|
24
27
|
});
|
|
25
28
|
} else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
import { getAvailableTransforms, createTransformedFiles } from "./useCodeUtils.js";
|
|
4
3
|
import { usePreference } from "../usePreference/index.js";
|
|
@@ -6,36 +5,34 @@ import { usePreference } from "../usePreference/index.js";
|
|
|
6
5
|
* Hook for managing code transforms and their application
|
|
7
6
|
* Uses the useLocalStorage hook for local storage persistence of transform preferences
|
|
8
7
|
*/
|
|
9
|
-
export function useTransformManagement(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
export function useTransformManagement({
|
|
9
|
+
context,
|
|
10
|
+
effectiveCode,
|
|
11
|
+
selectedVariantKey,
|
|
12
|
+
selectedVariant,
|
|
13
|
+
initialTransform,
|
|
14
|
+
shouldHighlight
|
|
15
|
+
}) {
|
|
16
16
|
// Transform state - get available transforms from context or from the effective code data
|
|
17
|
-
|
|
17
|
+
const availableTransforms = React.useMemo(() => {
|
|
18
18
|
// First try to get from context
|
|
19
|
-
if (context
|
|
19
|
+
if (context?.availableTransforms && context.availableTransforms.length > 0) {
|
|
20
20
|
return context.availableTransforms;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// Otherwise, get from the effective code data using the utility function
|
|
24
24
|
return getAvailableTransforms(effectiveCode, selectedVariantKey);
|
|
25
|
-
}, [context
|
|
25
|
+
}, [context?.availableTransforms, effectiveCode, selectedVariantKey]);
|
|
26
26
|
|
|
27
27
|
// Use localStorage hook for transform persistence - this is our single source of truth
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
_usePreference2 = _slicedToArray(_usePreference, 2),
|
|
34
|
-
storedValue = _usePreference2[0],
|
|
35
|
-
setStoredValue = _usePreference2[1];
|
|
28
|
+
const [storedValue, setStoredValue] = usePreference('transform', availableTransforms.length === 1 ? availableTransforms[0] : availableTransforms, () => {
|
|
29
|
+
// Don't use initialTransform as the fallback - localStorage should always take precedence
|
|
30
|
+
// We'll handle the initial transform separately below
|
|
31
|
+
return null;
|
|
32
|
+
});
|
|
36
33
|
|
|
37
34
|
// Handle validation manually - empty string means "no transform selected"
|
|
38
|
-
|
|
35
|
+
const selectedTransform = React.useMemo(() => {
|
|
39
36
|
// If we have a stored value (including empty string), use it
|
|
40
37
|
if (storedValue !== null) {
|
|
41
38
|
if (storedValue === '') {
|
|
@@ -54,19 +51,19 @@ export function useTransformManagement(_ref) {
|
|
|
54
51
|
}
|
|
55
52
|
return null;
|
|
56
53
|
}, [storedValue, availableTransforms, initialTransform]);
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
const setSelectedTransformAsUser = React.useCallback(value => {
|
|
55
|
+
const valueToStore = value === null ? '' : value;
|
|
59
56
|
setStoredValue(valueToStore);
|
|
60
57
|
}, [setStoredValue]);
|
|
61
58
|
|
|
62
59
|
// Memoize all transformed files based on selectedTransform
|
|
63
|
-
|
|
60
|
+
const transformedFiles = React.useMemo(() => {
|
|
64
61
|
return createTransformedFiles(selectedVariant, selectedTransform, shouldHighlight);
|
|
65
62
|
}, [selectedVariant, selectedTransform, shouldHighlight]);
|
|
66
63
|
return {
|
|
67
|
-
availableTransforms
|
|
68
|
-
selectedTransform
|
|
69
|
-
transformedFiles
|
|
64
|
+
availableTransforms,
|
|
65
|
+
selectedTransform,
|
|
66
|
+
transformedFiles,
|
|
70
67
|
selectTransform: setSelectedTransformAsUser
|
|
71
68
|
};
|
|
72
69
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
import { useUrlHashState } from "../useUrlHashState/index.js";
|
|
4
3
|
import { isHashRelevantToDemo } from "./useFileNavigation.js";
|
|
@@ -6,31 +5,24 @@ import { isHashRelevantToDemo } from "./useFileNavigation.js";
|
|
|
6
5
|
* Hook for managing UI state like expansion and focus
|
|
7
6
|
* Auto-expands if there's a relevant hash for this demo
|
|
8
7
|
*/
|
|
9
|
-
export function useUIState(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
var _React$useState = React.useState(defaultOpen || hasRelevantHash),
|
|
18
|
-
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
19
|
-
expanded = _React$useState2[0],
|
|
20
|
-
setExpanded = _React$useState2[1];
|
|
21
|
-
var expand = React.useCallback(function () {
|
|
22
|
-
return setExpanded(true);
|
|
23
|
-
}, []);
|
|
8
|
+
export function useUIState({
|
|
9
|
+
defaultOpen = false,
|
|
10
|
+
mainSlug
|
|
11
|
+
}) {
|
|
12
|
+
const [hash] = useUrlHashState();
|
|
13
|
+
const hasRelevantHash = isHashRelevantToDemo(hash, mainSlug);
|
|
14
|
+
const [expanded, setExpanded] = React.useState(defaultOpen || hasRelevantHash);
|
|
15
|
+
const expand = React.useCallback(() => setExpanded(true), []);
|
|
24
16
|
|
|
25
17
|
// Auto-expand if hash becomes relevant
|
|
26
|
-
React.useEffect(
|
|
18
|
+
React.useEffect(() => {
|
|
27
19
|
if (hasRelevantHash && !expanded) {
|
|
28
20
|
setExpanded(true);
|
|
29
21
|
}
|
|
30
22
|
}, [hasRelevantHash, expanded]);
|
|
31
23
|
return {
|
|
32
|
-
expanded
|
|
33
|
-
expand
|
|
34
|
-
setExpanded
|
|
24
|
+
expanded,
|
|
25
|
+
expand,
|
|
26
|
+
setExpanded
|
|
35
27
|
};
|
|
36
28
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
-
import _typeof from "@babel/runtime/helpers/esm/typeof";
|
|
3
1
|
import * as React from 'react';
|
|
4
2
|
import { usePreference } from "../usePreference/index.js";
|
|
5
3
|
import { useUrlHashState } from "../useUrlHashState/index.js";
|
|
@@ -20,27 +18,23 @@ function parseVariantFromHash(urlHash, mainSlug, variantKeys) {
|
|
|
20
18
|
if (!urlHash) {
|
|
21
19
|
return null;
|
|
22
20
|
}
|
|
23
|
-
|
|
21
|
+
const parts = urlHash.split(':');
|
|
24
22
|
|
|
25
23
|
// If there are 3 parts (slug:variant:file), the variant is in the middle
|
|
26
24
|
if (parts.length === 3) {
|
|
27
|
-
|
|
25
|
+
const variantPart = parts[1];
|
|
28
26
|
// Find matching variant key (case-insensitive kebab match)
|
|
29
|
-
|
|
30
|
-
return toKebabCase(key) === variantPart.toLowerCase();
|
|
31
|
-
});
|
|
27
|
+
const matchingVariant = variantKeys.find(key => toKebabCase(key) === variantPart.toLowerCase());
|
|
32
28
|
return matchingVariant || null;
|
|
33
29
|
}
|
|
34
30
|
|
|
35
31
|
// If there are 2 parts, could be slug:variant or slug:file
|
|
36
32
|
if (parts.length === 2) {
|
|
37
|
-
|
|
33
|
+
const secondPart = parts[1];
|
|
38
34
|
// Try to match as a variant first
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (_matchingVariant) {
|
|
43
|
-
return _matchingVariant;
|
|
35
|
+
const matchingVariant = variantKeys.find(key => toKebabCase(key) === secondPart.toLowerCase());
|
|
36
|
+
if (matchingVariant) {
|
|
37
|
+
return matchingVariant;
|
|
44
38
|
}
|
|
45
39
|
// If no matching variant and it looks like a filename, assume Default
|
|
46
40
|
if (secondPart.includes('.')) {
|
|
@@ -59,75 +53,64 @@ function parseVariantFromHash(urlHash, mainSlug, variantKeys) {
|
|
|
59
53
|
* Priority: URL hash > localStorage > initialVariant > first variant
|
|
60
54
|
* When hash has a variant, it overrides localStorage and is saved to localStorage
|
|
61
55
|
*/
|
|
62
|
-
export function useVariantSelection(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
56
|
+
export function useVariantSelection({
|
|
57
|
+
effectiveCode,
|
|
58
|
+
initialVariant,
|
|
59
|
+
variantType,
|
|
60
|
+
mainSlug,
|
|
61
|
+
saveHashVariantToLocalStorage = 'on-interaction'
|
|
62
|
+
}) {
|
|
69
63
|
// Get variant keys from effective code
|
|
70
|
-
|
|
71
|
-
return Object.keys(effectiveCode).filter(
|
|
72
|
-
|
|
73
|
-
return variant &&
|
|
64
|
+
const variantKeys = React.useMemo(() => {
|
|
65
|
+
return Object.keys(effectiveCode).filter(key => {
|
|
66
|
+
const variant = effectiveCode[key];
|
|
67
|
+
return variant && typeof variant === 'object' && 'source' in variant;
|
|
74
68
|
});
|
|
75
69
|
}, [effectiveCode]);
|
|
76
70
|
|
|
77
71
|
// Get URL hash and parse variant from it
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
urlHash = _useUrlHashState2[0],
|
|
81
|
-
setUrlHash = _useUrlHashState2[1];
|
|
82
|
-
var hashVariant = React.useMemo(function () {
|
|
83
|
-
return parseVariantFromHash(urlHash, mainSlug, variantKeys);
|
|
84
|
-
}, [urlHash, mainSlug, variantKeys]);
|
|
72
|
+
const [urlHash, setUrlHash] = useUrlHashState();
|
|
73
|
+
const hashVariant = React.useMemo(() => parseVariantFromHash(urlHash, mainSlug, variantKeys), [urlHash, mainSlug, variantKeys]);
|
|
85
74
|
|
|
86
75
|
// Use localStorage hook for variant persistence
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
_usePreference2 = _slicedToArray(_usePreference, 2),
|
|
91
|
-
storedValue = _usePreference2[0],
|
|
92
|
-
setStoredValue = _usePreference2[1];
|
|
76
|
+
const [storedValue, setStoredValue] = usePreference('variant', variantType || variantKeys, () => {
|
|
77
|
+
return null;
|
|
78
|
+
});
|
|
93
79
|
|
|
94
80
|
// Track if the last change was user-initiated (to prevent hash from overriding)
|
|
95
|
-
|
|
81
|
+
const isUserInitiatedChange = React.useRef(false);
|
|
96
82
|
// Track previous hash variant to detect hash changes
|
|
97
|
-
|
|
83
|
+
const prevHashVariant = React.useRef(hashVariant);
|
|
98
84
|
// Track previous storedValue to detect localStorage changes
|
|
99
|
-
|
|
85
|
+
const prevStoredValue = React.useRef(storedValue);
|
|
100
86
|
|
|
101
87
|
// Determine initial variant: hash > localStorage > initialVariant > first variant
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
119
|
-
selectedVariantKey = _React$useState2[0],
|
|
120
|
-
setSelectedVariantKeyState = _React$useState2[1];
|
|
88
|
+
const [selectedVariantKey, setSelectedVariantKeyState] = React.useState(() => {
|
|
89
|
+
// Priority 1: Hash variant
|
|
90
|
+
if (hashVariant && variantKeys.includes(hashVariant)) {
|
|
91
|
+
return hashVariant;
|
|
92
|
+
}
|
|
93
|
+
// Priority 2: localStorage
|
|
94
|
+
if (storedValue && variantKeys.includes(storedValue)) {
|
|
95
|
+
return storedValue;
|
|
96
|
+
}
|
|
97
|
+
// Priority 3: initialVariant prop
|
|
98
|
+
if (initialVariant && variantKeys.includes(initialVariant)) {
|
|
99
|
+
return initialVariant;
|
|
100
|
+
}
|
|
101
|
+
// Priority 4: First available variant
|
|
102
|
+
return variantKeys[0] || '';
|
|
103
|
+
});
|
|
121
104
|
|
|
122
105
|
// Track selected variant key in a ref for use in effect without causing re-runs
|
|
123
|
-
|
|
124
|
-
React.useEffect(
|
|
106
|
+
const selectedVariantKeyRef = React.useRef(selectedVariantKey);
|
|
107
|
+
React.useEffect(() => {
|
|
125
108
|
selectedVariantKeyRef.current = selectedVariantKey;
|
|
126
109
|
});
|
|
127
110
|
|
|
128
111
|
// When hash changes and has a variant, override current selection
|
|
129
112
|
// When hash is removed, fall back to localStorage
|
|
130
|
-
React.useEffect(
|
|
113
|
+
React.useEffect(() => {
|
|
131
114
|
// Skip if this was a user-initiated change
|
|
132
115
|
if (isUserInitiatedChange.current) {
|
|
133
116
|
// Only reset the flag once the hash has actually been cleared
|
|
@@ -139,8 +122,8 @@ export function useVariantSelection(_ref) {
|
|
|
139
122
|
}
|
|
140
123
|
|
|
141
124
|
// Only apply hash if it actually changed (not just a re-render with same hash)
|
|
142
|
-
|
|
143
|
-
|
|
125
|
+
const hashChanged = prevHashVariant.current !== hashVariant;
|
|
126
|
+
const storedValueChanged = prevStoredValue.current !== storedValue;
|
|
144
127
|
prevHashVariant.current = hashVariant;
|
|
145
128
|
prevStoredValue.current = storedValue;
|
|
146
129
|
if (!hashChanged && !storedValueChanged) {
|
|
@@ -165,18 +148,18 @@ export function useVariantSelection(_ref) {
|
|
|
165
148
|
storedValue, setStoredValue, saveHashVariantToLocalStorage]);
|
|
166
149
|
|
|
167
150
|
// Programmatic setter: doesn't save to localStorage (used for hash-driven changes)
|
|
168
|
-
|
|
169
|
-
|
|
151
|
+
const setSelectedVariantKeyProgrammatic = React.useCallback(value => {
|
|
152
|
+
const resolvedValue = typeof value === 'function' ? value(selectedVariantKey) : value;
|
|
170
153
|
if (variantKeys.includes(resolvedValue)) {
|
|
171
154
|
setSelectedVariantKeyState(resolvedValue);
|
|
172
155
|
}
|
|
173
156
|
}, [selectedVariantKey, variantKeys]);
|
|
174
157
|
|
|
175
158
|
// User setter: saves to localStorage (used for user-initiated changes like dropdown)
|
|
176
|
-
|
|
177
|
-
|
|
159
|
+
const setSelectedVariantKeyAsUser = React.useCallback(value => {
|
|
160
|
+
const resolvedValue = typeof value === 'function' ? value(selectedVariantKey) : value;
|
|
178
161
|
// If value is null, select the first variant (default)
|
|
179
|
-
|
|
162
|
+
const effectiveValue = resolvedValue ?? variantKeys[0];
|
|
180
163
|
if (effectiveValue && variantKeys.includes(effectiveValue)) {
|
|
181
164
|
// Mark as user-initiated to prevent hash effect from overriding
|
|
182
165
|
isUserInitiatedChange.current = true;
|
|
@@ -190,34 +173,34 @@ export function useVariantSelection(_ref) {
|
|
|
190
173
|
setStoredValue(effectiveValue);
|
|
191
174
|
}
|
|
192
175
|
}, [setStoredValue, selectedVariantKey, variantKeys, urlHash, mainSlug, setUrlHash]);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (variant &&
|
|
176
|
+
const selectedVariant = React.useMemo(() => {
|
|
177
|
+
const variant = effectiveCode[selectedVariantKey];
|
|
178
|
+
if (variant && typeof variant === 'object' && 'source' in variant) {
|
|
196
179
|
return variant;
|
|
197
180
|
}
|
|
198
181
|
return null;
|
|
199
182
|
}, [effectiveCode, selectedVariantKey]);
|
|
200
183
|
|
|
201
184
|
// Safety check: if selectedVariant doesn't exist, fall back to first variant
|
|
202
|
-
React.useEffect(
|
|
185
|
+
React.useEffect(() => {
|
|
203
186
|
if (!selectedVariant && variantKeys.length > 0) {
|
|
204
187
|
setSelectedVariantKeyProgrammatic(variantKeys[0]);
|
|
205
188
|
}
|
|
206
189
|
}, [selectedVariant, variantKeys, setSelectedVariantKeyProgrammatic]);
|
|
207
190
|
|
|
208
191
|
// Function to save variant to localStorage (used for on-interaction mode)
|
|
209
|
-
|
|
192
|
+
const saveVariantToLocalStorage = React.useCallback(variant => {
|
|
210
193
|
if (saveHashVariantToLocalStorage === 'on-interaction' && variant !== storedValue) {
|
|
211
194
|
setStoredValue(variant);
|
|
212
195
|
}
|
|
213
196
|
}, [saveHashVariantToLocalStorage, storedValue, setStoredValue]);
|
|
214
197
|
return {
|
|
215
|
-
variantKeys
|
|
216
|
-
selectedVariantKey
|
|
217
|
-
selectedVariant
|
|
198
|
+
variantKeys,
|
|
199
|
+
selectedVariantKey,
|
|
200
|
+
selectedVariant,
|
|
218
201
|
selectVariant: setSelectedVariantKeyAsUser,
|
|
219
202
|
selectVariantProgrammatic: setSelectedVariantKeyProgrammatic,
|
|
220
|
-
saveVariantToLocalStorage
|
|
221
|
-
hashVariant
|
|
203
|
+
saveVariantToLocalStorage,
|
|
204
|
+
hashVariant
|
|
222
205
|
};
|
|
223
206
|
}
|
package/esm/useCopier/index.js
CHANGED
|
@@ -1,62 +1,35 @@
|
|
|
1
|
-
import _regenerator from "@babel/runtime/helpers/esm/regenerator";
|
|
2
|
-
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
4
1
|
import * as React from 'react';
|
|
5
2
|
import copyToClipboard from 'clipboard-copy';
|
|
6
3
|
export function useCopier(contents, opts) {
|
|
7
|
-
|
|
8
|
-
onCopied
|
|
9
|
-
onError
|
|
10
|
-
onClick
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
setRecentlySuccessful
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
case 2:
|
|
35
|
-
setRecentlySuccessful(true);
|
|
36
|
-
onCopied == null || onCopied();
|
|
37
|
-
copyTimeoutRef.current = setTimeout(function () {
|
|
38
|
-
clearTimeout(copyTimeoutRef.current);
|
|
39
|
-
setRecentlySuccessful(false);
|
|
40
|
-
}, timeout);
|
|
41
|
-
_context.n = 4;
|
|
42
|
-
break;
|
|
43
|
-
case 3:
|
|
44
|
-
_context.p = 3;
|
|
45
|
-
_t = _context.v;
|
|
46
|
-
onError == null || onError(_t);
|
|
47
|
-
case 4:
|
|
48
|
-
onClick == null || onClick(event);
|
|
49
|
-
case 5:
|
|
50
|
-
return _context.a(2);
|
|
51
|
-
}
|
|
52
|
-
}, _callee, null, [[1, 3]]);
|
|
53
|
-
}));
|
|
54
|
-
return function (_x) {
|
|
55
|
-
return _ref2.apply(this, arguments);
|
|
56
|
-
};
|
|
57
|
-
}(), [contents, timeout, onCopied, onError, onClick]);
|
|
4
|
+
const {
|
|
5
|
+
onCopied,
|
|
6
|
+
onError,
|
|
7
|
+
onClick,
|
|
8
|
+
timeout = 2000
|
|
9
|
+
} = opts || {};
|
|
10
|
+
const copyTimeoutRef = React.useRef(undefined);
|
|
11
|
+
const [recentlySuccessful, setRecentlySuccessful] = React.useState(false);
|
|
12
|
+
const copy = React.useCallback(async event => {
|
|
13
|
+
clearTimeout(copyTimeoutRef.current);
|
|
14
|
+
setRecentlySuccessful(false);
|
|
15
|
+
try {
|
|
16
|
+
const content = typeof contents === 'function' ? contents() : contents;
|
|
17
|
+
if (content) {
|
|
18
|
+
await copyToClipboard(content);
|
|
19
|
+
}
|
|
20
|
+
setRecentlySuccessful(true);
|
|
21
|
+
onCopied?.();
|
|
22
|
+
copyTimeoutRef.current = setTimeout(() => {
|
|
23
|
+
clearTimeout(copyTimeoutRef.current);
|
|
24
|
+
setRecentlySuccessful(false);
|
|
25
|
+
}, timeout);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
onError?.(error);
|
|
28
|
+
}
|
|
29
|
+
onClick?.(event);
|
|
30
|
+
}, [contents, timeout, onCopied, onError, onClick]);
|
|
58
31
|
return {
|
|
59
|
-
copy
|
|
60
|
-
recentlySuccessful
|
|
32
|
+
copy,
|
|
33
|
+
recentlySuccessful
|
|
61
34
|
};
|
|
62
35
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
1
|
import LZString from 'lz-string';
|
|
3
2
|
/**
|
|
4
3
|
* Compress object for CodeSandbox API
|
|
@@ -13,30 +12,28 @@ function compress(object) {
|
|
|
13
12
|
* Utility function for creating CodeSandbox demos
|
|
14
13
|
* Returns the configuration that can be used with openWithForm
|
|
15
14
|
*/
|
|
16
|
-
export function createCodeSandbox(
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export function createCodeSandbox({
|
|
16
|
+
flattenedFiles,
|
|
17
|
+
rootFile
|
|
18
|
+
}) {
|
|
19
19
|
// Convert flattened files to string format
|
|
20
|
-
|
|
21
|
-
Object.entries(flattenedFiles).forEach(
|
|
22
|
-
var _ref3 = _slicedToArray(_ref2, 2),
|
|
23
|
-
filePath = _ref3[0],
|
|
24
|
-
fileData = _ref3[1];
|
|
20
|
+
const files = {};
|
|
21
|
+
Object.entries(flattenedFiles).forEach(([filePath, fileData]) => {
|
|
25
22
|
files[filePath] = {
|
|
26
23
|
content: fileData.source
|
|
27
24
|
};
|
|
28
25
|
});
|
|
29
|
-
|
|
30
|
-
files
|
|
26
|
+
const parameters = compress({
|
|
27
|
+
files
|
|
31
28
|
});
|
|
32
29
|
|
|
33
30
|
// ref: https://codesandbox.io/docs/learn/browser-sandboxes/cli-api#supported-parameters
|
|
34
|
-
|
|
35
|
-
parameters
|
|
36
|
-
query:
|
|
31
|
+
const formData = {
|
|
32
|
+
parameters,
|
|
33
|
+
query: `file=${rootFile}`
|
|
37
34
|
};
|
|
38
35
|
return {
|
|
39
36
|
url: 'https://codesandbox.io/api/v1/sandboxes/define',
|
|
40
|
-
formData
|
|
37
|
+
formData
|
|
41
38
|
};
|
|
42
39
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
1
|
/**
|
|
3
2
|
* Utility function for creating StackBlitz demos
|
|
4
3
|
* Returns the configuration that can be used with openWithForm
|
|
@@ -7,32 +6,27 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
|
7
6
|
/**
|
|
8
7
|
* Create StackBlitz configuration for use with openWithForm
|
|
9
8
|
*/
|
|
10
|
-
export function createStackBlitz(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
export function createStackBlitz({
|
|
10
|
+
title,
|
|
11
|
+
description,
|
|
12
|
+
flattenedFiles,
|
|
13
|
+
rootFile
|
|
14
|
+
}) {
|
|
15
15
|
// Convert flattened files to string format
|
|
16
|
-
|
|
17
|
-
Object.entries(flattenedFiles).forEach(
|
|
18
|
-
var _ref3 = _slicedToArray(_ref2, 2),
|
|
19
|
-
filePath = _ref3[0],
|
|
20
|
-
fileData = _ref3[1];
|
|
16
|
+
const files = {};
|
|
17
|
+
Object.entries(flattenedFiles).forEach(([filePath, fileData]) => {
|
|
21
18
|
files[filePath] = fileData.source;
|
|
22
19
|
});
|
|
23
|
-
|
|
20
|
+
const formData = {
|
|
24
21
|
'project[template]': 'node',
|
|
25
22
|
'project[title]': title,
|
|
26
|
-
'project[description]':
|
|
23
|
+
'project[description]': `# ${title}\n${description}`
|
|
27
24
|
};
|
|
28
|
-
Object.entries(files).forEach(
|
|
29
|
-
|
|
30
|
-
key = _ref5[0],
|
|
31
|
-
value = _ref5[1];
|
|
32
|
-
formData["project[files][".concat(key, "]")] = value;
|
|
25
|
+
Object.entries(files).forEach(([key, value]) => {
|
|
26
|
+
formData[`project[files][${key}]`] = value;
|
|
33
27
|
});
|
|
34
28
|
return {
|
|
35
|
-
url:
|
|
36
|
-
formData
|
|
29
|
+
url: `https://stackblitz.com/run?file=${rootFile}`,
|
|
30
|
+
formData
|
|
37
31
|
};
|
|
38
32
|
}
|