From ff0817e936421d976475ab4f8cf4f53a8fd22805 Mon Sep 17 00:00:00 2001 From: "Y." Date: Thu, 23 Apr 2026 16:34:06 +0800 Subject: [PATCH 1/5] feat(Typography): add component router --- site/docs/overview.en-US.md | 6 +++--- site/docs/overview.md | 6 +++--- site/mobile/mobile.config.js | 6 ++++++ site/web/site.config.js | 12 ++++++------ 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/site/docs/overview.en-US.md b/site/docs/overview.en-US.md index 2e846c24..8a9211ab 100644 --- a/site/docs/overview.en-US.md +++ b/site/docs/overview.en-US.md @@ -4,7 +4,7 @@ description: Component types will continue to be added according to business pra spline: explain --- -

Base6

+

Base7

- +

Navigation8

diff --git a/site/docs/overview.md b/site/docs/overview.md index 9e279c83..fde7e437 100644 --- a/site/docs/overview.md +++ b/site/docs/overview.md @@ -4,7 +4,7 @@ description: 将根据业务实践持续新增组件类型,敬请留意组件 spline: explain --- -

基础6

+

基础7

- +

导航8

diff --git a/site/mobile/mobile.config.js b/site/mobile/mobile.config.js index 93f845a9..b945c198 100644 --- a/site/mobile/mobile.config.js +++ b/site/mobile/mobile.config.js @@ -422,5 +422,11 @@ export default { name: 'watermark', component: () => import('tdesign-mobile-react/watermark/_example/index.tsx'), }, + { + title: 'Typography 排版', + titleEn: 'Typography', + name: 'typography', + component: () => import('tdesign-mobile-react/typography/_example/index.tsx'), + }, ], }; diff --git a/site/web/site.config.js b/site/web/site.config.js index aa792e3f..884b5a43 100644 --- a/site/web/site.config.js +++ b/site/web/site.config.js @@ -105,12 +105,12 @@ export const docs = [ component: () => import('tdesign-mobile-react/link/link.md'), componentEn: () => import('tdesign-mobile-react/link/link.en-US.md'), }, - // { - // title: 'Typography 排版', - // name: 'typography', - // path: '/mobile-react/components/typography', - // component: () => import('tdesign-mobile-react/typography/typography.md'), - // }, + { + title: 'Typography 排版', + name: 'typography', + path: '/mobile-react/components/typography', + component: () => import('tdesign-mobile-react/typography/typography.md'), + }, ], }, { From 324c0c6bcdb43834ad7999acde500e76b3f63d6c Mon Sep 17 00:00:00 2001 From: "Y." Date: Thu, 23 Apr 2026 16:42:24 +0800 Subject: [PATCH 2/5] docs(Typography): add api docs --- src/typography/defaultProps.ts | 22 +++++ src/typography/type.ts | 147 +++++++++++++++++++++++++++++ src/typography/typography.en-US.md | 64 +++++++++++++ src/typography/typography.md | 64 +++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 src/typography/defaultProps.ts create mode 100644 src/typography/type.ts create mode 100644 src/typography/typography.en-US.md create mode 100644 src/typography/typography.md diff --git a/src/typography/defaultProps.ts b/src/typography/defaultProps.ts new file mode 100644 index 00000000..2a427dc0 --- /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/type.ts b/src/typography/type.ts new file mode 100644 index 00000000..2d6e07d5 --- /dev/null +++ b/src/typography/type.ts @@ -0,0 +1,147 @@ +/* eslint-disable */ + +/** + * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC + * */ + +import type { 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 }>; + /** + * 点击省略按钮的回调 + */ + onExpand?: (expanded: boolean) => void; +} + +export interface TypographyCopyable { + /** + * 复制的文本内容,默认为全部文本 + * @default '' + */ + text?: string; + /** + * 自定义复制触发元素,一般用于自定义复制图标 + */ + suffix?: TNode<{ copied: boolean }>; + /** + * 点击复制按钮的回调 + */ + onCopy?: () => void; +} diff --git a/src/typography/typography.en-US.md b/src/typography/typography.en-US.md new file mode 100644 index 00000000..d621e521 --- /dev/null +++ b/src/typography/typography.en-US.md @@ -0,0 +1,64 @@ +:: BASE_DOC :: + +## API + + +### Text Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | className of component | N +style | Object | - | CSS(Cascading Style Sheets),Typescript: `React.CSSProperties` | N +children | TNode | - | children of text。Typescript: `string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-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 | - | className of component | N +style | Object | - | CSS(Cascading Style Sheets),Typescript: `React.CSSProperties` | N +children | TNode | - | children of title。Typescript: `string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +content | TNode | - | content of title。Typescript: `string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-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 | - | className of component | N +style | Object | - | CSS(Cascading Style Sheets),Typescript: `React.CSSProperties` | N +children | TNode | - | children of paragraph。Typescript: `string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +content | TNode | - | content of paragraph。Typescript: `string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-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-mobile-react/blob/develop/src/common.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-mobile-react/blob/develop/src/common.ts) | N +onCopy | Function | | Typescript: `() => void`
| N diff --git a/src/typography/typography.md b/src/typography/typography.md new file mode 100644 index 00000000..f794c1c6 --- /dev/null +++ b/src/typography/typography.md @@ -0,0 +1,64 @@ +:: 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-mobile-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-mobile-react/blob/develop/src/common.ts) | N +content | TNode | - | 段落内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-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-mobile-react/blob/develop/src/common.ts) | N +content | TNode | - | 段落内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-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-mobile-react/blob/develop/src/common.ts) | N +onExpand | Function | | TS 类型:`(expanded:boolean) => void`
点击省略按钮的回调 | N + +### TypographyCopyable + +名称 | 类型 | 默认值 | 描述 | 必传 +-- | -- | -- | -- | -- + text | String | - | 复制的文本内容,默认为全部文本 | N +suffix | TElement | - | 自定义复制触发元素,一般用于自定义复制图标。TS 类型:`TNode<{ copied: boolean }>`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +onCopy | Function | | TS 类型:`() => void`
点击复制按钮的回调 | N From 66cb86210e786ca712434bb2a3627b0d6210bed7 Mon Sep 17 00:00:00 2001 From: "Y." Date: Thu, 23 Apr 2026 16:42:56 +0800 Subject: [PATCH 3/5] feat(Typography): add component --- src/_util/copy-to-clipboard.ts | 129 ++++++++++++++++++++++++++ src/index.ts | 3 +- src/typography/Ellipsis.tsx | 121 +++++++++++++++++++++++++ src/typography/Paragraph.tsx | 39 ++++++++ src/typography/Text.tsx | 159 +++++++++++++++++++++++++++++++++ src/typography/Title.tsx | 40 +++++++++ src/typography/Typography.tsx | 19 ++++ src/typography/index.ts | 18 ++++ src/typography/style/css.js | 1 + src/typography/style/index.js | 1 + 10 files changed, 529 insertions(+), 1 deletion(-) create mode 100644 src/_util/copy-to-clipboard.ts 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/Typography.tsx create mode 100644 src/typography/index.ts create mode 100644 src/typography/style/css.js create mode 100644 src/typography/style/index.js diff --git a/src/_util/copy-to-clipboard.ts b/src/_util/copy-to-clipboard.ts new file mode 100644 index 00000000..264ad759 --- /dev/null +++ b/src/_util/copy-to-clipboard.ts @@ -0,0 +1,129 @@ +interface Options { + message?: string; + format?: string; // MIME type + onCopy?: (clipboardData: object) => void; +} + +// inspired by https://github.com/sudodoki/toggle-selection, refactor to esm +const deselectCurrent = () => { + const selection = document.getSelection(); + if (!selection.rangeCount) { + return () => {}; + } + let active = document.activeElement as HTMLElement | null; + + const ranges: Range[] = []; + for (let i = 0; i < selection.rangeCount; i++) { + ranges.push(selection.getRangeAt(i)); + } + + const tagName = active?.tagName?.toUpperCase(); // toUpperCase handles XHTML + switch (tagName) { + case 'INPUT': + case 'TEXTAREA': + (active as HTMLElement).blur(); + break; + + default: + active = null; + break; + } + + selection.removeAllRanges(); + return () => { + if (selection.type === 'Caret') { + selection.removeAllRanges(); + } + + if (!selection.rangeCount) { + ranges.forEach((range) => { + selection.addRange(range); + }); + } + + if (active) { + active.focus(); + } + }; +}; + +export const copy = (text: string, opts?: Options) => { + const options: Options = opts || {}; + let reselectPrevious: (() => void) | undefined; + let range: Range | undefined; + let selection: Selection | null | undefined; + let mark: HTMLSpanElement | undefined; + let success = false; + + try { + reselectPrevious = deselectCurrent(); + + range = document.createRange(); + selection = document.getSelection(); + + mark = document.createElement('span'); + mark.textContent = text; + // reset user styles for span element + mark.style.all = 'unset'; + // prevents scrolling to the end of the page + mark.style.position = 'fixed'; + mark.style.top = '0'; + mark.style.clip = 'rect(0, 0, 0, 0)'; + // used to preserve spaces and line breaks + mark.style.whiteSpace = 'pre'; + // do not inherit user-select (it may be `none`) + mark.style.webkitUserSelect = 'text'; + mark.style.userSelect = 'text'; + mark.addEventListener('copy', (e: ClipboardEvent) => { + e.stopPropagation(); + if (options.format) { + e.preventDefault(); + e.clipboardData?.clearData(); + e.clipboardData?.setData(options.format, text); + } + if (options.onCopy) { + e.preventDefault(); + options.onCopy(e.clipboardData as object); + } + }); + + document.body.appendChild(mark); + + range.selectNodeContents(mark); + selection?.addRange(range); + + const successful = document.execCommand('copy'); + if (!successful) { + throw new Error('copy command was unsuccessful'); + } + success = true; + } catch { + try { + (window as any).clipboardData.setData(options.format || 'text', text); + if (options.onCopy) { + options.onCopy((window as any).clipboardData); + } + success = true; + } catch { + // 移动端不使用 prompt 兜底,静默失败 + console.warn('Copy to clipboard failed'); + } + } finally { + if (selection) { + if (typeof selection.removeRange === 'function') { + selection.removeRange(range as Range); + } else { + selection.removeAllRanges(); + } + } + + if (mark) { + document.body.removeChild(mark); + } + if (reselectPrevious) { + reselectPrevious(); + } + } + + return success; +}; diff --git a/src/index.ts b/src/index.ts index 36d12c88..db18e1de 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,12 @@ /** - * 基础组件(除icon,5个) + * 基础组件(除icon,6个) */ export * from './button'; export * from './divider'; export * from './fab'; export * from './layout'; export * from './link'; +export * from './typography'; /** * 导航(8个) diff --git a/src/typography/Ellipsis.tsx b/src/typography/Ellipsis.tsx new file mode 100644 index 00000000..f55d49f4 --- /dev/null +++ b/src/typography/Ellipsis.tsx @@ -0,0 +1,121 @@ +import React, { useState, useMemo, useCallback, ReactNode, CSSProperties } from 'react'; +import useConfig from '../hooks/useConfig'; +import parseTNode from '../_util/parseTNode'; + +import type { TypographyEllipsis } from './type'; + +export interface EllipsisProps { + className?: string; + style?: CSSProperties; + children?: ReactNode; + ellipsis?: boolean | TypographyEllipsis; + renderCopy?: () => ReactNode; +} + +const Ellipsis: React.FC = (props) => { + const { className, style, children, ellipsis, renderCopy } = props; + const { classPrefix } = useConfig(); + const prefixCls = `${classPrefix}-typography`; + + const [isExpand, setIsExpand] = useState(false); + + const ellipsisState = useMemo((): TypographyEllipsis => { + const defaults: TypographyEllipsis = { row: 1, expandable: false, collapsible: true }; + if (typeof ellipsis === 'object') { + return { ...defaults, ...ellipsis }; + } + return defaults; + }, [ellipsis]); + + const ellipsisStyles = useMemo((): CSSProperties => { + if (!ellipsis) return {}; + + const base: CSSProperties = { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'normal', + display: '-webkit-box', + WebkitLineClamp: ellipsisState.row, + WebkitBoxOrient: 'vertical', + }; + + if (isExpand) { + base.overflow = 'visible'; + base.whiteSpace = 'normal'; + base.display = 'initial'; + } + + return base; + }, [ellipsis, ellipsisState.row, isExpand]); + + const handleExpand = useCallback(() => { + setIsExpand(true); + if (typeof ellipsis === 'object') { + ellipsis.onExpand?.(true); + } + }, [ellipsis]); + + const handleCollapse = useCallback(() => { + setIsExpand(false); + if (typeof ellipsis === 'object') { + ellipsis.onExpand?.(false); + } + }, [ellipsis]); + + const renderSuffix = useCallback( + (expanded: boolean): ReactNode => { + const { suffix } = ellipsisState; + if (!suffix) return null; + return parseTNode(suffix, { expanded }); + }, + [ellipsisState], + ); + + const renderEllipsisExpand = () => { + const { suffix, expandable, collapsible } = ellipsisState; + + const symbolStyle: CSSProperties = { + textDecoration: 'none', + whiteSpace: 'nowrap', + flex: 'none', + marginRight: renderCopy ? 8 : 0, + }; + + if (!isExpand && expandable) { + return ( + + {suffix ? renderSuffix(false) : '展开'} + + ); + } + + if (expandable && isExpand && collapsible) { + return ( + + {suffix ? renderSuffix(true) : '收起'} + + ); + } + + return null; + }; + + return ( +
+

{children}

+ {renderEllipsisExpand()} + {renderCopy?.()} +
+ ); +}; + +Ellipsis.displayName = 'Ellipsis'; + +export default Ellipsis; diff --git a/src/typography/Paragraph.tsx b/src/typography/Paragraph.tsx new file mode 100644 index 00000000..50ddd951 --- /dev/null +++ b/src/typography/Paragraph.tsx @@ -0,0 +1,39 @@ +import React, { forwardRef, ReactNode } from 'react'; +import classNames from 'classnames'; +import useConfig from '../hooks/useConfig'; +import useDefaultProps from '../hooks/useDefaultProps'; +import { paragraphDefaultProps } from './defaultProps'; +import Ellipsis from './Ellipsis'; + +import type { StyledProps } from '../common'; +import type { TdParagraphProps } from './type'; + +export interface ParagraphProps extends TdParagraphProps, StyledProps {} + +const Paragraph = forwardRef((originalProps, ref) => { + const props = useDefaultProps(originalProps, paragraphDefaultProps); + const { classPrefix } = useConfig(); + const prefixCls = `${classPrefix}-typography`; + + const { className, style, children, content, ellipsis } = props; + + const renderContent = (children ?? content) as ReactNode; + + if (ellipsis) { + return ( + + {renderContent} + + ); + } + + return ( +
+ {renderContent} +
+ ); +}); + +Paragraph.displayName = 'Paragraph'; + +export default Paragraph; diff --git a/src/typography/Text.tsx b/src/typography/Text.tsx new file mode 100644 index 00000000..61613138 --- /dev/null +++ b/src/typography/Text.tsx @@ -0,0 +1,159 @@ +import React, { forwardRef, useState, useCallback, useMemo, ReactNode } from 'react'; +import classNames from 'classnames'; +import { CopyIcon, CheckIcon } from 'tdesign-icons-react'; +import useConfig from '../hooks/useConfig'; +import useDefaultProps from '../hooks/useDefaultProps'; +import parseTNode from '../_util/parseTNode'; +import { copy } from '../_util/copy-to-clipboard'; +import { textDefaultProps } from './defaultProps'; +import Ellipsis from './Ellipsis'; + +import type { StyledProps } from '../common'; +import type { TdTextProps } from './type'; + +export interface TextProps extends TdTextProps, StyledProps {} + +const Text = forwardRef((originalProps, ref) => { + const props = useDefaultProps(originalProps, textDefaultProps); + const { classPrefix } = useConfig(); + const prefixCls = `${classPrefix}-typography`; + + const { + className, + style, + children, + code, + copyable, + delete: del, + disabled, + ellipsis, + italic, + keyboard, + mark, + strong, + theme, + underline, + } = props; + + const [isCopied, setIsCopied] = useState(false); + + const textClassNames = useMemo(() => { + const list: string[] = [prefixCls]; + if (disabled) { + list.push(`${prefixCls}--disabled`); + } else if (theme && ['primary', 'secondary', 'success', 'warning', 'error'].includes(theme)) { + list.push(`${prefixCls}--${theme}`); + } + return classNames(list, className); + }, [prefixCls, disabled, theme, className]); + + /** 文本装饰 - 支持多装饰嵌套,参考移动端 Vue 版 */ + const wrapperDecorations = useCallback( + (content: ReactNode): ReactNode => { + let currentContent = content; + + const wrap = (needed: boolean, Tag: string, styles: React.CSSProperties = {}) => { + if (!needed) return; + currentContent = React.createElement(Tag, { style: styles }, currentContent); + }; + + wrap(!!strong, 'strong'); + wrap(!!underline, 'u'); + wrap(!!del, 'del'); + wrap(!!code, 'code'); + wrap(mark !== false && mark !== undefined, 'mark', typeof mark === 'string' ? { backgroundColor: mark } : {}); + wrap(!!keyboard, 'kbd'); + wrap(!!italic, 'i'); + + return currentContent; + }, + [strong, underline, del, code, mark, keyboard, italic], + ); + + /** 获取要复制的文本 */ + const getChildrenText = useCallback((): string => { + if (typeof copyable === 'object' && copyable?.text) { + return copyable.text; + } + if (typeof children === 'string') { + return children; + } + if (Array.isArray(children)) { + return children + .map((child) => { + if (typeof child === 'string') return child; + return ''; + }) + .join(''); + } + return ''; + }, [copyable, children]); + + /** 复制点击处理 */ + const handleCopyClick = useCallback( + (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + + setIsCopied(true); + setTimeout(() => { + setIsCopied(false); + }, 1500); + + copy(getChildrenText()); + + if (typeof copyable === 'object' && typeof copyable.onCopy === 'function') { + copyable.onCopy(); + } + }, + [copyable, getChildrenText], + ); + + /** 渲染复制按钮 */ + const renderCopy = () => { + if (!copyable) return null; + + let icon: ReactNode = null; + + if (typeof copyable === 'object' && copyable.suffix) { + icon = parseTNode(copyable.suffix, { copied: isCopied }); + } + + // 如果没有自定义 suffix,使用默认图标 + if (!icon) { + icon = isCopied ? : ; + } + + return ( + + {icon} + + ); + }; + + const decoratedContent = wrapperDecorations(children as ReactNode); + + if (ellipsis) { + return ( + renderCopy() : undefined} + > + {decoratedContent} + + ); + } + + return ( + + {decoratedContent} + {renderCopy()} + + ); +}); + +Text.displayName = 'Text'; + +export default Text; diff --git a/src/typography/Title.tsx b/src/typography/Title.tsx new file mode 100644 index 00000000..6a0ccd72 --- /dev/null +++ b/src/typography/Title.tsx @@ -0,0 +1,40 @@ +import React, { forwardRef } from 'react'; +import classNames from 'classnames'; +import useConfig from '../hooks/useConfig'; +import useDefaultProps from '../hooks/useDefaultProps'; +import { titleDefaultProps } from './defaultProps'; +import Ellipsis from './Ellipsis'; + +import type { StyledProps } from '../common'; +import type { TdTitleProps } from './type'; + +export interface TitleProps extends TdTitleProps, StyledProps {} + +const Title = forwardRef((originalProps, ref) => { + const props = useDefaultProps(originalProps, titleDefaultProps); + const { classPrefix } = useConfig(); + const prefixCls = `${classPrefix}-typography`; + + const { className, style, children, content, ellipsis, level } = props; + + const Tag = level as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + const renderContent = (children ?? content) as React.ReactNode; + + if (ellipsis) { + return ( + + {renderContent} + + ); + } + + return ( + + {renderContent} + + ); +}); + +Title.displayName = 'Title'; + +export default Title; diff --git a/src/typography/Typography.tsx b/src/typography/Typography.tsx new file mode 100644 index 00000000..41fbf32c --- /dev/null +++ b/src/typography/Typography.tsx @@ -0,0 +1,19 @@ +import Text from './Text'; +import Title from './Title'; +import Paragraph from './Paragraph'; + +const Typography: { + Text: typeof Text; + Title: typeof Title; + Paragraph: typeof Paragraph; +} = () => null; + +Typography.Text = Text; +Typography.Title = Title; +Typography.Paragraph = Paragraph; + +Text.displayName = 'TypographyText'; +Title.displayName = 'TypographyTitle'; +Paragraph.displayName = 'TypographyParagraph'; + +export default Typography; diff --git a/src/typography/index.ts b/src/typography/index.ts new file mode 100644 index 00000000..2b6f3a0b --- /dev/null +++ b/src/typography/index.ts @@ -0,0 +1,18 @@ +import _Typography from './Typography'; +import _Text from './Text'; +import _Title from './Title'; +import _Paragraph from './Paragraph'; + +import './style/index.js'; + +export type { TextProps } from './Text'; +export type { TitleProps } from './Title'; +export type { ParagraphProps } from './Paragraph'; +export * from './type'; + +export const Typography = _Typography; +export const TypographyText = _Text; +export const TypographyTitle = _Title; +export const TypographyParagraph = _Paragraph; + +export default Typography; diff --git a/src/typography/style/css.js b/src/typography/style/css.js new file mode 100644 index 00000000..6a9a4b13 --- /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 00000000..0a516565 --- /dev/null +++ b/src/typography/style/index.js @@ -0,0 +1 @@ +import '../../_common/style/mobile/components/typography/_index.less'; From 309b6800748e9a8e42882f550d615f6a82f50670 Mon Sep 17 00:00:00 2001 From: "Y." Date: Thu, 23 Apr 2026 16:44:42 +0800 Subject: [PATCH 4/5] feat(Typography): add demos --- src/typography/_example/base.tsx | 12 +++++ src/typography/_example/combination.tsx | 57 ++++++++++++++++++++++++ src/typography/_example/copyable.tsx | 27 +++++++++++ src/typography/_example/ellipsis.tsx | 44 ++++++++++++++++++ src/typography/_example/index.tsx | 32 +++++++++++++ src/typography/_example/style/index.less | 40 +++++++++++++++++ src/typography/_example/theme.tsx | 17 +++++++ 7 files changed, 229 insertions(+) create mode 100644 src/typography/_example/base.tsx create mode 100644 src/typography/_example/combination.tsx create mode 100644 src/typography/_example/copyable.tsx create mode 100644 src/typography/_example/ellipsis.tsx create mode 100644 src/typography/_example/index.tsx create mode 100644 src/typography/_example/style/index.less create mode 100644 src/typography/_example/theme.tsx diff --git a/src/typography/_example/base.tsx b/src/typography/_example/base.tsx new file mode 100644 index 00000000..8f27161c --- /dev/null +++ b/src/typography/_example/base.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { TypographyText } from 'tdesign-mobile-react'; + +import './style/index.less'; + +export default function BaseDemo() { + return ( +
+ TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。 +
+ ); +} diff --git a/src/typography/_example/combination.tsx b/src/typography/_example/combination.tsx new file mode 100644 index 00000000..a6ff9b4c --- /dev/null +++ b/src/typography/_example/combination.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { TypographyText, TypographyTitle, TypographyParagraph } from 'tdesign-mobile-react'; + +import './style/index.less'; + +export default function CombinationDemo() { + return ( +
+ What is TDesign + + TDesign is an enterprise-level design system accumulated by Tencent's various business teams. + + + + TDesign features a unified design values, consistent design language, and visual style, helping users form + continuous and coherent perceptions of the experience. + {' '} + Based on this, TDesign offers out-of-the-box UI component libraries, design guidelines, and design assets, + elegantly and efficiently freeing design and development from repetitive tasks. Simultaneously, it facilitates + easy extension on top of TDesign, enabling a better alignment with business requirements. + + Comprehensive + + TDesign Support Vue 2, Vue 3,{' '} + React components for Desktop Application and{' '} + Vue 3, Wechat MiniProgram components + for Mobile Application. + + +
    +
  • Features
  • +
  • + Comprehensive +
      +
    • Consistency
    • +
    • Usability
    • +
    +
  • +
  • Join TDesign
  • +
+
+ +
    +
  1. Features
  2. +
  3. + Comprehensive +
      +
    1. Consistency
    2. +
    3. Usability
    4. +
    +
  4. +
  5. Join TDesign
  6. +
+
+
+ ); +} diff --git a/src/typography/_example/copyable.tsx b/src/typography/_example/copyable.tsx new file mode 100644 index 00000000..dfc1bd0a --- /dev/null +++ b/src/typography/_example/copyable.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { SmileIcon } from 'tdesign-icons-react'; +import { TypographyText } from 'tdesign-mobile-react'; + +import './style/index.less'; + +export default function CopyableDemo() { + return ( +
+
+ This is a copyable text. +
+
+ , + onCopy: () => { + console.log('触发 copy 事件,已复制文本'); + }, + }} + > + This is a copyable text with custom icon. + +
+
+ ); +} diff --git a/src/typography/_example/ellipsis.tsx b/src/typography/_example/ellipsis.tsx new file mode 100644 index 00000000..cc5287d9 --- /dev/null +++ b/src/typography/_example/ellipsis.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import { ChevronDownIcon } from 'tdesign-icons-react'; +import { TypographyParagraph } from 'tdesign-mobile-react'; +import type { TypographyEllipsis } from 'tdesign-mobile-react'; + +import './style/index.less'; + +const content = + 'TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。'; + +const ellipsisExpandable: TypographyEllipsis = { + row: 2, + expandable: true, + collapsible: true, + onExpand: (expanded: boolean) => { + console.log(`触发 expand 事件,当前状态:${expanded ? '展开' : '收起'}`); + }, +}; + +const ellipsisCustomSuffix: TypographyEllipsis = { + row: 1, + suffix: () => , + expandable: true, + collapsible: false, + onExpand: () => { + console.log('触发 expand 事件'); + }, +}; + +export default function EllipsisDemo() { + return ( +
+
+ {content} +
+
+ {content} +
+
+ {content} +
+
+ ); +} diff --git a/src/typography/_example/index.tsx b/src/typography/_example/index.tsx new file mode 100644 index 00000000..e729b036 --- /dev/null +++ b/src/typography/_example/index.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import TDemoBlock from '../../../site/mobile/components/DemoBlock'; +import TDemoHeader from '../../../site/mobile/components/DemoHeader'; + +import BaseDemo from './base'; +import CombinationDemo from './combination'; +import ThemeDemo from './theme'; +import CopyableDemo from './copyable'; +import EllipsisDemo from './ellipsis'; + +export default function TypographyDemo() { + return ( +
+ + + + + + + + + + + + + + + + +
+ ); +} diff --git a/src/typography/_example/style/index.less b/src/typography/_example/style/index.less new file mode 100644 index 00000000..9c31ab89 --- /dev/null +++ b/src/typography/_example/style/index.less @@ -0,0 +1,40 @@ +.tdesign-mobile-typography-demo { + display: flex; + padding: 0 16px; + background-color: var(--td-bg-color-container, #fff); + + &--inline { + display: inline-block; + } + + &--theme { + gap: 24px; + } + + &--border { + position: relative; + + &::after { + content: ''; + position: absolute; + bottom: 0; + left: 16px; + right: 16px; + border-bottom: 1px solid var(--td-stroke-color, #e7e7e7); + transform: scaleY(0.5); + } + } + + ul, + dl, + ol { + margin: 0; + padding: 0 0 0 1.2em; + line-height: 22px; + } + + ul { + display: block; + list-style-type: disc; + } +} diff --git a/src/typography/_example/theme.tsx b/src/typography/_example/theme.tsx new file mode 100644 index 00000000..17396e4a --- /dev/null +++ b/src/typography/_example/theme.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { TypographyText } from 'tdesign-mobile-react'; + +import './style/index.less'; + +export default function ThemeDemo() { + return ( +
+ 常规 + 主色 + 成功 + 警告 + 错误 + 标记 +
+ ); +} From 67f39b0efef598d177a75d42229c53260a5b6039 Mon Sep 17 00:00:00 2001 From: "Y." Date: Thu, 23 Apr 2026 16:59:42 +0800 Subject: [PATCH 5/5] test: update snapshots --- src/typography/_example/copyable.tsx | 4 +- src/typography/_example/index.tsx | 7 +- src/typography/_example/theme.tsx | 3 +- test/snap/__snapshots__/csr.test.jsx.snap | 818 ++++++++++++++++++++++ test/snap/__snapshots__/ssr.test.jsx.snap | 12 + 5 files changed, 838 insertions(+), 6 deletions(-) diff --git a/src/typography/_example/copyable.tsx b/src/typography/_example/copyable.tsx index dfc1bd0a..b6b8240f 100644 --- a/src/typography/_example/copyable.tsx +++ b/src/typography/_example/copyable.tsx @@ -8,7 +8,7 @@ export default function CopyableDemo() { return (
- This is a copyable text. + 这是一段可复制的文本
- This is a copyable text with custom icon. + 这是一段带自定义图标的可复制的文本
diff --git a/src/typography/_example/index.tsx b/src/typography/_example/index.tsx index e729b036..48c2466c 100644 --- a/src/typography/_example/index.tsx +++ b/src/typography/_example/index.tsx @@ -11,8 +11,11 @@ import EllipsisDemo from './ellipsis'; export default function TypographyDemo() { return (
- - + + diff --git a/src/typography/_example/theme.tsx b/src/typography/_example/theme.tsx index 17396e4a..2f85594e 100644 --- a/src/typography/_example/theme.tsx +++ b/src/typography/_example/theme.tsx @@ -6,8 +6,7 @@ import './style/index.less'; export default function ThemeDemo() { return (
- 常规 - 主色 + 主色 成功 警告 错误 diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index 18b9ec11..a00f49de 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -133421,6 +133421,812 @@ exports[`csr snapshot test > csr test src/tree-select/_example/normal.tsx 1`] =
`; +exports[`csr snapshot test > csr test src/typography/_example/base.tsx 1`] = ` +
+
+ + TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。 + +
+
+`; + +exports[`csr snapshot test > csr test src/typography/_example/combination.tsx 1`] = ` +
+
+

+ What is TDesign +

+ + + TDesign is an enterprise-level design system accumulated by Tencent's various business teams. + + +
+ + + TDesign features a unified design values, consistent design language, and visual style, helping users form continuous and coherent perceptions of the experience. + + + + Based on this, TDesign offers out-of-the-box UI component libraries, design guidelines, and design assets, elegantly and efficiently freeing design and development from repetitive tasks. Simultaneously, it facilitates easy extension on top of TDesign, enabling a better alignment with business requirements. +
+

+ Comprehensive +

+
+ TDesign Support + + + Vue 2 + + + , + + + Vue 3 + + + , + + + + React + + + components for Desktop Application and + + + + Vue 3 + + + , + + + Wechat MiniProgram + + + components for Mobile Application. +
+
+
    +
  • + Features +
  • +
  • + Comprehensive +
      +
    • + Consistency +
    • +
    • + Usability +
    • +
    +
  • +
  • + Join TDesign +
  • +
+
+
+
    +
  1. + Features +
  2. +
  3. + Comprehensive +
      +
    1. + Consistency +
    2. +
    3. + Usability +
    4. +
    +
  4. +
  5. + Join TDesign +
  6. +
+
+
+
+`; + +exports[`csr snapshot test > csr test src/typography/_example/copyable.tsx 1`] = ` +
+
+
+ + 这是一段可复制的文本 + + + + + + + + + + +
+
+ + 这是一段带自定义图标的可复制的文本 + + + + + + + + + + +
+
+
+`; + +exports[`csr snapshot test > csr test src/typography/_example/ellipsis.tsx 1`] = ` +
+
+
+
+

+ TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。 +

+
+
+
+
+

+ TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。 +

+ + 展开 + +
+
+
+
+

+ TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。 +

+ + + + + + + +
+
+
+
+`; + +exports[`csr snapshot test > csr test src/typography/_example/index.tsx 1`] = ` +
+
+
+

+ Typography 排版 +

+

+ 排版用于文本基础编排和样式,使用排版组件,可以快速完成页面中的文本内容制作,同时配合其他组件完成深色与浅色模式切换等风格统一的需求。 +

+
+
+
+

+ 组件类型 +

+

+ 基础文本 +

+
+
+
+ + TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。 + +
+
+
+
+
+

+ 组合用法 +

+
+
+
+

+ What is TDesign +

+ + + TDesign is an enterprise-level design system accumulated by Tencent's various business teams. + + +
+ + + TDesign features a unified design values, consistent design language, and visual style, helping users form continuous and coherent perceptions of the experience. + + + + Based on this, TDesign offers out-of-the-box UI component libraries, design guidelines, and design assets, elegantly and efficiently freeing design and development from repetitive tasks. Simultaneously, it facilitates easy extension on top of TDesign, enabling a better alignment with business requirements. +
+

+ Comprehensive +

+
+ TDesign Support + + + Vue 2 + + + , + + + Vue 3 + + + , + + + + React + + + components for Desktop Application and + + + + Vue 3 + + + , + + + Wechat MiniProgram + + + components for Mobile Application. +
+
+
    +
  • + Features +
  • +
  • + Comprehensive +
      +
    • + Consistency +
    • +
    • + Usability +
    • +
    +
  • +
  • + Join TDesign +
  • +
+
+
+
    +
  1. + Features +
  2. +
  3. + Comprehensive +
      +
    1. + Consistency +
    2. +
    3. + Usability +
    4. +
    +
  4. +
  5. + Join TDesign +
  6. +
+
+
+
+
+
+
+

+ 主题样式 +

+
+
+
+ + 主色 + + + 成功 + + + 警告 + + + 错误 + + + + 标记 + + +
+
+
+
+
+

+ 可复制 +

+
+
+
+
+ + 这是一段可复制的文本 + + + + + + + + + + +
+
+ + 这是一段带自定义图标的可复制的文本 + + + + + + + + + + +
+
+
+
+
+
+

+ 文本省略 +

+
+
+
+
+
+

+ TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。 +

+
+
+
+
+

+ TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。 +

+ + 展开 + +
+
+
+
+

+ TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。 +

+ + + + + + + +
+
+
+
+
+
+
+`; + +exports[`csr snapshot test > csr test src/typography/_example/theme.tsx 1`] = ` +
+
+ + 主色 + + + 成功 + + + 警告 + + + 错误 + + + + 标记 + + +
+
+`; + exports[`csr snapshot test > csr test src/upload/_example/base.tsx 1`] = `
ssr test src/tree-select/_example/multiple.tsx 1`] exports[`ssr snapshot test > ssr test src/tree-select/_example/normal.tsx 1`] = `"
"`; +exports[`ssr snapshot test > ssr test src/typography/_example/base.tsx 1`] = `"
TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。
"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/combination.tsx 1`] = `"

What is TDesign

TDesign is an enterprise-level design system accumulated by Tencent's various business teams.
TDesign features a unified design values, consistent design language, and visual style, helping users form continuous and coherent perceptions of the experience. Based on this, TDesign offers out-of-the-box UI component libraries, design guidelines, and design assets, elegantly and efficiently freeing design and development from repetitive tasks. Simultaneously, it facilitates easy extension on top of TDesign, enabling a better alignment with business requirements.

Comprehensive

TDesign Support Vue 2, Vue 3, React components for Desktop Application and Vue 3, Wechat MiniProgram components for Mobile Application.
  • Features
  • Comprehensive
    • Consistency
    • Usability
  • Join TDesign
  1. Features
  2. Comprehensive
    1. Consistency
    2. Usability
  3. Join TDesign
"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/copyable.tsx 1`] = `"
这是一段可复制的文本
这是一段带自定义图标的可复制的文本
"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/ellipsis.tsx 1`] = `"

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

展开

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/index.tsx 1`] = `"

Typography 排版

排版用于文本基础编排和样式,使用排版组件,可以快速完成页面中的文本内容制作,同时配合其他组件完成深色与浅色模式切换等风格统一的需求。

组件类型

基础文本

TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。

组合用法

What is TDesign

TDesign is an enterprise-level design system accumulated by Tencent's various business teams.
TDesign features a unified design values, consistent design language, and visual style, helping users form continuous and coherent perceptions of the experience. Based on this, TDesign offers out-of-the-box UI component libraries, design guidelines, and design assets, elegantly and efficiently freeing design and development from repetitive tasks. Simultaneously, it facilitates easy extension on top of TDesign, enabling a better alignment with business requirements.

Comprehensive

TDesign Support Vue 2, Vue 3, React components for Desktop Application and Vue 3, Wechat MiniProgram components for Mobile Application.
  • Features
  • Comprehensive
    • Consistency
    • Usability
  • Join TDesign
  1. Features
  2. Comprehensive
    1. Consistency
    2. Usability
  3. Join TDesign

主题样式

主色成功警告错误标记

可复制

这是一段可复制的文本
这是一段带自定义图标的可复制的文本

文本省略

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

展开

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/theme.tsx 1`] = `"
主色成功警告错误标记
"`; + exports[`ssr snapshot test > ssr test src/upload/_example/base.tsx 1`] = `"

上传图片

"`; exports[`ssr snapshot test > ssr test src/upload/_example/custom.tsx 1`] = `"
请上传身份证人像面
请上传身份证国徽面
"`; diff --git a/test/snap/__snapshots__/ssr.test.jsx.snap b/test/snap/__snapshots__/ssr.test.jsx.snap index d1eaf857..77c2c926 100644 --- a/test/snap/__snapshots__/ssr.test.jsx.snap +++ b/test/snap/__snapshots__/ssr.test.jsx.snap @@ -782,6 +782,18 @@ exports[`ssr snapshot test > ssr test src/tree-select/_example/multiple.tsx 1`] exports[`ssr snapshot test > ssr test src/tree-select/_example/normal.tsx 1`] = `"
"`; +exports[`ssr snapshot test > ssr test src/typography/_example/base.tsx 1`] = `"
TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。
"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/combination.tsx 1`] = `"

What is TDesign

TDesign is an enterprise-level design system accumulated by Tencent's various business teams.
TDesign features a unified design values, consistent design language, and visual style, helping users form continuous and coherent perceptions of the experience. Based on this, TDesign offers out-of-the-box UI component libraries, design guidelines, and design assets, elegantly and efficiently freeing design and development from repetitive tasks. Simultaneously, it facilitates easy extension on top of TDesign, enabling a better alignment with business requirements.

Comprehensive

TDesign Support Vue 2, Vue 3, React components for Desktop Application and Vue 3, Wechat MiniProgram components for Mobile Application.
  • Features
  • Comprehensive
    • Consistency
    • Usability
  • Join TDesign
  1. Features
  2. Comprehensive
    1. Consistency
    2. Usability
  3. Join TDesign
"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/copyable.tsx 1`] = `"
这是一段可复制的文本
这是一段带自定义图标的可复制的文本
"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/ellipsis.tsx 1`] = `"

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

展开

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/index.tsx 1`] = `"

Typography 排版

排版用于文本基础编排和样式,使用排版组件,可以快速完成页面中的文本内容制作,同时配合其他组件完成深色与浅色模式切换等风格统一的需求。

组件类型

基础文本

TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。

组合用法

What is TDesign

TDesign is an enterprise-level design system accumulated by Tencent's various business teams.
TDesign features a unified design values, consistent design language, and visual style, helping users form continuous and coherent perceptions of the experience. Based on this, TDesign offers out-of-the-box UI component libraries, design guidelines, and design assets, elegantly and efficiently freeing design and development from repetitive tasks. Simultaneously, it facilitates easy extension on top of TDesign, enabling a better alignment with business requirements.

Comprehensive

TDesign Support Vue 2, Vue 3, React components for Desktop Application and Vue 3, Wechat MiniProgram components for Mobile Application.
  • Features
  • Comprehensive
    • Consistency
    • Usability
  • Join TDesign
  1. Features
  2. Comprehensive
    1. Consistency
    2. Usability
  3. Join TDesign

主题样式

主色成功警告错误标记

可复制

这是一段可复制的文本
这是一段带自定义图标的可复制的文本

文本省略

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

展开

TDesign 秉承开放的设计理念从创立之初就采用开源协作的方式进行设计和开发。协作方案讨论、组件设计以及 API 设计,包括源代码在内均在公司内部完全开放,赢得了内部开发者和设计师的广泛关注。TDesign 遵循平等、开放、严格的原则,不论参与者的角色如何。

"`; + +exports[`ssr snapshot test > ssr test src/typography/_example/theme.tsx 1`] = `"
主色成功警告错误标记
"`; + exports[`ssr snapshot test > ssr test src/upload/_example/base.tsx 1`] = `"

上传图片

"`; exports[`ssr snapshot test > ssr test src/upload/_example/custom.tsx 1`] = `"
请上传身份证人像面
请上传身份证国徽面
"`;