mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-10-31 22:57:15 +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' | import './tag.scss' | ||||||
|  |  | ||||||
| type TPropsType = 'dark' | 'light' | 'outline' | 'light-outline' | type PropsType = 'dark' | 'light' | 'outline' | 'light-outline' | ||||||
| type TPropsStatus = 'primary' | 'success' | 'warning' | 'danger' | 'info' | type PropsStatus = 'primary' | 'success' | 'warning' | 'danger' | 'info' | ||||||
| type TPropsSize = 'mini' | 'small' | 'large' | 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({ | export default defineComponent({ | ||||||
|   name: 'GiTag', |   name: 'GiTag', | ||||||
|   props: { |   props: { | ||||||
|     type: { |     type: { | ||||||
|       type: String as PropType<TPropsType>, |       type: String as PropType<PropsType>, | ||||||
|       default: 'light' |       default: 'light' | ||||||
|     }, |     }, | ||||||
|     status: { |     status: { | ||||||
|       type: String as PropType<TPropsStatus>, |       type: String as PropType<PropsStatus>, | ||||||
|       default: 'primary' |       default: 'primary' | ||||||
|     }, |     }, | ||||||
|  |     color: { | ||||||
|  |       type: String as PropType<BaseColor | string>, | ||||||
|  |       default: '' | ||||||
|  |     }, | ||||||
|     size: { |     size: { | ||||||
|       type: String as PropType<TPropsSize>, |       type: String as PropType<PropsSize>, | ||||||
|       default: 'small' |       default: 'small' | ||||||
|     }, |     }, | ||||||
|     closable: { |     closable: { | ||||||
| @@ -30,17 +50,60 @@ export default defineComponent({ | |||||||
|     const className = computed(() => { |     const className = computed(() => { | ||||||
|       const arr = ['gi-tag'] |       const arr = ['gi-tag'] | ||||||
|       if (props.type) { |       if (props.type) { | ||||||
|         arr.push(`gi-tag-${props.type}`) |         arr.push(`gi-tag__type--${props.type}`) | ||||||
|       } |       } | ||||||
|       if (props.size) { |       if (props.size) { | ||||||
|         arr.push(`gi-tag-size-${props.size}`) |         arr.push(`gi-tag__size--${props.size}`) | ||||||
|       } |       } | ||||||
|       if (props.status) { |       if (props.status) { | ||||||
|         arr.push(`gi-tag-status-${props.status === 'info' ? 'gray' : props.status}`) |         arr.push(`gi-tag__status--${props.status}`) | ||||||
|       } |       } | ||||||
|       return arr |       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 = () => { |     const handleClick = () => { | ||||||
|       emit('click') |       emit('click') | ||||||
|     } |     } | ||||||
| @@ -57,7 +120,7 @@ export default defineComponent({ | |||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     return () => ( |     return () => ( | ||||||
|       <span class={className.value} onClick={handleClick}> |       <span class={className.value} style={calcStyle.value} onClick={handleClick}> | ||||||
|         {slots.default?.()} |         {slots.default?.()} | ||||||
|         {props.closable && CloseIcon} |         {props.closable && CloseIcon} | ||||||
|       </span> |       </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 { | .gi-tag { | ||||||
|   display: inline-flex; |   display: inline-flex; | ||||||
|   padding: 0 8px; |   padding: $tag-size-small-padding; | ||||||
|   // padding-top: 1px; |   height: $tag-size-small-height; | ||||||
|   height: 20px; |  | ||||||
|   font-size: 12px; |   font-size: 12px; | ||||||
|   line-height: 1; |   line-height: 1; | ||||||
|   border-radius: 3px; |   border-radius: 3px; | ||||||
| @@ -15,122 +24,28 @@ | |||||||
|  |  | ||||||
| .gi-tag-close-btn { | .gi-tag-close-btn { | ||||||
|   position: relative; |   position: relative; | ||||||
|   display: inline-flex; |   display: flex; | ||||||
|   justify-content: center; |   justify-content: center; | ||||||
|   align-items: center; |   align-items: center; | ||||||
|   cursor: pointer; |   cursor: pointer; | ||||||
|   margin-left: 4px; |   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 { |   .close-icon { | ||||||
|     width: 12px; |     width: 12px; | ||||||
|     height: 12px; |     height: 12px; | ||||||
|     z-index: 9; |     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__size--mini { | ||||||
|  |   height: $tag-size-mini-height; | ||||||
| .gi-tag-dark { |   padding: $tag-size-mini-padding; | ||||||
|   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-close-btn { |   .gi-tag-close-btn { | ||||||
|     .close-icon { |     .close-icon { | ||||||
| @@ -145,12 +60,95 @@ $status: primary, success, warning, danger, 'gray'; | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| .gi-tag-size-small { | .gi-tag__size--small { | ||||||
|   height: 24px; |   height: $tag-size-small-height; | ||||||
|  |   padding: $tag-size-small-padding; | ||||||
| } | } | ||||||
|  |  | ||||||
| .gi-tag-size-large { | .gi-tag__size--large { | ||||||
|   height: 28px; |   height: $tag-size-large-height; | ||||||
|   padding: 0 10px; |   padding: $tag-size-small-padding; | ||||||
|   font-size: 14px; | } | ||||||
|  |  | ||||||
|  | .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