forked from opentiny/tiny-vue
style(user-head): [user-head] improve typescript declaration of components (#1380)
This commit is contained in:
parent
e7a6dc33ed
commit
17dd913589
|
@ -10,8 +10,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { IUserHeadRenderlessParams } from '@/types'
|
||||||
|
|
||||||
export const computedStyle =
|
export const computedStyle =
|
||||||
({ state, props }) =>
|
({ state, props }: Pick<IUserHeadRenderlessParams, 'state' | 'props'>) =>
|
||||||
() => {
|
() => {
|
||||||
return {
|
return {
|
||||||
fill: state.color,
|
fill: state.color,
|
||||||
|
@ -22,13 +24,13 @@ export const computedStyle =
|
||||||
}
|
}
|
||||||
|
|
||||||
export const computedMessage =
|
export const computedMessage =
|
||||||
({ props }) =>
|
({ props }: Pick<IUserHeadRenderlessParams, 'props'>) =>
|
||||||
() => {
|
() => {
|
||||||
let result = ''
|
let result = ''
|
||||||
const total = Math.floor(props.messageTotal)
|
const total = Math.floor(props.messageTotal || NaN)
|
||||||
|
|
||||||
if (props.messageType === 'details' && !isNaN(total) && total > 0) {
|
if (props.messageType === 'details' && !isNaN(total) && total > 0) {
|
||||||
result = total
|
result = String(total)
|
||||||
|
|
||||||
if (props.messageUpperLimit && total > props.messageUpperLimit) {
|
if (props.messageUpperLimit && total > props.messageUpperLimit) {
|
||||||
result = `${props.messageUpperLimit}+`
|
result = `${props.messageUpperLimit}+`
|
||||||
|
@ -39,7 +41,7 @@ export const computedMessage =
|
||||||
}
|
}
|
||||||
|
|
||||||
export const computedFontSize =
|
export const computedFontSize =
|
||||||
({ props, state, mode }) =>
|
({ props, state, mode }: Pick<IUserHeadRenderlessParams, 'props' | 'state' | 'mode'>) =>
|
||||||
() => {
|
() => {
|
||||||
let fontSize = ''
|
let fontSize = ''
|
||||||
|
|
||||||
|
@ -74,12 +76,12 @@ export const computedFontSize =
|
||||||
}
|
}
|
||||||
|
|
||||||
export const computedLabel =
|
export const computedLabel =
|
||||||
({ state, props }) =>
|
({ state, props }: Pick<IUserHeadRenderlessParams, 'state' | 'props'>) =>
|
||||||
() =>
|
() =>
|
||||||
props.min ? state.internalValue.substr(0, 2) : state.internalValue.substr(0, 6)
|
props.min ? state.internalValue.substr(0, 2) : state.internalValue.substr(0, 6)
|
||||||
|
|
||||||
export const getInternalValue =
|
export const getInternalValue =
|
||||||
({ props }) =>
|
({ props }: Pick<IUserHeadRenderlessParams, 'props'>) =>
|
||||||
() => {
|
() => {
|
||||||
if (props.modelValue === null) {
|
if (props.modelValue === null) {
|
||||||
let result = ''
|
let result = ''
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { IUserHeadApi, IUserHeadProps, IUserHeadRenderlessParamUtils, IUserHeadState } from 'types/user-head.type'
|
||||||
import {
|
import {
|
||||||
computedMessage,
|
computedMessage,
|
||||||
computedStyle,
|
computedStyle,
|
||||||
|
@ -19,13 +20,18 @@ import {
|
||||||
handleClick,
|
handleClick,
|
||||||
mouseEnter
|
mouseEnter
|
||||||
} from './index'
|
} from './index'
|
||||||
|
import type { ISharedRenderlessParamHooks } from 'types/shared.type'
|
||||||
|
|
||||||
export const api = ['state', 'handleClick', 'mouseEnter']
|
export const api = ['state', 'handleClick', 'mouseEnter']
|
||||||
|
|
||||||
export const renderless = (props, { reactive, computed, inject }, { mode, emit }) => {
|
export const renderless = (
|
||||||
|
props: IUserHeadProps,
|
||||||
|
{ reactive, computed, inject }: ISharedRenderlessParamHooks,
|
||||||
|
{ mode, emit }: IUserHeadRenderlessParamUtils
|
||||||
|
): IUserHeadApi => {
|
||||||
const groupSize = inject('groupSize', null)
|
const groupSize = inject('groupSize', null)
|
||||||
|
|
||||||
const state = reactive({
|
const state: IUserHeadState = reactive({
|
||||||
internalValue: computed(() => api.getInternalValue()),
|
internalValue: computed(() => api.getInternalValue()),
|
||||||
label: computed(() => api.computedLabel()),
|
label: computed(() => api.computedLabel()),
|
||||||
style: computed(() => api.computedStyle()),
|
style: computed(() => api.computedStyle()),
|
||||||
|
@ -36,7 +42,7 @@ export const renderless = (props, { reactive, computed, inject }, { mode, emit }
|
||||||
backgroundColor: inject('backgroundColor', null) || props.backgroundColor
|
backgroundColor: inject('backgroundColor', null) || props.backgroundColor
|
||||||
})
|
})
|
||||||
|
|
||||||
const api = {
|
const api: IUserHeadApi = {
|
||||||
state,
|
state,
|
||||||
computedLabel: computedLabel({ state, props }),
|
computedLabel: computedLabel({ state, props }),
|
||||||
computedStyle: computedStyle({ state, props }),
|
computedStyle: computedStyle({ state, props }),
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import type { ExtractPropTypes } from 'vue'
|
||||||
|
import type { userHeadProps, $constants } from '@/user-head/src'
|
||||||
|
import type { ISharedRenderlessFunctionParams, ISharedRenderlessParamUtils } from './shared.type'
|
||||||
|
import type { computedFontSize, computedLabel, computedMessage, computedStyle, getInternalValue } from 'src/user-head'
|
||||||
|
|
||||||
|
export interface IUserHeadState {
|
||||||
|
internalValue: string | Record<string, any>
|
||||||
|
label: string
|
||||||
|
style: ReturnType<ReturnType<typeof computedStyle>>
|
||||||
|
message: string
|
||||||
|
fontSize: { fontSize: string }
|
||||||
|
size: number
|
||||||
|
color: string
|
||||||
|
backgroundColor: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IUserHeadProps = ExtractPropTypes<typeof userHeadProps>
|
||||||
|
|
||||||
|
export type IUserHeadConstants = typeof $constants
|
||||||
|
|
||||||
|
export type IUserHeadRenderlessParams = ISharedRenderlessFunctionParams<IUserHeadConstants> & {
|
||||||
|
api: IUserHeadApi
|
||||||
|
state: IUserHeadState
|
||||||
|
props: IUserHeadProps
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IUserHeadApi {
|
||||||
|
state: IUserHeadState
|
||||||
|
computedLabel: ReturnType<typeof computedLabel>
|
||||||
|
computedStyle: ReturnType<typeof computedStyle>
|
||||||
|
computedMessage: ReturnType<typeof computedMessage>
|
||||||
|
computedFontSize: ReturnType<typeof computedFontSize>
|
||||||
|
getInternalValue: ReturnType<typeof getInternalValue>
|
||||||
|
handleClick: (event: Event) => void
|
||||||
|
mouseEnter: (event: Event) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IUserHeadRenderlessParamUtils = ISharedRenderlessParamUtils<IUserHeadConstants>
|
|
@ -12,97 +12,99 @@
|
||||||
import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common'
|
import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common'
|
||||||
import template from 'virtual-template?pc|mobile|mobile-first'
|
import template from 'virtual-template?pc|mobile|mobile-first'
|
||||||
|
|
||||||
const $constants = {
|
export const $constants = {
|
||||||
ITEM_NAME: '.user-head-item'
|
ITEM_NAME: '.user-head-item'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const userHeadProps = {
|
||||||
|
...$props,
|
||||||
|
_constants: {
|
||||||
|
type: Object,
|
||||||
|
default: () => $constants
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @property {Boolean} [min=false] - 小尺寸模式
|
||||||
|
*/
|
||||||
|
min: Boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {Boolean} [round=true] - 圆形模式
|
||||||
|
*/
|
||||||
|
round: Boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {String} [color=#ffffff] - 文字颜色
|
||||||
|
*/
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#ffffff'
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {String} [backgroundColor=#BBBBBB] - 背景色
|
||||||
|
*/
|
||||||
|
backgroundColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#B5BBC1'
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {String} [type=label] - 头像类型,icon|image|label 可选
|
||||||
|
*/
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'label',
|
||||||
|
validator: (value: string) => Boolean(~['icon', 'image', 'label'].indexOf(value))
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {String} - 头像资源
|
||||||
|
* type=icon 时为图标类名,type=label时为字体串,type=image时为资源路径
|
||||||
|
*/
|
||||||
|
value: {
|
||||||
|
type: [Object, String],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {String} - 头像资源
|
||||||
|
* type=icon 时为图标类名,type=label时为字体串,type=image时为资源路径
|
||||||
|
*/
|
||||||
|
modelValue: {
|
||||||
|
type: [Object, String],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {Number} - 消息计数
|
||||||
|
*/
|
||||||
|
messageTotal: Number,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {String} [messageType=details] - 消息类型 details|basic 可选
|
||||||
|
*/
|
||||||
|
messageType: {
|
||||||
|
type: String,
|
||||||
|
default: 'details',
|
||||||
|
validator: (value: string) => Boolean(~['details', 'basic'].indexOf(value))
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property {Number} [messageUpperLimit=0] - 消息显示上限
|
||||||
|
*/
|
||||||
|
messageUpperLimit: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: Number,
|
||||||
|
default: 40
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: $prefix + 'UserHead',
|
name: $prefix + 'UserHead',
|
||||||
props: {
|
props: userHeadProps,
|
||||||
...$props,
|
|
||||||
_constants: {
|
|
||||||
type: Object,
|
|
||||||
default: () => $constants
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @property {Boolean} [min=false] - 小尺寸模式
|
|
||||||
*/
|
|
||||||
min: Boolean,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {Boolean} [round=true] - 圆形模式
|
|
||||||
*/
|
|
||||||
round: Boolean,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {String} [color=#ffffff] - 文字颜色
|
|
||||||
*/
|
|
||||||
color: {
|
|
||||||
type: String,
|
|
||||||
default: '#ffffff'
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {String} [backgroundColor=#BBBBBB] - 背景色
|
|
||||||
*/
|
|
||||||
backgroundColor: {
|
|
||||||
type: String,
|
|
||||||
default: '#B5BBC1'
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {String} [type=label] - 头像类型,icon|image|label 可选
|
|
||||||
*/
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'label',
|
|
||||||
validator: (value: string) => Boolean(~['icon', 'image', 'label'].indexOf(value))
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {String} - 头像资源
|
|
||||||
* type=icon 时为图标类名,type=label时为字体串,type=image时为资源路径
|
|
||||||
*/
|
|
||||||
value: {
|
|
||||||
type: [Object, String],
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {String} - 头像资源
|
|
||||||
* type=icon 时为图标类名,type=label时为字体串,type=image时为资源路径
|
|
||||||
*/
|
|
||||||
modelValue: {
|
|
||||||
type: [Object, String],
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {Number} - 消息计数
|
|
||||||
*/
|
|
||||||
messageTotal: Number,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {String} [messageType=details] - 消息类型 details|basic 可选
|
|
||||||
*/
|
|
||||||
messageType: {
|
|
||||||
type: String,
|
|
||||||
default: 'details',
|
|
||||||
validator: (value: string) => Boolean(~['details', 'basic'].indexOf(value))
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property {Number} [messageUpperLimit=0] - 消息显示上限
|
|
||||||
*/
|
|
||||||
messageUpperLimit: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: Number,
|
|
||||||
default: 40
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup(props, context) {
|
setup(props, context) {
|
||||||
return $setup({ props, context, template })
|
return $setup({ props, context, template })
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue