From fe7cba601bdefe6c6edcde0b3e51c2d0ef542312 Mon Sep 17 00:00:00 2001 From: insekkei <1183448115@qq.com> Date: Fri, 29 Mar 2024 08:32:24 +0800 Subject: [PATCH 01/20] feat(typography): typography finished --- .vscode/settings.json | 2 +- package.json | 5 + site/site.config.mjs | 8 + src/_common | 2 +- .../__snapshots__/vitest-guide.test.jsx.snap | 6 +- src/index.ts | 1 + src/typography/Ellipsis.tsx | 99 ++++ src/typography/Paragraph.tsx | 38 ++ src/typography/Text.tsx | 166 +++++++ src/typography/Title.tsx | 39 ++ src/typography/Truncate.tsx | 429 ++++++++++++++++++ src/typography/__tests__/typography.test.tsx | 117 +++++ src/typography/_example/base.jsx | 47 ++ src/typography/_example/copyable.jsx | 36 ++ src/typography/_example/ellipsis.jsx | 59 +++ src/typography/_example/text.jsx | 25 + src/typography/_example/title.jsx | 17 + src/typography/api.md | 3 + src/typography/defaultProps.ts | 22 + src/typography/index.ts | 17 + src/typography/style/css.js | 1 + src/typography/style/index.js | 1 + src/typography/type.ts | 156 +++++++ src/typography/typography.en-US.md | 62 +++ src/typography/typography.md | 62 +++ src/typography/useEllipsis.tsx | 65 +++ 26 files changed, 1480 insertions(+), 5 deletions(-) create mode 100644 src/typography/Ellipsis.tsx create mode 100644 src/typography/Paragraph.tsx create mode 100644 src/typography/Text.tsx create mode 100644 src/typography/Title.tsx create mode 100644 src/typography/Truncate.tsx create mode 100644 src/typography/__tests__/typography.test.tsx create mode 100644 src/typography/_example/base.jsx create mode 100644 src/typography/_example/copyable.jsx create mode 100644 src/typography/_example/ellipsis.jsx create mode 100644 src/typography/_example/text.jsx create mode 100644 src/typography/_example/title.jsx create mode 100644 src/typography/api.md create mode 100644 src/typography/defaultProps.ts create mode 100644 src/typography/index.ts create mode 100644 src/typography/style/css.js create mode 100644 src/typography/style/index.js create mode 100644 src/typography/type.ts create mode 100644 src/typography/typography.en-US.md create mode 100644 src/typography/typography.md create mode 100644 src/typography/useEllipsis.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index e500d7a72..4ca63e8b9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,7 +22,7 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "cSpell.words": ["activable", "actived", "borderless", "Cascader", "Popconfirm", "Swiper", "tdesign"] } \ No newline at end of file diff --git a/package.json b/package.json index 5e899cd03..3b38305d4 100644 --- a/package.json +++ b/package.json @@ -203,13 +203,18 @@ "@types/tinycolor2": "^1.4.3", "@types/validator": "^13.1.3", "classnames": "~2.3.1", + "copy-to-clipboard": "^3.3.3", "dayjs": "~1.11.4", "hoist-non-react-statics": "~3.3.2", + "install": "^0.13.0", "lodash": "~4.17.15", "mitt": "^3.0.0", + "npm": "^10.5.0", "raf": "~3.4.1", "react-is": "^18.2.0", + "react-lines-ellipsis": "^0.15.4", "react-popper": "~2.3.0", + "react-show-more-text": "^1.7.1", "react-transition-group": "~4.4.1", "sortablejs": "^1.15.0", "tdesign-icons-react": "^0.3.0", diff --git a/site/site.config.mjs b/site/site.config.mjs index 48fe71275..1834e6222 100644 --- a/site/site.config.mjs +++ b/site/site.config.mjs @@ -561,6 +561,14 @@ export const docs = [ component: () => import('tdesign-react/tooltip/tooltip.md'), componentEn: () => import('tdesign-react/tooltip/tooltip.en-US.md'), }, + { + title: 'Typography 排版', + titleEn: 'Typography', + name: 'typography', + path: '/react/components/typography', + component: () => import('tdesign-react/typography/typography.md'), + componentEn: () => import('tdesign-react/typography/typography.en-US.md'), + }, { title: 'Tree 树', titleEn: 'Tree', diff --git a/src/_common b/src/_common index 742a90e47..27dd7faa1 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit 742a90e47eed782f9d09ab7f981f60a950846c48 +Subproject commit 27dd7faa1436f53ff4a65c4fa9e1a6f83db13317 diff --git a/src/guide/__tests__/__snapshots__/vitest-guide.test.jsx.snap b/src/guide/__tests__/__snapshots__/vitest-guide.test.jsx.snap index 7f42bdb14..63e07e880 100644 --- a/src/guide/__tests__/__snapshots__/vitest-guide.test.jsx.snap +++ b/src/guide/__tests__/__snapshots__/vitest-guide.test.jsx.snap @@ -921,7 +921,7 @@ exports[`Guide Component > GuideStep.placement is equal to bottom-left 1`] = ` style="width: 16px; height: 16px; top: -8px; left: -8px;" />
GuideStep.stepOverlayClass is equal to t-test-guide-s style="width: 16px; height: 16px; top: -8px; left: -8px;" />
GuideStep.title works fine 1`] = ` style="width: 16px; height: 16px; top: -8px; left: -8px;" />
void; + width: number; + onTruncate?: (truncated: boolean) => void; + component: string; + collapsible: boolean; + expandable: boolean; + more: ReactNode; + less: ReactNode; +}; + +const Ellipsis = ({ + className, + children, + lines = 1, + ellipsisClassName, + ellipsisPrefix = '...', + onToggleExpand, + width = 0, + onTruncate, + component: Component = 'div', + collapsible = false, + expandable = false, + more, + less, + ...rest +}: TdEllipsis) => { + const { classPrefix } = useConfig(); + const symbolClassName = ellipsisClassName || `${classPrefix}-typography-ellipsis-symbol`; + + const isMountRef = useRef(false); + useEffect(() => { + isMountRef.current = true; + }, []); + + const [isExpanded, setIsExpanded] = useState(false); + const handleToggleExpand = (e) => { + if (!expandable) return; + + if (isMountRef.current) { + setIsExpanded(!isExpanded); + onToggleExpand?.(!isExpanded, e); + } + }; + + const truncateRef = useRef(); + const [isTruncated, setTruncated] = useState(false); + const handleTruncate = (truncated) => { + if (isMountRef.current && truncated !== isTruncated) { + setTruncated(truncated); + + if (truncated) { + truncateRef.current?.onResize(); + } + onTruncate?.(truncated); + } + }; + + return ( + + + {ellipsisPrefix} + + {more} + + + } + onTruncate={handleTruncate} + ref={truncateRef} + lineClassName={`${classPrefix}-typography-ellipsis-line`} + > + {children} + + {!isTruncated && collapsible && isExpanded && ( + + {less} + + )} + + ); +}; + +export default Ellipsis; diff --git a/src/typography/Paragraph.tsx b/src/typography/Paragraph.tsx new file mode 100644 index 000000000..48670c503 --- /dev/null +++ b/src/typography/Paragraph.tsx @@ -0,0 +1,38 @@ +import React, { forwardRef } from 'react'; +import classNames from 'classnames'; +import Ellipsis from './Ellipsis'; +import { TdParagraphProps } from './type'; +import { paragraphDefaultProps } from './defaultProps'; +import useConfig from '../hooks/useConfig'; +import useEllipsis from './useEllipsis'; + +export type TypographyParagraphProps = TdParagraphProps; + +const ParagraphFunction = (props: TypographyParagraphProps, ref: React.Ref) => { + const { classPrefix } = useConfig(); + const { ellipsis, children, className, ...rest } = props; + const prefixCls = `${classPrefix}-typography`; + + const { ellipsisProps } = useEllipsis(ellipsis); + + if (!ellipsis) { + return ( +
+ {children} +
+ ); + } + + return ( + + {children} + + ); +}; + +export const Paragraph = forwardRef(ParagraphFunction); + +Paragraph.displayName = 'Paragraph'; +Paragraph.defaultProps = paragraphDefaultProps; + +export default Paragraph; diff --git a/src/typography/Text.tsx b/src/typography/Text.tsx new file mode 100644 index 000000000..3ff74d434 --- /dev/null +++ b/src/typography/Text.tsx @@ -0,0 +1,166 @@ +import React, { forwardRef, useRef, useState } from 'react'; +import classNames from 'classnames'; +import { CheckIcon, CopyIcon } from 'tdesign-icons-react'; +import copy from 'copy-to-clipboard'; + +import Ellipsis from './Ellipsis'; +import { TdTextProps } from './type'; +import { titleDefaultProps } from './defaultProps'; +import useConfig from '../hooks/useConfig'; +import useEllipsis from './useEllipsis'; +import Button from '../button/Button'; +import Tooltip from '../tooltip'; +import { useLocaleReceiver } from '../locale/LocalReceiver'; + +export type TypographyTextProps = TdTextProps; + +const TextFunction = (props: TypographyTextProps, ref: React.Ref) => { + const { classPrefix } = useConfig(); + const prefixCls = `${classPrefix}-typography`; + + const [local, t] = useLocaleReceiver('typography'); + const copiedText = t(local.copied); + + const { + theme, + disabled, + className, + copyable, + strong, + mark, + code, + keyboard, + underline, + delete: deleteProp, + italic, + children, + ellipsis, + ...rest + } = props; + const getComponent = () => { + const componentMap = { + strong: !!strong, + mark: !!mark, + code: !!code, + kbd: !!keyboard, + u: !!underline, + del: !!deleteProp, + i: !!italic, + }; + return Object.entries(componentMap).find(([, condition]) => !!condition)?.[0]; + }; + + const currentRef = useRef(); + const { ellipsisProps } = useEllipsis(ellipsis); + const Component = getComponent(); + + const textEllipsisProps = { + ...ellipsisProps, + }; + + const [isCopied, setIsCopied] = useState(false); + + const copyProps = + typeof copyable === 'boolean' + ? { + text: children.toString(), + onCopy: Function.prototype, + tooltipProps: isCopied + ? { + content: copiedText, + } + : null, + } + : { + text: copyable?.text || children.toString(), + onCopy: copyable?.onCopy?.(), + tooltipProps: { + ...copyable?.tooltipProps, + content: isCopied ? copiedText : copyable?.tooltipProps?.content, + }, + suffix: copyable?.suffix, + }; + + const handleCopy = () => { + copy(copyProps?.text); + setIsCopied(true); + setTimeout(() => { + setIsCopied(false); + }, 1500); + copyProps.onCopy?.(); + }; + + const renderContent = (withChildren: boolean) => { + const { tooltipProps } = copyProps; + const wrapWithTooltip = (wrapContent) => + tooltipProps ? {wrapContent} : wrapContent; + + const getSuffix = () => { + if (typeof copyProps?.suffix === 'function') { + return copyProps.suffix({ copied: isCopied }); + } + return isCopied ? : ; + }; + + return ( + <> + {withChildren ? children : null} + {copyable + ? wrapWithTooltip( + , + expandable: true, + collapsible: true + }} + > + {textString} + + expaned ? 'less' : 'more', + expandable: false, + tooltipProps: { + content: 'long long long text' + }, + onExpand: handleExpand, + }} + style={{width: isExpanded ? '100%' : 300, display: 'block'}} + > + {textString} + + + {textString} + + {expaned ? : }, + expandable: true, + }} + > + {textString} + + + ) +}; + +export default EllipsisExample; diff --git a/src/typography/_example/text.jsx b/src/typography/_example/text.jsx new file mode 100644 index 000000000..b70324b3d --- /dev/null +++ b/src/typography/_example/text.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Space } from 'tdesign-react'; +import Typography from '../index'; + +const { Text } = Typography; + +export default function TextExample() { + return ( + + TDesign (primary) + TDesign (secondary) + TDesign (disabled) + TDesign (success) + TDesign (warning) + TDesign (error) + TDesign (mark) + TDesign (code) + TDesign (keyboard) + TDesign (underline) + TDesign (delete) + TDesign (strong) + TDesign (italic) + + ); +} diff --git a/src/typography/_example/title.jsx b/src/typography/_example/title.jsx new file mode 100644 index 000000000..c44cc7b7d --- /dev/null +++ b/src/typography/_example/title.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import Typography from '../index'; + +const {Title} = Typography; + +const TitleExample = () => ( + <> + h1. TDesign + h2. TDesign + h3. TDesign + h4. TDesign + h5. TDesign + h6. TDesign + + ) + +export default TitleExample; diff --git a/src/typography/api.md b/src/typography/api.md new file mode 100644 index 000000000..420f17e19 --- /dev/null +++ b/src/typography/api.md @@ -0,0 +1,3 @@ +### Typography Props +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- diff --git a/src/typography/defaultProps.ts b/src/typography/defaultProps.ts new file mode 100644 index 000000000..2a427dc0d --- /dev/null +++ b/src/typography/defaultProps.ts @@ -0,0 +1,22 @@ +/** + * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC + * */ + +import { TdTextProps, TdTitleProps, TdParagraphProps } from './type'; + +export const textDefaultProps: TdTextProps = { + code: false, + copyable: false, + delete: false, + disabled: false, + ellipsis: false, + italic: false, + keyboard: false, + mark: false, + strong: false, + underline: false, +}; + +export const titleDefaultProps: TdTitleProps = { ellipsis: false, level: 'h1' }; + +export const paragraphDefaultProps: TdParagraphProps = { ellipsis: false }; diff --git a/src/typography/index.ts b/src/typography/index.ts new file mode 100644 index 000000000..714105884 --- /dev/null +++ b/src/typography/index.ts @@ -0,0 +1,17 @@ +import _Paragraph from './Paragraph'; +import _Text from './Text'; +import _Title from './Title'; + +import './style/index.js'; + +export * from './type'; + +export const Paragraph = _Paragraph; +export const Text = _Text; +export const Title = _Title; + +export default { + Paragraph, + Text, + Title, +}; diff --git a/src/typography/style/css.js b/src/typography/style/css.js new file mode 100644 index 000000000..6a9a4b132 --- /dev/null +++ b/src/typography/style/css.js @@ -0,0 +1 @@ +import './index.css'; diff --git a/src/typography/style/index.js b/src/typography/style/index.js new file mode 100644 index 000000000..df223430b --- /dev/null +++ b/src/typography/style/index.js @@ -0,0 +1 @@ +import '../../_common/style/web/components/typography/_index.less'; diff --git a/src/typography/type.ts b/src/typography/type.ts new file mode 100644 index 000000000..51b33d6b6 --- /dev/null +++ b/src/typography/type.ts @@ -0,0 +1,156 @@ +/* eslint-disable */ + +/** + * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC + * */ + +import { TooltipProps } from '../tooltip'; +import { TNode } from '../common'; + +export interface TdTextProps { + /** + * 文本内容,同content + */ + children?: TNode; + /** + * 是否添加代码样式 + * @default false + */ + code?: boolean; + /** + * 是否可复制,可通过配置参数自定义复制操作的具体功能和样式 + * @default false + */ + copyable?: boolean | TypographyCopyable; + /** + * 是否添加删除线样式 + * @default false + */ + delete?: boolean; + /** + * 是否添加不可用样式 + * @default false + */ + disabled?: boolean; + /** + * 是否省略展示,可通过配置参数自定义省略操作的具体功能和样式 + * @default false + */ + ellipsis?: boolean | TypographyEllipsis; + /** + * 文本是否为斜体 + * @default false + */ + italic?: boolean; + /** + * 是否添加键盘样式 + * @default false + */ + keyboard?: boolean; + /** + * 是否添加标记样式,默认为黄色,可通过配置颜色修改标记样式,如#0052D9 + * @default false + */ + mark?: string | boolean; + /** + * 文本是否加粗 + * @default false + */ + strong?: boolean; + /** + * 主题 + */ + theme?: 'primary' | 'secondary' | 'success' | 'warning' | 'error'; + /** + * 是否添加下划线样式 + * @default false + */ + underline?: boolean; +} + +export interface TdTitleProps { + /** + * 段落内容,同 content + */ + children?: TNode; + /** + * 段落内容 + */ + content?: TNode; + /** + * 是否省略展示,可通过配置参数自定义省略操作的具体功能和样式 + * @default false + */ + ellipsis?: boolean | TypographyEllipsis; + /** + * 标题等级 + * @default h1 + */ + level?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; +} + +export interface TdParagraphProps { + /** + * 段落内容,同 content + */ + children?: TNode; + /** + * 段落内容 + */ + content?: TNode; + /** + * 是否省略展示,可通过配置参数自定义省略操作的具体功能和样式 + * @default false + */ + ellipsis?: boolean | TypographyEllipsis; +} + +export interface TypographyEllipsis { + /** + * 展开后是否可以重新收起 + * @default true + */ + collapsible?: boolean; + /** + * 是否可展开 + * @default true + */ + expandable?: boolean; + /** + * 省略配置默认展示行数 + * @default 1 + */ + row?: number; + /** + * 自定义省略触发元素,一般用于自定义折叠图标 + */ + suffix?: TNode<{ expanded: boolean }>; + /** + * 光标在省略图标上出现的tooltip的配置 + */ + tooltipProps?: TooltipProps; + /** + * 点击省略按钮的回调 + */ + onExpand?: (expanded: boolean) => void; +} + +export interface TypographyCopyable { + /** + * 复制的文本内容,默认为全部文本 + * @default '' + */ + text?: string; + /** + * 自定义复制触发元素,一般用于自定义复制图标 + */ + suffix?: TNode<{ copied: boolean }>; + /** + * 光标在复制图标上出现的tooltip的配置 + */ + tooltipProps?: TooltipProps; + /** + * 点击复制按钮的回调 + */ + onCopy?: () => void; +} diff --git a/src/typography/typography.en-US.md b/src/typography/typography.en-US.md new file mode 100644 index 000000000..27477926c --- /dev/null +++ b/src/typography/typography.en-US.md @@ -0,0 +1,62 @@ +:: BASE_DOC :: + +## API +### Text Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | 类名 | N +style | Object | - | 样式,Typescript:`React.CSSProperties` | N +children | TNode | - | children of text。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +code | Boolean | false | add code style | N +copyable | Boolean / Object | false | add copyable style。Typescript:`boolean \| TypographyCopyable` | N +delete | Boolean | false | add delete line style | N +disabled | Boolean | false | add disabled style | N +ellipsis | Boolean / Object | false | add ellipsis style。Typescript:`boolean \| TypographyEllipsis` | N +italic | Boolean | false | add italic style | N +keyboard | Boolean | false | add keyboard style | N +mark | String / Boolean | false | add mark style | N +strong | Boolean | false | add bold style | N +theme | String | - | theme of text。options: primary/secondary/success/warning/error | N +underline | Boolean | false | add underline style | N + +### Title Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | 类名 | N +style | Object | - | 样式,Typescript:`React.CSSProperties` | N +children | TNode | - | children of title。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +content | TNode | - | content of title。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +ellipsis | Boolean / Object | false | add ellipsis style。Typescript:`boolean \| TypographyEllipsis` | N +level | String | h1 | level of title。options: h1/h2/h3/h4/h5/h6 | N + +### Paragraph Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | 类名 | N +style | Object | - | 样式,Typescript:`React.CSSProperties` | N +children | TNode | - | children of paragraph。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +content | TNode | - | content of paragraph。Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +ellipsis | Boolean / Object | false | add ellipsis style。Typescript:`boolean \| TypographyEllipsis` | N + +### TypographyEllipsis + +name | type | default | description | required +-- | -- | -- | -- | -- +collapsible | Boolean | true | collapsible after expanding | N +expandable | Boolean | true | expandable | N +row | Number | 1 | default row number of ellipsis | N +suffix | TElement | - | custom element configuration for ellipsis and collapse icon。Typescript:`TNode<{ expanded: boolean }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +tooltipProps | Object | - | Configuration of the tooltip that appears on the ellipsis icon when the cursor is over it.。Typescript:`tooltipProps`,[Tooltip API Documents](./tooltip?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/typography/type.ts) | N +onExpand | Function | | Typescript:`(expanded:boolean) => void`
| N + +### TypographyCopyable + +name | type | default | description | required +-- | -- | -- | -- | -- + text | String | - | copied content | N +suffix | TElement | - | custom element configuration for copy icon。Typescript:`TNode<{ copied: boolean }>`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +tooltipProps | Object | - | Configuration of the tooltip that appears on the copy icon when the cursor is over it.。Typescript:`tooltipProps`,[Tooltip API Documents](./tooltip?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/typography/type.ts) | N +onCopy | Function | | Typescript:`() => void`
| N \ No newline at end of file diff --git a/src/typography/typography.md b/src/typography/typography.md new file mode 100644 index 000000000..21a5a5a1a --- /dev/null +++ b/src/typography/typography.md @@ -0,0 +1,62 @@ +:: BASE_DOC :: + +## API +### Text Props + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +className | String | - | 类名 | N +style | Object | - | 样式,TS 类型:`React.CSSProperties` | N +children | TNode | - | 文本内容,同content。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +code | Boolean | false | 是否添加代码样式 | N +copyable | Boolean / Object | false | 是否可复制,可通过配置参数自定义复制操作的具体功能和样式。TS 类型:`boolean \| TypographyCopyable` | N +delete | Boolean | false | 是否添加删除线样式 | N +disabled | Boolean | false | 是否添加不可用样式 | N +ellipsis | Boolean / Object | false | 是否省略展示,可通过配置参数自定义省略操作的具体功能和样式。TS 类型:`boolean \| TypographyEllipsis` | N +italic | Boolean | false | 文本是否为斜体 | N +keyboard | Boolean | false | 是否添加键盘样式 | N +mark | String / Boolean | false | 是否添加标记样式,默认为黄色,可通过配置颜色修改标记样式,如#0052D9 | N +strong | Boolean | false | 文本是否加粗 | N +theme | String | - | 主题。可选项:primary/secondary/success/warning/error | N +underline | Boolean | false | 是否添加下划线样式 | N + +### Title Props + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +className | String | - | 类名 | N +style | Object | - | 样式,TS 类型:`React.CSSProperties` | N +children | TNode | - | 段落内容,同 content。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +content | TNode | - | 段落内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +ellipsis | Boolean / Object | false | 是否省略展示,可通过配置参数自定义省略操作的具体功能和样式。TS 类型:`boolean \| TypographyEllipsis` | N +level | String | h1 | 标题等级。可选项:h1/h2/h3/h4/h5/h6 | N + +### Paragraph Props + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +className | String | - | 类名 | N +style | Object | - | 样式,TS 类型:`React.CSSProperties` | N +children | TNode | - | 段落内容,同 content。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +content | TNode | - | 段落内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +ellipsis | Boolean / Object | false | 是否省略展示,可通过配置参数自定义省略操作的具体功能和样式。TS 类型:`boolean \| TypographyEllipsis` | N + +### TypographyEllipsis + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +collapsible | Boolean | true | 展开后是否可以重新收起 | N +expandable | Boolean | true | 是否可展开 | N +row | Number | 1 | 省略配置默认展示行数 | N +suffix | TElement | - | 自定义省略触发元素,一般用于自定义折叠图标。TS 类型:`TNode<{ expanded: boolean }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +tooltipProps | Object | - | 光标在省略图标上出现的tooltip的配置。TS 类型:`tooltipProps`,[Tooltip API Documents](./tooltip?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/typography/type.ts) | N +onExpand | Function | | TS 类型:`(expanded:boolean) => void`
点击省略按钮的回调 | N + +### TypographyCopyable + +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- + text | String | - | 复制的文本内容,默认为全部文本 | N +suffix | TElement | - | 自定义复制触发元素,一般用于自定义复制图标。TS 类型:`TNode<{ copied: boolean }>`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N +tooltipProps | Object | - | 光标在复制图标上出现的tooltip的配置。TS 类型:`tooltipProps`,[Tooltip API Documents](./tooltip?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/typography/type.ts) | N +onCopy | Function | | TS 类型:`() => void`
点击复制按钮的回调 | N \ No newline at end of file diff --git a/src/typography/useEllipsis.tsx b/src/typography/useEllipsis.tsx new file mode 100644 index 000000000..d4c04c8ed --- /dev/null +++ b/src/typography/useEllipsis.tsx @@ -0,0 +1,65 @@ +/* eslint-disable no-nested-ternary */ +import React, { useState } from 'react'; + +import { TypographyEllipsis } from './type'; +import Tooltip from '../tooltip'; +import { useLocaleReceiver } from '../locale/LocalReceiver'; + +export default function useEllipsis(ellipsis: boolean | TypographyEllipsis) { + const [local, t] = useLocaleReceiver('typography'); + const expandText = t(local.expand); + const collapseText = t(local.collapse); + + let formattedEllipsis: TypographyEllipsis = {}; + if (ellipsis) { + formattedEllipsis = + ellipsis === true + ? { + row: 1, + expandable: false, + tooltipProps: null, + suffix: () => '', + collapsible: true, + } + : { + row: ellipsis.row || 1, + expandable: ellipsis.expandable ?? false, + tooltipProps: ellipsis.tooltipProps || null, + // eslint-disable-next-line no-nested-ternary + suffix: (expanded) => + typeof ellipsis?.suffix === 'function' + ? ellipsis?.suffix(expanded) + : expanded + ? collapseText + : ellipsis?.expandable + ? `${expandText}` + : '...', + collapsible: ellipsis?.collapsible ?? false, + }; + } + + const [isClamped, setIsClamped] = useState(true); + const handleExpand = (expanded: boolean) => { + if (typeof expanded !== 'boolean') return; + setIsClamped(!expanded); + (ellipsis as TypographyEllipsis).onExpand?.(!expanded); + }; + + const getEllipsisSuffix = () => { + if (formattedEllipsis?.tooltipProps) { + return {formattedEllipsis.suffix?.(!isClamped)}; + } + return formattedEllipsis.suffix?.(!isClamped); + }; + + const ellipsisProps = { + lines: formattedEllipsis.row, + more: getEllipsisSuffix(), + less: getEllipsisSuffix(), + onToggleExpand: handleExpand, + expandable: formattedEllipsis.expandable, + collapsible: formattedEllipsis.collapsible, + }; + + return { ellipsisProps }; +} From 7fb11b678f585e89ba3d89f605f30578f38ffd39 Mon Sep 17 00:00:00 2001 From: insekkei <1183448115@qq.com> Date: Fri, 29 Mar 2024 10:30:49 +0800 Subject: [PATCH 02/20] feat(typography): lint change --- src/typography/Ellipsis.tsx | 21 +++++++++++++-------- src/typography/Text.tsx | 17 +++++++++++------ src/typography/Truncate.tsx | 3 ++- src/typography/useEllipsis.tsx | 1 - 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/typography/Ellipsis.tsx b/src/typography/Ellipsis.tsx index 25c03bb9a..ce0595bcb 100644 --- a/src/typography/Ellipsis.tsx +++ b/src/typography/Ellipsis.tsx @@ -8,12 +8,12 @@ type TdEllipsis = { className?: string; children: ReactNode; lines: number; - ellipsisClassName: string; - ellipsisPrefix: ReactNode; + ellipsisClassName?: string; + ellipsisPrefix?: ReactNode; onToggleExpand?: (isExpanded: boolean, e: Event) => void; - width: number; + width?: number; onTruncate?: (truncated: boolean) => void; - component: string; + component: keyof HTMLElementTagNameMap; collapsible: boolean; expandable: boolean; more: ReactNode; @@ -54,21 +54,26 @@ const Ellipsis = ({ } }; - const truncateRef = useRef(); + const truncateRef = useRef(); const [isTruncated, setTruncated] = useState(false); const handleTruncate = (truncated) => { if (isMountRef.current && truncated !== isTruncated) { setTruncated(truncated); - if (truncated) { - truncateRef.current?.onResize(); + if (truncated && truncateRef.current) { + truncateRef.current.onResize?.(); } onTruncate?.(truncated); } }; + const componentProps = { + className, + ...rest, + }; + return ( - + !!condition)?.[0]; + return Object.entries(componentMap).find(([, condition]) => !!condition)?.[0] as keyof HTMLElementTagNameMap; }; const currentRef = useRef(); @@ -95,9 +95,9 @@ const TextFunction = (props: TypographyTextProps, ref: React.Ref tooltipProps ? {wrapContent} : wrapContent; - const getSuffix = () => { + const getSuffix = (): ReactElement => { if (typeof copyProps?.suffix === 'function') { - return copyProps.suffix({ copied: isCopied }); + return copyProps.suffix({ copied: isCopied }) as ReactElement; } return isCopied ? : ; }; @@ -107,7 +107,13 @@ const TextFunction = (props: TypographyTextProps, ref: React.Ref, +