import React, { type FC, useCallback, useMemo, useState, useRef } from 'react'; import { openCodeSandbox, openStackBlitz, FormattedMessage, // @ts-ignore getSketchJSON, type IPreviewerProps } from 'dumi'; // icons import { AiOutlineCodeSandbox, AiOutlineThunderbolt, AiOutlineBranches } from 'react-icons/ai'; import { BsCode, BsCodeSlash } from 'react-icons/bs'; import { AiOutlineSketch } from 'react-icons/ai'; import { Icon, Button, HStack, Tooltip, Collapse, Popover, VStack, Box, useDisclosure, useColorModeValue, PopoverTrigger, PopoverContent, PopoverArrow, PopoverBody } from '@chakra-ui/react'; import Tabs, { TabList, TabPanel, TabPanels, Tab } from 'dumi/theme/builtins/Tabs'; import SourceCode, { type SourceCodeProps, type CodeTheme } from 'dumi/theme/builtins/SourceCode'; import Copy from '../../components/Copy'; import useThemeConfig from '../../hooks/useThemeConfig'; export type Actions = | 'CSB' | 'CODEPEN' | 'STACKBLITZ' | 'EXTERNAL' | 'HTML2SKETCH'; export interface IPreviewerActionsProps extends IPreviewerProps { /** * disabled actions */ disabledActions?: Actions[]; forceShowCode?: boolean; } const PreviewerActions: FC< IPreviewerActionsProps & Partial > = (props) => { const { disabledActions, asset, forceShowCode, showlinenumber, demoUrl, theme: formatTheme, demoContainer } = props; const { code } = useThemeConfig(); const sketchInstanceRef = useRef(); const [sketchComponent, setSketchComponent] = useState(); const checkActionEnable = useCallback<(action: Actions) => boolean>( (action) => { return !disabledActions?.includes(action); }, [disabledActions] ); const files = Object.entries(asset.dependencies).filter( ([, { type }]) => type === 'FILE' ); const { isOpen, onToggle } = useDisclosure({ isOpen: forceShowCode }); const actionsBorderColor = useColorModeValue('gray.200', 'whiteAlpha.200'); const isSingleFile = files.length === 1; const computedLang = useCallback<(key?: number) => any>( (key = 0) => files[key][0].match(/\.([^.]+)$/)?.[1] || 'text', [files] ); const handleSketch = useCallback( (type: 'group' | 'symbol') => { return getSketchJSON(demoContainer, { type }).then((data: any) => { setSketchComponent(JSON.stringify(data)); (sketchInstanceRef.current as unknown as HTMLElement)?.click?.(); }); }, [demoContainer] ); const sourceCodeTheme = useMemo(() => { return formatTheme ?? code?.theme; }, [formatTheme, code]); return ( <> {checkActionEnable('CSB') && ( } > )} {checkActionEnable('STACKBLITZ') && ( } > )} {checkActionEnable('HTML2SKETCH') && getSketchJSON && ( } > )} {checkActionEnable('EXTERNAL') && ( } > )} {!forceShowCode && ( } > )} {isSingleFile ? ( {files[0][1].value} ) : ( {files.map(([filename], i) => ( {filename} ))} {files.map(([, { value }], i) => ( {value} ))} )} ); }; export default PreviewerActions;