title.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import React, { PureComponent } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { strings } from '@douyinfe/semi-foundation/typography/constants';
  4. import Base from './base';
  5. import { Ellipsis, TypographyBaseType, OmitTypographyProps } from './interface';
  6. import { ArrayElement } from '@douyinfe/semi-foundation/utils/type';
  7. type OmitTitleProps = OmitTypographyProps;
  8. export interface CopyableConfig {
  9. content?: string;
  10. copyTip?: React.ReactNode;
  11. successTip?: React.ReactNode;
  12. icon?: React.ReactNode;
  13. onCopy?: (e: React.MouseEvent, content: string, res: boolean) => void;
  14. render?: (copied: boolean, doCopy: (e: React.MouseEvent) => void, configs: CopyableConfig) => React.ReactNode
  15. }
  16. export type LinkType = React.AnchorHTMLAttributes<HTMLAnchorElement> | boolean;
  17. export interface TitleProps extends Omit<React.HTMLAttributes<HTMLHeadingElement>, OmitTitleProps> {
  18. className?: string;
  19. component?: React.ElementType;
  20. copyable?: CopyableConfig | boolean;
  21. delete?: boolean;
  22. disabled?: boolean;
  23. /**
  24. * ellipsis 用于设置截断相关参数.
  25. * Ellipsis is used to set ellipsis related parameters.
  26. * ellipsis 仅支持纯文本的截断,不支持 reactNode 等复杂类型,请确保 children 传入内容类型为 string.
  27. * Ellipsis only supports ellipsis of plain text, and does not support complex types such as reactNode.
  28. * Please ensure that the content type of children is string.
  29. * Semi 截断有两种策略, CSS 截断和 JS 截断。
  30. * Semi ellipsis has two strategies, CSS ellipsis and JS ellipsis.
  31. * - 当设置中间截断(pos='middle')、可展开(expandable)、有后缀(suffix 非空)、可复制(copyable),启用 JS 截断策略
  32. * - When setting middle ellipsis (pos='middle')、expandable、suffix is not empty string、copyable,
  33. * the JS ellipsis strategy is enabled
  34. * - 非以上场景,启用 CSS 截断策略
  35. * - Otherwise, enable the CSS ellipsis strategy
  36. *
  37. * 通常来说 CSS 截断的性能优于 JS 截断。在 children 不变, 容器尺寸不变的情况下,CSS 截断只涉及 1-2 次计算,js 截断基于二分法,可能涉及多次计算。
  38. * In general CSS ellipsis performs better than JS ellipsis. when the children and container size remain unchanged,
  39. * CSS ellipsis only involves 1-2 calculations, while JS ellipsis is based on dichotomy and may require multiple calculations.
  40. * 同时使用大量带有截断功能的 Typography 需注意性能消耗,如在 Table 中,可通过设置合理的页容量进行分页减少性能损耗
  41. * Pay attention to performance consumption when using a large number of Typography with ellipsis. For example, in Table,
  42. * you can reduce performance loss by setting a reasonable pageSize for paging
  43. */
  44. ellipsis?: Ellipsis | boolean;
  45. heading?: ArrayElement<typeof strings.HEADING>;
  46. link?: LinkType;
  47. mark?: boolean;
  48. strong?: boolean;
  49. style?: React.CSSProperties;
  50. type?: TypographyBaseType;
  51. underline?: boolean;
  52. weight?: ArrayElement<typeof strings.WEIGHT> | number
  53. }
  54. export default class Title extends PureComponent<TitleProps> {
  55. static propTypes = {
  56. copyable: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
  57. delete: PropTypes.bool,
  58. disabled: PropTypes.bool,
  59. // editable: PropTypes.bool,
  60. ellipsis: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
  61. mark: PropTypes.bool,
  62. link: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
  63. underline: PropTypes.bool,
  64. strong: PropTypes.bool,
  65. type: PropTypes.oneOf(strings.TYPE),
  66. heading: PropTypes.oneOf(strings.HEADING),
  67. style: PropTypes.object,
  68. className: PropTypes.string,
  69. component: PropTypes.string,
  70. weight: PropTypes.oneOfType([PropTypes.oneOf(strings.WEIGHT), PropTypes.number]),
  71. };
  72. static defaultProps = {
  73. copyable: false,
  74. delete: false,
  75. disabled: false,
  76. // editable: false,
  77. ellipsis: false,
  78. mark: false,
  79. underline: false,
  80. strong: false,
  81. link: false,
  82. type: 'primary',
  83. heading: 1,
  84. style: {},
  85. className: '',
  86. };
  87. render() {
  88. const { heading, ...rest } = this.props;
  89. const component = strings.HEADING.indexOf(heading) !== -1 ? `h${heading}` : 'h1';
  90. // Passing headings to support custom components
  91. return <Base component={component as React.ElementType} heading={component} {...rest} />;
  92. }
  93. }