mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-11-01 08:57:14 +08:00 
			
		
		
		
	feat: GiTag 组件功能扩展,提供 color 属性,用于自定义颜色
This commit is contained in:
		| @@ -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<TPropsType>, | ||||
|       type: String as PropType<PropsType>, | ||||
|       default: 'light' | ||||
|     }, | ||||
|     status: { | ||||
|       type: String as PropType<TPropsStatus>, | ||||
|       type: String as PropType<PropsStatus>, | ||||
|       default: 'primary' | ||||
|     }, | ||||
|     color: { | ||||
|       type: String as PropType<BaseColor | string>, | ||||
|       default: '' | ||||
|     }, | ||||
|     size: { | ||||
|       type: String as PropType<TPropsSize>, | ||||
|       type: String as PropType<PropsSize>, | ||||
|       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 () => ( | ||||
|       <span class={className.value} onClick={handleClick}> | ||||
|       <span class={className.value} style={calcStyle.value} onClick={handleClick}> | ||||
|         {slots.default?.()} | ||||
|         {props.closable && CloseIcon} | ||||
|       </span> | ||||
|   | ||||
| @@ -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); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user