2025/2/8第一次更新

This commit is contained in:
爱吃咸鱼小猫咪
2025-02-08 18:50:38 +08:00
commit d7af560866
26519 changed files with 5046029 additions and 0 deletions
@@ -0,0 +1,4 @@
export * from './steps-custom'
export * from './step-custom'
export * from './use-steps'
export * from './use-step'
@@ -0,0 +1,191 @@
import { computed, inject } from 'vue'
import { stepsContextKey } from '../../../../tokens'
import { useComponentColor, useNamespace } from '../../../../hooks'
import type { CSSProperties, Ref } from 'vue'
import type { StepProps } from '../steps-item'
import type { StepsMode } from '../steps'
type ModeSelector = 'dot' | 'icon'
type StepModeClass = (selector?: ModeSelector) => string
type StepModeStyle = (selector?: ModeSelector) => CSSProperties
export const useStepCustomStyle = (
props: StepProps,
isActive: Ref<boolean>,
stepMode: Ref<StepsMode>
) => {
const ns = useNamespace('step')
const stepsContext = inject(stepsContextKey)
const normalColor = computed<string | undefined>(
() => props.color || stepsContext?.color
)
const activeColor = computed<string | undefined>(
() => props.activeColor || stepsContext?.activeColor
)
// 解析颜色
const [textColorClass, textColorStyle] = useComponentColor(
normalColor,
'text'
)
const [textActiveColorClass, textActiveColorStyle] = useComponentColor(
activeColor,
'text'
)
const [bgColorClass, bgColorStyle] = useComponentColor(normalColor, 'bg')
const [bgActiveColorClass, bgActiveColorStyle] = useComponentColor(
activeColor,
'bg'
)
// step对应的类
const stepClass = computed<string>(() => {
const cls: string[] = [ns.b()]
if (isActive.value) cls.push(ns.is('active'))
// 设置颜色
if (isActive.value) {
if (textActiveColorClass.value) cls.push(textActiveColorClass.value)
} else {
if (textColorClass.value) cls.push(textColorClass.value)
}
return cls.join(' ')
})
// step对应的样式
const stepStyle = computed<CSSProperties>(() => {
const style: CSSProperties = {}
// 设置颜色
if (isActive.value) {
if (!textActiveColorClass.value)
style.color = textActiveColorStyle.value || 'var(--tn-color-primary)'
} else {
if (!textColorClass.value)
style.color = textColorStyle.value || 'var(--tn-color-gray)'
}
return style
})
// step-mode对应的类
const modeClass = computed<StepModeClass>(() => {
return (selector?: ModeSelector) => {
const cls: string[] = []
if (!selector) {
cls.push(ns.e(`mode-${stepMode.value}`))
}
if (stepMode.value === 'dot') {
if (isActive.value) {
if (bgActiveColorClass.value) cls.push(bgActiveColorClass.value)
} else {
if (bgColorClass.value) cls.push(bgColorClass.value)
}
}
if (stepMode.value === 'number') {
if (isActive.value) {
if (bgActiveColorClass.value) cls.push(bgActiveColorClass.value)
}
}
if (stepMode.value === 'dotIcon') {
if (isActive.value && selector === 'icon') {
if (textActiveColorClass.value) cls.push(textActiveColorClass.value)
}
if (!isActive.value && selector === 'dot') {
if (bgColorClass.value) cls.push(bgColorClass.value)
}
}
return cls.join(' ')
}
})
// step-mode对应的样式
const modeStyle = computed<StepModeStyle>(() => {
return (selector?: ModeSelector) => {
const style: CSSProperties = {}
if (stepMode.value === 'dot') {
if (isActive.value) {
if (!bgActiveColorClass.value)
style.backgroundColor =
bgActiveColorStyle.value || 'var(--tn-color-primary)'
} else {
if (!bgColorClass.value)
style.backgroundColor = bgColorStyle.value || 'var(--tn-color-gray)'
}
}
if (stepMode.value === 'number') {
if (isActive.value) {
if (!bgActiveColorClass.value) {
style.backgroundColor =
bgActiveColorStyle.value || 'var(--tn-color-primary)'
style.color = 'var(--tn-color-white)'
}
}
}
if (stepMode.value === 'dotIcon') {
if (isActive.value && selector === 'icon') {
if (!textActiveColorClass.value) {
style.color =
textActiveColorStyle.value || 'var(--tn-color-primary)'
}
}
if (!isActive.value && selector === 'dot') {
if (!bgColorClass.value)
style.backgroundColor = bgColorStyle.value || 'var(--tn-color-gray)'
}
}
return style
}
})
// step-line对应的类
const lineClass = computed<string>(() => {
const cls: string[] = [ns.e('line'), ns.is('no-title', !props.title)]
if (isActive.value) {
if (bgActiveColorClass.value) cls.push(bgActiveColorClass.value)
} else {
if (bgColorClass.value) cls.push(bgColorClass.value)
}
return cls.join(' ')
})
// step-line对应的样式
const lineStyle = computed<CSSProperties>(() => {
const style: CSSProperties = {}
if (isActive.value) {
if (!bgActiveColorClass.value)
style.backgroundColor =
bgActiveColorStyle.value || 'var(--tn-color-primary)'
} else {
if (!bgColorClass.value)
style.backgroundColor = bgColorStyle.value || 'var(--tn-color-gray)'
}
return style
})
return {
ns,
stepClass,
stepStyle,
modeClass,
modeStyle,
lineClass,
lineStyle,
}
}
@@ -0,0 +1,9 @@
import { useNamespace } from '../../../../hooks'
export const useStepsCustomStyle = () => {
const ns = useNamespace('steps')
return {
ns,
}
}
@@ -0,0 +1,57 @@
import {
computed,
getCurrentInstance,
inject,
nextTick,
onMounted,
onUnmounted,
} from 'vue'
import { stepsContextKey } from '../../../../tokens'
import { debugWarn } from '../../../../utils'
import type { StepProps } from '../steps-item'
import type { StepsMode } from '../steps'
export const useStep = (props: StepProps) => {
const instance = getCurrentInstance()
if (!instance) {
debugWarn('TnStep', '请在 setup 中使用 useStep')
}
const { emit, uid } = instance!
const stepsContext = inject(stepsContextKey)
// 判断当前是否被激活
const isActive = computed<boolean>(
() => stepsContext?.activeUidList.includes(uid) || false
)
// 步骤条模式
const stepMode = computed<StepsMode>(() => stepsContext?.mode || 'dot')
// item点击事件
const itemClickEvent = () => {
if (props.disabled || stepsContext?.disabled) return
stepsContext?.setActiveItem(uid)
emit('click')
}
onMounted(() => {
nextTick(() => {
stepsContext?.addItem({ uid })
})
})
onUnmounted(() => {
stepsContext?.removeItem(uid)
})
return {
isActive,
stepMode,
itemClickEvent,
}
}
@@ -0,0 +1,96 @@
import { getCurrentInstance, provide, reactive, ref, toRefs, watch } from 'vue'
import { stepsContextKey } from '../../../../tokens'
import { CHANGE_EVENT, UPDATE_MODEL_EVENT } from '../../../../constants'
import { useOrderedChildren } from '../../../../hooks'
import { debugWarn } from '../../../../utils'
import type { StepsProps } from '../steps'
import type { StepContext } from '../../../../tokens'
export const useSteps = (props: StepsProps) => {
const instance = getCurrentInstance()
if (!instance) {
debugWarn('TnSteps', '请在 setup 中使用 useSteps')
}
const { emit } = instance!
const {
children: items,
addChild,
removeChild: removeItem,
} = useOrderedChildren<StepContext>()
// 当前已激活的Uid列表
const activeUidList = ref<number[]>([])
let innerUpdate = false
// 更新当前激活的Uid列表
const setActiveUidList = (uid?: number, changeEmit = false) => {
if (uid === undefined) {
activeUidList.value = []
return
}
// 查找出当前激活的uid的index
const index = items.value.findIndex((item) => item.uid === uid)
if (index === -1) return
// 根据index查找出当前激活的uid列表
activeUidList.value = items.value
.slice(0, index + 1)
.map((item) => item.uid)
// 触发更新事件
emit(UPDATE_MODEL_EVENT, index)
if (changeEmit) {
emit(CHANGE_EVENT, index)
}
}
// 设置当前激活的Step
const setActiveItem = (uid: number) => {
if (props.disabled) return
innerUpdate = true
setActiveUidList(uid, true)
}
watch(
() => props.modelValue,
(val) => {
if (innerUpdate) {
innerUpdate = false
return
}
if (val !== undefined) {
const uid = items.value?.[val]?.uid
setActiveUidList(uid)
}
}
)
// 添加item到items
const addItem = (item: StepContext) => {
addChild(item)
if (
!activeUidList.value.length &&
props.modelValue !== undefined &&
props.modelValue >= 0
) {
setActiveUidList(items.value?.[props.modelValue]?.uid)
}
}
provide(
stepsContextKey,
reactive({
...toRefs(props),
items,
activeUidList,
addItem,
removeItem,
setActiveItem,
})
)
}