@xdp/button
Version:
button el-button vue3
166 lines (150 loc) • 3.9 kB
text/typescript
/** 历史兼容别名 → ElPopconfirm 标准属性 */
const POP_LEGACY_MAP = {
popTitle: 'title',
popPlacement: 'placement'
} as const
/** 按钮侧保留的属性 key */
const BUTTON_PROP_KEYS = [
'type',
'size',
'disabled',
'danger',
'showDisabled',
'icon',
'loading',
'plain',
'link',
'round',
'circle',
'square',
'map',
'buttonType',
'text'
]
/** ElPopconfirm 可透传属性 */
const POP_PROP_KEYS = [
'title',
'placement',
'width',
'icon',
'iconColor',
'hideIcon',
'confirmButtonText',
'cancelButtonText',
'confirmButtonType',
'cancelButtonType',
'teleported',
'persistent',
'effect',
'trigger',
'popperClass',
'popperStyle'
]
/** rich pop(ElPopover)可透传属性 */
const POPOVER_PROP_KEYS = [
'placement',
'width',
'teleported',
'persistent',
'effect',
'trigger',
'popperClass',
'popperStyle'
]
const POP_RESERVED_KEYS = new Set([
'needPop',
'popTitle',
'popMessage',
'popPlacement',
'popProps',
'popLegacyCancel',
'buttonComp'
])
function pick (source: Record<string, any>, keys: string[]) {
return keys.reduce((acc, key) => {
if (source[key] !== undefined) {
acc[key] = source[key]
}
return acc
}, {} as Record<string, any>)
}
function mapLegacy (source: Record<string, any>) {
return Object.entries(POP_LEGACY_MAP).reduce((acc, [legacyKey, epKey]) => {
if (source[legacyKey] !== undefined) {
acc[epKey] = source[legacyKey]
}
return acc
}, {} as Record<string, any>)
}
/** 从 popXxx 前缀属性提取 ElPopconfirm 属性,如 popConfirmButtonText → confirmButtonText */
function extractPopPrefixedAttrs (source: Record<string, any>) {
return Object.entries(source).reduce((acc, [key, value]) => {
if (
key.startsWith('pop') &&
key.length > 3 &&
!POP_RESERVED_KEYS.has(key) &&
value !== undefined
) {
acc[key.charAt(3).toLowerCase() + key.slice(4)] = value
}
return acc
}, {} as Record<string, any>)
}
export interface PopSlotScope {
title?: string
message?: string
confirm?: (e?: MouseEvent) => void
cancel?: (e?: MouseEvent) => void
}
export function useButtonPop (
props: Record<string, any>,
attrs: Record<string, any>,
slots: Record<string, any>
) {
const merged = { ...props, ...attrs }
const needPop = merged.needPop !== false
const { onClick, onCancel, ...rest } = attrs as {
onClick?: (e?: MouseEvent, confirmed?: boolean) => void
onCancel?: (e?: MouseEvent) => void
[key: string]: any
}
const buttonProps = pick(merged, BUTTON_PROP_KEYS)
const popProps = {
title: '确定删除该信息',
cancelButtonType: 'default',
placement: 'top',
width: 280,
...pick(rest, POP_PROP_KEYS),
...extractPopPrefixedAttrs(rest),
...mapLegacy(props),
...mapLegacy(attrs as Record<string, any>),
...(props.popProps ?? attrs.popProps)
}
delete popProps.hideAfter
const legacyTitle = props.popTitle ?? attrs.popTitle
const resolvedMessage = props.popMessage ?? attrs.popMessage
const resolvedTitle = legacyTitle ?? (resolvedMessage ? undefined : popProps.title)
const hasReferenceSlot = Boolean(slots.reference || slots.button)
const hasRichPop = Boolean(
resolvedMessage ||
slots['pop-title'] ||
slots['pop-message'] ||
slots.pop ||
(hasReferenceSlot && slots.default)
)
const popLegacyCancel = props.popLegacyCancel ?? attrs.popLegacyCancel ?? true
const popoverProps = pick(popProps, POPOVER_PROP_KEYS)
return {
needPop,
buttonProps,
popProps,
popoverProps,
resolvedTitle,
resolvedMessage,
hasRichPop,
hasReferenceSlot,
onClick,
onCancel,
popLegacyCancel
}
}