From 050a171e91ae8f62aeb17d108ccb4a3c7c49eb4b Mon Sep 17 00:00:00 2001 From: Charles7c Date: Tue, 6 Aug 2024 21:46:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20GiTag=20=E7=BB=84=E4=BB=B6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=89=A9=E5=B1=95=EF=BC=8C=E6=8F=90=E4=BE=9B=20color?= =?UTF-8?q?=20=E5=B1=9E=E6=80=A7=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GiTag/index.tsx | 85 +++++++++++-- src/components/GiTag/tag.scss | 224 ++++++++++++++++----------------- 2 files changed, 185 insertions(+), 124 deletions(-) diff --git a/src/components/GiTag/index.tsx b/src/components/GiTag/index.tsx index bf55d6b..a3ce9fd 100644 --- a/src/components/GiTag/index.tsx +++ b/src/components/GiTag/index.tsx @@ -1,23 +1,43 @@ -import { type PropType, computed, defineComponent } from 'vue' +import { type CSSProperties, type PropType, computed, defineComponent } from 'vue' import './tag.scss' -type TPropsType = 'dark' | 'light' | 'outline' | 'light-outline' -type TPropsStatus = 'primary' | 'success' | 'warning' | 'danger' | 'info' -type TPropsSize = 'mini' | 'small' | 'large' +type PropsType = 'dark' | 'light' | 'outline' | 'light-outline' +type PropsStatus = 'primary' | 'success' | 'warning' | 'danger' | 'info' +type PropsSize = 'mini' | 'small' | 'large' + +const baseColorObj = { + red: '#FF0000 ', + orangered: '#f77234', + orange: '#ff7d00', + gold: '#f7ba1e', + lime: '#9fdb1d', + green: '#00b42a', + cyan: '#14c9c9', + blue: '#3491fa', + purple: '#722ed1', + pink: '#f5319d', + gray: '#86909c' +} + +type BaseColor = keyof typeof baseColorObj export default defineComponent({ name: 'GiTag', props: { type: { - type: String as PropType, + type: String as PropType, default: 'light' }, status: { - type: String as PropType, + type: String as PropType, default: 'primary' }, + color: { + type: String as PropType, + default: '' + }, size: { - type: String as PropType, + type: String as PropType, default: 'small' }, closable: { @@ -30,17 +50,60 @@ export default defineComponent({ const className = computed(() => { const arr = ['gi-tag'] if (props.type) { - arr.push(`gi-tag-${props.type}`) + arr.push(`gi-tag__type--${props.type}`) } if (props.size) { - arr.push(`gi-tag-size-${props.size}`) + arr.push(`gi-tag__size--${props.size}`) } if (props.status) { - arr.push(`gi-tag-status-${props.status === 'info' ? 'gray' : props.status}`) + arr.push(`gi-tag__status--${props.status}`) } return arr }) + // 十六进制颜色 转 rgb + function hexToRgb(hex: string) { + if (hex.includes('#')) { + hex = hex.slice(1) + } + const r = Number.parseInt(hex.slice(0, 2), 16) + const g = Number.parseInt(hex.slice(2, 4), 16) + const b = Number.parseInt(hex.slice(4, 6), 16) + return { r, g, b } + } + + const calcStyle = computed(() => { + const obj: CSSProperties = {} + if (props.color) { + const color = baseColorObj[props.color] || props.color + const { r, g, b } = hexToRgb(color) + if (props.type === 'light') { + obj.color = color + obj.backgroundColor = `rgba(${r}, ${g}, ${b}, 0.1)` + obj['--tag-close-hover-bg-color'] = color + } + if (props.type === 'dark') { + obj.color = '#fff' + obj.backgroundColor = color + obj['--tag-close-hover-color'] = color + obj['--tag-close-hover-bg-color'] = `rgba(255, 255, 255, 0.9)` + } + if (props.type === 'outline') { + obj.color = color + obj.backgroundColor = 'transparent' + obj.borderColor = color + obj['--tag-close-hover-bg-color'] = color + } + if (props.type === 'light-outline') { + obj.color = color + obj.backgroundColor = `rgba(${r}, ${g}, ${b}, 0.1)` + obj.borderColor = `rgba(${r}, ${g}, ${b}, 0.2)` + obj['--tag-close-hover-bg-color'] = color + } + } + return obj + }) + const handleClick = () => { emit('click') } @@ -57,7 +120,7 @@ export default defineComponent({ ) return () => ( - + {slots.default?.()} {props.closable && CloseIcon} diff --git a/src/components/GiTag/tag.scss b/src/components/GiTag/tag.scss index 5cdaf15..01b7006 100644 --- a/src/components/GiTag/tag.scss +++ b/src/components/GiTag/tag.scss @@ -1,8 +1,17 @@ +$status: primary, success, warning, danger; + +$tag-size-mini-height: 20px; +$tag-size-small-height: 22px; +$tag-size-large-height: 24px; + +$tag-size-mini-padding: 0 6px; +$tag-size-small-padding: 0 8px; +$tag-size-large-padding: 0 10px; + .gi-tag { display: inline-flex; - padding: 0 8px; - // padding-top: 1px; - height: 20px; + padding: $tag-size-small-padding; + height: $tag-size-small-height; font-size: 12px; line-height: 1; border-radius: 3px; @@ -15,122 +24,28 @@ .gi-tag-close-btn { position: relative; - display: inline-flex; + display: flex; justify-content: center; align-items: center; cursor: pointer; margin-left: 4px; + width: 16px; + height: 16px; + box-sizing: border-box; + background-color: transparent; + border-radius: var(--border-radius-circle); + transition: background-color 0.1s cubic-bezier(0, 0, 1, 1); .close-icon { width: 12px; height: 12px; z-index: 9; } - - &::before { - width: 16px; - height: 16px; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - content: ''; - position: absolute; - display: block; - box-sizing: border-box; - background-color: transparent; - border-radius: var(--border-radius-circle); - transition: background-color 0.1s cubic-bezier(0, 0, 1, 1); - } } -$status: primary, success, warning, danger, 'gray'; - -.gi-tag-dark { - color: #fff; - - @each $i in $status { - &.gi-tag-status-#{$i} { - border: 1px solid rgb(var(--#{$i}-6)); - background-color: rgb(var(--#{$i}-6)); - - .gi-tag-close-btn { - &:hover { - color: rgb(var(--#{$i}-6)); - - &::before { - background-color: rgb(var(--#{$i}-2)); - } - } - } - } - } -} - -.gi-tag-light { - color: #fff; - - @each $i in $status { - &.gi-tag-status-#{$i} { - color: rgb(var(--#{$i}-6)); - background-color: rgb(var(--#{$i}-1)); - - .gi-tag-close-btn { - &:hover { - color: #fff; - - &::before { - background-color: rgb(var(--#{$i}-6)); - } - } - } - } - } -} - -.gi-tag-outline { - background: transparent; - - @each $i in $status { - &.gi-tag-status-#{$i} { - color: rgb(var(--#{$i}-6)); - border: 1px solid rgb(var(--#{$i}-6)); - - .gi-tag-close-btn { - &:hover { - color: #fff; - - &::before { - background-color: rgb(var(--#{$i}-6)); - } - } - } - } - } -} - -.gi-tag-light-outline { - @each $i in $status { - &.gi-tag-status-#{$i} { - color: rgb(var(--#{$i}-6)); - border: 1px solid rgb(var(--#{$i}-2)); - background-color: rgb(var(--#{$i}-1)); - - .gi-tag-close-btn { - &:hover { - color: #fff; - - &::before { - background-color: rgb(var(--#{$i}-6)); - } - } - } - } - } -} - -.gi-tag-size-mini { - height: 22px; - padding: 0 4px; +.gi-tag__size--mini { + height: $tag-size-mini-height; + padding: $tag-size-mini-padding; .gi-tag-close-btn { .close-icon { @@ -145,12 +60,95 @@ $status: primary, success, warning, danger, 'gray'; } } -.gi-tag-size-small { - height: 24px; +.gi-tag__size--small { + height: $tag-size-small-height; + padding: $tag-size-small-padding; } -.gi-tag-size-large { - height: 28px; - padding: 0 10px; - font-size: 14px; +.gi-tag__size--large { + height: $tag-size-large-height; + padding: $tag-size-small-padding; +} + +.gi-tag__type--light { + color: #fff; + + @each $i in $status { + &.gi-tag__status--#{$i} { + color: rgb(var(--#{$i}-6)); + background-color: rgb(var(--#{$i}-1)); + --tag-close-hover-color: #fff; + --tag-close-hover-bg-color: rgb(var(--#{$i}-6)); + + .gi-tag-close-btn { + &:hover { + color: var(--tag-close-hover-color); + background-color: var(--tag-close-hover-bg-color); + } + } + } + } +} + +.gi-tag__type--dark { + color: #fff; + + @each $i in $status { + &.gi-tag__status--#{$i} { + background-color: rgb(var(--#{$i}-6)); + --tag-close-hover-color: rgb(var(--#{$i}-6)); + --tag-close-hover-bg-color: rgba(255, 255, 255, 0.9); + + .gi-tag-close-btn { + &:hover { + color: var(--tag-close-hover-color); + background-color: var(--tag-close-hover-bg-color); + } + } + } + } +} + +.gi-tag__type--outline { + background: transparent; + border-width: 1px; + border-style: solid; + + @each $i in $status { + &.gi-tag__status--#{$i} { + color: rgb(var(--#{$i}-6)); + border-color: rgb(var(--#{$i}-6)); + --tag-close-hover-color: #fff; + --tag-close-hover-bg-color: rgb(var(--#{$i}-6)); + + .gi-tag-close-btn { + &:hover { + color: var(--tag-close-hover-color); + background-color: var(--tag-close-hover-bg-color); + } + } + } + } +} + +.gi-tag__type--light-outline { + border-width: 1px; + border-style: solid; + + @each $i in $status { + &.gi-tag__status--#{$i} { + color: rgb(var(--#{$i}-6)); + border-color: rgb(var(--#{$i}-2)); + background-color: rgb(var(--#{$i}-1)); + --tag-close-hover-color: #fff; + --tag-close-hover-bg-color: rgb(var(--#{$i}-6)); + + .gi-tag-close-btn { + &:hover { + color: var(--tag-close-hover-color); + background-color: var(--tag-close-hover-bg-color); + } + } + } + } } \ No newline at end of file