├── .changelogrc.js ├── .commitlintrc.js ├── .dumi └── theme │ └── builtins │ ├── Previewer.tsx │ └── ToSketch │ ├── ToSketchLayout.tsx │ ├── index.ts │ ├── useElements.ts │ └── useSketchJSON.ts ├── .dumirc.ts ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .fatherrc.ts ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md └── workflows │ ├── deploy.yml │ ├── preview.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── .gitpod.yml ├── .husky ├── commit-msg └── pre-commit ├── .npmrc ├── .prettierignore ├── .prettierrc.js ├── .releaserc.js ├── .stylelintrc.js ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README.zh-CN.md ├── config └── routes.ts ├── docs ├── e2e │ ├── basic │ │ ├── background.md │ │ ├── canvas.md │ │ ├── demos │ │ │ ├── BackgroundImage │ │ │ │ ├── Inline.less │ │ │ │ ├── InlinePng.tsx │ │ │ │ ├── InlineSvg.tsx │ │ │ │ ├── WithSize.tsx │ │ │ │ └── WithoutSize.tsx │ │ │ ├── CanvasBasic.tsx │ │ │ ├── CanvasCors.tsx │ │ │ ├── Checkbox.tsx │ │ │ ├── Image │ │ │ │ ├── ImageInline.tsx │ │ │ │ ├── ImageNoProtocol.tsx │ │ │ │ ├── ImagePng.tsx │ │ │ │ ├── ImageSvg.tsx │ │ │ │ └── TwoInlineImage.tsx │ │ │ ├── Overflow │ │ │ │ ├── switch.css │ │ │ │ └── switch.tsx │ │ │ ├── Position.less │ │ │ ├── Position.tsx │ │ │ ├── Radio.tsx │ │ │ ├── Select.tsx │ │ │ ├── Switch.tsx │ │ │ └── Text │ │ │ │ ├── BlockAlign.tsx │ │ │ │ ├── Ellipsis.tsx │ │ │ │ ├── FlexAlign.tsx │ │ │ │ ├── Input.tsx │ │ │ │ ├── InputAligin.tsx │ │ │ │ ├── InputVerticalAligin.tsx │ │ │ │ ├── Label.tsx │ │ │ │ ├── MutliLine.tsx │ │ │ │ ├── Span.tsx │ │ │ │ ├── SpanIcon.tsx │ │ │ │ ├── SpanInlineBlock.tsx │ │ │ │ ├── SpanLinkRow.tsx │ │ │ │ ├── TagInlineBlock.tsx │ │ │ │ ├── Text.less │ │ │ │ ├── TextAlignment │ │ │ │ ├── index.tsx │ │ │ │ └── style.css │ │ │ │ └── TextArea.tsx │ │ ├── image.md │ │ ├── overflow.md │ │ ├── position.md │ │ ├── pseudo.md │ │ └── text.md │ ├── components │ │ ├── ant-design.md │ │ ├── antd │ │ │ ├── Checkbox.tsx │ │ │ ├── DatePicker.tsx │ │ │ ├── DefaultModal.tsx │ │ │ ├── Input.tsx │ │ │ ├── Modal.less │ │ │ ├── Radio.tsx │ │ │ ├── Rate.tsx │ │ │ ├── Skeleton.tsx │ │ │ ├── Steps.tsx │ │ │ ├── Table.tsx │ │ │ ├── Tabs.tsx │ │ │ └── Tooltip.tsx │ │ ├── modal.md │ │ ├── pro-components.md │ │ └── procomponents │ │ │ ├── ProCard.tsx │ │ │ └── ProTable.tsx │ ├── index.md │ ├── styles │ │ ├── demos │ │ │ ├── LineGradient.tsx │ │ │ ├── Scale.less │ │ │ └── Scale.tsx │ │ ├── gradient.md │ │ └── transform.md │ ├── svg.md │ └── svg │ │ ├── basic.md │ │ ├── demos │ │ ├── GroupNoFill.tsx │ │ ├── Icons.tsx │ │ ├── Layout.tsx │ │ ├── RadialGradient.tsx │ │ ├── SvgBackground.tsx │ │ ├── SvgGroup.tsx │ │ ├── SvgIllustration.tsx │ │ ├── SvgMutliPath.tsx │ │ ├── SvgPathGroup.tsx │ │ ├── SvgSimpleIllustration.tsx │ │ ├── SvgTest.tsx │ │ ├── Text.tsx │ │ ├── TransformAttr.tsx │ │ ├── UseSymbol.tsx │ │ └── svg │ │ │ ├── background.svg │ │ │ ├── illustration.svg │ │ │ ├── layout.svg │ │ │ ├── noFill.svg │ │ │ ├── radialGradient.svg │ │ │ ├── test.svg │ │ │ ├── text.svg │ │ │ └── transform.svg │ │ ├── icon.md │ │ └── illustration.md ├── guide │ ├── framework.md │ ├── index.md │ ├── install.md │ └── test.md ├── index.md └── sketch │ ├── button.md │ └── demo │ ├── Button.tsx │ ├── Footer.tsx │ ├── Icon.tsx │ └── utils │ └── symbolName.ts ├── jest.config.ts ├── jsconfig.json ├── package.json ├── public └── favicon.ico ├── src ├── constraints │ └── symbolParams │ │ ├── Modal.ts │ │ ├── WelcomeHeader.ts │ │ └── index.ts ├── function │ ├── adjustSymbolParams.ts │ ├── index.ts │ ├── nodeToGroup.ts │ ├── nodeToLayers.ts │ ├── nodeToSymbol.ts │ └── setting.ts ├── index.ts ├── models │ ├── Base │ │ ├── BaseLayer.ts │ │ ├── BaseShadow.ts │ │ ├── BaseStyle.ts │ │ └── Frame.ts │ ├── Document │ │ ├── Page.ts │ │ └── SketchDocument.ts │ ├── Layer │ │ ├── Artboard.ts │ │ ├── Bitmap.ts │ │ ├── Ellipse.ts │ │ ├── Group.ts │ │ ├── Rectangle.ts │ │ ├── ShapeGroup.ts │ │ ├── ShapePath.ts │ │ ├── Svg.ts │ │ ├── SymbolInstance.ts │ │ ├── SymbolMaster.ts │ │ └── Text.ts │ ├── Style │ │ ├── Border.ts │ │ ├── Color.ts │ │ ├── ColorAsset.ts │ │ ├── Fill.ts │ │ ├── Gradient.ts │ │ ├── Image.ts │ │ ├── InnerShadow.ts │ │ ├── Shadow.ts │ │ ├── SketchBorderOptions.ts │ │ ├── Style.ts │ │ └── TextStyle.ts │ ├── index.ts │ └── utils.ts ├── parser │ ├── canvas.ts │ ├── colorAsset.ts │ ├── group.ts │ ├── image.ts │ ├── index.ts │ ├── inputText.ts │ ├── pseudoShape.ts │ ├── pseudoText.ts │ ├── shape.ts │ ├── sharedTextStyle.ts │ ├── svg.ts │ ├── svgson.ts │ └── text.ts ├── types │ ├── gradient.ts │ ├── index.ts │ ├── layout.ts │ ├── model.ts │ ├── sketchFormat.ts │ ├── symbol.ts │ └── type.ts └── utils │ ├── background.ts │ ├── clipPath.ts │ ├── fetch.ts │ ├── hierarchy.ts │ ├── image.ts │ ├── layout.ts │ ├── matrix.ts │ ├── name.ts │ ├── nodeType.ts │ ├── overflow.ts │ ├── pseudo.ts │ ├── style.ts │ ├── svg.ts │ ├── text.ts │ ├── utils.ts │ └── visibility.ts ├── tests ├── __mocks__ │ └── uuid.ts ├── __tests__ │ ├── antd │ │ ├── __snapshots__ │ │ │ └── antd.spec.tsx.snap │ │ ├── antd.spec.tsx │ │ ├── json │ │ │ ├── default-modal.json │ │ │ ├── radio.json │ │ │ ├── svg-button.json │ │ │ └── svg-icon.json │ │ └── utils.ts │ ├── e2e │ │ └── image.spec.tsx │ ├── function │ │ ├── adjustSymbolParams.spec.ts │ │ ├── html │ │ │ ├── nodeToGroup.html │ │ │ └── nodeToLayers.html │ │ ├── nodeToGroup.spec.ts │ │ ├── nodeToLayers.spec.ts │ │ ├── nodeToSymbol.spec.ts │ │ └── setting.spec.ts │ ├── model │ │ ├── Base │ │ │ ├── BaseLayer.spec.ts │ │ │ ├── Frame.spec.ts │ │ │ └── __snapshots__ │ │ │ │ └── Frame.spec.ts.snap │ │ ├── Document │ │ │ ├── Page.spec.ts │ │ │ ├── __snapshots__ │ │ │ │ └── Page.spec.ts.snap │ │ │ └── sketch.spec.ts │ │ ├── Layer │ │ │ ├── Artboard.spec.ts │ │ │ ├── Bitmap.spec.ts │ │ │ ├── Ellipse.spec.ts │ │ │ ├── Group.spec.ts │ │ │ ├── Rectangle.spec.ts │ │ │ ├── ShapeGroup.spec.ts │ │ │ ├── ShapePath.spec.ts │ │ │ ├── Svg.spec.ts │ │ │ ├── SymbolInstance.spec.ts │ │ │ ├── SymbolMaster.spec.ts │ │ │ ├── Text.spec.ts │ │ │ └── __snapshots__ │ │ │ │ ├── Bitmap.spec.ts.snap │ │ │ │ ├── Rectangle.spec.ts.snap │ │ │ │ ├── ShapeGroup.spec.ts.snap │ │ │ │ └── ShapePath.spec.ts.snap │ │ └── Style │ │ │ ├── Color.spec.ts │ │ │ ├── ColorAsset.spec.ts │ │ │ ├── Gradient.spec.ts │ │ │ ├── Image.spec.ts │ │ │ ├── Shadow.spec.ts │ │ │ ├── SketchBorderOptions.spec.ts │ │ │ ├── Style.spec.ts │ │ │ ├── TextStyle.spec.ts │ │ │ └── __snapshots__ │ │ │ ├── Color.spec.ts.snap │ │ │ └── TextStyle.spec.ts.snap │ ├── parser │ │ ├── InputText.spec.ts │ │ ├── canvas.spec.ts │ │ ├── colorAsset.test.ts │ │ ├── group.spec.ts │ │ ├── html │ │ │ ├── shape.html │ │ │ └── text.html │ │ ├── image.spec.ts │ │ ├── pseudoShape.spec.ts │ │ ├── pseudoText.spec.ts │ │ ├── shape.spec.ts │ │ ├── sharedTextStyle.spec.ts │ │ ├── svg.spec.ts │ │ ├── svgson.spec.ts │ │ └── text.spec.ts │ └── utils │ │ ├── background.spec.ts │ │ ├── image.spec.ts │ │ ├── layout.spec.ts │ │ ├── matrix.spec.ts │ │ ├── name.spec.ts │ │ ├── nodeType.test.ts │ │ ├── persudo.spec.ts │ │ ├── style.spec.ts │ │ ├── svg.spec.ts │ │ ├── utils.spec.ts │ │ └── visibility.spec.ts ├── __utils__ │ ├── index.ts │ ├── json │ │ ├── antd.json │ │ ├── behance.json │ │ ├── dropbox.json │ │ ├── inline-image.json │ │ ├── parser │ │ │ ├── antd.json │ │ │ ├── basic.json │ │ │ └── up-circle.json │ │ ├── plus.json │ │ ├── png-url-image.json │ │ ├── pseudo-text.json │ │ ├── shape.json │ │ ├── svg-path.json │ │ ├── svg.json │ │ ├── text.json │ │ └── up-circle.json │ ├── svg │ │ ├── antdOpt.svg │ │ ├── antdRaw.svg │ │ ├── bgOpt.svg │ │ ├── bgRaw.svg │ │ └── illustration.svg │ └── testSvgData.ts └── setup.ts ├── tsconfig-check.json └── tsconfig.json /.changelogrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | displayTypes: ['feat', 'fix', 'style', 'pref'], 3 | }; 4 | -------------------------------------------------------------------------------- /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['gitmoji'], 3 | }; 4 | -------------------------------------------------------------------------------- /.dumi/theme/builtins/Previewer.tsx: -------------------------------------------------------------------------------- 1 | import Previewer from 'dumi/theme-default/builtins/Previewer'; 2 | import React from 'react'; 3 | 4 | import { TestLayout, useElements } from './ToSketch'; 5 | 6 | const CustomPreviewer: typeof Previewer = ({ 7 | children, 8 | hideSketchLayout, 9 | ...props 10 | }) => { 11 | const { ref, elements } = useElements(); 12 | return ( 13 | 14 | {hideSketchLayout ? ( 15 | children 16 | ) : ( 17 | 18 |
{children}
19 |
20 | )} 21 |
22 | ); 23 | }; 24 | 25 | export default CustomPreviewer; 26 | -------------------------------------------------------------------------------- /.dumi/theme/builtins/ToSketch/ToSketchLayout.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Card, Col, Divider, Row, Space } from 'antd'; 2 | import React, { FC, ReactNode, useState } from 'react'; 3 | import ReactJson from 'react-json-view'; 4 | import useSketchJSON from './useSketchJSON'; 5 | 6 | interface FooterProps { 7 | elements: Element[] | Element; 8 | buttons?: { name: string; onClick: () => void }[]; 9 | children?: ReactNode; 10 | } 11 | 12 | const ToSketchLayout: FC = ({ elements, children, buttons }) => { 13 | const { sketchJSON, generateGroup, generateSymbol } = useSketchJSON(); 14 | const [showJSON, setShowJSON] = useState(false); 15 | 16 | return ( 17 |
18 | {children} 19 | 20 | 21 | 22 | 23 | 24 | 32 | 33 | 34 | 35 | {buttons?.map((button) => ( 36 | 39 | ))} 40 | 47 | 55 | 56 | 57 | 58 | 59 | {showJSON ? ( 60 | 61 | 62 | 63 | 64 | 65 | ) : null} 66 | 67 |
68 | ); 69 | }; 70 | 71 | export default ToSketchLayout; 72 | -------------------------------------------------------------------------------- /.dumi/theme/builtins/ToSketch/index.ts: -------------------------------------------------------------------------------- 1 | export { default as TestLayout } from './ToSketchLayout'; 2 | export { default as useElements } from './useElements'; 3 | -------------------------------------------------------------------------------- /.dumi/theme/builtins/ToSketch/useElements.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | 3 | export default () => { 4 | const ref = useRef(null); 5 | const [elements, setElements] = useState([]); 6 | 7 | useEffect(() => { 8 | if (elements.length === 0 && ref.current) { 9 | // @ts-ignore 10 | setElements(ref.current); 11 | } 12 | }); 13 | return { ref, elements, setElements }; 14 | }; 15 | -------------------------------------------------------------------------------- /.dumi/theme/builtins/ToSketch/useSketchJSON.ts: -------------------------------------------------------------------------------- 1 | import SketchFormat from '@sketch-hq/sketch-file-format-ts'; 2 | import { message } from 'antd'; 3 | import copy from 'copy-to-clipboard'; 4 | import { nodeToGroup, nodeToSymbol } from 'html2sketch'; 5 | import { useState } from 'react'; 6 | 7 | declare global { 8 | interface Window { 9 | DUMI_HTML2SKETCH: { 10 | nodeToSymbol: any; 11 | nodeToGroup: any; 12 | }; 13 | } 14 | } 15 | 16 | if (typeof window !== 'undefined') { 17 | window.DUMI_HTML2SKETCH = { 18 | nodeToSymbol, 19 | nodeToGroup, 20 | }; 21 | } 22 | 23 | const useSketchJSON = () => { 24 | const [sketchJSON, setJSON] = useState(); 25 | 26 | const parserFactory = async ( 27 | elements: Element | Element[], 28 | parserFunc: ( 29 | el: Element, 30 | ) => Promise, 31 | ) => { 32 | try { 33 | console.groupCollapsed('[html2sketch]开始转换...'); 34 | let result; 35 | if (elements instanceof Array) { 36 | const objects: Object[] = []; 37 | 38 | for (let i = 0; i < elements.length; i += 1) { 39 | const el = elements[i]; 40 | // eslint-disable-next-line no-await-in-loop 41 | const symbolJSON = await parserFunc(el); 42 | objects.push(symbolJSON); 43 | } 44 | 45 | result = objects; 46 | } else { 47 | result = await parserFunc(elements); 48 | } 49 | console.groupEnd(); 50 | console.log('解析结果:', result); 51 | copy(JSON.stringify(result)); 52 | setJSON(result); 53 | await message.success('转换成功🎉 已复制到剪切板'); 54 | return result; 55 | } catch (e) { 56 | await message.error('解析失败,请检查 Console 输出 😶'); 57 | console.groupEnd(); 58 | console.groupEnd(); 59 | console.error('报错如下:'); 60 | console.error(e); 61 | } 62 | }; 63 | 64 | /** 65 | * 生成 Group 的方法 66 | * @param elements 67 | */ 68 | 69 | return { 70 | sketchJSON, 71 | generateSymbol: async (elements: Element | Element[]) => { 72 | await parserFactory(elements, async (el: Element) => 73 | (await nodeToSymbol(el)).toSketchJSON(), 74 | ); 75 | }, 76 | generateGroup: async (elements: Element | Element[]) => { 77 | await parserFactory(elements, async (el: Element) => 78 | (await nodeToGroup(el)).toSketchJSON(), 79 | ); 80 | }, 81 | }; 82 | }; 83 | 84 | export default useSketchJSON; 85 | -------------------------------------------------------------------------------- /.dumirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'dumi'; 2 | import { resolve } from 'path'; 3 | 4 | import { nav, sidebar } from './config/routes'; 5 | 6 | const isProdSite = 7 | // 不是预览模式 同时是生产环境 8 | process.env.PREVIEW !== '1' && process.env.NODE_ENV === 'production'; 9 | 10 | export default defineConfig({ 11 | themeConfig: { 12 | name: 'html2sketch', 13 | logo: 'https://gw.alipayobjects.com/zos/antfincdn/8AsXJa8sgo/Logo.svg', 14 | nav, 15 | sidebar, 16 | }, 17 | theme: { 18 | '@c-primary': '#ff9800', 19 | }, 20 | outputPath: 'docs-dist', 21 | // 部署在非根目录时, base 和 publicPath 都需要配置 22 | base: isProdSite ? '/html2sketch/' : '/', 23 | publicPath: isProdSite ? '/html2sketch/' : '/', 24 | alias: { 25 | '@docs-utils': resolve(__dirname, './.dumi/theme/builtins/ToSketch'), 26 | }, 27 | hash: true, 28 | }); 29 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /lambda/mock/** 2 | /scripts 3 | /config 4 | /example 5 | _test_ 6 | __test__ 7 | 8 | /node_modules 9 | jest* 10 | /es 11 | /lib 12 | /docs 13 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const config = require('@umijs/max/eslint'); 2 | 3 | module.exports = { 4 | ...config, 5 | rules: { 6 | ...config.rules, 7 | 'no-param-reassign': 0, 8 | }, 9 | settings: { 10 | 'import/resolver': { 11 | alias: { 12 | map: [ 13 | ['html2sketch', './src/'], 14 | ['html2sketch/*', './src/*'], 15 | ['@docs-utils', './docs/__utils__'], 16 | ['@test-utils', './tests/__utils__'], 17 | ], 18 | }, 19 | typescript: { 20 | alwaysTryTypes: true, 21 | }, 22 | }, 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /.fatherrc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'father'; 2 | 3 | export default defineConfig({ 4 | cjs: { 5 | output: 'lib', 6 | transformer: 'babel', 7 | }, 8 | esm: { 9 | output: 'es', 10 | }, 11 | umd: { 12 | entry: 'src/index.ts', 13 | output: 'dist', 14 | name: 'html2sketch', 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: '报告Bug 🐛' 3 | about: 报告 html2sketch 的 bug 4 | title: '🐛[BUG]' 5 | labels: '🐛 BUG' 6 | assignees: '' 7 | --- 8 | 9 | ### 🐛 bug 描述 10 | 11 | 14 | 15 | ### 📷 复现步骤 16 | 17 | 20 | 21 | ### 🏞 期望结果 22 | 23 | 26 | 27 | ### 💻 复现代码 28 | 29 | 33 | 34 | [可复现 demo](https://codesandbox.io/s/html2ksetch-demo-m53be?file=/src/Demo.tsx) 35 | 36 | ### © 版本信息 37 | 38 | - html2sketch 版本: [e.g. 1.0.0] 39 | - 浏览器环境 40 | - 开发环境 [e.g. mac OS] 41 | 42 | ### 🚑 其他信息 43 | 44 | 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: '功能需求 ✨' 3 | about: 对 html2sketch 的需求或建议 4 | title: '👑 [需求]' 5 | labels: '👑 Feature' 6 | assignees: '' 7 | --- 8 | 9 | ### 🥰 需求描述 10 | 11 | 14 | 15 | ### 🧐 解决方案 16 | 17 | 20 | 21 | ### 🚑 其他信息 22 | 23 | 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: '疑问或需要帮助 ❓' 3 | about: 对 html2sketch 使用的疑问或需要帮助 4 | title: '🧐[问题]' 5 | labels: '🧐 Question' 6 | assignees: '' 7 | --- 8 | 9 | ### 🧐 问题描述 10 | 11 | 14 | 15 | ### 💻 示例代码 16 | 17 | 20 | 21 | ### 🚑 其他信息 22 | 23 | 26 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build-and-deploy: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 🛎️ 13 | uses: actions/checkout@v3 14 | 15 | - name: Install pnpm 16 | uses: pnpm/action-setup@v2 17 | with: 18 | version: 7 19 | 20 | - name: Setup Node.js environment 21 | uses: actions/setup-node@v3 22 | with: 23 | node-version: '16' 24 | 25 | - name: Install and Build 🔧 26 | run: | 27 | pnpm i 28 | pnpm run lint 29 | pnpm run docs:build 30 | 31 | - name: Deploy 🚀 32 | uses: JamesIves/github-pages-deploy-action@4.1.1 33 | with: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | BRANCH: gh-pages # The branch the action should deploy to. 36 | FOLDER: docs-dist # The folder the action should deploy. 37 | CLEAN: true # Automatically remove deleted files from the deploy branch 38 | -------------------------------------------------------------------------------- /.github/workflows/preview.yml: -------------------------------------------------------------------------------- 1 | name: Surge PR Preview 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | preview: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | 11 | - name: Install pnpm 12 | uses: pnpm/action-setup@v2 13 | with: 14 | version: 7 15 | 16 | - uses: afc163/surge-preview@v1 17 | with: 18 | surge_token: ${{ secrets.SURGE_TOKEN }} 19 | github_token: ${{ secrets.GITHUB_TOKEN }} 20 | build: | 21 | pnpm i 22 | pnpm run docs:preview 23 | dist: docs-dist 24 | 25 | - name: Get the preview_url 26 | run: echo "url => ${{ steps.preview_step.outputs.preview_url }}" 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release CI 2 | on: 3 | push: 4 | branches: 5 | - master 6 | - beta 7 | 8 | jobs: 9 | test: 10 | name: Test 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | 15 | - name: Install pnpm 16 | uses: pnpm/action-setup@v2 17 | with: 18 | version: 7 19 | 20 | - name: Setup Node.js environment 21 | uses: actions/setup-node@v3 22 | with: 23 | node-version: '16' 24 | 25 | - name: Install deps 26 | run: pnpm install 27 | 28 | - name: Test 29 | run: pnpm run test 30 | 31 | release: 32 | needs: test 33 | name: Release 34 | runs-on: ubuntu-latest 35 | steps: 36 | - uses: actions/checkout@v3 37 | 38 | - name: Install pnpm 39 | uses: pnpm/action-setup@v2 40 | with: 41 | version: 7 42 | 43 | - name: Setup Node.js environment 44 | uses: actions/setup-node@v3 45 | with: 46 | node-version: '16' 47 | 48 | - name: Install deps 49 | run: pnpm install 50 | 51 | - name: build 52 | run: pnpm run build 53 | 54 | - name: release 55 | run: pnpm run release 56 | env: 57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 59 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test CI 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | runs-on: macos-latest 6 | 7 | steps: 8 | - uses: actions/checkout@v3 9 | 10 | - name: Install pnpm 11 | uses: pnpm/action-setup@v2 12 | with: 13 | version: 7 14 | 15 | - name: Setup Node.js environment 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: '16' 19 | 20 | - name: Install deps 21 | run: pnpm install 22 | 23 | - name: lint 24 | run: pnpm run ci 25 | 26 | - name: test 27 | run: pnpm run test:coverage 28 | 29 | - name: Generate coverage 30 | run: bash <(curl -s https://codecov.io/bash) 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | **/node_modules 5 | # roadhog-api-doc ignore 6 | /src/utils/request-temp.js 7 | _roadhog-api-doc 8 | 9 | # production 10 | **/dist 11 | /.vscode 12 | /es 13 | /lib 14 | 15 | # misc 16 | .DS_Store 17 | storybook-static 18 | npm-debug.log* 19 | yarn-error.log 20 | 21 | /coverage 22 | .idea 23 | package-lock.json 24 | *bak 25 | .vscode 26 | 27 | # visual studio code 28 | .history 29 | *.log 30 | functions/* 31 | lambda/mock/index.js 32 | .temp/** 33 | 34 | # umi 35 | .dumi/tmp 36 | .dumi/tmp-test 37 | .dumi/tmp-production 38 | 39 | # screenshot 40 | screenshot 41 | .firebase 42 | example/.temp/* 43 | .eslintcache 44 | techUI* 45 | docs-dist 46 | .env 47 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: npm install 3 | command: npm start 4 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no-install lint-staged 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com/ 2 | electron_mirror=https://npmmirror.com/mirrors/electron/ 3 | lockfile=false 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.svg 2 | .umi 3 | .umi-production 4 | /dist 5 | .dockerignore 6 | .DS_Store 7 | .eslintignore 8 | *.png 9 | *.toml 10 | docker 11 | .editorconfig 12 | Dockerfile* 13 | .gitignore 14 | .prettierignore 15 | LICENSE 16 | .eslintcache 17 | *.lock 18 | yarn-error.log 19 | tests/__tests__/antd/json 20 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | singleQuote: true, 4 | trailingComma: 'all', 5 | proseWrap: 'never', 6 | endOfLine: 'lf', 7 | overrides: [{ files: '.prettierrc', options: { parser: 'json' } }], 8 | plugins: [require.resolve('prettier-plugin-organize-imports')], 9 | pluginSearchDirs: false, 10 | }; 11 | -------------------------------------------------------------------------------- /.releaserc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | //负责解析 commit 4 | [ 5 | '@semantic-release/commit-analyzer', 6 | { 7 | // 自定义配置,如果不填则是默认的 conventional-changelog-angular 8 | config: 'conventional-changelog-gitmoji-config', 9 | // build 会触发新的构建 10 | releaseRules: [{ type: 'build', release: 'patch' }], 11 | }, 12 | ], 13 | [ 14 | '@semantic-release/release-notes-generator', //此处生成 github-release 的日志 15 | { 16 | //指定配置,这里才是负责生成日志的,也就是说,如果自定义了writerOpts,只有在这里写才会生效 17 | config: 'conventional-changelog-gitmoji-config', 18 | }, 19 | ], 20 | [ 21 | '@semantic-release/changelog', //此处会调用上一个插件生成的新增日志,然后合并到原有日志中 22 | { 23 | changelogFile: 'CHANGELOG.md', 24 | changelogTitle: '# html2sketch 更新日志', 25 | }, 26 | ], 27 | '@semantic-release/npm', // 如果是npm包会自动更新版本号并发布 28 | '@semantic-release/github', // 推送代码回到GitHub 29 | [ 30 | '@semantic-release/git', //发布release 31 | { 32 | assets: ['CHANGELOG.md', 'package.json'], 33 | message: 34 | ':bookmark: chore(release): ${nextRelease.gitTag} [skip ci] \n\n${nextRelease.notes}', 35 | }, 36 | ], 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@umijs/max/stylelint'); 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Arvin Xu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/e2e/basic/background.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 解析图片放在背景中的测试 4 | 5 | 加载方式: 6 | 7 | - 网址 8 | - Base64 9 | 10 | 图片类型 11 | 12 | - svg 13 | - png 14 | 15 | ## 背景图片为 image 不限制尺寸 16 | 17 | 18 | 19 | ## 背景图片为 image 限制尺寸 20 | 21 | 22 | 23 | ## 背景内联 Svg 24 | 25 | 26 | 27 | ## 背景内联 Png 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/e2e/basic/canvas.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Canvas 解析 3 | --- 4 | 5 | ## 基本 Canvas 解析 6 | 7 | 8 | 9 | ## Canvas 跨域图片解析 10 | 11 | 12 | 13 | ### 跨域问题说明 14 | 15 | 某些 Canvas 由于绘制了跨域图片,因此无法使用 `toDataURL` 方法 ,会报错: 16 | 17 | ``` 18 | Tainted canvases may not be exported 19 | ``` 20 | 21 | ### 解决方案 22 | 23 | 这个时候解决方案有两种: 24 | 25 | #### 你可以控制 `img` 26 | 27 | 如果你可以控制提供 canvas 渲染的 img 节点,那一切都行相对容易,给 img 节点添加上 `crossOrigin` 属性即可 28 | 29 | ```html 30 | 31 | 32 | 33 | 38 | ``` 39 | 40 | 不过这样的前提是你的图片服务器请求头中必须带有 `Access-Control-Allow-Origin "*"` ,否则就会提示跨域问题 41 | 42 | PS: 如果无法处理图片服务器,可以利用 `cors-anywhere` 进行中转,或自行搭建代理 43 | 44 | ``` 45 | https://cors-anywhere.herokuapp.com/${url} 46 | ``` 47 | 48 | #### 你不能控制 `img` 49 | 50 | 如果你没法拿到 image 的 src 只能通过禁用 chrome 的同源策略才能解决 51 | 52 | 禁用方法(以 macOS 为例): 53 | 54 | macOS: 55 | 56 | ```bash 57 | open -a "/Applications/Google Chrome.app" --args \ 58 | --disable-web-security \ 59 | --user-data-dir=/Users/{your account name}/chromeTempData/ 60 | ``` 61 | 62 | 第一次打开如下图,就说明已经禁用同源策略了: ![](https://gw.alipayobjects.com/zos/antfincdn/hokkCFfJB9/1a018628-ae13-4fbc-82c4-eac5626e33c6.png) 63 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/BackgroundImage/Inline.less: -------------------------------------------------------------------------------- 1 | .base { 2 | display: block; 3 | width: 14px; 4 | height: 14px; 5 | background-color: #006eff; 6 | background-repeat: no-repeat; 7 | background-position: center; 8 | background-size: 100% auto; 9 | } 10 | .checkSvg { 11 | .base; 12 | 13 | background-image: url('https://ue.qzone.qq.com/work/sketch-dev/sketch-test/tea-table-components/src/checkbox.svg'); 14 | } 15 | 16 | .checkPng { 17 | .base; 18 | 19 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAASCAYAAABB7B6eAAAAAXNSR0IArs4c6QAAALtJREFUOBGtlDEOwyAMRbN06Uk69S65UY+TLj1Wl94gC3muYikBnEBsS5YVsN83EBiGQEspPQJxexTwFz7j434m4GuFE/4WKwJSOs/ty8Dd3TuQGvzH+LOAM3jDJ7xpD8nrhn8oEjvdQ3La4bIUCt5C3pgpQk4ffBUYKRTo1goRJvvhehgUH4q44A0icvi51f8WhVkRSm0lMXAVPRG51rnCNRoiMXBDJBaeicjbUl5/TfJG4P6Hy9uEVb8Awfj6IeYP7jsAAAAASUVORK5CYII='); 20 | } 21 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/BackgroundImage/InlinePng.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | // @ts-ignore 4 | import styles from './Inline.less'; 5 | 6 | export default () => { 7 | return ; 8 | }; 9 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/BackgroundImage/InlineSvg.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | // @ts-ignore 4 | import styles from './Inline.less'; 5 | 6 | export default () => ; 7 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/BackgroundImage/WithSize.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => ( 4 |
12 | ); 13 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/BackgroundImage/WithoutSize.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => ( 4 |
12 | ); 13 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/CanvasCors.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * hideSketchLayout: true 3 | */ 4 | import { TestLayout, useElements } from '@docs-utils'; 5 | import React, { useEffect } from 'react'; 6 | 7 | export default () => { 8 | const { elements, ref } = useElements(); 9 | 10 | useEffect(() => { 11 | const canvas = ref.current; 12 | const ctx = canvas.getContext('2d'); 13 | const image = document.getElementById('source'); 14 | 15 | image!.onload = function () { 16 | ctx.drawImage(image, 0, 0); 17 | }; 18 | }, []); 19 | return ( 20 | 21 |
22 | 23 |
24 |
25 | {'image'} 30 |
31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import { Checkbox } from 'antd'; 2 | import React, { FC } from 'react'; 3 | 4 | const SwitchDemo: FC = () => ( 5 | <> 6 | no checked 7 | Checkbox 8 | 9 | ); 10 | 11 | export default SwitchDemo; 12 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Image/ImageNoProtocol.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * 5 | */ 6 | export default () => { 7 | return ( 8 | Png 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Image/ImagePng.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * 5 | */ 6 | export default () => { 7 | return ( 8 |
9 | Png 14 |
15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Image/ImageSvg.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => ( 4 | <> 5 | Ant Design 9 |
10 | 12 15 | 开启引导 16 | 12 21 |
22 | 23 | ); 24 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Overflow/switch.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './switch.css'; 3 | 4 | export default () => ( 5 | 9 | ); 10 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Position.less: -------------------------------------------------------------------------------- 1 | .ant-radio-inner { 2 | position: relative; 3 | top: 0; 4 | left: 0; 5 | display: block; 6 | width: 16px; 7 | height: 16px; 8 | background-color: #fff; 9 | border-color: #d9d9d9; 10 | border-style: solid; 11 | border-width: 1px; 12 | border-radius: 50%; 13 | transition: all 0.3s; 14 | 15 | &::after { 16 | position: absolute; 17 | top: 50%; 18 | left: 50%; 19 | display: block; 20 | width: 16px; 21 | height: 16px; 22 | margin-top: -8px; 23 | margin-left: -8px; 24 | background-color: #1890ff; 25 | border-top: 0; 26 | border-left: 0; 27 | border-radius: 16px; 28 | transform: scale(0.5); 29 | opacity: 1; 30 | transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86); 31 | content: ' '; 32 | z-index: 10; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Position.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './Position.less'; 4 | 5 | export default () => ( 6 |
7 | 8 |
9 | ); 10 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Radio.tsx: -------------------------------------------------------------------------------- 1 | import { Radio } from 'antd'; 2 | import React from 'react'; 3 | 4 | export default () => ( 5 |
6 | 内容 7 |
8 | ); 9 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Select.tsx: -------------------------------------------------------------------------------- 1 | import { Select } from 'antd'; 2 | import React from 'react'; 3 | 4 | const { Option } = Select; 5 | 6 | export default () => { 7 | return ( 8 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Switch.tsx: -------------------------------------------------------------------------------- 1 | import { Space, Switch } from 'antd'; 2 | import React, { FC } from 'react'; 3 | 4 | const SwitchDemo: FC = () => ( 5 | 6 | 10 | 15 | 20 | 26 | 31 | 37 | 43 | 50 | 51 | ); 52 | 53 | export default SwitchDemo; 54 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/BlockAlign.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './Text.less'; 4 | 5 | /** 6 | * 7 | */ 8 | export default () => { 9 | return ( 10 | <> 11 | 左边 12 |
右边
13 | 14 | 中间 15 | 16 | 19 | 中间 20 | 21 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/Ellipsis.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * 5 | */ 6 | export default () => ( 7 |
16 | 位全眼等越子亲作向下入第金社准。 17 |
18 | ); 19 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/Input.tsx: -------------------------------------------------------------------------------- 1 | import { Input } from 'antd'; 2 | import React from 'react'; 3 | 4 | /** 5 | * 6 | */ 7 | export default () => ; 8 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/InputAligin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => ( 4 | <> 5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 | 15 | ); 16 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/InputVerticalAligin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => ( 4 |
5 | 6 |
7 | ); 8 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/Label.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './Text.less'; 4 | 5 | /** 6 | * 7 | */ 8 | export default () => { 9 | return ( 10 | <> 11 |
12 | 右边是冒号 13 |
14 |
15 | 左边是冒号 16 |
17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/MutliLine.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * 5 | */ 6 | export default () => ( 7 |
8 | 龙东何同三族府满于矿强更红表元组。 龙东何同三族府满于矿强更红表元组。 9 | 龙东何同三族府满于矿强更红表元组。 龙东何同三族府满于矿强更红表元组。 10 |
11 | ); 12 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/Span.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * 5 | */ 6 | export default () => ( 7 | 8 | 共 2 条 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/SpanIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { AppleOutlined } from '@ant-design/icons'; 4 | 5 | /** 6 | * 7 | */ 8 | export default () => ( 9 | 10 | 11 | Tab 1 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/SpanInlineBlock.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './Text.less'; 4 | /** 5 | * 6 | */ 7 | export default () => ( 8 | 9 | 共 1000 条 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/SpanLinkRow.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * 5 | */ 6 | export default () => ( 7 |
8 | 规划应用全局设置创建应用应用管理配置资源应用实例 9 |
10 | ); 11 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/TagInlineBlock.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * 5 | */ 6 | export default () => ( 7 | 21 | 蓝色 22 | 23 | ); 24 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/Text.less: -------------------------------------------------------------------------------- 1 | .label::after { 2 | position: relative; 3 | top: -0.5px; 4 | margin: 0 8px 0 2px; 5 | content: ':'; 6 | } 7 | .l-label::before { 8 | position: relative; 9 | top: -0.5px; 10 | margin-left: 2px; 11 | content: ':'; 12 | } 13 | 14 | .inline-block { 15 | display: inline-block; 16 | margin-right: 10px; 17 | font-size: 12px; 18 | font-variant: normal; 19 | vertical-align: middle; 20 | background-color: navajowhite; 21 | } 22 | 23 | .row-item { 24 | display: flex; 25 | width: 60px; 26 | height: 40px; 27 | } 28 | 29 | .row-item-reverse { 30 | display: flex; 31 | width: 60px; 32 | height: 40px; 33 | } 34 | .column-item { 35 | display: flex; 36 | flex-direction: column; 37 | width: 60px; 38 | height: 40px; 39 | } 40 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/TextAlignment/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import './style.css'; 4 | 5 | /** 6 | * 7 | */ 8 | export default () => ( 9 |
10 | 前置对象 11 |
12 |
13 | 24 |
25 |
26 |
基本信息
27 |
28 | ); 29 | -------------------------------------------------------------------------------- /docs/e2e/basic/demos/Text/TextArea.tsx: -------------------------------------------------------------------------------- 1 | import { Input } from 'antd'; 2 | import React from 'react'; 3 | 4 | const { TextArea } = Input; 5 | 6 | /** 7 | * 8 | */ 9 | export default () => { 10 | return