mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 02:49:18 +08:00
docs: fix suspense fallback trigger by RiddleButton (#52138)
This commit is contained in:
@@ -8,6 +8,7 @@ import classNames from 'classnames';
|
||||
import { FormattedMessage, useLiveDemo, useSiteData } from 'dumi';
|
||||
import LZString from 'lz-string';
|
||||
|
||||
import RiddleButton from './RiddleButton';
|
||||
import useLocation from '../../../hooks/useLocation';
|
||||
import BrowserFrame from '../../common/BrowserFrame';
|
||||
import ClientOnly from '../../common/ClientOnly';
|
||||
@@ -16,11 +17,9 @@ import EditButton from '../../common/EditButton';
|
||||
import CodePenIcon from '../../icons/CodePenIcon';
|
||||
import CodeSandboxIcon from '../../icons/CodeSandboxIcon';
|
||||
import ExternalLinkIcon from '../../icons/ExternalLinkIcon';
|
||||
import RiddleIcon from '../../icons/RiddleIcon';
|
||||
import DemoContext from '../../slots/DemoContext';
|
||||
import type { SiteContextProps } from '../../slots/SiteContext';
|
||||
import SiteContext from '../../slots/SiteContext';
|
||||
import { ping } from '../../utils';
|
||||
import type { AntdPreviewerProps } from './Previewer';
|
||||
|
||||
const { ErrorBoundary } = Alert;
|
||||
@@ -39,27 +38,6 @@ const track = ({ type, demo }: { type: string; demo: string }) => {
|
||||
window.gtag('event', 'demo', { event_category: type, event_label: demo });
|
||||
};
|
||||
|
||||
let pingDeferrer: PromiseLike<boolean>;
|
||||
|
||||
function useShowRiddleButton() {
|
||||
const [showRiddleButton, setShowRiddleButton] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
pingDeferrer ??= new Promise<boolean>((resolve) => {
|
||||
ping((status) => {
|
||||
if (status !== 'timeout' && status !== 'error') {
|
||||
return resolve(true);
|
||||
}
|
||||
|
||||
return resolve(false);
|
||||
});
|
||||
});
|
||||
pingDeferrer.then(setShowRiddleButton);
|
||||
}, []);
|
||||
|
||||
return showRiddleButton;
|
||||
}
|
||||
|
||||
const useStyle = createStyles(({ token }) => {
|
||||
const { borderRadius } = token;
|
||||
return {
|
||||
@@ -98,7 +76,7 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
|
||||
title,
|
||||
description,
|
||||
originDebug,
|
||||
jsx,
|
||||
jsx = '',
|
||||
style,
|
||||
compact,
|
||||
background,
|
||||
@@ -117,7 +95,6 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
|
||||
|
||||
const entryName = 'index.tsx';
|
||||
const entryCode = asset.dependencies[entryName].value;
|
||||
const showRiddleButton = useShowRiddleButton();
|
||||
|
||||
const previewDemo = useRef<React.ReactNode>(null);
|
||||
const demoContainer = useRef<HTMLElement>(null);
|
||||
@@ -127,11 +104,10 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
|
||||
setSource: setLiveDemoSource,
|
||||
} = useLiveDemo(asset.id, {
|
||||
iframe: Boolean(iframe),
|
||||
containerRef: demoContainer,
|
||||
containerRef: demoContainer as React.RefObject<HTMLElement>,
|
||||
});
|
||||
const anchorRef = useRef<HTMLAnchorElement>(null);
|
||||
const codeSandboxIconRef = useRef<HTMLFormElement>(null);
|
||||
const riddleIconRef = useRef<HTMLFormElement>(null);
|
||||
const codepenIconRef = useRef<HTMLFormElement>(null);
|
||||
const [codeExpand, setCodeExpand] = useState<boolean>(false);
|
||||
const { theme } = useContext<SiteContextProps>(SiteContext);
|
||||
@@ -277,19 +253,6 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
|
||||
.join(';'),
|
||||
js_pre_processor: 'typescript',
|
||||
};
|
||||
|
||||
const riddlePrefillConfig = {
|
||||
title: `${localizedTitle} - antd@${dependencies.antd}`,
|
||||
js: `${
|
||||
/import React(\D*)from 'react';/.test(jsx) ? '' : `import React from 'react';\n`
|
||||
}import { createRoot } from 'react-dom/client';\n${jsx.replace(
|
||||
/export default/,
|
||||
'const ComponentDemo =',
|
||||
)}\n\ncreateRoot(mountNode).render(<ComponentDemo />);\n`,
|
||||
css: '',
|
||||
json: JSON.stringify({ name: 'antd-demo', dependencies }, null, 2),
|
||||
};
|
||||
|
||||
// Reorder source code
|
||||
let parsedSourceCode = suffix === 'tsx' ? entryCode : jsx;
|
||||
let importReactContent = "import React from 'react';";
|
||||
@@ -440,24 +403,13 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
<CodeSandboxIcon className="code-box-codesandbox" />
|
||||
</Tooltip>
|
||||
</form>
|
||||
{showRiddleButton ? (
|
||||
<form
|
||||
className="code-box-code-action"
|
||||
action="//riddle.alibaba-inc.com/riddles/define"
|
||||
method="POST"
|
||||
target="_blank"
|
||||
ref={riddleIconRef}
|
||||
onClick={() => {
|
||||
track({ type: 'riddle', demo: asset.id });
|
||||
riddleIconRef.current?.submit();
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="data" value={JSON.stringify(riddlePrefillConfig)} />
|
||||
<Tooltip title={<FormattedMessage id="app.demo.riddle" />}>
|
||||
<RiddleIcon className="code-box-riddle" />
|
||||
</Tooltip>
|
||||
</form>
|
||||
) : null}
|
||||
<RiddleButton
|
||||
title={localizedTitle}
|
||||
dependencies={dependencies}
|
||||
jsx={jsx}
|
||||
track={track}
|
||||
asset={asset}
|
||||
/>
|
||||
<Tooltip title={<FormattedMessage id="app.demo.stackblitz" />}>
|
||||
<span
|
||||
className="code-box-code-action"
|
||||
|
||||
@@ -7,6 +7,7 @@ import DesignPreviewer from './DesignPreviewer';
|
||||
|
||||
export interface AntdPreviewerProps extends IPreviewerProps {
|
||||
originDebug?: IPreviewerProps['debug'];
|
||||
jsx?: string;
|
||||
}
|
||||
|
||||
const Previewer: React.FC<AntdPreviewerProps> = (props) => {
|
||||
|
||||
91
.dumi/theme/builtins/Previewer/RiddleButton.tsx
Normal file
91
.dumi/theme/builtins/Previewer/RiddleButton.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import React, { Suspense, useEffect, useRef, useState } from 'react';
|
||||
import { Tooltip } from 'antd';
|
||||
import { FormattedMessage } from 'dumi';
|
||||
|
||||
import type { IPreviewerProps } from 'dumi';
|
||||
|
||||
import RiddleIcon from '../../icons/RiddleIcon';
|
||||
import { ping } from '../../utils';
|
||||
|
||||
let pingDeferrer: PromiseLike<boolean>;
|
||||
|
||||
function useShowRiddleButton() {
|
||||
const [showRiddleButton, setShowRiddleButton] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
pingDeferrer ??= new Promise<boolean>((resolve) => {
|
||||
ping((status) => {
|
||||
if (status !== 'timeout' && status !== 'error') {
|
||||
return resolve(true);
|
||||
}
|
||||
|
||||
return resolve(false);
|
||||
});
|
||||
});
|
||||
pingDeferrer.then(setShowRiddleButton);
|
||||
}, []);
|
||||
|
||||
return showRiddleButton;
|
||||
}
|
||||
|
||||
interface RiddleButtonProps {
|
||||
title?: string;
|
||||
dependencies: Record<PropertyKey, string>;
|
||||
jsx: string;
|
||||
track: ({
|
||||
type,
|
||||
demo,
|
||||
}: {
|
||||
type: string;
|
||||
demo: string;
|
||||
}) => void;
|
||||
asset: IPreviewerProps['asset'];
|
||||
}
|
||||
|
||||
const RiddleButton: React.FC<RiddleButtonProps> = ({
|
||||
title,
|
||||
dependencies = {},
|
||||
jsx,
|
||||
track,
|
||||
asset,
|
||||
}) => {
|
||||
const riddleIconRef = useRef<HTMLFormElement>(null);
|
||||
const showRiddleButton = useShowRiddleButton();
|
||||
|
||||
const riddlePrefillConfig = {
|
||||
title: `${title} - antd@${dependencies.antd}`,
|
||||
js: `${
|
||||
/import React(\D*)from 'react';/.test(jsx) ? '' : `import React from 'react';\n`
|
||||
}import { createRoot } from 'react-dom/client';\n${jsx.replace(
|
||||
/export default/,
|
||||
'const ComponentDemo =',
|
||||
)}\n\ncreateRoot(mountNode).render(<ComponentDemo />);\n`,
|
||||
css: '',
|
||||
json: JSON.stringify({ name: 'antd-demo', dependencies }, null, 2),
|
||||
};
|
||||
|
||||
return showRiddleButton ? (
|
||||
<form
|
||||
className="code-box-code-action"
|
||||
action="//riddle.alibaba-inc.com/riddles/define"
|
||||
method="POST"
|
||||
target="_blank"
|
||||
ref={riddleIconRef}
|
||||
onClick={() => {
|
||||
track({ type: 'riddle', demo: asset.id });
|
||||
riddleIconRef.current?.submit();
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="data" value={JSON.stringify(riddlePrefillConfig)} />
|
||||
<Tooltip title={<FormattedMessage id="app.demo.riddle" />}>
|
||||
<RiddleIcon className="code-box-riddle" />
|
||||
</Tooltip>
|
||||
</form>
|
||||
) : null;
|
||||
};
|
||||
|
||||
export default (props: RiddleButtonProps) => (
|
||||
<Suspense>
|
||||
<RiddleButton {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
Reference in New Issue
Block a user