From 3aec03a8ae8d3a4007fe89d85d6170bfdf477852 Mon Sep 17 00:00:00 2001 From: Ming <66944708+zym19960704@users.noreply.github.com> Date: Sun, 28 Apr 2024 19:42:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(Text):=20=E6=96=87=E6=9C=AC=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=96=B0=E5=A2=9E=20gradient=20=E5=B1=9E=E6=80=A7=20(?= =?UTF-8?q?#779)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 文本组件新增gradient属性,增加相应的demo * feat: pr问题修改,增加统一处理deg的方法 --------- Co-authored-by: blankzhang --- components/_util/utils.ts | 14 ++++++++ components/text/interface.ts | 6 ++++ components/text/props.ts | 6 ++-- components/text/text.tsx | 15 ++++++++ docs/.vitepress/components/text/gradient.vue | 36 ++++++++++++++++++++ docs/.vitepress/components/text/index.md | 31 ++++++++++++----- 6 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 docs/.vitepress/components/text/gradient.vue diff --git a/components/_util/utils.ts b/components/_util/utils.ts index 97155c23..0e52cb4e 100644 --- a/components/_util/utils.ts +++ b/components/_util/utils.ts @@ -104,6 +104,20 @@ export const pxfy = (value: string | number): string => { return value as string; }; +// 90 => 90deg +export const degfy = (value: string | number): string => { + // 如果输入值是字符串,且已经包含了"deg"后缀,则直接返回 + if (isString(value) && value.endsWith('deg')) { + return value; + } + if (isFinite(Number(value))) { + return `${Number(value)}deg`; + } + + // 如果输入值既不是数字也不是字符串,或者是一个不能转换为数字的字符串,返回一个错误信息 + throw new Error(`Invalid deg: ${value}`); +}; + export function getParentNode(node: Node): Node | null { // document type if (node.nodeType === 9) { diff --git a/components/text/interface.ts b/components/text/interface.ts index 60b30ac8..beeb27e8 100644 --- a/components/text/interface.ts +++ b/components/text/interface.ts @@ -1,3 +1,9 @@ export type Type = 'default' | 'success' | 'info' | 'warning' | 'danger'; export type Size = 'small' | 'middle' | 'large'; + +export interface Gradient { + from: string; + to: string; + deg: number | string; +} diff --git a/components/text/props.ts b/components/text/props.ts index 6d08072c..e44bc730 100644 --- a/components/text/props.ts +++ b/components/text/props.ts @@ -1,7 +1,6 @@ import type { ComponentObjectPropsOptions, PropType } from 'vue'; - import type { ExtractPublicPropTypes } from '../_util/interface'; -import type { Size, Type } from './interface'; +import type { Gradient, Size, Type } from './interface'; export const textProps = { type: { @@ -18,6 +17,9 @@ export const textProps = { type: String, default: 'span', }, + gradient: { + type: Object as PropType, + }, } as const satisfies ComponentObjectPropsOptions; export type TextProps = ExtractPublicPropTypes; diff --git a/components/text/text.tsx b/components/text/text.tsx index 01ee0b6d..98cf543e 100644 --- a/components/text/text.tsx +++ b/components/text/text.tsx @@ -2,6 +2,7 @@ import { computed, defineComponent, h } from 'vue'; import getPrefixCls from '../_util/getPrefixCls'; import { useTheme } from '../_theme/useTheme'; import { getSlot } from '../_util/vnode'; +import { degfy } from '../_util/utils'; import { textProps } from './props'; const prefixCls = getPrefixCls('text'); @@ -24,9 +25,22 @@ export default defineComponent({ [`${prefixCls}-tag--mark`]: props.tag === 'mark', // 定义mark样式 })); + const gradientStyle = computed(() => { + if (props.gradient && props.gradient.from && props.gradient.to) { + const deg = degfy(props.gradient.deg || 0); + return { + backgroundImage: `linear-gradient(${deg}, ${props.gradient.from}, ${props.gradient.to})`, + backgroundClip: 'text', + textFillColor: 'transparent', + }; + } + return {}; + }); + return { prefixCls, textClass, + gradientStyle, }; }, render() { @@ -35,6 +49,7 @@ export default defineComponent({ this.tag || 'span', { class: this.textClass, + style: this.gradientStyle, }, children, ); diff --git a/docs/.vitepress/components/text/gradient.vue b/docs/.vitepress/components/text/gradient.vue new file mode 100644 index 00000000..524f6a3e --- /dev/null +++ b/docs/.vitepress/components/text/gradient.vue @@ -0,0 +1,36 @@ + + + diff --git a/docs/.vitepress/components/text/index.md b/docs/.vitepress/components/text/index.md index 3c5d2e8d..41739bd8 100644 --- a/docs/.vitepress/components/text/index.md +++ b/docs/.vitepress/components/text/index.md @@ -42,19 +42,34 @@ tag.vue mixin.vue ::: -## Text Props +### 颜色渐变 +通过`gradient`,可以设置文字的颜色渐变,纯色则form和to保持一致即可。 -| 属性 | 说明 | 类型 | 默认值 | -| ------ | ----------------------------------------------------------- | ------- | --------- | -| type | 类型,可选值为`default` `success` `info` `warning` `danger` | string | `default` | -| size | 尺寸,可选值为`small` `middle` `large` | string | `middle` | -| strong | 是否字体加粗 | boolean | `false` | -| italic | 是否字体倾斜 | boolean | `false` | -| tag | 自定义元素标签,可选值为`span` `div` `p` `h1` `h2` `h3` 等 | string | `span` | +:::demo +gradient.vue +::: +## Text Props + +| 属性 | 说明 | 类型 | 默认值 | +| -------- | ----------------------------------------------------------- | ------------------ | --------- | +| type | 类型,可选值为`default` `success` `info` `warning` `danger` | `string` | `default` | +| size | 尺寸,可选值为`small` `middle` `large` | `string` | `middle` | +| strong | 是否字体加粗 | `boolean` | `false` | +| italic | 是否字体倾斜 | `boolean` | `false` | +| tag | 自定义元素标签,可选值为`span` `div` `p` `h1` `h2` `h3` 等 | `string` | `span` | +| gradient | 文本渐变色配置 | `Object` | `-` | ## Text Slots | slot 名称 | 说明 | | --------- | -------- | | default | 默认内容 | + +## Gradient Props + +| 属性 | 说明 | 类型 | 默认值 | +| ---- | --------------------------------- | ------------- | ------ | +| from | 起始颜色 | string | `-` | +| to | 结束颜色 | string | `-` | +| deg | 渐变角度,默认为0,即从上之下渐变 | number/string | `0` | \ No newline at end of file