From 853283b7e4754bc5e4b0d150605357cc9c7d187e Mon Sep 17 00:00:00 2001 From: MadCcc <1075746765@qq.com> Date: Mon, 20 Feb 2023 10:51:18 +0800 Subject: [PATCH] docs: DatePicker design tab (#40745) * docs: DatePicker design tab * docs: add design demo * docs: add anchor for design demo * docs: init g6 * docs: behavior map * test: fix test cov * docs: behavior map comp * docs: add map title * docs: fix ssr * docs: update demo * docs: optimize copy ux * docs: update demo * chore: code clean --- .../builtins/Previewer/CodePreviewer.tsx | 556 ++++++++++++++++++ .../builtins/Previewer/DesignPreviewer.tsx | 102 ++++ .../builtins/Previewer/fromDumiProps.tsx | 95 --- .dumi/theme/builtins/Previewer/index.tsx | 520 +--------------- .dumi/theme/common/BehaviorMap/index.tsx | 334 +++++++++++ .dumi/theme/layouts/GlobalLayout.tsx | 18 +- .dumi/theme/slots/Content/index.tsx | 8 +- .dumi/theme/slots/ContentTabs/index.tsx | 57 ++ .jest.js | 1 + components/date-picker/demo/aaa.css | 0 .../date-picker/design/behavior-pattern.tsx | 112 ++++ .../design/demo/date-extra-info.tsx | 120 ++++ .../design/demo/pick-date-range.tsx | 9 + .../date-picker/design/demo/pick-date.tsx | 9 + .../design/demo/pick-month-range.tsx | 9 + .../date-picker/design/demo/pick-month.tsx | 9 + .../design/demo/pick-quarter-range.tsx | 9 + .../date-picker/design/demo/pick-quarter.tsx | 9 + .../design/demo/pick-time-range.tsx | 9 + .../date-picker/design/demo/pick-time.tsx | 9 + .../design/demo/pick-week-range.tsx | 9 + .../date-picker/design/demo/pick-week.tsx | 9 + .../design/demo/pick-year-range.tsx | 9 + .../date-picker/design/demo/pick-year.tsx | 9 + .../date-picker/design/demo/preset-range.tsx | 18 + .../date-picker/design/demo/preset-time.tsx | 17 + .../date-picker/index.$tab-design.zh-CN.md | 39 ++ components/date-picker/index.en-US.md | 3 +- components/date-picker/index.ts | 3 + components/date-picker/index.zh-CN.md | 3 +- components/icon/index.en-US.md | 5 +- components/icon/index.zh-CN.md | 5 +- package.json | 3 + 33 files changed, 1508 insertions(+), 619 deletions(-) create mode 100644 .dumi/theme/builtins/Previewer/CodePreviewer.tsx create mode 100644 .dumi/theme/builtins/Previewer/DesignPreviewer.tsx delete mode 100644 .dumi/theme/builtins/Previewer/fromDumiProps.tsx create mode 100644 .dumi/theme/common/BehaviorMap/index.tsx create mode 100644 .dumi/theme/slots/ContentTabs/index.tsx delete mode 100644 components/date-picker/demo/aaa.css create mode 100644 components/date-picker/design/behavior-pattern.tsx create mode 100644 components/date-picker/design/demo/date-extra-info.tsx create mode 100644 components/date-picker/design/demo/pick-date-range.tsx create mode 100644 components/date-picker/design/demo/pick-date.tsx create mode 100644 components/date-picker/design/demo/pick-month-range.tsx create mode 100644 components/date-picker/design/demo/pick-month.tsx create mode 100644 components/date-picker/design/demo/pick-quarter-range.tsx create mode 100644 components/date-picker/design/demo/pick-quarter.tsx create mode 100644 components/date-picker/design/demo/pick-time-range.tsx create mode 100644 components/date-picker/design/demo/pick-time.tsx create mode 100644 components/date-picker/design/demo/pick-week-range.tsx create mode 100644 components/date-picker/design/demo/pick-week.tsx create mode 100644 components/date-picker/design/demo/pick-year-range.tsx create mode 100644 components/date-picker/design/demo/pick-year.tsx create mode 100644 components/date-picker/design/demo/preset-range.tsx create mode 100644 components/date-picker/design/demo/preset-time.tsx create mode 100644 components/date-picker/index.$tab-design.zh-CN.md diff --git a/.dumi/theme/builtins/Previewer/CodePreviewer.tsx b/.dumi/theme/builtins/Previewer/CodePreviewer.tsx new file mode 100644 index 0000000000..cf9d1516df --- /dev/null +++ b/.dumi/theme/builtins/Previewer/CodePreviewer.tsx @@ -0,0 +1,556 @@ +import { + CheckOutlined, + LinkOutlined, + SnippetsOutlined, + ThunderboltOutlined, +} from '@ant-design/icons'; +import type { Project } from '@stackblitz/sdk'; +import stackblitzSdk from '@stackblitz/sdk'; +import { Alert, Badge, Space, Tooltip } from 'antd'; +import classNames from 'classnames'; +import LZString from 'lz-string'; +import React, { useContext, useEffect, useRef, useState } from 'react'; +import CopyToClipboard from 'react-copy-to-clipboard'; +import type { IPreviewerProps } from 'dumi'; +import { FormattedMessage } from 'dumi'; +import Prism from 'prismjs'; +import JsonML from 'jsonml.js/lib/utils'; +import toReactElement from 'jsonml-to-react-element'; +import { ping } from '../../utils'; +import ClientOnly from '../../common/ClientOnly'; +import BrowserFrame from '../../common/BrowserFrame'; +import EditButton from '../../common/EditButton'; +import CodePenIcon from '../../common/CodePenIcon'; +import CodePreview from '../../common/CodePreview'; +import CodeSandboxIcon from '../../common/CodeSandboxIcon'; +import RiddleIcon from '../../common/RiddleIcon'; +import ExternalLinkIcon from '../../common/ExternalLinkIcon'; +import type { SiteContextProps } from '../../slots/SiteContext'; +import SiteContext from '../../slots/SiteContext'; +import useLocation from '../../../hooks/useLocation'; + +const { ErrorBoundary } = Alert; + +function toReactComponent(jsonML: any) { + return toReactElement(jsonML, [ + [ + (node: any) => JsonML.isElement(node) && JsonML.getTagName(node) === 'pre', + (node: any, index: any) => { + // ref: https://github.com/benjycui/bisheng/blob/master/packages/bisheng/src/bisheng-plugin-highlight/lib/browser.js#L7 + const attr = JsonML.getAttributes(node); + return React.createElement( + 'pre', + { + key: index, + className: `language-${attr.lang}`, + }, + React.createElement('code', { + dangerouslySetInnerHTML: { __html: attr.highlighted }, + }), + ); + }, + ], + ]); +} + +function compress(string: string): string { + return LZString.compressToBase64(string) + .replace(/\+/g, '-') // Convert '+' to '-' + .replace(/\//g, '_') // Convert '/' to '_' + .replace(/=+$/, ''); // Remove ending '=' +} + +const track = ({ type, demo }: { type: string; demo: string }) => { + if (!window.gtag) { + return; + } + window.gtag('event', 'demo', { event_category: type, event_label: demo }); +}; + +let pingDeferrer: PromiseLike; + +function useShowRiddleButton() { + const [showRiddleButton, setShowRiddleButton] = useState(false); + + useEffect(() => { + pingDeferrer ??= new Promise((resolve) => { + ping((status) => { + if (status !== 'timeout' && status !== 'error') { + return resolve(true); + } + + return resolve(false); + }); + }); + pingDeferrer.then(setShowRiddleButton); + }, []); + + return showRiddleButton; +} + +const CodePreviewer: React.FC = (props) => { + const { + asset, + expand, + iframe, + demoUrl, + children, + title, + description, + debug, + jsx, + style, + compact, + background, + filePath, + version, + } = props; + + const location = useLocation(); + + const entryCode = asset.dependencies['index.tsx'].value; + const showRiddleButton = useShowRiddleButton(); + + const liveDemo = useRef(null); + const anchorRef = useRef(null); + const codeSandboxIconRef = useRef(null); + const riddleIconRef = useRef(null); + const codepenIconRef = useRef(null); + const [codeExpand, setCodeExpand] = useState(false); + const [copyTooltipOpen, setCopyTooltipOpen] = useState(false); + const [copied, setCopied] = useState(false); + const [codeType, setCodeType] = useState('tsx'); + const { theme } = useContext(SiteContext); + + const { hash, pathname, search } = location; + const docsOnlineUrl = `https://ant.design${pathname}${search}#${asset.id}`; + + const [showOnlineUrl, setShowOnlineUrl] = useState(false); + + const highlightedCodes = { + jsx: Prism.highlight(jsx, Prism.languages.javascript, 'jsx'), + tsx: Prism.highlight(entryCode, Prism.languages.javascript, 'jsx'), + }; + + const highlightedStyle = style ? Prism.highlight(style, Prism.languages.css, 'css') : ''; + + useEffect(() => { + const regexp = /preview-(\d+)-ant-design/; // matching PR preview addresses + setShowOnlineUrl( + process.env.NODE_ENV === 'development' || regexp.test(window.location.hostname), + ); + }, []); + + const handleCodeExpand = (demo: string) => { + setCodeExpand((prev) => !prev); + track({ type: 'expand', demo }); + }; + + const handleCodeCopied = (demo: string) => { + setCopied(true); + track({ type: 'copy', demo }); + }; + + const onCopyTooltipOpenChange = (open: boolean) => { + setCopyTooltipOpen(open); + if (open) { + setCopied(false); + } + }; + + useEffect(() => { + if (asset.id === hash.slice(1)) { + anchorRef.current?.click(); + } + }, []); + + useEffect(() => { + setCodeExpand(expand); + }, [expand]); + + if (!liveDemo.current) { + liveDemo.current = iframe ? ( + +