fix(eslint): fix eslint error (#935)

This commit is contained in:
ajaxzheng 2023-11-25 18:22:18 +08:00 committed by GitHub
parent eee8e3df29
commit 4004ecd3b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
525 changed files with 2884 additions and 2922 deletions

View File

@ -20,6 +20,7 @@ module.exports = {
'vue/prefer-separate-static-class': 'off', 'vue/prefer-separate-static-class': 'off',
'vue/comma-dangle': 'off', 'vue/comma-dangle': 'off',
'vue/prefer-template': 'off', 'vue/prefer-template': 'off',
'vue/no-unused-refs': 'off',
'vue/singleline-html-element-content-newline': 'off', 'vue/singleline-html-element-content-newline': 'off',
'curly': 'off', 'curly': 'off',
'sort-imports': 'off', 'sort-imports': 'off',
@ -34,7 +35,6 @@ module.exports = {
'prefer-const': 'off', 'prefer-const': 'off',
'multiline-ternary': 'off', 'multiline-ternary': 'off',
'@typescript-eslint/comma-dangle': 'off', '@typescript-eslint/comma-dangle': 'off',
// '@typescript-eslint/indent': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unsafe-member-access': 'off',

View File

@ -17,8 +17,8 @@
"devDependencies": { "devDependencies": {
"@types/react": "^18.2.14", "@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6", "@types/react-dom": "^18.2.6",
"@typescript-eslint/eslint-plugin": "^5.61.0", "@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^5.61.0", "@typescript-eslint/parser": "^6.12.0",
"@vitejs/plugin-react": "^4.0.1", "@vitejs/plugin-react": "^4.0.1",
"autoprefixer": "^10.4.12", "autoprefixer": "^10.4.12",
"eslint": "^8.44.0", "eslint": "^8.44.0",

View File

@ -25,8 +25,6 @@
"bugs": { "bugs": {
"url": "https://github.com/opentiny/tiny-vue/issues" "url": "https://github.com/opentiny/tiny-vue/issues"
}, },
"sideEffects": false,
"type": "module",
"main": "packages/index.js", "main": "packages/index.js",
"engines": { "engines": {
"node": ">=16", "node": ">=16",
@ -143,7 +141,7 @@
"@types/eslint": "^8.4.10", "@types/eslint": "^8.4.10",
"@types/node": "^18.11.18", "@types/node": "^18.11.18",
"@types/shelljs": "^0.8.12", "@types/shelljs": "^0.8.12",
"@typescript-eslint/parser": "^5.48.0", "@typescript-eslint/parser": "^6.12.0",
"@volar-plugins/eslint": "^2.0.0", "@volar-plugins/eslint": "^2.0.0",
"@volar-plugins/prettier": "^2.0.0", "@volar-plugins/prettier": "^2.0.0",
"@volar-plugins/prettyhtml": "^2.0.0", "@volar-plugins/prettyhtml": "^2.0.0",

View File

@ -2,27 +2,25 @@ import { eventBus } from './utils'
const $busMap = new Map() const $busMap = new Map()
export const emit = (props) => (evName, ...args) => { export const emit =
const reactEvName = 'on' (props) =>
+ evName.substr(0, 1).toUpperCase() (evName, ...args) => {
+ evName.substr(1) const reactEvName = 'on' + evName.substr(0, 1).toUpperCase() + evName.substr(1)
if (props[reactEvName] && typeof props[reactEvName] === 'function') { if (props[reactEvName] && typeof props[reactEvName] === 'function') {
props[reactEvName](...args) props[reactEvName](...args)
} } else {
else { const $bus = $busMap.get(props)
const $bus = $busMap.get(props) if ($bus) {
if ($bus) { $bus.emit(evName, ...args)
$bus.emit(evName, ...args) }
} }
} }
}
export const on = (props) => (evName, callback) => { export const on = (props) => (evName, callback) => {
if ($busMap.get(props)) { if ($busMap.get(props)) {
const $bus = $busMap.get(props) const $bus = $busMap.get(props)
$bus.on(evName, callback) $bus.on(evName, callback)
} } else {
else {
const $bus = eventBus() const $bus = eventBus()
$bus.on(evName, callback) $bus.on(evName, callback)
$busMap.set(props, $bus) $busMap.set(props, $bus)
@ -43,8 +41,7 @@ export const once = (props) => (evName, callback) => {
if ($busMap.get(props)) { if ($busMap.get(props)) {
$bus = $busMap.get(props) $bus = $busMap.get(props)
$bus.on(evName, onceCallback) $bus.on(evName, onceCallback)
} } else {
else {
$bus = eventBus() $bus = eventBus()
$bus.on(evName, onceCallback) $bus.on(evName, onceCallback)
$busMap.set(props, $bus) $busMap.set(props, $bus)
@ -54,8 +51,8 @@ export const emitEvent = (vm) => {
const broadcast = (vm, componentName, eventName, ...args) => { const broadcast = (vm, componentName, eventName, ...args) => {
const children = vm.$children const children = vm.$children
Array.isArray(children) Array.isArray(children) &&
&& children.forEach((child) => { children.forEach((child) => {
const name = child.$options && child.$options.componentName const name = child.$options && child.$options.componentName
const component = child const component = child
@ -63,8 +60,7 @@ export const emitEvent = (vm) => {
component.emit(eventName, ...args) component.emit(eventName, ...args)
// todo: 调研 component.$emitter // todo: 调研 component.$emitter
// component.$emitter && component.$emitter.emit(eventName, params) // component.$emitter && component.$emitter.emit(eventName, params)
} } else {
else {
broadcast(child, componentName, eventName, ...args) broadcast(child, componentName, eventName, ...args)
} }
}) })
@ -78,8 +74,7 @@ export const emitEvent = (vm) => {
while (parent && parent.type && (!name || name !== componentName)) { while (parent && parent.type && (!name || name !== componentName)) {
parent = parent.$parent parent = parent.$parent
if (parent) if (parent) name = parent.$options && parent.$options.componentName
name = parent.$options && parent.$options.componentName
} }
if (parent) { if (parent) {

View File

@ -21,9 +21,10 @@ function defaultBreaker({ type }) {
export function traverseFiber(fiber, handler, breaker = defaultBreaker) { export function traverseFiber(fiber, handler, breaker = defaultBreaker) {
if (!fiber) return if (!fiber) return
typeof handler === 'function' && handler(fiber) typeof handler === 'function' && handler(fiber)
Array.isArray(handler) && handler.forEach(task => { Array.isArray(handler) &&
typeof task === 'function' && task(fiber) handler.forEach((task) => {
}) typeof task === 'function' && task(fiber)
})
traverseFiber(fiber.sibling, handler, breaker) traverseFiber(fiber.sibling, handler, breaker)
breaker(fiber) || traverseFiber(fiber.child, handler, breaker) breaker(fiber) || traverseFiber(fiber.child, handler, breaker)
} }
@ -40,22 +41,21 @@ export function getParentFiber(fiber, isFirst = true, child = fiber) {
} }
export function creatFiberCombine(fiber) { export function creatFiberCombine(fiber) {
if(!fiber) return if (!fiber) return
const refs = {}; const refs = {}
const children = []; const children = []
traverseFiber(fiber.child, [ traverseFiber(fiber.child, [
(fiber) => { (fiber) => {
if (typeof fiber.type === 'string' && fiber.stateNode.getAttribute('v_ref')) { if (typeof fiber.type === 'string' && fiber.stateNode.getAttribute('v_ref')) {
refs[fiber.stateNode.getAttribute('v_ref')] = fiber.stateNode; refs[fiber.stateNode.getAttribute('v_ref')] = fiber.stateNode
} } else if (fiber.memoizedProps.v_ref) {
else if (fiber.memoizedProps.v_ref) { refs[fiber.memoizedProps.v_ref] = fiber
refs[fiber.memoizedProps.v_ref] = fiber;
} }
}, },
(fiber) => { (fiber) => {
if (fiber.type && typeof fiber.type !== 'string') { if (fiber.type && typeof fiber.type !== 'string') {
children.push(fiber); children.push(fiber)
} }
} }
]) ])
@ -74,11 +74,7 @@ export function useFiber() {
useEffect(() => { useEffect(() => {
if (ref.current) { if (ref.current) {
const current_fiber = getFiberByDom(ref.current) const current_fiber = getFiberByDom(ref.current)
setParent( setParent(getParentFiber(current_fiber.return))
getParentFiber(
current_fiber.return
)
)
setCurrent(current_fiber.return) setCurrent(current_fiber.return)
} }
}, []) }, [])

View File

@ -1,4 +1,4 @@
import { useState, useRef } from "react" import { useState, useRef } from 'react'
export function useExcuteOnce(cb, ...args) { export function useExcuteOnce(cb, ...args) {
const isExcuted = useRef(false) const isExcuted = useRef(false)
@ -12,7 +12,7 @@ export function useExcuteOnce(cb, ...args) {
export function useReload() { export function useReload() {
const [_, reload] = useState(0) const [_, reload] = useState(0)
return () => reload(pre => pre + 1) return () => reload((pre) => pre + 1)
} }
export function useOnceResult(func, ...args) { export function useOnceResult(func, ...args) {

View File

@ -1,4 +1,3 @@
import { useEffect } from 'react'
import { Svg } from './svg-render' import { Svg } from './svg-render'
import { generateVueHooks, useVueLifeHooks } from './vue-hooks.js' import { generateVueHooks, useVueLifeHooks } from './vue-hooks.js'
import { emitEvent } from './event.js' import { emitEvent } from './event.js'
@ -9,6 +8,7 @@ import { useVm } from './vm.js'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
import { stringifyCssClass } from './csscls.js' import { stringifyCssClass } from './csscls.js'
import { useExcuteOnce, useReload, useOnceResult } from './hooks.js' import { useExcuteOnce, useReload, useOnceResult } from './hooks.js'
// 导入 vue 响应式系统 // 导入 vue 响应式系统
import { effectScope, nextTick, reactive } from '@vue/runtime-core' import { effectScope, nextTick, reactive } from '@vue/runtime-core'
import { useCreateVueInstance } from './vue-instance' import { useCreateVueInstance } from './vue-instance'
@ -29,17 +29,7 @@ export const $props = {
export const mergeClass = (...cssClasses) => twMerge(stringifyCssClass(cssClasses)) export const mergeClass = (...cssClasses) => twMerge(stringifyCssClass(cssClasses))
const setup = ({ const setup = ({ props, renderless, api, extendOptions = {}, classes = {}, constants, vm, parent, $bus }) => {
props,
renderless,
api,
extendOptions = {},
classes = {},
constants,
vm,
parent,
$bus
}) => {
const render = typeof props.tiny_renderless === 'function' ? props.tiny_renderless : renderless const render = typeof props.tiny_renderless === 'function' ? props.tiny_renderless : renderless
const { dispatch, broadcast } = emitEvent(vm) const { dispatch, broadcast } = emitEvent(vm)
@ -51,7 +41,7 @@ const setup = ({
nextTick, nextTick,
dispatch, dispatch,
broadcast, broadcast,
t() { }, t() {},
mergeClass, mergeClass,
mode: props.tiny_mode mode: props.tiny_mode
} }
@ -71,7 +61,7 @@ const setup = ({
a: filterAttrs, a: filterAttrs,
m: mergeClass, m: mergeClass,
vm: utils.vm, vm: utils.vm,
gcls: (key) => getElementCssClass(classes, key), gcls: (key) => getElementCssClass(classes, key)
} }
if (Array.isArray(api)) { if (Array.isArray(api)) {
@ -87,14 +77,7 @@ const setup = ({
return attrs return attrs
} }
export const useSetup = ({ export const useSetup = ({ props, renderless, api, extendOptions = {}, classes = {}, constants }) => {
props,
renderless,
api,
extendOptions = {},
classes = {},
constants
}) => {
const $bus = useOnceResult(() => eventBus()) const $bus = useOnceResult(() => eventBus())
// 刷新逻辑 // 刷新逻辑
@ -157,21 +140,10 @@ export const useSetup = ({
} }
} }
export { export { Svg, If, Component, Slot, For, Transition, vc, emitEvent, useVm, useFiber }
Svg,
If,
Component,
Slot,
For,
Transition,
vc,
emitEvent,
useVm,
useFiber,
}
export * from './vue-hooks.js' export * from './vue-hooks.js'
export * from './vue-props.js' export * from './vue-props.js'
export * from './render-stack.js' export * from './render-stack.js'
export * from './vue-instance.js' export * from './vue-instance.js'
export * from './hooks' export * from './hooks'

View File

@ -3,83 +3,73 @@ import { computed } from './vue-hooks'
// 响应式核心 // 响应式核心
const reactiveMap = new WeakMap() const reactiveMap = new WeakMap()
const reactive = ( const reactive = (staticObject, handler = {}, path = [], rootStaticObject = staticObject) => {
staticObject, reactiveMap.has(staticObject) ||
handler = {}, reactiveMap.set(
path = [], staticObject,
rootStaticObject = staticObject new Proxy(staticObject, {
) => { get(target, property, receiver) {
reactiveMap.has(staticObject) || reactiveMap.set(staticObject, new Proxy(staticObject, { const targetVal = target[property]
get( if (targetVal && targetVal['v-hooks-type'] === computed) {
target, return targetVal.value
property, }
receiver
) {
const targetVal = target[property]
if (targetVal && targetVal['v-hooks-type'] === computed) {
return targetVal.value
}
const _path = [...path, property] const _path = [...path, property]
const res = typeof targetVal === 'object' const res = typeof targetVal === 'object' ? reactive(targetVal, handler, _path, rootStaticObject) : targetVal
? reactive(targetVal, handler, _path, rootStaticObject)
: targetVal
// 监听访问 // 监听访问
handler.get && handler.get({ handler.get &&
result: res, handler.get({
root: rootStaticObject, result: res,
path: _path, root: rootStaticObject,
target, path: _path,
property, target,
receiver property,
receiver
})
return res
},
set(target, property, value, receiver) {
const targetVal = target[property]
if (targetVal && targetVal['v-hooks-type'] === computed) {
targetVal.value = value
return true
}
const _path = [...path, property]
// 监听修改
handler.set &&
handler.set({
target,
property,
receiver,
root: rootStaticObject,
path: _path,
newVal: value,
oldVal: target[property]
})
target[property] = value
return true
}
}) })
)
return res
},
set(
target,
property,
value,
receiver
) {
const targetVal = target[property]
if (targetVal && targetVal['v-hooks-type'] === computed) {
targetVal.value = value
return true
}
const _path = [...path, property]
// 监听修改
handler.set && handler.set({
target,
property,
receiver,
root: rootStaticObject,
path: _path,
newVal: value,
oldVal: target[property]
})
target[property] = value
return true
}
}))
return reactiveMap.get(staticObject) return reactiveMap.get(staticObject)
} }
export const useReload = () => { export const useReload = () => {
const setReload = useState(0)[1] const setReload = useState(0)[1]
return () => setReload(pre => pre + 1) return () => setReload((pre) => pre + 1)
} }
const isObject = (val) => val !== null && typeof val === 'object' const isObject = (val) => val !== null && typeof val === 'object'
// 用于从 hooks 链表中查找 reactive 生成的 state // 用于从 hooks 链表中查找 reactive 生成的 state
export function Reactive(obj) { export function Reactive(obj) {
Object.keys(obj).forEach(key => { Object.keys(obj).forEach((key) => {
this[key] = obj[key] this[key] = obj[key]
}) })
} }

View File

@ -1,8 +1,8 @@
const renderStack = [] const renderStack = []
export const getParent = () => renderStack[renderStack.length - 1] || ({}) export const getParent = () => renderStack[renderStack.length - 1] || {}
export const getRoot = () => renderStack[0] || ({}) export const getRoot = () => renderStack[0] || {}
export const EnterStack = (props) => { export const EnterStack = (props) => {
renderStack.push(props) renderStack.push(props)
@ -12,4 +12,4 @@ export const EnterStack = (props) => {
export const LeaveStack = () => { export const LeaveStack = () => {
renderStack.pop() renderStack.pop()
return '' return ''
} }

View File

@ -2,13 +2,11 @@
const reactEventPrefix = /^on[A-Z]/ const reactEventPrefix = /^on[A-Z]/
export function getEventByReactProps(props) { export function getEventByReactProps(props) {
const $listeners = {} const $listeners = {}
Object Object.keys(props)
.keys(props) .filter((propName) => {
.filter(propName => { return reactEventPrefix.test(propName) && typeof props[propName] === 'function'
return reactEventPrefix.test(propName)
&& typeof props[propName] === 'function'
}) })
.map(reactEvName => { .map((reactEvName) => {
return { return {
reactEvName, reactEvName,
vueEvName: reactEvName.substr(2).toLowerCase() vueEvName: reactEvName.substr(2).toLowerCase()
@ -23,9 +21,8 @@ export function getEventByReactProps(props) {
} }
export function getAttrsByReactProps(props) { export function getAttrsByReactProps(props) {
const $attrs = {} const $attrs = {}
Object Object.keys(props)
.keys(props) .filter((propName) => {
.filter(propName => {
return !reactEventPrefix.test(propName) && !['children'].includes(propName) return !reactEventPrefix.test(propName) && !['children'].includes(propName)
}) })
.forEach((attr) => { .forEach((attr) => {

View File

@ -42,9 +42,7 @@ export const eventBus = () => {
return return
} }
$bus[eventName] = $bus[eventName].filter( $bus[eventName] = $bus[eventName].filter((subscriber) => subscriber !== callback)
subscriber => subscriber !== callback
)
} }
const emit = (eventName, ...args) => { const emit = (eventName, ...args) => {
@ -52,7 +50,7 @@ export const eventBus = () => {
return return
} }
$bus[eventName].forEach(subscriber => subscriber(...args)) $bus[eventName].forEach((subscriber) => subscriber(...args))
} }
const once = (eventName, callback) => { const once = (eventName, callback) => {
@ -78,28 +76,22 @@ export const eventBus = () => {
export function VueClassName(className) { export function VueClassName(className) {
if (typeof className === 'string') { if (typeof className === 'string') {
return className return className
} } else if (Array.isArray(className)) {
else if (Array.isArray(className)) {
return className.reduce((pre, cur, index) => { return className.reduce((pre, cur, index) => {
if (typeof cur === 'string') { if (typeof cur === 'string') {
return `${pre}${index === 0 ? '' : ' '}${cur}` return `${pre}${index === 0 ? '' : ' '}${cur}`
} } else {
else {
return `${pre}${index === 0 ? '' : ' '}${VueClassName(cur)}` return `${pre}${index === 0 ? '' : ' '}${VueClassName(cur)}`
} }
}, '') }, '')
} } else if (typeof className === 'object') {
else if (typeof className === 'object') { return Object.keys(className).reduce((pre, key, index) => {
return Object if (className[key]) {
.keys(className) return `${pre}${index === 0 ? '' : ' '}${key}`
.reduce((pre, key, index) => { } else {
if (className[key]) { return pre
return `${pre}${index === 0 ? '' : ' '}${key}` }
} }, '')
else {
return pre
}
}, '')
} }
} }
@ -119,22 +111,22 @@ export const getElementCssClass = (classes = {}, key) => {
} }
export function getPropByPath(obj, path) { export function getPropByPath(obj, path) {
let tempObj = obj; let tempObj = obj
//将a[b].c转换为a.b.c // 将a[b].c转换为a.b.c
path = path.replace(/\[(\w+)\]/g, '.$1'); path = path.replace(/\[(\w+)\]/g, '.$1')
//将.a.b转换为a.b // 将.a.b转换为a.b
path = path.replace(/^\./, ''); path = path.replace(/^\./, '')
let keyArr = path.split('.'); let keyArr = path.split('.')
let len = keyArr.length; let len = keyArr.length
for (let i = 0; i < len - 1; i++) { for (let i = 0; i < len - 1; i++) {
let key = keyArr[i]; let key = keyArr[i]
if (key in tempObj) { if (key in tempObj) {
tempObj = tempObj[key]; tempObj = tempObj[key]
} else { } else {
return return
} }
} }
return tempObj[keyArr[keyArr.length - 1]] return tempObj[keyArr[keyArr.length - 1]]
} }

View File

@ -1,8 +1,5 @@
import { useFiber, getParentFiber, creatFiberCombine } from './fiber.js' import { useFiber, getParentFiber, creatFiberCombine } from './fiber.js'
import { import { getEventByReactProps, getAttrsByReactProps } from './resolve-props.js'
getEventByReactProps,
getAttrsByReactProps
} from './resolve-props.js'
import { Reactive } from './reactive.js' import { Reactive } from './reactive.js'
import { emit, on, off, once } from './event.js' import { emit, on, off, once } from './event.js'
@ -10,19 +7,11 @@ const vmProxy = {
$parent: ({ fiber }) => { $parent: ({ fiber }) => {
const parentFiber = getParentFiber(fiber) const parentFiber = getParentFiber(fiber)
if (!parentFiber) return null if (!parentFiber) return null
return createVmProxy( return createVmProxy(creatFiberCombine(parentFiber))
creatFiberCombine(
parentFiber
)
)
}, },
$el: ({ fiber }) => fiber.child?.stateNode, $el: ({ fiber }) => fiber.child?.stateNode,
$refs: ({ refs, fiber }) => createRefsProxy(refs, fiber.constructor), $refs: ({ refs, fiber }) => createRefsProxy(refs, fiber.constructor),
$children: ({ children }) => children.map((fiber) => createVmProxy( $children: ({ children }) => children.map((fiber) => createVmProxy(creatFiberCombine(getParentFiber(fiber)))),
creatFiberCombine(
getParentFiber(fiber)
)
)),
$listeners: ({ fiber }) => getEventByReactProps(fiber.memoizedProps), $listeners: ({ fiber }) => getEventByReactProps(fiber.memoizedProps),
$attrs: ({ fiber }) => getAttrsByReactProps(fiber.memoizedProps), $attrs: ({ fiber }) => getAttrsByReactProps(fiber.memoizedProps),
$slots: ({ fiber }) => fiber.memoizedProps.slots, $slots: ({ fiber }) => fiber.memoizedProps.slots,
@ -39,58 +28,50 @@ const vmProxy = {
$on: ({ fiber }) => on(fiber.memoizedProps), $on: ({ fiber }) => on(fiber.memoizedProps),
$once: ({ fiber }) => once(fiber.memoizedProps), $once: ({ fiber }) => once(fiber.memoizedProps),
$off: ({ fiber }) => off(fiber.memoizedProps), $off: ({ fiber }) => off(fiber.memoizedProps),
$set: () => (target, propName, value) => target[propName] = value $set: () => (target, propName, value) => (target[propName] = value)
} }
const vmProxyMap = new WeakMap() const vmProxyMap = new WeakMap()
function createVmProxy(fiberCombine) { function createVmProxy(fiberCombine) {
if (!vmProxyMap.has(fiberCombine)) { if (!vmProxyMap.has(fiberCombine)) {
vmProxyMap.set(fiberCombine, new Proxy(fiberCombine, { vmProxyMap.set(
get( fiberCombine,
target, new Proxy(fiberCombine, {
property, get(target, property, receiver) {
receiver if (!vmProxy[property]) {
) { return target.fiber.memoizedProps[property]
if (!vmProxy[property]) { }
return target.fiber.memoizedProps[property] return vmProxy[property](target, receiver)
},
set(target, property, value) {
return true
} }
return vmProxy[property](target, receiver) })
}, )
set(
target,
property,
value
) {
return true
}
}))
} }
return vmProxyMap.get(fiberCombine) return vmProxyMap.get(fiberCombine)
} }
function createEmptyProxy() { function createEmptyProxy() {
return new Proxy({}, { return new Proxy(
get() { {},
return undefined {
}, get() {
set() { return undefined
return true },
set() {
return true
}
} }
}) )
} }
function createRefsProxy(refs, FiberNode) { function createRefsProxy(refs, FiberNode) {
return new Proxy(refs, { return new Proxy(refs, {
get( get(target, property) {
target,
property
) {
if (target[property] instanceof FiberNode) { if (target[property] instanceof FiberNode) {
return createVmProxy( return createVmProxy(creatFiberCombine(target[property]))
creatFiberCombine(target[property]) } else {
)
}
else {
return target[property] return target[property]
} }
} }
@ -105,9 +86,7 @@ function findStateInHooks(hookStart) {
if (refCurrent instanceof Reactive) break if (refCurrent instanceof Reactive) break
curHook = curHook.next curHook = curHook.next
} }
return curHook return curHook && curHook.memoizedState && curHook.memoizedState.current
&& curHook.memoizedState
&& curHook.memoizedState.current
} }
export function useVm() { export function useVm() {

View File

@ -35,12 +35,10 @@ import { useExcuteOnce } from './hooks'
import { useEffect } from 'react' import { useEffect } from 'react'
// 通用 // 通用
const inject = () => { } const inject = () => {}
const provide = () => { } const provide = () => {}
export function generateVueHooks({ export function generateVueHooks({ $bus }) {
$bus
}) {
const reload = () => $bus.emit('event:reload') const reload = () => $bus.emit('event:reload')
function toPageLoad(reactiveHook, reload) { function toPageLoad(reactiveHook, reload) {
@ -53,9 +51,9 @@ export function generateVueHooks({
typeof reload === 'function' && reload() typeof reload === 'function' && reload()
}, },
{ {
flush: "sync" flush: 'sync'
} }
); )
}) })
return result return result
} }
@ -158,4 +156,4 @@ export function useVueLifeHooks($bus) {
}, []) }, [])
} }
export * from '@vue/runtime-core' export * from '@vue/runtime-core'

View File

@ -12,11 +12,11 @@ const collectRefs = (rootEl, $children) => {
// 收集普通元素 ref // 收集普通元素 ref
traverseFiber(rootFiber, (fiber) => { traverseFiber(rootFiber, (fiber) => {
if (typeof fiber.type === 'string' && fiber.stateNode.getAttribute('v-ref')) { if (typeof fiber.type === 'string' && fiber.stateNode.getAttribute('v-ref')) {
refs[fiber.stateNode.getAttribute('v-ref')] = fiber.stateNode; refs[fiber.stateNode.getAttribute('v-ref')] = fiber.stateNode
} }
}) })
// 收集组件元素 ref // 收集组件元素 ref
$children.forEach(child => { $children.forEach((child) => {
if (child.$props['v-ref']) { if (child.$props['v-ref']) {
refs[child.$props['v-ref']] = child refs[child.$props['v-ref']] = child
} }
@ -24,48 +24,42 @@ const collectRefs = (rootEl, $children) => {
return refs return refs
} }
export function useCreateVueInstance({ export function useCreateVueInstance({ $bus, props }) {
$bus,
props
}) {
const ref = useRef() const ref = useRef()
const vm = useOnceResult(() => reactive({ const vm = useOnceResult(() =>
$el: undefined, reactive({
$options: props.$options || ({}), $el: undefined,
$props: props, $options: props.$options || {},
$parent: getParent().vm || {}, $props: props,
$root: getRoot().vm || {}, $parent: getParent().vm || {},
$slots: props.slots, $root: getRoot().vm || {},
$scopedSlots: props.slots, $slots: props.slots,
$listeners: props.$listeners, $scopedSlots: props.slots,
$attrs: props.$attrs, $listeners: props.$listeners,
// 通过 fiber 计算 $attrs: props.$attrs,
$children: [], // 通过 fiber 计算
$refs: computed(() => collectRefs(vm.$el, vm.$children)), $children: [],
// 方法 $refs: computed(() => collectRefs(vm.$el, vm.$children)),
$set: (target, property, value) => target[property] = value, // 方法
$delete: (target, property) => delete target[property], $set: (target, property, value) => (target[property] = value),
$watch: (expression, callback, options) => { $delete: (target, property) => delete target[property],
if (typeof expression === 'string') { $watch: (expression, callback, options) => {
watch( if (typeof expression === 'string') {
() => getPropByPath(vm, expression), watch(() => getPropByPath(vm, expression), callback, options)
callback, } else if (typeof expression === 'function') {
options watch(expression, callback, options)
) }
} },
else if (typeof expression === 'function') { $on: (event, callback) => $bus.on(event, callback),
watch(expression, callback, options) $once: (event, callback) => $bus.once(event, callback),
} $off: (event, callback) => $bus.off(event, callback),
}, $emit: (event, ...args) => $bus.emit(event, ...args),
$on: (event, callback) => $bus.on(event, callback), $forceUpdate: () => $bus.emit('event:reload'),
$once: (event, callback) => $bus.once(event, callback), $nextTick: nextTick,
$off: (event, callback) => $bus.off(event, callback), $destroy: () => {},
$emit: (event, ...args) => $bus.emit(event, ...args), $mount: () => {}
$forceUpdate: () => $bus.emit('event:reload'), })
$nextTick: nextTick, )
$destroy: () => { },
$mount: () => { }
}))
useExcuteOnce(() => { useExcuteOnce(() => {
const { $listeners } = props const { $listeners } = props
@ -88,4 +82,4 @@ export function useCreateVueInstance({
ref, ref,
vm vm
} }
} }

View File

@ -4,28 +4,25 @@ export function defineVueProps(propsOptions, props) {
const $listeners = {} const $listeners = {}
const reactEventPrefix = /^on[A-Z]/ const reactEventPrefix = /^on[A-Z]/
const propsArray = Array.isArray(propsOptions) ? propsOptions : Object.keys(propsOptions); const propsArray = Array.isArray(propsOptions) ? propsOptions : Object.keys(propsOptions)
Object.keys(props).forEach(key => { Object.keys(props).forEach((key) => {
if (propsArray.includes(key)) { if (propsArray.includes(key)) {
$props[key] = props[key] $props[key] = props[key]
} } else {
else {
if (reactEventPrefix.test(key)) { if (reactEventPrefix.test(key)) {
$listeners[key.substr(2).toLowerCase()] = props[key] $listeners[key.substr(2).toLowerCase()] = props[key]
} } else {
else {
$attrs[key] = props[key] $attrs[key] = props[key]
} }
} }
}); })
if (typeof propsOptions === 'object') { if (typeof propsOptions === 'object') {
Object Object.keys(propsOptions)
.keys(propsOptions) .filter((key) => !$props[key])
.filter(key => !$props[key]) .forEach((key) => {
.forEach(key => {
const options = propsOptions[key] const options = propsOptions[key]
const defaultValue = (typeof options.default === 'function') ? options.default() : options.default const defaultValue = typeof options.default === 'function' ? options.default() : options.default
defaultValue !== undefined && ($props[key] = defaultValue) defaultValue !== undefined && ($props[key] = defaultValue)
}) })
} }
@ -35,4 +32,4 @@ export function defineVueProps(propsOptions, props) {
$attrs, $attrs,
$listeners $listeners
} }
} }

View File

@ -1,6 +1,5 @@
import Alert from '@opentiny/react-alert/src/mobile-first' import Alert from '@opentiny/react-alert/src/mobile-first'
import Button from '@opentiny/react-button/src/mobile-first' import Button from '@opentiny/react-button/src/mobile-first'
import { $prefix } from '@opentiny/react-common'
const components = [Alert, Button] const components = [Alert, Button]

View File

@ -3,15 +3,13 @@ import mobile from './mobile'
import mobileFirst from './mobile-first' import mobileFirst from './mobile-first'
export default function (props) { export default function (props) {
const { const { tiny_mode = 'pc' } = props
tiny_mode = 'pc'
} = props
const S = ({ const S = {
pc, pc,
mobile, mobile,
'mobile-first': mobileFirst 'mobile-first': mobileFirst
})[tiny_mode] }[tiny_mode]
return (S(props)) return S(props)
} }

View File

@ -1,3 +1,3 @@
import Badge from './src/index' import Badge from './src/index'
export default Badge export default Badge

View File

@ -2,14 +2,12 @@ import pc from './pc'
import mobile from './mobile' import mobile from './mobile'
export default function (props) { export default function (props) {
const { const { tiny_mode = 'pc' } = props
tiny_mode = 'pc'
} = props
const S = ({ const S = {
pc, pc,
mobile mobile
})[tiny_mode] }[tiny_mode]
return (S(props)) return S(props)
} }

View File

@ -3,15 +3,13 @@ import mobile from './mobile'
import mobileFirst from './mobile-first' import mobileFirst from './mobile-first'
export default function (props) { export default function (props) {
const { const { tiny_mode = 'pc' } = props
tiny_mode = 'pc'
} = props
const S = ({ const S = {
pc, pc,
mobile, mobile,
'mobile-first': mobileFirst 'mobile-first': mobileFirst
})[tiny_mode] }[tiny_mode]
return (S(props)) return S(props)
} }

View File

@ -1,3 +1,3 @@
import Switch from "./src/index" import Switch from './src/index'
export default Switch export default Switch

View File

@ -9,19 +9,19 @@ const $constants = {
} }
} }
export default function (props) { export default function (props) {
const { const { tiny_mode = 'pc', _constants = $constants } = props || {}
tiny_mode = 'pc',
_constants = $constants
} = props || {}
const defaultProps = Object.assign({ const defaultProps = Object.assign(
_constants, {
tiny_mode _constants,
}, props) tiny_mode
},
props
)
const S = ({ const S = {
pc, pc
})[tiny_mode] }[tiny_mode]
return (S && S(defaultProps)) return S && S(defaultProps)
} }

View File

@ -10,7 +10,7 @@
* *
*/ */
import { IActionMenuRenderlessParams, IActionMenuItemData } from '@/types' import type { IActionMenuRenderlessParams, IActionMenuItemData } from '@/types'
export const handleMoreClick = (emit: IActionMenuRenderlessParams['emit']) => () => { export const handleMoreClick = (emit: IActionMenuRenderlessParams['emit']) => () => {
emit('more-click') emit('more-click')

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
IActionMenuApi, IActionMenuApi,
IActionMenuProps, IActionMenuProps,
IActionMenuState, IActionMenuState,

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { IAlertRenderlessParams } from '@/types' import type { IAlertRenderlessParams } from '@/types'
export const handleClose = export const handleClose =
({ emit, state }: Pick<IAlertRenderlessParams, 'emit' | 'state'>) => ({ emit, state }: Pick<IAlertRenderlessParams, 'emit' | 'state'>) =>

View File

@ -10,7 +10,13 @@
* *
*/ */
import { IAlertApi, IAlertProps, IAlertState, ISharedRenderlessParamHooks, IAlertRenderlessParamUtils } from '@/types' import type {
IAlertApi,
IAlertProps,
IAlertState,
ISharedRenderlessParamHooks,
IAlertRenderlessParamUtils
} from '@/types'
import { handleClose, computedGetIcon, computedGetTitle, handleHeaderClick } from './index' import { handleClose, computedGetIcon, computedGetTitle, handleHeaderClick } from './index'
export const api = ['handleClose', 'state', 'handleHeaderClick'] export const api = ['handleClose', 'state', 'handleHeaderClick']

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { IAnchorRenderlessParams, IAnchorLinkItem } from '@/types' import type { IAnchorRenderlessParams, IAnchorLinkItem } from '@/types'
import { addClass, removeClass } from '../common/deps/dom' import { addClass, removeClass } from '../common/deps/dom'
export const setFixAnchor = export const setFixAnchor =

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICElinksMapNSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICElinksMapNSES FOR MORE DETAILS.
* *
*/ */
import { import type {
IAnchorState, IAnchorState,
IAnchorProps, IAnchorProps,
IAnchorApi, IAnchorApi,

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { IBadgeRenderlessParams, IBadgeContent } from '@/types' import type { IBadgeRenderlessParams, IBadgeContent } from '@/types'
export const computedContent = export const computedContent =
({ props, state }: Pick<IBadgeRenderlessParams, 'props' | 'state'>) => ({ props, state }: Pick<IBadgeRenderlessParams, 'props' | 'state'>) =>

View File

@ -12,7 +12,7 @@
import { computedContent, computedValueRef } from './index' import { computedContent, computedValueRef } from './index'
import { xss } from '../common/xss' import { xss } from '../common/xss'
import { IBadgeState, IBadgeProps, IBadgeApi, IBadgeRenderlessParams } from '@/types' import type { IBadgeState, IBadgeProps, IBadgeApi, IBadgeRenderlessParams } from '@/types'
export const api = ['state'] export const api = ['state']

View File

@ -1,17 +1,24 @@
import { IBreadcrumbItemProps } from '@/types' import type { IBreadcrumbItemProps } from '@/types'
export const linkClick = export const linkClick =
({ props, refs, router, emit, breadcrumbEmitter, constants }: Pick<IBreadcrumbItemProps, 'props' | 'refs' | 'router' | 'emit' | 'breadcrumbEmitter' | 'constants'>) => ({
(event: MouseEvent) => { props,
const { replace, to, option } = props refs,
const currentBreadcrumbItem = { link: refs.link, replace, to, event, option } router,
emit,
breadcrumbEmitter,
constants
}: Pick<IBreadcrumbItemProps, 'props' | 'refs' | 'router' | 'emit' | 'breadcrumbEmitter' | 'constants'>) =>
(event: MouseEvent) => {
const { replace, to, option } = props
const currentBreadcrumbItem = { link: refs.link, replace, to, event, option }
breadcrumbEmitter.emit(constants.EVENT_NAME.breadcrumbItemSelect, currentBreadcrumbItem) breadcrumbEmitter.emit(constants.EVENT_NAME.breadcrumbItemSelect, currentBreadcrumbItem)
emit('select', currentBreadcrumbItem) emit('select', currentBreadcrumbItem)
if (!to || !router) { if (!to || !router) {
return return
}
replace ? router.replace(to) : router.push(to)
} }
replace ? router.replace(to) : router.push(to)
}

View File

@ -10,12 +10,21 @@
* *
*/ */
import { IBreadcrumbItemProps, IBreadcrumbItemApi, IBreadcrumbItemRenderlessParamUtils, ISharedRenderlessParamHooks } from '@/types' import type {
IBreadcrumbItemProps,
IBreadcrumbItemApi,
IBreadcrumbItemRenderlessParamUtils,
ISharedRenderlessParamHooks
} from '@/types'
import { linkClick } from './index' import { linkClick } from './index'
export const api = ['linkClick'] export const api = ['linkClick']
export const renderless = (props: IBreadcrumbItemProps, { inject }: ISharedRenderlessParamHooks, { refs, router, emit }: IBreadcrumbItemRenderlessParamUtils) => { export const renderless = (
props: IBreadcrumbItemProps,
{ inject }: ISharedRenderlessParamHooks,
{ refs, router, emit }: IBreadcrumbItemRenderlessParamUtils
) => {
const breadcrumbEmitter = inject('breadcrumbEmitter') const breadcrumbEmitter = inject('breadcrumbEmitter')
const breadcrumb = inject('breadcrumb') const breadcrumb = inject('breadcrumb')
const constants = breadcrumb._constants const constants = breadcrumb._constants

View File

@ -10,12 +10,16 @@
* *
*/ */
import { IBreadcrumbRenderlessParams } from '@/types' import type { IBreadcrumbRenderlessParams } from '@/types'
export const breadcrumbItemSelect = ({ api, emit, state, constants }: Pick<IBreadcrumbRenderlessParams, 'api' | 'emit' | 'state' | 'constants'>) => export const breadcrumbItemSelect = ({
{ api,
state.breadcrumbEmitter.on(constants.EVENT_NAME.breadcrumbItemSelect, (value) => { emit,
state.currentBreadcrumbItem = value state,
emit('select', value) constants
}) }: Pick<IBreadcrumbRenderlessParams, 'api' | 'emit' | 'state' | 'constants'>) => {
} state.breadcrumbEmitter.on(constants.EVENT_NAME.breadcrumbItemSelect, (value) => {
state.currentBreadcrumbItem = value
emit('select', value)
})
}

View File

@ -10,12 +10,22 @@
* *
*/ */
import { IBreadcrumbProps, IBreadcrumbState, IBreadcrumbApi, IBreadcrumbRenderlessParamUtils, ISharedRenderlessParamHooks } from '@/types' import type {
IBreadcrumbProps,
IBreadcrumbState,
IBreadcrumbApi,
IBreadcrumbRenderlessParamUtils,
ISharedRenderlessParamHooks
} from '@/types'
import { breadcrumbItemSelect } from './index' import { breadcrumbItemSelect } from './index'
export const api = ['breadcrumbItemSelect'] export const api = ['breadcrumbItemSelect']
export const renderless = (props: IBreadcrumbProps, { reactive, provide }: ISharedRenderlessParamHooks, { emit, constants, emitter }: IBreadcrumbRenderlessParamUtils): IBreadcrumbApi => { export const renderless = (
props: IBreadcrumbProps,
{ reactive, provide }: ISharedRenderlessParamHooks,
{ emit, constants, emitter }: IBreadcrumbRenderlessParamUtils
): IBreadcrumbApi => {
const state: IBreadcrumbState = reactive({ const state: IBreadcrumbState = reactive({
breadcrumbEmitter: emitter(), breadcrumbEmitter: emitter(),
currentBreadcrumbItem: {} currentBreadcrumbItem: {}

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { IButtonGroupRenderlessParams, IButtonGroupNode, IButtonGroupItemClass } from '@/types' import type { IButtonGroupRenderlessParams, IButtonGroupNode, IButtonGroupItemClass } from '@/types'
export const handleChange = export const handleChange =
({ emit, state }: Pick<IButtonGroupRenderlessParams, 'emit' | 'state'>) => ({ emit, state }: Pick<IButtonGroupRenderlessParams, 'emit' | 'state'>) =>

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { import type {
IButtonGroupState, IButtonGroupState,
ISharedRenderlessParamHooks, ISharedRenderlessParamHooks,
IButtonGroupProps, IButtonGroupProps,

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { IButtonRenderlessParams, IButtonState } from '@/types' import type { IButtonRenderlessParams, IButtonState } from '@/types'
export const handleClick = export const handleClick =
({ emit, props, state }: Pick<IButtonRenderlessParams, 'emit' | 'props' | 'state'>) => ({ emit, props, state }: Pick<IButtonRenderlessParams, 'emit' | 'props' | 'state'>) =>

View File

@ -9,13 +9,8 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { import type { ISharedRenderlessParamHooks, IButtonProps, IButtonApi, IButtonRenderlessParamUtils } from '@/types'
IButtonState,
ISharedRenderlessParamHooks,
IButtonProps,
IButtonApi,
IButtonRenderlessParamUtils
} from '@/types'
import { handleClick, clearTimer } from './index' import { handleClick, clearTimer } from './index'
export const api = ['state', 'handleClick'] export const api = ['state', 'handleClick']

View File

@ -161,7 +161,7 @@ const getCalendarItem = function (item, props, isFunction, type, isNext, isLast)
for (let i = item.start; i <= item.end; i++) { for (let i = item.start; i <= item.end; i++) {
let disabled = type === 'cur' && isFunction ? props.disabled(item.year + '-' + item.month + '-' + i) : false let disabled = type === 'cur' && isFunction ? props.disabled(item.year + '-' + item.month + '-' + i) : false
res.push({ value: i, year: item.year, month: item.month, isNext: isNext, isLast: isLast, disabled }) res.push({ value: i, year: item.year, month: item.month, isNext, isLast, disabled })
} }
return res return res
} }
@ -297,7 +297,7 @@ export const getEventByMonth =
const startTime = getTime(date + ' ' + state.dayStartTime) const startTime = getTime(date + ' ' + state.dayStartTime)
const endTime = getTime(date + ' ' + state.dayEndTime) const endTime = getTime(date + ' ' + state.dayEndTime)
const obj = { const obj = {
date: date, date,
day: state.weekDays[new Date(date).getDay()], day: state.weekDays[new Date(date).getDay()],
events: [] events: []
} }
@ -377,7 +377,7 @@ export const getEventByTime =
(day, start, end) => { (day, start, end) => {
const date = typeof day === 'object' ? day.year + '-' + day.month + '-' + day.value : day const date = typeof day === 'object' ? day.year + '-' + day.month + '-' + day.value : day
const startTime = getTime(date + ' ' + start) const startTime = getTime(date + ' ' + start)
const endTime = getTime(date + ' ' + (end ? end : start)) const endTime = getTime(date + ' ' + (end || start))
let result = [] let result = []
if (state.mode === 'timeline') { if (state.mode === 'timeline') {
@ -413,7 +413,7 @@ export const isStartOrEndDay =
(type, day, start, end, event) => { (type, day, start, end, event) => {
const date = day.toString().length > 2 ? day : state.activeYear + '-' + state.activeMonth + '-' + day const date = day.toString().length > 2 ? day : state.activeYear + '-' + state.activeMonth + '-' + day
const startTime = getTime(date + ' ' + start) const startTime = getTime(date + ' ' + start)
const endTime = getTime(date + ' ' + (end ? end : start)) const endTime = getTime(date + ' ' + (end || start))
if (type === 'start') { if (type === 'start') {
return event.start >= startTime && event.start < endTime return event.start >= startTime && event.start < endTime

View File

@ -76,7 +76,7 @@ const initState = ({ reactive, props, computed, api, images, modesIcon }) => {
dayStartTime: props._constants.DAY_START_TIME, dayStartTime: props._constants.DAY_START_TIME,
dayEndTime: props._constants.DAY_END_TIME, dayEndTime: props._constants.DAY_END_TIME,
wednesday: props._constants.WEDNESDAY, wednesday: props._constants.WEDNESDAY,
modesIcon: modesIcon, modesIcon,
images, images,
weekDays: [0, 1, 2, 3, 4, 5, 6], weekDays: [0, 1, 2, 3, 4, 5, 6],
dayTimes: computed(() => api.genDayTimes()), dayTimes: computed(() => api.genDayTimes()),

View File

@ -10,7 +10,7 @@
* *
*/ */
import { ICascaderMenuRenderlessParamUtils, ICascaderMenuRenderlessParams, ICascaderMenuState } from '@/types' import type { ICascaderMenuRenderlessParamUtils, ICascaderMenuRenderlessParams, ICascaderMenuState } from '@/types'
export const handleExpand = (state: ICascaderMenuState) => (e: MouseEvent) => export const handleExpand = (state: ICascaderMenuState) => (e: MouseEvent) =>
(state.activeNode = e.target as HTMLElement) (state.activeNode = e.target as HTMLElement)

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
ICascaderMenuState, ICascaderMenuState,
ICascaderMenuProps, ICascaderMenuProps,
ISharedRenderlessParamHooks, ISharedRenderlessParamHooks,

View File

@ -13,11 +13,11 @@ export const syncCheckStatus =
(value) => { (value) => {
const { valueField, textField, modelValue: propsModelValue, visible } = props const { valueField, textField, modelValue: propsModelValue, visible } = props
const { lazy, isLeaf: leafField } = api.getNodeConfig() const { lazy, isLeaf: leafField } = api.getNodeConfig()
let currentData, let currentData
navList = [], let navList = []
modelValue = value || propsModelValue || [], let modelValue = value || propsModelValue || []
len = modelValue.length, let len = modelValue.length
isLeaf let isLeaf
if (!visible) { if (!visible) {
return return

View File

@ -52,8 +52,8 @@ export const renderless = (props, { computed, reactive, watch }, { emit, constan
filterOptions: [] filterOptions: []
}, },
options: computed(() => { options: computed(() => {
let arr, let arr
list = [state.rootData] let list = [state.rootData]
state.navList.map((option) => { state.navList.map((option) => {
arr = option.childNodes arr = option.childNodes
arr && arr.length && list.push(arr) arr && arr.length && list.push(arr)

View File

@ -10,7 +10,7 @@
* *
*/ */
import { ICascaderNodeRenderlessParams, ICascaderPanelNode } from '@/types' import type { ICascaderNodeRenderlessParams, ICascaderPanelNode } from '@/types'
export const comptCheckPath = export const comptCheckPath =
({ api, parent, state }: Pick<ICascaderNodeRenderlessParams, 'api' | 'parent' | 'state'>) => ({ api, parent, state }: Pick<ICascaderNodeRenderlessParams, 'api' | 'parent' | 'state'>) =>

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
ICascaderNodeApi, ICascaderNodeApi,
ICascaderNodeProps, ICascaderNodeProps,
ISharedRenderlessParamHooks, ISharedRenderlessParamHooks,

View File

@ -15,7 +15,7 @@ import { isEqual } from '../common/object'
import { isEmpty } from '../cascader' import { isEmpty } from '../cascader'
import { KEY_CODE, CASCADER } from '../common' import { KEY_CODE, CASCADER } from '../common'
import scrollIntoViewCommon from '../common/deps/scroll-into-view' import scrollIntoViewCommon from '../common/deps/scroll-into-view'
import { import type {
ICascaderPanelApi, ICascaderPanelApi,
ICascaderPanelData, ICascaderPanelData,
ICascaderPanelLazyLoadNode, ICascaderPanelLazyLoadNode,
@ -328,7 +328,7 @@ export const getCheckedNodes =
return flag return flag
} }
for (let i = 0; i < checkedValue.length; i++) { for (let i = 0; i < checkedValue.length; i++) {
if (Array.isArray(checkedValue[i]) ) { if (Array.isArray(checkedValue[i])) {
if (checkedValue[i].length) { if (checkedValue[i].length) {
flag = checkedValue[i][checkedValue[i].length - 1] === str flag = checkedValue[i][checkedValue[i].length - 1] === str
} }
@ -350,7 +350,7 @@ export const getCheckedNodes =
const node = api.getNodeByValue(state.checkedValue) const node = api.getNodeByValue(state.checkedValue)
return (isEmpty(state.checkedValue) || !node) ? [] : [node] return isEmpty(state.checkedValue) || !node ? [] : [node]
} }
export const clearCheckedNodes = export const clearCheckedNodes =

View File

@ -9,7 +9,12 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { ICascaderPanelConfig, ICascaderPanelData, ICascaderPanelNodePropValue, ICascaderPanelNodeValue } from '@/types' import type {
ICascaderPanelConfig,
ICascaderPanelData,
ICascaderPanelNodePropValue,
ICascaderPanelNodeValue
} from '@/types'
import { isEqual } from '../common/object' import { isEqual } from '../common/object'
import { capitalize } from '../common/string' import { capitalize } from '../common/string'

View File

@ -10,12 +10,7 @@
* *
*/ */
import { import type { ICascaderPanelConfig, ICascaderPanelData, ICascaderPanelNode, ICascaderPanelNodePropValue } from '@/types'
ICascaderPanelConfig,
ICascaderPanelData,
ICascaderPanelNode,
ICascaderPanelNodePropValue
} from '@/types'
import Node from './node' import Node from './node'
import { valueEquals, coerceTruthyValueToArray as toArray } from './index' import { valueEquals, coerceTruthyValueToArray as toArray } from './index'

View File

@ -37,7 +37,7 @@ import {
import { merge } from '../common/object' import { merge } from '../common/object'
import { isEmpty } from '../cascader' import { isEmpty } from '../cascader'
import Store from './store.js' import Store from './store.js'
import { import type {
ICascaderPanelApi, ICascaderPanelApi,
ICascaderPanelProps, ICascaderPanelProps,
ICascaderPanelRenderlessParamUtils, ICascaderPanelRenderlessParamUtils,

View File

@ -1,402 +1,456 @@
import TreeStore from '../common/deps/tree-model/tree-store' import TreeStore from '../common/deps/tree-model/tree-store'
export const close = ({ state, emit }) => () => { export const close =
state.search.show = false ({ state, emit }) =>
emit('update:visible', false) () => {
emit('close', false) state.search.show = false
} emit('update:visible', false)
emit('close', false)
export const syncCheckStatus = ({ state, api }) => (value) => {
value && state.store.setDefaultCheckedKey(value)
state.checkList = api.getCheckedNodes()
}
export const watchModelValue = ({ props, state, emit }) => () => {
const { textSplit } = props
emit('update:text', state.checkLabels.join(textSplit))
}
export const watchVisible = ({ emit, state, props, api }) => (visible) => {
const { modelValue } = props
if (visible) {
api.watchModelValue(modelValue)
api.initTreeStore()
api.searchBoxToggle(false)
} }
emit('update:visible', visible) export const syncCheckStatus =
setTimeout(() => { ({ state, api }) =>
state.toggle = visible (value) => {
}, 0) value && state.store.setDefaultCheckedKey(value)
} state.checkList = api.getCheckedNodes()
}
export const watchModelValue =
({ props, state, emit }) =>
() => {
const { textSplit } = props
emit('update:text', state.checkLabels.join(textSplit))
}
export const watchVisible =
({ emit, state, props, api }) =>
(visible) => {
const { modelValue } = props
if (visible) {
api.watchModelValue(modelValue)
api.initTreeStore()
api.searchBoxToggle(false)
}
emit('update:visible', visible)
setTimeout(() => {
state.toggle = visible
}, 0)
}
const hasChildren = (option) => option && !option.isLeaf const hasChildren = (option) => option && !option.isLeaf
export const selectOption = ({ emit, state, api }) => (option, deep = true) => { export const selectOption =
const isAdd = !option.checked || option.indeterminate ({ emit, state, api }) =>
(option, deep = true) => {
const isAdd = !option.checked || option.indeterminate
if (option.disabled) { if (option.disabled) {
return return
}
state.store.setChecked(option, isAdd, deep)
state.checkList = api.getCheckedNodes()
emit('click', option, isAdd)
}
export const nodeExpand = ({ emit, state, props, api }) => (option) => {
if (option.isLeaf) {
return
}
const { valueField } = props
const { lazy, load } = api.getNodeConfig()
const { navList, level, waitLoadCheckList } = state
const len = navList.length
const appendNavList = () => {
const isSame = level < len && navList[level] === option
if (hasChildren(option)) {
state.level += 1
if (!isSame) {
state.navList = [...navList.slice(0, level), option]
}
} }
option.expand() state.store.setChecked(option, isAdd, deep)
emit('node-expand', option) state.checkList = api.getCheckedNodes()
emit('click', option, isAdd)
} }
if (load && lazy && (option.selfWaitLoad || (!option.loaded && !option.isLeaf))) { export const nodeExpand =
state.loading = true ({ emit, state, props, api }) =>
option.loading = true (option) => {
load(option, (nodes) => { if (option.isLeaf) {
let index, node return
}
state.loading = false const { valueField } = props
option.loading = false const { lazy, load } = api.getNodeConfig()
option.loaded = true const { navList, level, waitLoadCheckList } = state
nodes.map((data) => { const len = navList.length
index = -1
state.store.append(data, option.data)
waitLoadCheckList.some((item, i) => {
if (item.data[valueField] === data[valueField]) {
index = i
return true
}
return false
})
node = state.store.getNode(data)
if (index !== -1 && node) { const appendNavList = () => {
state.waitLoadCheckList.splice(index, 1) const isSame = level < len && navList[level] === option
if (hasChildren(option)) {
state.level += 1
if (!isSame) {
state.navList = [...navList.slice(0, level), option]
} }
}
option.expand()
emit('node-expand', option)
}
if (load && lazy && (option.selfWaitLoad || (!option.loaded && !option.isLeaf))) {
state.loading = true
option.loading = true
load(option, (nodes) => {
let index, node
state.loading = false
option.loading = false
option.loaded = true
nodes.map((data) => {
index = -1
state.store.append(data, option.data)
waitLoadCheckList.some((item, i) => {
if (item.data[valueField] === data[valueField]) {
index = i
return true
}
return false
})
node = state.store.getNode(data)
if (index !== -1 && node) {
state.waitLoadCheckList.splice(index, 1)
}
})
option.checked && !state.store.checkStrictly && option.setChecked(true, !state.store.checkStrictly)
state.checkList = api.getCheckedNodes()
appendNavList()
}) })
option.checked && !state.store.checkStrictly && option.setChecked(true, !state.store.checkStrictly)
state.checkList = api.getCheckedNodes()
appendNavList()
})
} else {
appendNavList()
}
}
export const confirm = ({ emit, state, props }) => () => {
const { emitPath, valueField } = props
let value,
data = []
state.computedCheckList.forEach((node) => {
if (node.waitLoad) {
value = emitPath ? node.rawValue : node.data[valueField]
} else { } else {
value = emitPath ? node.getPathData(valueField) : node.data[valueField] appendNavList()
} }
data.push(value) }
})
state.search.show = false export const confirm =
emit('confirm', state) ({ emit, state, props }) =>
emit('update:visible', false) () => {
emit('update:modelValue', data) const { emitPath, valueField } = props
} let value
let data = []
export const loopSearchOption = ({ state, props, api }) => (param) => { state.computedCheckList.forEach((node) => {
const { options, prefixText = '', textSplit = '/', checkStrictly } = param || {} if (node.waitLoad) {
const { valueField, textField, childrenField } = props value = emitPath ? node.rawValue : node.data[valueField]
const { input } = state.search } else {
value = emitPath ? node.getPathData(valueField) : node.data[valueField]
}
data.push(value)
})
const list = [] state.search.show = false
options.forEach((item) => { emit('confirm', state)
const text = item[textField] emit('update:visible', false)
const textNavStr = prefixText ? prefixText + textSplit + text : text emit('update:modelValue', data)
const value = item[valueField] }
const childNodes = item[childrenField]
const len = childNodes && childNodes.length
if ((checkStrictly || (!checkStrictly && !len)) && text.indexOf(input) > -1) { export const loopSearchOption =
list.push({ ({ state, props, api }) =>
[valueField]: value, (param) => {
[textField]: textNavStr const { options, prefixText = '', textSplit = '/', checkStrictly } = param || {}
}) const { valueField, textField, childrenField } = props
const { input } = state.search
const list = []
options.forEach((item) => {
const text = item[textField]
const textNavStr = prefixText ? prefixText + textSplit + text : text
const value = item[valueField]
const childNodes = item[childrenField]
const len = childNodes && childNodes.length
if ((checkStrictly || (!checkStrictly && !len)) && text.includes(input)) {
list.push({
[valueField]: value,
[textField]: textNavStr
})
}
if (len) {
const arr = api.loopSearchOption({
options: childNodes,
prefixText: textNavStr,
textSplit,
checkStrictly
})
list.push(...arr)
}
})
return list
}
export const filterOptionsHandler =
({ state, props }) =>
(list) => {
const { valueField } = props
state.search.loaded = true
state.search.filterOptions = list.map((item) => {
return {
data: item,
node: state.store.getNode(item[valueField])
}
})
}
export const searchMethod =
({ state, props, api }) =>
() => {
const { searchConfig } = props
const { input, options } = state.search
let list = []
const { checkStrictly } = api.getNodeConfig()
if (searchConfig && searchConfig.searchMethod) {
list = searchConfig.searchMethod({ input, options, state }) || []
} else if (input) {
list = api.loopSearchOption({ options, checkStrictly })
} }
if (len) { if (typeof list.then === 'function') {
const arr = api.loopSearchOption({ list.then((data) => api.filterOptionsHandler(data))
options: childNodes, } else {
prefixText: textNavStr, api.filterOptionsHandler(list)
textSplit,
checkStrictly
})
list.push(...arr)
} }
}) }
return list export const searchBoxToggle =
} ({ state, props, api }) =>
(bool) => {
const { searchConfig = {} } = props
const { lazy } = api.getNodeConfig()
state.search.show = bool
state.search.loaded = false
export const filterOptionsHandler = ({ state, props }) => (list) => { if (bool) {
const { valueField } = props state.search.options =
!lazy && searchConfig.options && searchConfig.options.length ? searchConfig.options : state.store.getAllData()
state.search.loaded = true } else {
state.search.filterOptions = list.map((item) => { state.search.input = ''
return { state.search.filterOptions = []
data: item,
node: state.store.getNode(item[valueField])
} }
})
}
export const searchMethod = ({ state, props, api }) => () => {
const { searchConfig } = props
const { input, options } = state.search
let list = []
const { checkStrictly } = api.getNodeConfig()
if (searchConfig && searchConfig.searchMethod) {
list = searchConfig.searchMethod({ input, options, state }) || []
} else if (input) {
list = api.loopSearchOption({ options, checkStrictly })
} }
if (typeof list.then === 'function') { export const isSelected =
list.then((data) => api.filterOptionsHandler(data)) ({ state }) =>
} else { (option) => {
api.filterOptionsHandler(list) const { navList } = state
}
}
export const searchBoxToggle = ({ state, props, api }) => (bool) => { return navList.includes(option)
const { searchConfig = {} } = props
const { lazy } = api.getNodeConfig()
state.search.show = bool
state.search.loaded = false
if (bool) {
state.search.options =
!lazy && searchConfig.options && searchConfig.options.length ? searchConfig.options : state.store.getAllData()
} else {
state.search.input = ''
state.search.filterOptions = []
}
}
export const isSelected = ({ state }) => (option) => {
const { navList } = state
return navList.some((item) => item === option)
}
export const created = ({ api }) => () => {
api.initTreeStore()
}
export const setLevel = ({ state, api }) => (level, option) => {
if (!api.disabledNavOption(level, option)) {
state.level = level
}
}
export const searchSelectHandler = ({ emit, api }) => (option) => {
api.selectOption(option)
emit('search-click', option)
}
export const renderSearchOption = ({ state }) => (text) => {
return (text || '').split(state.search.input)
}
export const loadData = ({ props, state }) => (data) => {
props.visible && state.store.setData(data)
}
export const computedNavListHandler = ({ state, props, t }) => () => {
const { textField } = props
return [{ data: { [textField]: t('ui.base.all') } }, ...state.navList]
}
export const disabledNavOption = ({ state }) => (level, option) => {
const node = state.navList[level]
return option.selfWaitLoad && (!node || !node.childNodes.length)
}
export const getNodeConfig = ({ constants, props }) => () => {
const { nodeConfig, valueField, childrenField } = props
return Object.assign({ nodeKey: valueField, children: childrenField }, constants.defaultNodeConfig, nodeConfig)
}
export const initTreeStore = ({ props, state, api }) => () => {
const { data, valueField, textField, visible, modelValue } = props
const {
lazy,
nodeKey,
load,
children,
afterLoad,
isLeaf,
currentNodeKey,
checkStrictly,
checkDescendants,
defaultExpandedKeys,
defaultCheckedKeys,
defaultExpandAll,
autoExpandParent,
filterNodeMethod
} = api.getNodeConfig()
if (!visible) {
return
} }
const defaultValue = (defaultCheckedKeys || modelValue).map((data) => { export const created =
if (Array.isArray(data)) { ({ api }) =>
data = data[data.length - 1] () => {
api.initTreeStore()
}
export const setLevel =
({ state, api }) =>
(level, option) => {
if (!api.disabledNavOption(level, option)) {
state.level = level
} }
return data
})
if (state.store) {
api.syncCheckStatus(defaultValue)
return
} }
state.store = new TreeStore({ export const searchSelectHandler =
data, ({ emit, api }) =>
lazy, (option) => {
load, api.selectOption(option)
key: nodeKey, emit('search-click', option)
props: { }
label: textField,
export const renderSearchOption =
({ state }) =>
(text) => {
return (text || '').split(state.search.input)
}
export const loadData =
({ props, state }) =>
(data) => {
props.visible && state.store.setData(data)
}
export const computedNavListHandler =
({ state, props, t }) =>
() => {
const { textField } = props
return [{ data: { [textField]: t('ui.base.all') } }, ...state.navList]
}
export const disabledNavOption =
({ state }) =>
(level, option) => {
const node = state.navList[level]
return option.selfWaitLoad && (!node || !node.childNodes.length)
}
export const getNodeConfig =
({ constants, props }) =>
() => {
const { nodeConfig, valueField, childrenField } = props
return Object.assign({ nodeKey: valueField, children: childrenField }, constants.defaultNodeConfig, nodeConfig)
}
export const initTreeStore =
({ props, state, api }) =>
() => {
const { data, valueField, textField, visible, modelValue } = props
const {
lazy,
nodeKey,
load,
children, children,
isLeaf afterLoad,
}, isLeaf,
afterLoad: () => { currentNodeKey,
checkStrictly,
checkDescendants,
defaultExpandedKeys,
defaultCheckedKeys,
defaultExpandAll,
autoExpandParent,
filterNodeMethod
} = api.getNodeConfig()
if (!visible) {
return
}
const defaultValue = (defaultCheckedKeys || modelValue).map((data) => {
if (Array.isArray(data)) {
data = data[data.length - 1]
}
return data
})
if (state.store) {
api.syncCheckStatus(defaultValue)
return
}
state.store = new TreeStore({
data,
lazy,
load,
key: nodeKey,
props: {
label: textField,
children,
isLeaf
},
afterLoad: () => {
state.rootData = state.root.childNodes || []
api.syncCheckStatus()
afterLoad && afterLoad()
},
checkStrictly,
currentNodeKey,
checkDescendants,
defaultExpandedKeys,
defaultCheckedKeys: defaultValue,
defaultExpandAll,
autoExpandParent,
filterNodeMethod
})
state.root = state.store.root
if (!lazy) {
state.rootData = state.root.childNodes || [] state.rootData = state.root.childNodes || []
api.syncCheckStatus() api.syncCheckStatus()
afterLoad && afterLoad() } else {
}, state.waitLoadCheckList = defaultValue.map((item, index) => {
checkStrictly, return {
currentNodeKey, data: {
checkDescendants, [textField]: item,
defaultExpandedKeys, [valueField]: item
defaultCheckedKeys: defaultValue, },
defaultExpandAll, rawValue: (defaultCheckedKeys || modelValue)[index],
autoExpandParent, waitLoad: true
filterNodeMethod
})
state.root = state.store.root
if (!lazy) {
state.rootData = state.root.childNodes || []
api.syncCheckStatus()
} else {
state.waitLoadCheckList = defaultValue.map((item, index) => {
return {
data: {
[textField]: item,
[valueField]: item
},
rawValue: (defaultCheckedKeys || modelValue)[index],
waitLoad: true
}
})
}
}
export const clean = ({ state }) => () => {
const { options, waitLoadList } = state.selected
state.selected.removeList = [...waitLoadList, ...options]
state.selected.options = []
state.selected.waitLoadList = []
}
export const getCheckedNodes = ({ state }) => () => {
return state.store.getCheckedNodes(!state.store.checkStrictly, false, true)
}
export const toggleCheckList = ({ state, props, api }) => (show) => {
const { valueField } = props
if (!state.computedCheckList.length) {
return
}
state.selected.show = show
if (show) {
state.selected.options = state.checkList.slice()
state.selected.waitLoadList = state.waitLoadCheckList.slice()
} else {
let index
state.selected.removeList.forEach((option) => {
if (option.waitLoad) {
index = state.store.defaultCheckedKeys.indexOf(option.data[valueField])
if (index !== -1) {
state.store.defaultCheckedKeys.splice(index, 1)
} }
} else { })
state.store.setChecked(option, false, false) }
}
})
state.checkList = api.getCheckedNodes()
state.selected.removeList = []
state.waitLoadCheckList = state.selected.waitLoadList.slice()
} }
}
export const removeOption = ({ state }) => (option) => { export const clean =
const { options, waitLoadList } = state.selected ({ state }) =>
let index () => {
const { options, waitLoadList } = state.selected
if ((index = options.indexOf(option)) > -1) { state.selected.removeList = [...waitLoadList, ...options]
state.selected.options.splice(index, 1) state.selected.options = []
state.selected.removeList.push(option) state.selected.waitLoadList = []
} else if ((index = waitLoadList.indexOf(option)) > -1) {
state.selected.waitLoadList.splice(index, 1)
state.selected.removeList.push(option)
} }
}
export const computedSelectedListHandler = ({ state }) => () => { export const getCheckedNodes =
const { options, waitLoadList } = state.selected ({ state }) =>
() => {
return [...waitLoadList, ...options] return state.store.getCheckedNodes(!state.store.checkStrictly, false, true)
} }
export const inputKeyword = ({ state, api }) => () => { export const toggleCheckList =
const { search } = state ({ state, props, api }) =>
const show = !!search.input (show) => {
if (search.show !== show) { const { valueField } = props
api.searchBoxToggle(show)
if (!state.computedCheckList.length) {
return
}
state.selected.show = show
if (show) {
state.selected.options = state.checkList.slice()
state.selected.waitLoadList = state.waitLoadCheckList.slice()
} else {
let index
state.selected.removeList.forEach((option) => {
if (option.waitLoad) {
index = state.store.defaultCheckedKeys.indexOf(option.data[valueField])
if (index !== -1) {
state.store.defaultCheckedKeys.splice(index, 1)
}
} else {
state.store.setChecked(option, false, false)
}
})
state.checkList = api.getCheckedNodes()
state.selected.removeList = []
state.waitLoadCheckList = state.selected.waitLoadList.slice()
}
}
export const removeOption =
({ state }) =>
(option) => {
const { options, waitLoadList } = state.selected
let index
if ((index = options.indexOf(option)) > -1) {
state.selected.options.splice(index, 1)
state.selected.removeList.push(option)
} else if ((index = waitLoadList.indexOf(option)) > -1) {
state.selected.waitLoadList.splice(index, 1)
state.selected.removeList.push(option)
}
}
export const computedSelectedListHandler =
({ state }) =>
() => {
const { options, waitLoadList } = state.selected
return [...waitLoadList, ...options]
}
export const inputKeyword =
({ state, api }) =>
() => {
const { search } = state
const show = !!search.input
if (search.show !== show) {
api.searchBoxToggle(show)
}
} }
}

View File

@ -75,8 +75,8 @@ export const renderless = (props, { computed, reactive, watch }, { t, emit, cons
waitLoadList: [] waitLoadList: []
}, },
options: computed(() => { options: computed(() => {
let data, let data
list = [state.rootData] let list = [state.rootData]
state.navList.map((option) => { state.navList.map((option) => {
data = option.childNodes data = option.childNodes
data && data.length && list.push(data) data && data.length && list.push(data)

View File

@ -30,7 +30,7 @@ function getBoundedPrecision(value, maxDecimals, optionals) {
function toFixed(value, maxDecimals, roundingFunction, optionals) { function toFixed(value, maxDecimals, roundingFunction, optionals) {
let boundedPrecision = getBoundedPrecision(value, maxDecimals, optionals) let boundedPrecision = getBoundedPrecision(value, maxDecimals, optionals)
let power = Math.pow(10, boundedPrecision) let power = 10 ** boundedPrecision
let output = (roundingFunction(value * `1e+${boundedPrecision}`) / power).toFixed(boundedPrecision) let output = (roundingFunction(value * `1e+${boundedPrecision}`) / power).toFixed(boundedPrecision)

View File

@ -43,7 +43,7 @@ const isStack = ({ props }) => {
Object.keys(stack).forEach((key) => { Object.keys(stack).forEach((key) => {
stack[key].forEach((stackItem) => { stack[key].forEach((stackItem) => {
const isExist = columns.some((col) => col === stackItem) const isExist = columns.includes(stackItem)
if (isExist) { if (isExist) {
flag = true flag = true
} }

View File

@ -21,7 +21,14 @@ import {
computedIsDisabled, computedIsDisabled,
toggleEvent toggleEvent
} from './index' } from './index'
import { addToStore, computedIsChecked, computedStore, computedIsLimitDisabled, computedIsShowText, computedShowText } from '../checkbox' import {
addToStore,
computedIsChecked,
computedStore,
computedIsLimitDisabled,
computedIsShowText,
computedShowText
} from '../checkbox'
export const api = ['state', 'handleChange'] export const api = ['state', 'handleChange']

View File

@ -10,7 +10,7 @@
* *
*/ */
import { ICheckboxRenderlessParams, ICheckboxState, ICheckboxChangeEvent, ICheckboxProps } from '@/types' import type { ICheckboxRenderlessParams, ICheckboxState, ICheckboxChangeEvent, ICheckboxProps } from '@/types'
import { isNull } from '../common/type' import { isNull } from '../common/type'
export const addToStore = export const addToStore =

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
ICheckboxApi, ICheckboxApi,
ICheckboxProps, ICheckboxProps,
ICheckboxState, ICheckboxState,

View File

@ -10,9 +10,7 @@
* *
*/ */
import { import type { ICollapseItemRenderlessParams } from '@/types'
ICollapseItemRenderlessParams
} from '@/types'
export const handleFocus = export const handleFocus =
({ state, interval }: Pick<ICollapseItemRenderlessParams, 'state' | 'interval'>) => ({ state, interval }: Pick<ICollapseItemRenderlessParams, 'state' | 'interval'>) =>
@ -27,7 +25,14 @@ export const handleFocus =
} }
export const handleHeaderClick = export const handleHeaderClick =
({ componentName, dispatch, eventName, props, parent, state }: Pick<ICollapseItemRenderlessParams, 'componentName' | 'dispatch' | 'eventName' | 'props' | 'parent' | 'state'>) => ({
componentName,
dispatch,
eventName,
props,
parent,
state
}: Pick<ICollapseItemRenderlessParams, 'componentName' | 'dispatch' | 'eventName' | 'props' | 'parent' | 'state'>) =>
() => { () => {
if (props.disabled) { if (props.disabled) {
return return
@ -40,6 +45,11 @@ export const handleHeaderClick =
} }
export const handleEnterClick = export const handleEnterClick =
({ componentName, dispatch, eventName, parent }: Pick<ICollapseItemRenderlessParams, 'componentName' | 'dispatch' | 'eventName' | 'parent'>) => ({
componentName,
dispatch,
eventName,
parent
}: Pick<ICollapseItemRenderlessParams, 'componentName' | 'dispatch' | 'eventName' | 'parent'>) =>
() => () =>
dispatch(componentName, eventName, parent) dispatch(componentName, eventName, parent)

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
ICollapseItemProps, ICollapseItemProps,
ICollapseItemState, ICollapseItemState,
ICollapseItemApi, ICollapseItemApi,
@ -22,12 +22,16 @@ import { guid } from '../common/string'
export const api = ['state', 'isActive', 'handleFocus', 'handleEnterClick', 'handleHeaderClick'] export const api = ['state', 'isActive', 'handleFocus', 'handleEnterClick', 'handleHeaderClick']
export const renderless = (props: ICollapseItemProps, { computed, reactive }: ISharedRenderlessParamHooks, { parent, constants, dispatch }: ICollapseItemRenderlessParamUtils) => { export const renderless = (
props: ICollapseItemProps,
{ computed, reactive }: ISharedRenderlessParamHooks,
{ parent, constants, dispatch }: ICollapseItemRenderlessParamUtils
) => {
const _constants = parent.collapse._constants const _constants = parent.collapse._constants
const componentName = _constants.COMPONENT_NAME.Collapse const componentName = _constants.COMPONENT_NAME.Collapse
const eventName = _constants.EVENT_NAME.CollapseItemClick const eventName = _constants.EVENT_NAME.CollapseItemClick
const state:ICollapseItemState = reactive({ const state: ICollapseItemState = reactive({
id: guid(), id: guid(),
isClick: false, isClick: false,
focusing: false, focusing: false,

View File

@ -9,13 +9,11 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { import type { ICollapseRenderlessParams } from '@/types'
ICollapseRenderlessParams
} from '@/types'
export const setActiveNames = export const setActiveNames =
({ emit, props, state }: Pick<ICollapseRenderlessParams, 'emit' | 'props' | 'state' >) => ({ emit, props, state }: Pick<ICollapseRenderlessParams, 'emit' | 'props' | 'state'>) =>
(activeNames: string | string[]):void => { (activeNames: string | string[]): void => {
activeNames = [].concat(activeNames) activeNames = [].concat(activeNames)
const value: string | string[] = props.accordion ? activeNames[0] : activeNames const value: string | string[] = props.accordion ? activeNames[0] : activeNames
state.activeNames = activeNames state.activeNames = activeNames
@ -25,7 +23,7 @@ export const setActiveNames =
} }
export const handleItemClick = export const handleItemClick =
({ api, props, state }: Pick<ICollapseRenderlessParams, 'api' | 'props' | 'state' >) => ({ api, props, state }: Pick<ICollapseRenderlessParams, 'api' | 'props' | 'state'>) =>
(item?: Object) => { (item?: Object) => {
const activeNames = state.activeNames.slice(0) const activeNames = state.activeNames.slice(0)
const index = activeNames.indexOf(item.name) const index = activeNames.indexOf(item.name)

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { import type {
ICollapseProps, ICollapseProps,
ICollapseState, ICollapseState,
ICollapseApi, ICollapseApi,
@ -21,7 +21,11 @@ import { setActiveNames, handleItemClick } from './index'
export const api = ['state'] export const api = ['state']
export const renderless = (props: ICollapseProps, { reactive, watch }: ISharedRenderlessParamHooks, { parent, emit, constants }: ICollapseRenderlessParamUtils) => { export const renderless = (
props: ICollapseProps,
{ reactive, watch }: ISharedRenderlessParamHooks,
{ parent, emit, constants }: ICollapseRenderlessParamUtils
) => {
const eventName = constants.EVENT_NAME.CollapseItemClick const eventName = constants.EVENT_NAME.CollapseItemClick
const state: ICollapseState = reactive({ const state: ICollapseState = reactive({
@ -40,7 +44,7 @@ export const renderless = (props: ICollapseProps, { reactive, watch }: ISharedRe
(value) => { (value) => {
state.activeNames = value || value === 0 ? [].concat(value) : [] state.activeNames = value || value === 0 ? [].concat(value) : []
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }
) )
parent.$on(eventName, api.handleItemClick) parent.$on(eventName, api.handleItemClick)

View File

@ -1,14 +1,8 @@
import { IColorPickerRef as Ref } from '@/types' import type { IColorPickerRef as Ref } from '@/types'
import type Color from './utils/color' import type Color from './utils/color'
export const onCancel = ( export const onCancel = (tmpColor: Color, triggerBg: Ref<string>, isShow: Ref<boolean>, pre: Ref<string>, emit) => {
tmpColor: Color, return (color: Ref<Color>) => {
triggerBg: Ref<string>,
isShow: Ref<boolean>,
pre: Ref<string>,
emit
) => {
return (color: Ref<Color>)=>{
tmpColor.reset(color.value.getHex()) tmpColor.reset(color.value.getHex())
triggerBg.value = pre.value triggerBg.value = pre.value
isShow.value = false isShow.value = false
@ -16,14 +10,8 @@ export const onCancel = (
} }
} }
export const onConfirm = ( export const onConfirm = (triggerBg: Ref<string>, pre: Ref<string>, hex: Ref<string>, isShow: Ref<boolean>, emit) => {
triggerBg: Ref<string>, return (color: string) => {
pre: Ref<string>,
hex: Ref<string>,
isShow: Ref<boolean>,
emit
) => {
return (color: string)=>{
pre.value = triggerBg.value pre.value = triggerBg.value
triggerBg.value = color triggerBg.value = color
hex.value = color hex.value = color
@ -32,30 +20,22 @@ export const onConfirm = (
} }
} }
export const onHueUpdate = ( export const onHueUpdate = (tmpColor: Color, triggerBg: Ref<string>) => {
tmpColor: Color,
triggerBg: Ref<string>
) => {
return (h: number) => { return (h: number) => {
triggerBg.value = tmpColor.getHex(); triggerBg.value = tmpColor.getHex()
tmpColor.set({h}) tmpColor.set({ h })
} }
} }
export const onSVUpdate = ( export const onSVUpdate = (tmpColor: Color, triggerBg: Ref<string>) => {
tmpColor: Color, return ({ s, v }) => {
triggerBg: Ref<string> triggerBg.value = tmpColor.getHex()
) => { tmpColor.set({ s, v })
return ({s,v})=>{
triggerBg.value = tmpColor.getHex();
tmpColor.set({s,v})
} }
} }
export const onColorUpdate = ( export const onColorUpdate = (triggerBg: Ref<string>) => {
triggerBg: Ref<string>
) => {
return (color: Ref<Color>) => { return (color: Ref<Color>) => {
triggerBg.value = color.value.getHex(); triggerBg.value = color.value.getHex()
} }
} }

View File

@ -40,7 +40,7 @@ export default class Color {
private s = 0 private s = 0
private v = 0 private v = 0
private a = 100 private a = 100
private preH = 0; private preH = 0
private enableAlpha = false private enableAlpha = false
constructor(value: string, alpha = false) { constructor(value: string, alpha = false) {
this.reset(value) this.reset(value)
@ -62,16 +62,18 @@ export default class Color {
this.s = s this.s = s
this.v = v this.v = v
this.a = a this.a = a
this.preH = h; this.preH = h
} }
set({ h, s, v, a }: { h?: number; s?: number; v?: number; a?: number }) { set({ h, s, v, a }: { h?: number; s?: number; v?: number; a?: number }) {
this.h = h ?? this.h this.h = h ?? this.h
this.s = s ?? this.s this.s = s ?? this.s
this.v = v ?? this.v this.v = v ?? this.v
this.a = a ?? this.a this.a = a ?? this.a
} }
setPrevH(val: number){
this.preH = val; setPrevH(val: number) {
this.preH = val
} }
/** /**
@ -108,7 +110,7 @@ export default class Color {
} }
} }
get(key: 'h' | 's' | 'v' | 'a' |'preH') { get(key: 'h' | 's' | 'v' | 'a' | 'preH') {
return this[key] return this[key]
} }
} }

View File

@ -1,4 +1,4 @@
import { IColorSelectPanelRef as Ref } from '@/types' import type { IColorSelectPanelRef as Ref } from '@/types'
import Color from './utils/color' import Color from './utils/color'
import { onConfirm, onCancel, onHueUpdate, onSVUpdate, onColorUpdate } from './index' import { onConfirm, onCancel, onHueUpdate, onSVUpdate, onColorUpdate } from './index'
@ -25,12 +25,8 @@ export const renderless = (props, context, { emit }) => {
const changeVisible = (state: boolean) => { const changeVisible = (state: boolean) => {
isShow.value = state isShow.value = state
} }
const stack: Ref<string[]> = context.ref( const stack: Ref<string[]> = context.ref([...(history?.value ?? [])])
[...(history?.value ?? [])] const predefineStack: Ref<string[]> = context.ref([...(predefine?.value ?? [])])
)
const predefineStack: Ref<string[]> = context.ref(
[...(predefine?.value ?? [])]
)
const state = context.reactive({ const state = context.reactive({
isShow, isShow,
hex, hex,
@ -49,19 +45,27 @@ export const renderless = (props, context, { emit }) => {
onSVUpdate: onSVUpdate(tmpColor, triggerBg), onSVUpdate: onSVUpdate(tmpColor, triggerBg),
onColorUpdate: onColorUpdate(triggerBg) onColorUpdate: onColorUpdate(triggerBg)
} }
context.watch(predefine, (newPredefine: string[]) => { context.watch(
predefineStack.value = [...newPredefine] predefine,
}, { deep: true }) (newPredefine: string[]) => {
context.watch(history, (newHistory: string[]) => { predefineStack.value = [...newPredefine]
stack.value = [...newHistory] },
}, { deep: true }) { deep: true }
context.watch(modelValue, (newValue)=>{ )
context.watch(
history,
(newHistory: string[]) => {
stack.value = [...newHistory]
},
{ deep: true }
)
context.watch(modelValue, (newValue) => {
pre.value = newValue pre.value = newValue
hex.value = newValue hex.value = newValue
state.hex = newValue state.hex = newValue
state.triggerBg = newValue; state.triggerBg = newValue
}) })
context.watch(visible, (visible)=>{ context.watch(visible, (visible) => {
isShow.value = visible isShow.value = visible
}) })
return api return api

View File

@ -1,12 +1,12 @@
import { IColorSelectPanelRef as Ref } from '@/types' import type { IColorSelectPanelRef as Ref } from '@/types'
import Color from '../utils/color' import type Color from '../utils/color'
import { draggable } from '../utils/use-drag' import { draggable } from '../utils/use-drag'
import { onDrag, updateThumb } from '.' import { onDrag, updateThumb } from '.'
export const api = ['state', 'color', 'slider', 'alphaWrapper', 'alphaThumb'] export const api = ['state', 'color', 'slider', 'alphaWrapper', 'alphaThumb']
export const renderless = (props, context, { emit }) => { export const renderless = (props, context, { emit }) => {
const color:Color = props.color const color: Color = props.color
const [rr, gg, bb] = color.getRGB() const [rr, gg, bb] = color.getRGB()
const r = context.ref(rr) const r = context.ref(rr)
const g = context.ref(gg) const g = context.ref(gg)
@ -23,7 +23,8 @@ export const renderless = (props, context, { emit }) => {
g.value = gg g.value = gg
b.value = bb b.value = bb
alpha.value = color.get('a') alpha.value = color.get('a')
}, {deep: true} },
{ deep: true }
) )
context.watch(alpha, (newAlpha) => { context.watch(alpha, (newAlpha) => {
updateThumb(newAlpha, alphaThumb.value, alphaWrapper.value) updateThumb(newAlpha, alphaThumb.value, alphaWrapper.value)
@ -33,7 +34,7 @@ export const renderless = (props, context, { emit }) => {
return `linear-gradient(to right, rgba(${r.value}, ${g.value}, ${b.value}, 0) 0%, rgba(${r.value}, ${g.value}, ${b.value}, 1) 100%)` return `linear-gradient(to right, rgba(${r.value}, ${g.value}, ${b.value}, 0) 0%, rgba(${r.value}, ${g.value}, ${b.value}, 1) 100%)`
}) })
const state = context.reactive({ const state = context.reactive({
background, background
}) })
const api = { const api = {
state, state,

View File

@ -1,4 +1,4 @@
import { IColorSelectPanelRef } from '@/types' import type { IColorSelectPanelRef } from '@/types'
import type Color from '../utils/color' import type Color from '../utils/color'
export const setPosition = (el: HTMLElement, x: number, y: number) => { export const setPosition = (el: HTMLElement, x: number, y: number) => {

View File

@ -1,7 +1,7 @@
import { IColorSelectPanelRef as Ref } from '@/types' import type { IColorSelectPanelRef as Ref } from '@/types'
import { draggable } from '../utils/use-drag' import { draggable } from '../utils/use-drag'
import { getThumbTop, resetCursor, updateThumb, updateCursor } from './index' import { getThumbTop, resetCursor, updateThumb, updateCursor } from './index'
import Color from '../utils/color' import type Color from '../utils/color'
export const api = ['state', 'cursor', 'wrapper', 'bar', 'thumb'] export const api = ['state', 'cursor', 'wrapper', 'bar', 'thumb']
export const renderless = (props, context, { emit, expose }) => { export const renderless = (props, context, { emit, expose }) => {
@ -9,20 +9,24 @@ export const renderless = (props, context, { emit, expose }) => {
const wrapper: Ref<HTMLElement> = context.ref() const wrapper: Ref<HTMLElement> = context.ref()
const thumb: Ref<HTMLElement> = context.ref() const thumb: Ref<HTMLElement> = context.ref()
const bar: Ref<HTMLElement> = context.ref() const bar: Ref<HTMLElement> = context.ref()
const color:Color = props.color const color: Color = props.color
const h = context.ref(color.get('h')) const h = context.ref(color.get('h'))
const background:string = `hsl(${h.value}deg, 100%, 50%)` const background: string = `hsl(${h.value}deg, 100%, 50%)`
const state = context.reactive({ const state = context.reactive({
background background
}) })
const api = { state, cursor, wrapper, bar, thumb } const api = { state, cursor, wrapper, bar, thumb }
context.watch(()=>props, ()=>{ context.watch(
h.value = color.get('h') () => props,
resetCursor(color.get('s'), color.get('v'), wrapper, cursor, thumb, color, h) () => {
}, {deep: true}) h.value = color.get('h')
context.watch(h,(newHue: string) => { resetCursor(color.get('s'), color.get('v'), wrapper, cursor, thumb, color, h)
},
{ deep: true }
)
context.watch(h, (newHue: string) => {
state.background = `hsl(${newHue}deg, 100%, 50%)` state.background = `hsl(${newHue}deg, 100%, 50%)`
}) })
context.onMounted(() => { context.onMounted(() => {

View File

@ -1,4 +1,4 @@
import { IColorSelectPanelRef } from '@/types' import type { IColorSelectPanelRef } from '@/types'
import Color from './utils/color' import Color from './utils/color'
export const onConfirm = ( export const onConfirm = (
@ -95,7 +95,7 @@ export const handleHistoryClick = (
res.value = history res.value = history
const tmpColor = new Color(history) const tmpColor = new Color(history)
color.value.set({ color.value.set({
...tmpColor.getHSV(), ...tmpColor.getHSV()
}) })
emit('color-update', color) emit('color-update', color)
} }
@ -112,7 +112,7 @@ export const handlePredefineClick = (
res.value = selectedColor res.value = selectedColor
const tmpColor = new Color(selectedColor) const tmpColor = new Color(selectedColor)
color.value.set({ color.value.set({
...tmpColor.getHSV(), ...tmpColor.getHSV()
}) })
emit('color-update', color) emit('color-update', color)
} }

View File

@ -64,13 +64,15 @@ export default class Color {
this.v = v this.v = v
this.a = a this.a = a
} }
set({ h, s, v, a }: { h?: number; s?: number; v?: number; a?: number }) { set({ h, s, v, a }: { h?: number; s?: number; v?: number; a?: number }) {
this.h = h ?? this.h this.h = h ?? this.h
this.s = s ?? this.s this.s = s ?? this.s
this.v = v ?? this.v this.v = v ?? this.v
this.a = a ?? this.a this.a = a ?? this.a
} }
setPrevH(val: number){
setPrevH(val: number) {
this.preH = val this.preH = val
} }
@ -108,7 +110,7 @@ export default class Color {
} }
} }
get(key: 'h' | 's' | 'v' | 'a' |'preH') { get(key: 'h' | 's' | 'v' | 'a' | 'preH') {
return this[key] return this[key]
} }
} }

View File

@ -1,4 +1,4 @@
import { IColorSelectPanelRef as Ref } from '@/types' import type { IColorSelectPanelRef as Ref } from '@/types'
import Color from './utils/color' import Color from './utils/color'
import { onConfirm, onCancel, onHSVUpdate, onAlphaUpdate, handleHistoryClick, handlePredefineClick } from '.' import { onConfirm, onCancel, onHSVUpdate, onAlphaUpdate, handleHistoryClick, handlePredefineClick } from '.'
@ -31,7 +31,7 @@ export const renderless = (props, context, { emit }) => {
const changeVisible = (state: boolean) => { const changeVisible = (state: boolean) => {
isShow.value = state isShow.value = state
} }
const color:Ref<Color> = context.ref(new Color(hex.value, props.alpha)) const color: Ref<Color> = context.ref(new Color(hex.value, props.alpha))
const state = context.reactive({ const state = context.reactive({
isShow, isShow,
hex, hex,
@ -58,9 +58,13 @@ export const renderless = (props, context, { emit }) => {
}, },
{ deep: true } { deep: true }
) )
context.watch(state,()=>{ context.watch(
state.color = state.color state,
}, {deep: true}) () => {
state.color = state.color
},
{ deep: true }
)
context.watch(modelValue, (newValue) => { context.watch(modelValue, (newValue) => {
pre.value = res.value pre.value = res.value
hex.value = newValue hex.value = newValue

View File

@ -186,7 +186,7 @@ export class BigIntDecimal {
const trimRet = trimNumber(mergedValue) const trimRet = trimNumber(mergedValue)
this.negative = trimRet.negative this.negative = trimRet.negative
const numbers = trimRet.trimStr.split('.') const numbers = trimRet.trimStr.split('.')
this.integer = numbers[0].indexOf('e') === -1 ? BigInt(numbers[0]) : numbers[0] this.integer = !numbers[0].includes('e') ? BigInt(numbers[0]) : numbers[0]
const decimalStr = numbers[1] || '0' const decimalStr = numbers[1] || '0'
this.decimal = convertBigInt(decimalStr) this.decimal = convertBigInt(decimalStr)
this.decimalLen = decimalStr.length this.decimalLen = decimalStr.length

View File

@ -97,8 +97,8 @@ export const getCalendar = (year, month) => {
end: lastDays end: lastDays
}, },
current: { current: {
year: year, year,
month: month, month,
start: 1, start: 1,
end: days end: days
}, },

View File

@ -116,7 +116,7 @@ const camelizeRE = /-(\w)/g
const camelize = cached((str) => str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))) const camelize = cached((str) => str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')))
/** TINY_DUP dom.ts*/ /** TINY_DUP dom.ts */
const getElementStyle = (elem, styleKey) => { const getElementStyle = (elem, styleKey) => {
if (!elem || !styleKey) return '' if (!elem || !styleKey) return ''
@ -136,13 +136,13 @@ const getElementStyle = (elem, styleKey) => {
return elem.style[key] return elem.style[key]
} }
} }
/** TINY_DUP dom.ts*/ /** TINY_DUP dom.ts */
const canScroll = (el, isVertical) => { const canScroll = (el, isVertical) => {
const overflowKey = { undefined: 'overflow', true: 'overflow-y', false: 'overflow-x' }[String(isVertical)] const overflowKey = { undefined: 'overflow', true: 'overflow-y', false: 'overflow-x' }[String(isVertical)]
const overflowVal = getElementStyle(el, overflowKey) const overflowVal = getElementStyle(el, overflowKey)
return ['scroll', 'auto', 'overlay'].some((s) => overflowVal.includes(s)) return ['scroll', 'auto', 'overlay'].some((s) => overflowVal.includes(s))
} }
/** TINY_DUP dom.ts*/ /** TINY_DUP dom.ts */
export const getScrollContainer = (el, isVertical) => { export const getScrollContainer = (el, isVertical) => {
let parentEl = el let parentEl = el

View File

@ -132,8 +132,8 @@ const getOffsetRectRelativeToCustomParent = (el: HTMLElement, parent: HTMLElemen
// 如果是fixed定位直接返回相对视口位置 // 如果是fixed定位直接返回相对视口位置
if (fixed) { if (fixed) {
return { return {
top: top, top,
left: left, left,
bottom: top + height, bottom: top + height,
right: left + width, right: left + width,
width, width,
@ -357,10 +357,12 @@ class Popper {
return this return this
} }
onUpdate(callback) { onUpdate(callback) {
this.state.updateCallback = callback this.state.updateCallback = callback
return this return this
} }
update() { update() {
let data = { instance: this, styles: {} } as unknown as UpdateData let data = { instance: this, styles: {} } as unknown as UpdateData
@ -374,6 +376,7 @@ class Popper {
typeof this.state.updateCallback === 'function' && this.state.updateCallback(data) typeof this.state.updateCallback === 'function' && this.state.updateCallback(data)
} }
/** 按顺序执行Modifiers 如果传入终点modifier,则执行到指定位置 */ /** 按顺序执行Modifiers 如果传入终点modifier,则执行到指定位置 */
runModifiers(data: UpdateData, modifiers: Function[], ends?: Function) { runModifiers(data: UpdateData, modifiers: Function[], ends?: Function) {
let modifiersToRun = modifiers.slice() let modifiersToRun = modifiers.slice()
@ -394,6 +397,7 @@ class Popper {
return data return data
} }
// 此时才把offsets.popper 赋值给popper dom, offsets.array赋值给array dom // 此时才把offsets.popper 赋值给popper dom, offsets.array赋值给array dom
applyStyle(data: UpdateData) { applyStyle(data: UpdateData) {
let styles: any = { position: data.offsets.popper.position } let styles: any = { position: data.offsets.popper.position }
@ -416,6 +420,7 @@ class Popper {
return data return data
} }
// 判断 placement是不是2段式的是则处理一下偏移。 修改data.offsets.popper的值 // 判断 placement是不是2段式的是则处理一下偏移。 修改data.offsets.popper的值
shift(data: UpdateData) { shift(data: UpdateData) {
let placement = data.placement let placement = data.placement
@ -444,6 +449,7 @@ class Popper {
return data return data
} }
// 校正popper的位置在boundaries 的内部 // 校正popper的位置在boundaries 的内部
preventOverflow(data: UpdateData) { preventOverflow(data: UpdateData) {
let order = this._options.preventOverflowOrder let order = this._options.preventOverflowOrder
@ -493,6 +499,7 @@ class Popper {
}) })
return data return data
} }
// 校正popper的位置在reference的边上。 如果2个分离了重新调整popper的位置。 可能是担心 modifiers.offset 带来的副作用吧 // 校正popper的位置在reference的边上。 如果2个分离了重新调整popper的位置。 可能是担心 modifiers.offset 带来的副作用吧
keepTogether(data: UpdateData) { keepTogether(data: UpdateData) {
let popper = getPopperClientRect(data.offsets.popper) let popper = getPopperClientRect(data.offsets.popper)
@ -516,6 +523,7 @@ class Popper {
return data return data
} }
// 根据flip的策略计算当前应该显示的位置。 空间不够要计算出flip的位置。 可能是担心preventOverflow 时造成pop, reference会重叠。 重叠了就要flip一下 // 根据flip的策略计算当前应该显示的位置。 空间不够要计算出flip的位置。 可能是担心preventOverflow 时造成pop, reference会重叠。 重叠了就要flip一下
flip(data: UpdateData) { flip(data: UpdateData) {
// 只翻转一次避免重复的flip // 只翻转一次避免重复的flip
@ -563,6 +571,7 @@ class Popper {
}) })
return data return data
} }
// 根据入参option上的offset, 给data.offset.popper进行校正 // 根据入参option上的offset, 给data.offset.popper进行校正
offset(data: UpdateData) { offset(data: UpdateData) {
let offset = this._options.offset let offset = this._options.offset
@ -580,6 +589,7 @@ class Popper {
return data return data
} }
// 计算arrow的位置,保存在data.offsets.arrow ={top,left} // 计算arrow的位置,保存在data.offsets.arrow ={top,left}
arrow(data: UpdateData) { arrow(data: UpdateData) {
let arrow: string | HTMLElement = this._options.arrowElement // 小三角的dom let arrow: string | HTMLElement = this._options.arrowElement // 小三角的dom
@ -650,6 +660,7 @@ class Popper {
let isParentFixed = isFixed(reference) let isParentFixed = isFixed(reference)
return isParentFixed ? 'fixed' : 'absolute' return isParentFixed ? 'fixed' : 'absolute'
} }
/** 实时计算一下popper, reference的 位置信息, 用于 */ /** 实时计算一下popper, reference的 位置信息, 用于 */
_getRefPopOffsets(popper, reference, placement) { _getRefPopOffsets(popper, reference, placement) {
placement = placement.split('-')[0] placement = placement.split('-')[0]
@ -689,6 +700,7 @@ class Popper {
reference: referenceOffsets reference: referenceOffsets
} }
} }
_setupEventListeners() { _setupEventListeners() {
this.state.updateBoundFn = this.update.bind(this) this.state.updateBoundFn = this.update.bind(this)
@ -715,6 +727,7 @@ class Popper {
} }
} }
} }
_removeEventListeners() { _removeEventListeners() {
off(window, 'resize', this.state.updateBoundFn) off(window, 'resize', this.state.updateBoundFn)
@ -735,6 +748,7 @@ class Popper {
this.state.updateBoundFn = null as any this.state.updateBoundFn = null as any
} }
/** 实时计算一下Boundary的位置 */ /** 实时计算一下Boundary的位置 */
_getBoundaries(data: UpdateData, padding: number, boundariesElement: string | HTMLElement) { _getBoundaries(data: UpdateData, padding: number, boundariesElement: string | HTMLElement) {
let boundaries = { right: 0, left: 0, top: 0, bottom: 0 } let boundaries = { right: 0, left: 0, top: 0, bottom: 0 }

View File

@ -74,19 +74,19 @@ const triggerTouch = (eventName, mouseEv) => {
} }
const onMouse = (touchType) => (ev) => { const onMouse = (touchType) => (ev) => {
if ('mousedown' === ev.type) { if (ev.type === 'mousedown') {
initiated = true initiated = true
} }
if ('mouseup' === ev.type) { if (ev.type === 'mouseup') {
initiated = false initiated = false
} }
if ('mousemove' === ev.type && !initiated) { if (ev.type === 'mousemove' && !initiated) {
return return
} }
if ('mousedown' === ev.type || !mouseTarget) { if (ev.type === 'mousedown' || !mouseTarget) {
mouseTarget = ev.target mouseTarget = ev.target
} }
@ -94,7 +94,7 @@ const onMouse = (touchType) => (ev) => {
triggerTouch(touchType, ev) triggerTouch(touchType, ev)
} }
if ('mouseup' === ev.type) { if (ev.type === 'mouseup') {
eventTarget = null eventTarget = null
mouseTarget = null mouseTarget = null
} }

View File

@ -401,7 +401,7 @@ export default class TreeStore {
getAllData() { getAllData() {
const children = this.props.children const children = this.props.children
const walkTree = (nodes) => { const walkTree = (nodes) => {
return nodes.map(node => { return nodes.map((node) => {
return { ...node.data, [children]: walkTree(node.childNodes) } return { ...node.data, [children]: walkTree(node.childNodes) }
}) })
} }

View File

@ -13,8 +13,8 @@
import PopupManager from './popup-manager' import PopupManager from './popup-manager'
import PopperJS from './popper' import PopperJS from './popper'
import { on } from './dom' import { on } from './dom'
import { ISharedRenderlessFunctionParams } from 'types/shared.type' import type { ISharedRenderlessFunctionParams } from 'types/shared.type'
import Popper from './popper' import type Popper from './popper'
interface IPopperState { interface IPopperState {
popperJS: Popper popperJS: Popper
@ -167,7 +167,7 @@ export default (options: IPopperInputParams) => {
state.popperJS = null as any state.popperJS = null as any
} }
/** remove时执行真的移除popper dom操作。*/ /** remove时执行真的移除popper dom操作。 */
const destroyPopper = (remove: 'remove' | boolean) => { const destroyPopper = (remove: 'remove' | boolean) => {
if (remove) { if (remove) {
if (state.popperElm) { if (state.popperElm) {

View File

@ -13,7 +13,7 @@
import { merge } from '../object' import { merge } from '../object'
import PopupManager from './popup-manager' import PopupManager from './popup-manager'
import { addClass } from './dom' import { addClass } from './dom'
import { ISharedRenderlessFunctionParams } from 'types/shared.type' import type { ISharedRenderlessFunctionParams } from 'types/shared.type'
let idSeed = 1 let idSeed = 1
const isServer = typeof window === 'undefined' const isServer = typeof window === 'undefined'

View File

@ -57,5 +57,5 @@ export const getActualTarget = (e) => {
if (!e || !e.target) { if (!e || !e.target) {
return null return null
} }
return (e.target.shadowRoot && e.composed) ? (e.composedPath()[0] || e.target) : e.target return e.target.shadowRoot && e.composed ? e.composedPath()[0] || e.target : e.target
} }

View File

@ -127,7 +127,8 @@ export const DATE = {
YearMonth: 'yyyy-MM' YearMonth: 'yyyy-MM'
} }
const TriggerTypes = 'date,datetime,time,time-select,week,month,year,years,yearrange,daterange,monthrange,timerange,datetimerange,dates' const TriggerTypes =
'date,datetime,time,time-select,week,month,year,years,yearrange,daterange,monthrange,timerange,datetimerange,dates'
export const DATEPICKER = { export const DATEPICKER = {
Day: 'day', Day: 'day',

View File

@ -376,7 +376,7 @@ Schema.prototype = {
} }
} }
/**注册的新类型的检验 */ /** 注册的新类型的检验 */
Schema.register = (type, validator) => { Schema.register = (type, validator) => {
if (typeof validator !== 'function') { if (typeof validator !== 'function') {
throw new TypeError('Cannot register a validator by type, validator is not a function') throw new TypeError('Cannot register a validator by type, validator is not a function')

View File

@ -42,11 +42,11 @@ export const getYearLabel =
if (state.currentView === Year) { if (state.currentView === Year) {
const startYear = state.startYear const startYear = state.startYear
if (yearTranslation) { if (yearTranslation) {
return startYear + ' ' + yearTranslation + ' - ' + (startYear + PanelYearNum - 1) + ' ' + yearTranslation return startYear + ' ' + yearTranslation + ' - ' + (startYear + PanelYearNum - 1) + ' ' + yearTranslation
} }
return startYear + ' - ' + (startYear + PanelYearNum - 1) return startYear + ' - ' + (startYear + PanelYearNum - 1)
} }
@ -286,7 +286,7 @@ export const handleYearPick =
api.cusEmit(state.date) api.cusEmit(state.date)
} else if ([DATEPICKER.Years].includes(state.selectionMode)) { } else if ([DATEPICKER.Years].includes(state.selectionMode)) {
state.date = value.map((year) => new Date(year, 0, 2)) state.date = value.map((year) => new Date(year, 0, 2))
api.cusEmit(state.date, state.selectionMode === DATEPICKER.YearRange ? value.length < 2 : true) api.cusEmit(state.date, state.selectionMode === DATEPICKER.YearRange ? value.length < 2 : true)
} else { } else {
state.date = changeYearMonthAndClampDate(state.date, value, state.month) state.date = changeYearMonthAndClampDate(state.date, value, state.month)

View File

@ -24,37 +24,41 @@ export const getDateStr = (year, month, day = '01', seperator = '/') => {
return arr.join(seperator) return arr.join(seperator)
} }
export const getCurrentDate = ({ api, props }) => (dateValue) => { export const getCurrentDate =
const today = new Date() ({ api, props }) =>
const theDate = new Date(dateValue) (dateValue) => {
const year = theDate.getFullYear() const today = new Date()
const month = theDate.getMonth() + 1 const theDate = new Date(dateValue)
const day = theDate.getDate() const year = theDate.getFullYear()
const yearMonth = getDateStr(year, month) const month = theDate.getMonth() + 1
const day = theDate.getDate()
const yearMonth = getDateStr(year, month)
const startWeek = new Date(year, month - 1, 1).getDay() const startWeek = new Date(year, month - 1, 1).getDay()
const index = startWeek + day - 1 const index = startWeek + day - 1
const { disabledDate } = props.pickerOptions || {} const { disabledDate } = props.pickerOptions || {}
return { return {
value: api.formatDate(theDate), value: api.formatDate(theDate),
yearMonth: yearMonth, yearMonth,
index, index,
day, day,
year, year,
month, month,
isStartDay: false, isStartDay: false,
isEndDay: false, isEndDay: false,
disabled: typeof disabledDate === 'function' && !!disabledDate(theDate), disabled: typeof disabledDate === 'function' && !!disabledDate(theDate),
isToday: isSameDay(today, theDate) isToday: isSameDay(today, theDate)
}
} }
}
export const formatDate = ({ props, constants }) => (date, dateFormat) => { export const formatDate =
const { YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE ({ props, constants }) =>
const defaultFormet = [YEAR_MONTH_RANGE, YEAR_MONTH].includes(props.type) ? 'yyyy/MM/01' : 'yyyy/MM/dd' (date, dateFormat) => {
return format(date, dateFormat === undefined ? defaultFormet : dateFormat) const { YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE
} const defaultFormet = [YEAR_MONTH_RANGE, YEAR_MONTH].includes(props.type) ? 'yyyy/MM/01' : 'yyyy/MM/dd'
return format(date, dateFormat === undefined ? defaultFormet : dateFormat)
}
const getDateFromStr = (dateStr, direction = 'top') => { const getDateFromStr = (dateStr, direction = 'top') => {
const arr = dateStr.split('/').map((item) => +item) const arr = dateStr.split('/').map((item) => +item)
@ -63,294 +67,326 @@ const getDateFromStr = (dateStr, direction = 'top') => {
return new Date(yarr, month, 1) return new Date(yarr, month, 1)
} }
export const loadingDate = ({ state, api }) => (direction) => { export const loadingDate =
const list = Object.keys(state.dateList) ({ state, api }) =>
(direction) => {
const list = Object.keys(state.dateList)
const value = direction === 'top' ? list[0] : list[list.length - 1] const value = direction === 'top' ? list[0] : list[list.length - 1]
const date = getDateFromStr(value, direction) const date = getDateFromStr(value, direction)
api.initPanel({ dateValue: date, direction }) api.initPanel({ dateValue: date, direction })
setTimeout(() => { setTimeout(() => {
state.loading = false state.loading = false
}, 100) }, 100)
}
export const initPanel = ({ state, api }) => ({ dateValue, direction, isInit }) => {
const currentDate = dateValue || (Array.isArray(state.date) ? state.date[0] : state.date) || new Date()
let month = currentDate.getMonth() + 1
let year = direction === 'top' ? currentDate.getFullYear() - state.yearNum : currentDate.getFullYear()
if (isInit) {
// init component
year -= Math.floor(state.yearNum / 2)
} }
let date = new Date(year, month - 1, 1) // 加载日历的起始日期 export const initPanel =
const dateList = {} ({ state, api }) =>
({ dateValue, direction, isInit }) => {
const currentDate = dateValue || (Array.isArray(state.date) ? state.date[0] : state.date) || new Date()
Array.from({ length: 12 * state.yearNum }).map(() => { let month = currentDate.getMonth() + 1
const startWeek = date.getDay() let year = direction === 'top' ? currentDate.getFullYear() - state.yearNum : currentDate.getFullYear()
dateList[getDateStr(year, month)] = Array.from({ length: startWeek }).map(() => ({}))
const days = getDaysByMonth(year, month)
Array.from({ length: days }).map((v, index) => { if (isInit) {
const day = index + 1 // init component
const dayInfo = api.getCurrentDate(new Date(year, month - 1, day)) year -= Math.floor(state.yearNum / 2)
dateList[getDateStr(year, month)].push(dayInfo)
})
month++
if (month > 12) {
year++
month = 1
} }
date = new Date(year, month - 1, 1) let date = new Date(year, month - 1, 1) // 加载日历的起始日期
}) const dateList = {}
state.dateList = Array.from({ length: 12 * state.yearNum }).map(() => {
direction === 'top' ? Object.assign({}, dateList, state.dateList) : Object.assign({}, state.dateList, dateList) const startWeek = date.getDay()
} dateList[getDateStr(year, month)] = Array.from({ length: startWeek }).map(() => ({}))
const days = getDaysByMonth(year, month)
export const getWeeksByMonth = ({ state }) => (yearMonth) => { Array.from({ length: days }).map((v, index) => {
const length = state.dateList[yearMonth].length const day = index + 1
return Math.ceil(length / 7) const dayInfo = api.getCurrentDate(new Date(year, month - 1, day))
}
export const getDaysByWeek = ({ state, api }) => (yearMonth, week) => { dateList[getDateStr(year, month)].push(dayInfo)
const length = state.dateList[yearMonth].length })
const weeks = api.getWeeksByMonth(yearMonth)
return week === weeks ? length % 7 : 7 month++
}
export const getDate = ({ state }) => ({ date, yearMonth, index }) => { if (month > 12) {
let currentDate year++
month = 1
if (date) {
const theDate = new Date(date)
const key = getDateStr(theDate.getFullYear(), theDate.getMonth + 1)
currentDate = state.dateList[key].filter((item) => item.day === theDate.getDate()).shift()
} else {
currentDate = state.dateList[yearMonth][index]
}
return currentDate || {}
}
export const getSelectedPosition = ({ state, api }) => (dateFormat) => {
const { selected } = state
const length = selected.length
if (!length) {
return ''
}
const index = selected.indexOf(api.formatDate(dateFormat))
return index === 0 ? 'start' : index === length - 1 ? 'end' : index > -1 ? 'inner' : ''
}
export const watchVisible = ({ emit, api, state }) => (bool) => {
if (bool) {
api.watchModelValue()
const currentDate = (Array.isArray(state.date) ? state.date[0] : state.date) || new Date()
setTimeout(() => api.scrollToCurrentDate({ date: currentDate }), 300)
}
emit('update:visible', bool)
}
export const scrollToCurrentDate = ({ state, vm, nextTick }) => ({ date, value }) => {
const { isYearMonthPanel, computedYears, months } = state
let field,
list,
year,
month,
index = -1
if (date) {
year = date.getFullYear()
month = date.getMonth() + 1
}
if (isYearMonthPanel) {
field = 'year'
value = value || `${year}`
list = computedYears
} else {
field = 'yearMonth'
value = value || getDateStr(year, month)
list = months
}
list.some((item, i) => {
if (item[field] === value) {
index = i
return true
}
return false
})
nextTick(() => {
index !== -1 && vm.$refs.recycleScroller.scrollToItem(index)
})
}
export const watchModelValue = ({ props, state, constants }) => () => {
const { DATE, DATE_TIME, DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE
const { modelValue, type } = props
if ([DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) {
state.date = modelValue && modelValue.length ? modelValue.map((date) => new Date(date)) : []
}
if ([DATE, DATE_TIME, YEAR_MONTH].includes(type)) {
state.date = modelValue ? new Date(modelValue) : ''
}
if ([DATE_TIME_RANGE, DATE_TIME].includes(type)) {
// sync date to time
const length = type === DATE_TIME ? 1 : 2
Array.from({ length }).forEach((v, index) => {
const date = type === DATE_TIME ? state.date : state.date[index]
if (date) {
state.timeList[index] = [
getFormatTime(date.getHours()),
getFormatTime(date.getMinutes()),
getFormatTime(date.getSeconds())
]
} }
date = new Date(year, month - 1, 1)
})
state.dateList =
direction === 'top' ? Object.assign({}, dateList, state.dateList) : Object.assign({}, state.dateList, dateList)
}
export const getWeeksByMonth =
({ state }) =>
(yearMonth) => {
const length = state.dateList[yearMonth].length
return Math.ceil(length / 7)
}
export const getDaysByWeek =
({ state, api }) =>
(yearMonth, week) => {
const length = state.dateList[yearMonth].length
const weeks = api.getWeeksByMonth(yearMonth)
return week === weeks ? length % 7 : 7
}
export const getDate =
({ state }) =>
({ date, yearMonth, index }) => {
let currentDate
if (date) {
const theDate = new Date(date)
const key = getDateStr(theDate.getFullYear(), theDate.getMonth + 1)
currentDate = state.dateList[key].filter((item) => item.day === theDate.getDate()).shift()
} else {
currentDate = state.dateList[yearMonth][index]
}
return currentDate || {}
}
export const getSelectedPosition =
({ state, api }) =>
(dateFormat) => {
const { selected } = state
const length = selected.length
if (!length) {
return ''
}
const index = selected.indexOf(api.formatDate(dateFormat))
return index === 0 ? 'start' : index === length - 1 ? 'end' : index > -1 ? 'inner' : ''
}
export const watchVisible =
({ emit, api, state }) =>
(bool) => {
if (bool) {
api.watchModelValue()
const currentDate = (Array.isArray(state.date) ? state.date[0] : state.date) || new Date()
setTimeout(() => api.scrollToCurrentDate({ date: currentDate }), 300)
}
emit('update:visible', bool)
}
export const scrollToCurrentDate =
({ state, vm, nextTick }) =>
({ date, value }) => {
const { isYearMonthPanel, computedYears, months } = state
let field
let list
let year
let month
let index = -1
if (date) {
year = date.getFullYear()
month = date.getMonth() + 1
}
if (isYearMonthPanel) {
field = 'year'
value = value || `${year}`
list = computedYears
} else {
field = 'yearMonth'
value = value || getDateStr(year, month)
list = months
}
list.some((item, i) => {
if (item[field] === value) {
index = i
return true
}
return false
})
nextTick(() => {
index !== -1 && vm.$refs.recycleScroller.scrollToItem(index)
}) })
} }
}
export const selectOption = ({ emit, state, props, constants }) => ({ value, index }) => { export const watchModelValue =
const { DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE ({ props, state, constants }) =>
const { type } = props () => {
const { dateList, years } = state const { DATE, DATE_TIME, DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE
const current = [YEAR_MONTH_RANGE, YEAR_MONTH].includes(type) ? years[value][index] : dateList[value][index] const { modelValue, type } = props
if ([DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) {
if (!current || current.disabled) { state.date = modelValue && modelValue.length ? modelValue.map((date) => new Date(date)) : []
return
}
if ([DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) {
if (state.date.length > 1) {
state.date = []
} }
state.date.push(new Date(current.value)) if ([DATE, DATE_TIME, YEAR_MONTH].includes(type)) {
state.date = modelValue ? new Date(modelValue) : ''
if (state.date.length === 2) {
state.date.sort((a, b) => a.getTime() - b.getTime())
} }
} else {
state.date = new Date(current.value)
emit('click', current) if ([DATE_TIME_RANGE, DATE_TIME].includes(type)) {
} // sync date to time
} const length = type === DATE_TIME ? 1 : 2
Array.from({ length }).forEach((v, index) => {
export const confirm = ({ emit, state, props, api, constants }) => () => { const date = type === DATE_TIME ? state.date : state.date[index]
const { DATE_TIME, DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE } = constants.TYPE if (date) {
const { date, timeList } = state state.timeList[index] = [
const { type } = props getFormatTime(date.getHours()),
getFormatTime(date.getMinutes()),
if ([DATE_TIME, DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) { getFormatTime(date.getSeconds())
// sync time to date ]
const length = type === DATE_TIME ? 1 : 2
Array.from({ length }).forEach((v, index) => {
let thisDate = type === DATE_TIME ? date : date[index]
if (thisDate) {
const currentDate = api.getCurrentDate(thisDate)
const time = timeList[index]
thisDate = new Date(currentDate.year, currentDate.month - 1, currentDate.day, time[0], time[1], time[2])
if (type === DATE_TIME) {
state.date = thisDate
} else {
state.date[index] = thisDate
} }
} })
}) }
} }
emit('confirm', state.date) export const selectOption =
emit('update:visible', false) ({ emit, state, props, constants }) =>
emit('update:modelValue', state.date) ({ value, index }) => {
} const { DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE
const { type } = props
const { dateList, years } = state
const current = [YEAR_MONTH_RANGE, YEAR_MONTH].includes(type) ? years[value][index] : dateList[value][index]
export const timeConfirm = ({ emit, state }) => (value) => { if (!current || current.disabled) {
state.timeVisible = false return
state.timeList[state.showTimeIndex] = value
emit('time-confirm', value)
}
export const timeToggle = ({ state }) => (index) => {
state.showTimeIndex = index
state.time = state.timeList[index]
state.timeVisible = true
}
export const selectedComputed = ({ state, props, constants, api }) => () => {
const { type } = props
const { DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE } = constants.TYPE
if ([DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) {
if (state.date && state.date.length) {
if (state.date.length === 1) {
return [api.formatDate(state.date[0])]
}
const list = []
let date1 = state.date[0].getTime()
let date2 = state.date[1].getTime()
while (date1 <= date2) {
const date = new Date(date1)
list.push(api.formatDate(date))
if (type === YEAR_MONTH_RANGE) {
date1 = api.getOffsetMonth(date, 1).getTime()
} else {
date1 += 3600 * 24 * 1000
}
}
return list
} }
return [] if ([DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) {
if (state.date.length > 1) {
state.date = []
}
state.date.push(new Date(current.value))
if (state.date.length === 2) {
state.date.sort((a, b) => a.getTime() - b.getTime())
}
} else {
state.date = new Date(current.value)
emit('click', current)
}
} }
return state.date ? [api.formatDate(state.date)] : [] export const confirm =
} ({ emit, state, props, api, constants }) =>
() => {
const { DATE_TIME, DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE } = constants.TYPE
const { date, timeList } = state
const { type } = props
export const scrollStart = ({ state, api, props }) => () => { if ([DATE_TIME, DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) {
if (state.loading || !props.visible || !state.ready) { // sync time to date
return const length = type === DATE_TIME ? 1 : 2
Array.from({ length }).forEach((v, index) => {
let thisDate = type === DATE_TIME ? date : date[index]
if (thisDate) {
const currentDate = api.getCurrentDate(thisDate)
const time = timeList[index]
thisDate = new Date(currentDate.year, currentDate.month - 1, currentDate.day, time[0], time[1], time[2])
if (type === DATE_TIME) {
state.date = thisDate
} else {
state.date[index] = thisDate
}
}
})
}
emit('confirm', state.date)
emit('update:visible', false)
emit('update:modelValue', state.date)
} }
state.loading = true export const timeConfirm =
const value = state.isYearMonthPanel ? state.computedYears[1].year : state.months[1].yearMonth ({ emit, state }) =>
(value) => {
state.timeVisible = false
state.timeList[state.showTimeIndex] = value
state.isYearMonthPanel ? api.loadYearMonth('top') : api.loadingDate('top') emit('time-confirm', value)
api.scrollToCurrentDate({ value })
}
export const scrollEnd = ({ state, api }) => () => {
if (state.loading) {
return
} }
state.loading = true export const timeToggle =
state.isYearMonthPanel ? api.loadYearMonth('down') : api.loadingDate('down') ({ state }) =>
} (index) => {
state.showTimeIndex = index
state.time = state.timeList[index]
state.timeVisible = true
}
export const selectedComputed =
({ state, props, constants, api }) =>
() => {
const { type } = props
const { DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE } = constants.TYPE
if ([DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE].includes(type)) {
if (state.date && state.date.length) {
if (state.date.length === 1) {
return [api.formatDate(state.date[0])]
}
const list = []
let date1 = state.date[0].getTime()
let date2 = state.date[1].getTime()
while (date1 <= date2) {
const date = new Date(date1)
list.push(api.formatDate(date))
if (type === YEAR_MONTH_RANGE) {
date1 = api.getOffsetMonth(date, 1).getTime()
} else {
date1 += 3600 * 24 * 1000
}
}
return list
}
return []
}
return state.date ? [api.formatDate(state.date)] : []
}
export const scrollStart =
({ state, api, props }) =>
() => {
if (state.loading || !props.visible || !state.ready) {
return
}
state.loading = true
const value = state.isYearMonthPanel ? state.computedYears[1].year : state.months[1].yearMonth
state.isYearMonthPanel ? api.loadYearMonth('top') : api.loadingDate('top')
api.scrollToCurrentDate({ value })
}
export const scrollEnd =
({ state, api }) =>
() => {
if (state.loading) {
return
}
state.loading = true
state.isYearMonthPanel ? api.loadYearMonth('down') : api.loadingDate('down')
}

View File

@ -36,11 +36,7 @@ export const api = [
'formatDate' 'formatDate'
] ]
export const renderless = ( export const renderless = (props, { computed, reactive, watch, onMounted }, { emit, vm, nextTick, constants }) => {
props,
{ computed, reactive, watch, onMounted },
{ emit, vm, nextTick, constants }
) => {
const { DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE const { DATE_RANGE, DATE_TIME_RANGE, YEAR_MONTH_RANGE, YEAR_MONTH } = constants.TYPE
const api = {} const api = {}
const state = reactive({ const state = reactive({

View File

@ -1,52 +1,56 @@
import { getDateStr } from './index' import { getDateStr } from './index'
export const initYearMonthPanel = ({ state, props }) => ({ dateValue, direction, isInit }) => { export const initYearMonthPanel =
const years = [] ({ state, props }) =>
const currentDate = dateValue || (Array.isArray(state.date) ? state.date[0] : state.date) || new Date() ({ dateValue, direction, isInit }) => {
let year = direction === 'top' ? currentDate.getFullYear() - state.yearNum : currentDate.getFullYear() const years = []
const today = new Date() const currentDate = dateValue || (Array.isArray(state.date) ? state.date[0] : state.date) || new Date()
const thisYear = today.getFullYear() let year = direction === 'top' ? currentDate.getFullYear() - state.yearNum : currentDate.getFullYear()
const thisMonth = today.getMonth() + 1 const today = new Date()
const { disabledDate } = props.pickerOptions || {} const thisYear = today.getFullYear()
const thisMonth = today.getMonth() + 1
const { disabledDate } = props.pickerOptions || {}
if (isInit) { if (isInit) {
// init component // init component
year -= Math.floor(state.yearNum / 2) year -= Math.floor(state.yearNum / 2)
} }
Array.from({ length: state.yearNum }).map((item, index) => { Array.from({ length: state.yearNum }).map((item, index) => {
const currentYear = year + index + 1 const currentYear = year + index + 1
years[currentYear] = Array.from({ length: 12 }).map((v, index2) => { years[currentYear] = Array.from({ length: 12 }).map((v, index2) => {
const month = index2 + 1 const month = index2 + 1
return { return {
value: getDateStr(currentYear, month), value: getDateStr(currentYear, month),
year: currentYear, year: currentYear,
month: month, month,
disabled: typeof disabledDate === 'function' && !!disabledDate(new Date(currentYear, month - 1, 1)), disabled: typeof disabledDate === 'function' && !!disabledDate(new Date(currentYear, month - 1, 1)),
isToday: thisYear === currentYear && thisMonth === month isToday: thisYear === currentYear && thisMonth === month
} }
})
}) })
})
state.years = direction === 'top' ? Object.assign({}, years, state.years) : Object.assign({}, state.years, years) state.years = direction === 'top' ? Object.assign({}, years, state.years) : Object.assign({}, state.years, years)
}
export const loadYearMonth = ({ state, api }) => (direction) => {
const list = Object.keys(state.years)
let date
if (direction === 'top') {
date = new Date(list[0], 0, 1)
} else {
date = new Date(list[list.length - 1], 0, 1)
} }
api.initYearMonthPanel({ dateValue: date, direction }) export const loadYearMonth =
({ state, api }) =>
(direction) => {
const list = Object.keys(state.years)
let date
setTimeout(() => { if (direction === 'top') {
state.loading = false date = new Date(list[0], 0, 1)
}, 100) } else {
} date = new Date(list[list.length - 1], 0, 1)
}
api.initYearMonthPanel({ dateValue: date, direction })
setTimeout(() => {
state.loading = false
}, 100)
}
// 获取偏移量月份 // 获取偏移量月份
export const getOffsetMonth = () => (date, offset) => { export const getOffsetMonth = () => (date, offset) => {

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
IDatePickerColumn, IDatePickerColumn,
IDatePickerConstants, IDatePickerConstants,
IDatePickerOriginColumn, IDatePickerOriginColumn,
@ -19,8 +19,10 @@ import {
IDatePickerState IDatePickerState
} from '@/types' } from '@/types'
export const getMonthEndDay = (constants: IDatePickerConstants) => (year: number, month: number): number => export const getMonthEndDay =
constants.MonthDay - new Date(year, month - 1, constants.MonthDay).getDate() (constants: IDatePickerConstants) =>
(year: number, month: number): number =>
constants.MonthDay - new Date(year, month - 1, constants.MonthDay).getDate()
export const getTrueValue = (value: string): number => { export const getTrueValue = (value: string): number => {
if (!value) { if (!value) {
@ -40,7 +42,10 @@ export const getTrueValue = (value: string): number => {
export const getBoundary = export const getBoundary =
({ api, constants, props }: Pick<IDatePickerRenderlessParams, 'api' | 'constants' | 'props'>) => ({ api, constants, props }: Pick<IDatePickerRenderlessParams, 'api' | 'constants' | 'props'>) =>
({ type, value: val }: { ({
type,
value: val
}: {
type: string type: string
value: Date value: Date
}): { }): {
@ -83,7 +88,13 @@ export const getBoundary =
} }
export const updateInnerValue = export const updateInnerValue =
({ api, constants, props, refs, state }: Pick<IDatePickerRenderlessParams, 'api' | 'constants' | 'props' | 'refs' | 'state'>) => ({
api,
constants,
props,
refs,
state
}: Pick<IDatePickerRenderlessParams, 'api' | 'constants' | 'props' | 'refs' | 'state'>) =>
() => { () => {
const indexes = refs.picker && refs.picker.getIndexes() const indexes = refs.picker && refs.picker.getIndexes()
@ -118,17 +129,19 @@ export const updateInnerValue =
state.innerValue = api.formatValue(value) state.innerValue = api.formatValue(value)
} }
export const formatValue = (props: IDatePickerProps) => (value: number): Date => { export const formatValue =
if (!Object.prototype.toString.call(value) === '[object Date]' && !isNaN(value.getTime())) { (props: IDatePickerProps) =>
value = props.minDate (value: number): Date => {
if (!Object.prototype.toString.call(value) === '[object Date]' && !isNaN(value.getTime())) {
value = props.minDate
}
value = Math.max(value, props.minDate.getTime())
value = Math.min(value, props.maxDate.getTime())
return new Date(value)
} }
value = Math.max(value, props.minDate.getTime())
value = Math.min(value, props.maxDate.getTime())
return new Date(value)
}
export const onChange = export const onChange =
({ api, emit, refs, nextTick }: Pick<IDatePickerRenderlessParams, 'api' | 'emit' | 'refs' | 'nextTick'>) => ({ api, emit, refs, nextTick }: Pick<IDatePickerRenderlessParams, 'api' | 'emit' | 'refs' | 'nextTick'>) =>
() => { () => {
@ -153,7 +166,13 @@ export const padZero = (num: number, targetLength = 2): string => {
} }
export const updateColumnValue = export const updateColumnValue =
({ constants, nextTick, props, refs, state }: Pick<IDatePickerRenderlessParams, 'constants' | 'nextTick' | 'props' | 'refs' | 'state'>) => ({
constants,
nextTick,
props,
refs,
state
}: Pick<IDatePickerRenderlessParams, 'constants' | 'nextTick' | 'props' | 'refs' | 'state'>) =>
() => { () => {
const value = state.innerValue const value = state.innerValue
const { formatter } = props const { formatter } = props
@ -309,7 +328,12 @@ export const getDisplayValue =
} }
export const hookMounted = export const hookMounted =
({ constants, parent, refs, nextTick }: Pick<IDatePickerRenderlessParams, 'constants' | 'parent' | 'refs' | 'nextTick'>) => ({
constants,
parent,
refs,
nextTick
}: Pick<IDatePickerRenderlessParams, 'constants' | 'parent' | 'refs' | 'nextTick'>) =>
() => { () => {
nextTick(() => { nextTick(() => {
parent.$emit(constants.HookMounted, refs.refrence.$el) parent.$emit(constants.HookMounted, refs.refrence.$el)

View File

@ -28,7 +28,7 @@ import {
updateColumnValue updateColumnValue
} from './index' } from './index'
import { DATE } from '../common' import { DATE } from '../common'
import { import type {
IDatePickerApi, IDatePickerApi,
IDatePickerProps, IDatePickerProps,
IDatePickerRenderlessParamUtils, IDatePickerRenderlessParamUtils,

View File

@ -370,16 +370,16 @@ export const handleRangePick =
const defaultTime = state.defaultTime || [] const defaultTime = state.defaultTime || []
let minDateVal = val.minDate let minDateVal = val.minDate
let maxDateVal = val.maxDate let maxDateVal = val.maxDate
if (state.singleSelect) { if (state.singleSelect) {
Object.assign(state.rangeState, { selecting: false }) Object.assign(state.rangeState, { selecting: false })
const effectDate = val.minDate || val.maxDate const effectDate = val.minDate || val.maxDate
const rangeDate = state.shortcutType === 'startFrom' ? state.maxRangeDate : state.minRangeDate const rangeDate = state.shortcutType === 'startFrom' ? state.maxRangeDate : state.minRangeDate
minDateVal = rangeDate > effectDate ? effectDate : rangeDate minDateVal = rangeDate > effectDate ? effectDate : rangeDate
maxDateVal = rangeDate > effectDate ? rangeDate : effectDate maxDateVal = rangeDate > effectDate ? rangeDate : effectDate
} }
const minDate = modifyWithTimeString(minDateVal, defaultTime[0], t) const minDate = modifyWithTimeString(minDateVal, defaultTime[0], t)
const maxDate = modifyWithTimeString(maxDateVal, defaultTime[1], t) const maxDate = modifyWithTimeString(maxDateVal, defaultTime[1], t)
@ -586,10 +586,12 @@ export const computerLabel =
export const computerEnableYearArrow = (state) => () => export const computerEnableYearArrow = (state) => () =>
state.unlinkPanels && state.rightYear * 12 + state.rightMonth - (state.leftYear * 12 + state.leftMonth + 1) >= 12 state.unlinkPanels && state.rightYear * 12 + state.rightMonth - (state.leftYear * 12 + state.leftMonth + 1) >= 12
export const watchPickerVisible = ({ state, constants }) => (val) => { export const watchPickerVisible =
if (!val) { ({ state, constants }) =>
state.singleSelect = false (val) => {
state.minRangeDate = constants.startDate if (!val) {
state.maxRangeDate = constants.endDate state.singleSelect = false
state.minRangeDate = constants.startDate
state.maxRangeDate = constants.endDate
}
} }
}

View File

@ -21,7 +21,7 @@ import {
clearTime clearTime
} from '../common/deps/date-util' } from '../common/deps/date-util'
import { DATEPICKER } from '../common' import { DATEPICKER } from '../common'
import { IDateTableRow } from '@/types' import type { IDateTableRow } from '@/types'
const formatJudg = ({ day, offset, j, i, cell, count, dateCountOfLastMonth }) => { const formatJudg = ({ day, offset, j, i, cell, count, dateCountOfLastMonth }) => {
const nodfpm = day + offset < 0 ? 7 + day + offset : day + offset const nodfpm = day + offset < 0 ? 7 + day + offset : day + offset
@ -180,7 +180,7 @@ export const getRows =
let count = 1 let count = 1
const isFunction = props.formatWeeks instanceof Function const isFunction = props.formatWeeks instanceof Function
const arr: Date[][] = [] const arr: Date[][] = []
// 日期表格行从0开始共6行[0, 5] // 日期表格行从0开始共6行[0, 5]
@ -243,7 +243,7 @@ export const getRows =
if (props.showWeekNumber && isFunction) { if (props.showWeekNumber && isFunction) {
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
let val = getWeekNumber(nextDate(startDate, i * 7 + 1)) let val = getWeekNumber(nextDate(startDate, i * 7 + 1))
rows[i][0].text = props.formatWeeks(val, res) rows[i][0].text = props.formatWeeks(val, res)
} }
} }

View File

@ -10,7 +10,12 @@
* *
*/ */
import { IDropdownItemRenderlessParams, IDropdownItemStyle, IDropdownItemTag, IDropdownItemOptionStyle } from '@/types' import type {
IDropdownItemRenderlessParams,
IDropdownItemStyle,
IDropdownItemTag,
IDropdownItemOptionStyle
} from '@/types'
import { on, off } from '../common/deps/dom' import { on, off } from '../common/deps/dom'
export const getTitle = (props: IDropdownItemRenderlessParams['props']) => (): string => { export const getTitle = (props: IDropdownItemRenderlessParams['props']) => (): string => {

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
IDropdownItemState, IDropdownItemState,
IDropdownItemApi, IDropdownItemApi,
IDropdownItemProps, IDropdownItemProps,

View File

@ -10,7 +10,7 @@
* *
*/ */
import { IDropdownMenuRenderlessParams, IDropdownMenuPopperParams, IDropdownItemVm } from '@/types' import type { IDropdownMenuRenderlessParams, IDropdownMenuPopperParams, IDropdownItemVm } from '@/types'
import userPopper from '../common/deps/vue-popper' import userPopper from '../common/deps/vue-popper'
export const toggleItem = export const toggleItem =

View File

@ -10,7 +10,7 @@
* *
*/ */
import { import type {
IDropdownVm, IDropdownVm,
IDropdownMenuState, IDropdownMenuState,
IDropdownMenuApi, IDropdownMenuApi,

View File

@ -10,8 +10,7 @@
* *
*/ */
import { IDropdownRenderlessParams } from '@/types' import type { IDropdownRenderlessParams } from '@/types'
import type { ComponentPublicInstance } from 'vue'
import { KEY_CODE } from '../common' import { KEY_CODE } from '../common'
import { addClass, removeClass, on, off } from '../common/deps/dom' import { addClass, removeClass, on, off } from '../common/deps/dom'

View File

@ -11,7 +11,7 @@
*/ */
import { guid } from '../common/string' import { guid } from '../common/string'
import { import type {
IDropdownState, IDropdownState,
IDropdownApi, IDropdownApi,
IDropdownProps, IDropdownProps,

View File

@ -26,8 +26,7 @@ import type {
IFileUploadDownloadFileInner, IFileUploadDownloadFileInner,
IFileUploadBatchSegmentDownload, IFileUploadBatchSegmentDownload,
IFileUploadSliceDownloadChunk, IFileUploadSliceDownloadChunk,
IFileUploadLargeDocumentDownload, IFileUploadLargeDocumentDownload
IFileUploadDownloadFileSingleInner
} from '@/types' } from '@/types'
import { extend } from '../common/object' import { extend } from '../common/object'
@ -349,10 +348,10 @@ const calcFileForMobile = (rawFile: File, file: IFileUploadFile) => {
const size = rawFile.size / 1024 const size = rawFile.size / 1024
if (size < 1024) { if (size < 1024) {
file.size = Math.round(size * Math.pow(10, 1)) / Math.pow(10, 1) + 'KB' file.size = Math.round(size * 10 ** 1) / 10 ** 1 + 'KB'
} else { } else {
const fileSize = size / 1024 const fileSize = size / 1024
file.size = Math.round(fileSize * Math.pow(10, 1)) / Math.pow(10, 1) + 'MB' file.size = Math.round(fileSize * 10 ** 1) / 10 ** 1 + 'MB'
} }
} }
@ -582,7 +581,7 @@ export const handleStart =
rawFiles.forEach((rawFile) => api.addFileToList(rawFile, updateId, reUpload)) rawFiles.forEach((rawFile) => api.addFileToList(rawFile, updateId, reUpload))
const { UPLOADING, READY } = constants.FILE_STATUS const { UPLOADING, READY } = constants.FILE_STATUS
state.uploadingFiles = state.uploadFiles.filter((file) => [UPLOADING, READY].indexOf(file.status) > -1) state.uploadingFiles = state.uploadFiles.filter((file) => [UPLOADING, READY].includes(file.status))
if (state.isEdm && state.isSuccess) { if (state.isEdm && state.isSuccess) {
rawFiles.forEach((rawFile) => { rawFiles.forEach((rawFile) => {
@ -877,7 +876,7 @@ export const clearUploadingFiles =
({ constants, state }: Pick<IFileUploadRenderlessParams, 'constants' | 'state'>) => ({ constants, state }: Pick<IFileUploadRenderlessParams, 'constants' | 'state'>) =>
() => { () => {
const { SUCESS, FAIL } = constants.FILE_STATUS const { SUCESS, FAIL } = constants.FILE_STATUS
const isUploadComplete = state.uploadingFiles.every((file) => [SUCESS, FAIL].indexOf(file.status) > -1) const isUploadComplete = state.uploadingFiles.every((file) => [SUCESS, FAIL].includes(file.status))
if (isUploadComplete) { if (isUploadComplete) {
state.uploadingFiles = [] state.uploadingFiles = []
@ -1039,12 +1038,11 @@ const getTranslateFile =
} else { } else {
const content = data.headers['content-disposition'] const content = data.headers['content-disposition']
const name = content ? content.match(/fileName.?=(.*)/)[1] || content.match(/fileName=(.*)/)[1] : '' const name = content ? content.match(/fileName.?=(.*)/)[1] || content.match(/fileName=(.*)/)[1] : ''
const type = const type = !name.includes('.')
name.indexOf('.') === -1 ? data.headers['content-type']
? data.headers['content-type'] : type !== 'zip'
: type !== 'zip' ? 'application / x - xls'
? 'application / x - xls' : 'application/zip'
: 'application/zip'
const blob = new Blob([data.data], { type }) const blob = new Blob([data.data], { type })
aLinkDownload({ blob, name }) aLinkDownload({ blob, name })
} }
@ -1189,7 +1187,7 @@ export const validateDownloadStatus =
} }
} }
if (data.data && data.data.type && data.data.type.indexOf('application/json') > -1) { if (data.data && data.data.type && data.data.type.includes('application/json')) {
const reader = new FileReader() const reader = new FileReader()
reader.onload = (e) => { reader.onload = (e) => {
const errRes = JSON.parse(e.target.result) const errRes = JSON.parse(e.target.result)
@ -1199,7 +1197,7 @@ export const validateDownloadStatus =
return true return true
} }
if (!isLessThan17G && data.headers['content-type'].indexOf('application/json') > -1) { if (!isLessThan17G && data.headers['content-type'].includes('application/json')) {
const errRes = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(data.data))) const errRes = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(data.data)))
errorHandle({ state, file, errRes, Modal, downloadOps }) errorHandle({ state, file, errRes, Modal, downloadOps })
return true return true
@ -1307,7 +1305,7 @@ export const downloadFileSingle =
.catch((data) => { .catch((data) => {
if (data.response && state.errorStatusCodes.includes(data.response.status)) { if (data.response && state.errorStatusCodes.includes(data.response.status)) {
const downloadOps = props.edm.download || {} const downloadOps = props.edm.download || {}
const tokenParams = { token: downloadOps.token, file: file, type: 'download' } const tokenParams = { token: downloadOps.token, file, type: 'download' }
api.getToken(tokenParams).then((data) => { api.getToken(tokenParams).then((data) => {
api.afterDownload({ batchIndex, data, file, range, isChunk, isBatch, isLessThan17G }) api.afterDownload({ batchIndex, data, file, range, isChunk, isBatch, isLessThan17G })
}) })
@ -1491,7 +1489,7 @@ export const downloadFileSingleInner =
({ file, isBatch }) => { ({ file, isBatch }) => {
const { SIZE_17G } = constants.EDM const { SIZE_17G } = constants.EDM
const downloadOps = props.edm.download || {} const downloadOps = props.edm.download || {}
let tokenParams = { token: downloadOps.token, file: file, type: 'download' } let tokenParams = { token: downloadOps.token, file, type: 'download' }
api.getToken(tokenParams).then((data) => { api.getToken(tokenParams).then((data) => {
if (!data) return if (!data) return
if (state.isHwh5) { if (state.isHwh5) {
@ -2128,7 +2126,7 @@ export const sliceChunk =
state.batchQueueListen[file.docId + '-0'] = 0 state.batchQueueListen[file.docId + '-0'] = 0
for (let i = 0; i < chunkSize; i++) { for (let i = 0; i < chunkSize; i++) {
if (file.records.indexOf(i.toString()) > -1) { if (file.records.includes(i.toString())) {
continue continue
} }

View File

@ -9,7 +9,7 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
* *
*/ */
import { import type {
IFileUploadState, IFileUploadState,
IFileUploadApi, IFileUploadApi,
IFileUploadProps, IFileUploadProps,

View File

@ -1,6 +1,8 @@
export const click = ({ props, emit }) => (index) => { export const click =
const i = props.modelValue === index ? undefined : index ({ props, emit }) =>
(index) => {
emit('update:modelValue', i) const i = props.modelValue === index ? undefined : index
emit('click', index)
} emit('update:modelValue', i)
emit('click', index)
}

View File

@ -1,151 +1,171 @@
import { cloneDeep } from '../chart-core/deps/utils' import { cloneDeep } from '../chart-core/deps/utils'
export const isEmpty = (value) => [undefined, null, ''].indexOf(value) !== -1 export const isEmpty = (value) => [undefined, null, ''].includes(value)
export const resize = ({ state, vm, props }) => () => { export const resize =
const refs = vm.$refs ({ state, vm, props }) =>
() => {
const refs = vm.$refs
if (state.showPanel) { if (state.showPanel) {
const pos = refs.maskPoint.getBoundingClientRect() const pos = refs.maskPoint.getBoundingClientRect()
const height = window.innerHeight - pos.top const height = window.innerHeight - pos.top
refs.panelMask.style.top = pos.top + 'px' refs.panelMask.style.top = pos.top + 'px'
refs.panelMask.style.height = height + 'px' refs.panelMask.style.height = height + 'px'
if (!props.panelClass) { if (!props.panelClass) {
refs.panel.style.maxHeight = (height * 0.7 || 0).toFixed() + 'px' refs.panel.style.maxHeight = (height * 0.7 || 0).toFixed() + 'px'
}
} }
} }
}
export const panelToggle = ({ state, props, api, emit }) => (index) => { export const panelToggle =
const { modelValue } = props ({ state, props, api, emit }) =>
(index) => {
const { modelValue } = props
emit('panel', { index, modelValue }) emit('panel', { index, modelValue })
if (index === 'filter') { if (index === 'filter') {
state.showPanelIndex = -1 state.showPanelIndex = -1
state.filterPanel.show = !state.filterPanel.show state.filterPanel.show = !state.filterPanel.show
if (state.filterPanel.show) { if (state.filterPanel.show) {
state.filterPanel.selected = props.filterValue.slice() state.filterPanel.selected = props.filterValue.slice()
api.resize()
}
return
}
state.filterPanel.show = false
if (state.showPanelIndex === index) {
state.showPanelIndex = -1
} else {
let value = modelValue[index]
value = isEmpty(value) ? [] : Array.isArray(value) ? value : [value]
state.showPanelIndex = index
state.selectPanel.selected = value.slice()
api.resize() api.resize()
} }
return
} }
state.filterPanel.show = false export const selectOption =
({ state, api }) =>
(value) => {
const {
selectPanel: { config }
} = state
if (state.showPanelIndex === index) { if (config.type === 'tag' && config.multiple) {
state.showPanelIndex = -1 state.selectPanel.selected = value
} else { } else if (!config.multiple) {
let value = modelValue[index] state.selectPanel.selected = [value]
value = isEmpty(value) ? [] : Array.isArray(value) ? value : [value]
state.showPanelIndex = index
state.selectPanel.selected = value.slice()
api.resize() api.confirm()
}
}
export const selectOption = ({ state, api }) => (value) => {
const {
selectPanel: { config }
} = state
if (config.type === 'tag' && config.multiple) {
state.selectPanel.selected = value
} else if (!config.multiple) {
state.selectPanel.selected = [value]
api.confirm()
}
}
export const filterSelectOption = ({ state, props }) => (value, index) => {
const { filterGroup } = props
if (filterGroup[index].type === 'tag' && !filterGroup[index].multiple) {
state.filterPanel.selected[index] = value
}
}
export const reset = ({ state, props }) => (isFilterGroup) => {
const { modelValue, filterValue } = props
if (isFilterGroup) {
state.filterPanel.selected = cloneDeep(filterValue)
} else {
let value = modelValue[state.showPanelIndex]
value = isEmpty(value) ? [] : Array.isArray(value) ? value : [value]
state.selectPanel.selected = value.slice()
}
}
export const filterConfirm = ({ state, emit }) => () => {
const filterValue = state.filterPanel.selected.slice()
state.filterPanel.show = false
emit('update:filter-value', cloneDeep(filterValue))
}
export const confirm = ({ state, props, emit, api }) => (isFilterGroup) => {
if (isFilterGroup) {
api.filterConfirm()
return
}
const {
showPanelIndex,
selectPanel: { config }
} = state
let modelValue = props.modelValue
if (config.multiple) {
modelValue[showPanelIndex] = state.selectPanel.selected
} else {
modelValue[showPanelIndex] = state.selectPanel.selected[0]
}
state.showPanelIndex = -1
emit('update:modelValue', modelValue.slice())
}
export const cancel = ({ state, emit }) => () => {
state.showPanelIndex = -1
state.filterPanel.show = false
emit('cancel', state)
}
export const labelListComputed = ({ props }) => () => {
const { data, modelValue } = props
return data.map((item, index) => {
const data = modelValue[index]
const values = item.options.map((option) => option.value)
if (item.type === 'tag' && item.multiple) {
if (data && data.length) {
return data
.map((value) => {
const i = values.indexOf(value)
return i !== -1 ? item.options[i].label : item.options[i].value
})
.join('; ')
} else {
return item.placeholder
}
} else if (!item.multiple) {
if (isEmpty(data)) {
return item.placeholder
}
const i = values.indexOf(data)
return i !== -1 ? item.options[i].label : data
} }
}) }
}
export const selectOptionAll = ({ state }) => () => { export const filterSelectOption =
state.selectPanel.selected = [] ({ state, props }) =>
} (value, index) => {
const { filterGroup } = props
if (filterGroup[index].type === 'tag' && !filterGroup[index].multiple) {
state.filterPanel.selected[index] = value
}
}
export const reset =
({ state, props }) =>
(isFilterGroup) => {
const { modelValue, filterValue } = props
if (isFilterGroup) {
state.filterPanel.selected = cloneDeep(filterValue)
} else {
let value = modelValue[state.showPanelIndex]
value = isEmpty(value) ? [] : Array.isArray(value) ? value : [value]
state.selectPanel.selected = value.slice()
}
}
export const filterConfirm =
({ state, emit }) =>
() => {
const filterValue = state.filterPanel.selected.slice()
state.filterPanel.show = false
emit('update:filter-value', cloneDeep(filterValue))
}
export const confirm =
({ state, props, emit, api }) =>
(isFilterGroup) => {
if (isFilterGroup) {
api.filterConfirm()
return
}
const {
showPanelIndex,
selectPanel: { config }
} = state
let modelValue = props.modelValue
if (config.multiple) {
modelValue[showPanelIndex] = state.selectPanel.selected
} else {
modelValue[showPanelIndex] = state.selectPanel.selected[0]
}
state.showPanelIndex = -1
emit('update:modelValue', modelValue.slice())
}
export const cancel =
({ state, emit }) =>
() => {
state.showPanelIndex = -1
state.filterPanel.show = false
emit('cancel', state)
}
export const labelListComputed =
({ props }) =>
() => {
const { data, modelValue } = props
return data.map((item, index) => {
const data = modelValue[index]
const values = item.options.map((option) => option.value)
if (item.type === 'tag' && item.multiple) {
if (data && data.length) {
return data
.map((value) => {
const i = values.indexOf(value)
return i !== -1 ? item.options[i].label : item.options[i].value
})
.join('; ')
} else {
return item.placeholder
}
} else if (!item.multiple) {
if (isEmpty(data)) {
return item.placeholder
}
const i = values.indexOf(data)
return i !== -1 ? item.options[i].label : data
}
})
}
export const selectOptionAll =
({ state }) =>
() => {
state.selectPanel.selected = []
}

View File

@ -1,31 +1,37 @@
import { isEmpty } from './index' import { isEmpty } from './index'
const selectOptionAll = ({ state, emit }) => () => { const selectOptionAll =
state.selected = [] ({ state, emit }) =>
() => {
state.selected = []
emit('click', state.selected) emit('click', state.selected)
emit('update:modelValue', state.selected) emit('update:modelValue', state.selected)
}
const selectOption = ({ state, props, emit }) => (value) => {
if (props.type === 'tag' && props.multiple) {
const index = state.selected.indexOf(value)
index === -1 ? state.selected.push(value) : state.selected.splice(index, 1)
const values = state.selected
emit('click', values)
emit('update:modelValue', values.slice())
} else if (props.type === 'tag' && !props.multiple) {
state.selected = [value]
emit('click', value)
emit('update:modelValue', value)
} }
}
const setSelectedOption = ({ state }) => (value) => { const selectOption =
state.selected = isEmpty(value) ? [] : Array.isArray(value) ? value.slice() : [value] ({ state, props, emit }) =>
} (value) => {
if (props.type === 'tag' && props.multiple) {
const index = state.selected.indexOf(value)
index === -1 ? state.selected.push(value) : state.selected.splice(index, 1)
const values = state.selected
emit('click', values)
emit('update:modelValue', values.slice())
} else if (props.type === 'tag' && !props.multiple) {
state.selected = [value]
emit('click', value)
emit('update:modelValue', value)
}
}
const setSelectedOption =
({ state }) =>
(value) => {
state.selected = isEmpty(value) ? [] : Array.isArray(value) ? value.slice() : [value]
}
export const api = ['state', 'selectOptionAll', 'selectOption'] export const api = ['state', 'selectOptionAll', 'selectOption']

Some files were not shown because too many files have changed in this diff Show More