beta/src/components/MDX/Sandpack/utils.ts (84 lines of code) (raw):

/* * Copyright (c) Facebook, Inc. and its affiliates. */ import type {SandpackFile} from '@codesandbox/sandpack-react'; export type ViewportSizePreset = | 'iPhone X' | 'Pixel 2' | 'iPad' | 'Moto G4' | 'Surface Duo'; export type ViewportSize = | ViewportSizePreset | 'auto' | {width: number; height: number}; export type ViewportOrientation = 'portrait' | 'landscape'; export const generateRandomId = (): string => Math.floor(Math.random() * 10000).toString(); const VIEWPORT_SIZE_PRESET_MAP: Record< ViewportSizePreset, {x: number; y: number} > = { 'iPhone X': {x: 375, y: 812}, iPad: {x: 768, y: 1024}, 'Pixel 2': {x: 411, y: 731}, 'Moto G4': {x: 360, y: 640}, 'Surface Duo': {x: 540, y: 720}, }; export const computeViewportSize = ( viewport: ViewportSize, orientation: ViewportOrientation ): {width?: number; height?: number} => { if (viewport === 'auto') { return {}; } if (typeof viewport === 'string') { const {x, y} = VIEWPORT_SIZE_PRESET_MAP[viewport]; return orientation === 'portrait' ? {width: x, height: y} : {width: y, height: x}; } return viewport; }; export const createFileMap = (codeSnippets: any) => { return codeSnippets.reduce( (result: Record<string, SandpackFile>, codeSnippet: React.ReactElement) => { if (codeSnippet.props.mdxType !== 'pre') { return result; } const {props} = codeSnippet.props.children; let filePath; // path in the folder structure let fileHidden = false; // if the file is available as a tab let fileActive = false; // if the file tab is shown by default if (props.metastring) { const [name, ...params] = props.metastring.split(' '); filePath = '/' + name; if (params.includes('hidden')) { fileHidden = true; } if (params.includes('active')) { fileActive = true; } } else { if (props.className === 'language-js') { filePath = '/App.js'; } else if (props.className === 'language-css') { filePath = '/styles.css'; } else { throw new Error( `Code block is missing a filename: ${props.children}` ); } } if (result[filePath]) { throw new Error( `File ${filePath} was defined multiple times. Each file snippet should have a unique path name` ); } result[filePath] = { code: props.children as string, hidden: fileHidden, active: fileActive, }; return result; }, {} ); };