From 00dd4c5121af2438a2a0f3944c7230584d1d7c27 Mon Sep 17 00:00:00 2001 From: shenjunjian <40288193@qq.com> Date: Sat, 25 Jan 2025 18:13:04 -0800 Subject: [PATCH 01/25] =?UTF-8?q?fix(utils):=20=E8=B0=83=E6=95=B4sha256,?= =?UTF-8?q?=20=E7=A7=BB=E9=99=A4=20getWindow,=20isWeb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/nuxt/playground/package.json | 3 +-- examples/vue2/package.json | 3 +-- examples/vue3/package.json | 3 +-- packages/renderless/src/file-upload/index.ts | 6 +++--- packages/utils/src/crypt/index.ts | 8 ++------ packages/utils/src/globalConfig/index.ts | 8 -------- packages/utils/src/index.ts | 8 +++++--- packages/utils/src/logger/index.ts | 4 +--- 8 files changed, 14 insertions(+), 29 deletions(-) diff --git a/examples/nuxt/playground/package.json b/examples/nuxt/playground/package.json index d1626056a8..027faa28a3 100644 --- a/examples/nuxt/playground/package.json +++ b/examples/nuxt/playground/package.json @@ -26,7 +26,6 @@ "@opentiny/vue-vite-import": "workspace:~", "@tiptap/vue-3": "^2.1.0", "@vitejs/plugin-vue-jsx": "^3.0.0", - "js-sha256": "^0.9.0", "onigasm": "^2.2.5", "postcss": "^8.4.16", "typescript": "^5.0.0", @@ -34,4 +33,4 @@ "vite-plugin-dynamic-import": "^1.2.4", "vite-svg-loader": "^3.6.0" } -} +} \ No newline at end of file diff --git a/examples/vue2/package.json b/examples/vue2/package.json index f52a430768..b6ef4c5451 100644 --- a/examples/vue2/package.json +++ b/examples/vue2/package.json @@ -37,7 +37,6 @@ "@vue/composition-api": "1.7.2", "@vue/runtime-dom": "^3.2.31", "@vue/test-utils": "^1.3.3", - "js-sha256": "^0.9.0", "jsdom": "^21.0.0", "onigasm": "^2.2.5", "postcss": "^8.4.16", @@ -60,4 +59,4 @@ "vue-template-compiler": "2.6.14", "vue-tsc": "^1.0.16" } -} +} \ No newline at end of file diff --git a/examples/vue3/package.json b/examples/vue3/package.json index e8b1eb3ae4..0ba1c2b6ce 100644 --- a/examples/vue3/package.json +++ b/examples/vue3/package.json @@ -40,7 +40,6 @@ "@vitest/ui": "^0.31.0", "@vue/runtime-core": "3.2.31", "@vue/test-utils": "^2.2.7", - "js-sha256": "^0.9.0", "jsdom": "^21.0.0", "onigasm": "^2.2.5", "postcss": "^8.4.16", @@ -59,4 +58,4 @@ "vue": "^3.3.9", "vue-i18n": "^9.1.7" } -} +} \ No newline at end of file diff --git a/packages/renderless/src/file-upload/index.ts b/packages/renderless/src/file-upload/index.ts index 88147cbd2e..27d96eebaa 100644 --- a/packages/renderless/src/file-upload/index.ts +++ b/packages/renderless/src/file-upload/index.ts @@ -30,7 +30,7 @@ import type { } from '@/types' import { extend } from '../common/object' -import { xss, logger, crypt } from '@opentiny/utils' +import { xss, logger, sha256 } from '@opentiny/utils' import uploadAjax from '../common/deps/upload-ajax' import { isObject } from '../common/type' import { isEmptyObject } from '../common/type' @@ -513,7 +513,7 @@ export const getFileHash = reader.readAsArrayBuffer(file.raw) reader.onload = async (e) => { if (file.status === constants.FILE_STATUS.FAIL) return - const hash = await crypt.sha256(e.target && e.target.result) + const hash = sha256(e.target && e.target.result) file.hash = file.raw.hash = hash resolve(hash) emit('hash-progress', 100) @@ -2046,7 +2046,7 @@ export const segmentUpload = reader.readAsArrayBuffer(file) reader.onload = async (e) => { if (props.edm.isCheckCode === true) { - const hash = await crypt.sha256(e.target && e.target.result) + const hash = sha256(e.target && e.target.result) file.hash = hash } resolve(file) diff --git a/packages/utils/src/crypt/index.ts b/packages/utils/src/crypt/index.ts index ab9013c618..0f7e4db0d3 100644 --- a/packages/utils/src/crypt/index.ts +++ b/packages/utils/src/crypt/index.ts @@ -1,14 +1,10 @@ -import { getWindow } from '../globalConfig' - /** 生成字节流或字符串的sha256编码 */ -export async function sha256(message: ArrayBuffer | string) { +export function sha256(message: ArrayBuffer | string) { const isArrayBuffer = Object.prototype.toString.call(message) === '[object ArrayBuffer]' const msgUint8 = isArrayBuffer ? message : new TextEncoder().encode(message as string) // 编码为(utf-8)Uint8Array - const hashBuffer = await getWindow().crypto.subtle.digest('SHA-256', msgUint8) // 计算消息的哈希值 + const hashBuffer = globalThis.crypto.subtle.digest('SHA-256', msgUint8) // 计算消息的哈希值 const hashArray = Array.from(new Uint8Array(hashBuffer)) // 将缓冲区转换为字节数组 const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('') // 将字节数组转换为十六进制字符串 return hashHex } - -export default { sha256 } diff --git a/packages/utils/src/globalConfig/index.ts b/packages/utils/src/globalConfig/index.ts index bd33d8f4f1..cb1fc3f3fd 100644 --- a/packages/utils/src/globalConfig/index.ts +++ b/packages/utils/src/globalConfig/index.ts @@ -1,11 +1,3 @@ -export const isWeb = () => - typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document - -/** 获取globalThis. 在web上, window===globalThis 在node.js中, global=== globalThis。 - * 所以该函数没必要存在,待移除 - */ -export const getWindow = () => (isWeb() ? window : global) - // 需要微前端的用户传入该变量 export const globalConfig = { viewportWindow: null // 获取真实视口的window,解决在微前端中某些bug diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index a6cd61e0da..a273b3fe04 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,12 +1,14 @@ import xss from './xss' import logger from './logger' -import crypt from './crypt' import ResizeObserver from './resize-observer' -export { xss, logger, crypt, ResizeObserver } +export { xss, logger, ResizeObserver } + +export { sha256 } from './crypt' +export { globalConfig, getViewportWindow } from './globalConfig' -export { getWindow, isWeb, globalConfig, getViewportWindow } from './globalConfig' export { getDays, getWeek, lastMonth, nextMonth, getCalendar, transformArray, parseDate } from './calendar' + export { isLeapYear, toDate, diff --git a/packages/utils/src/logger/index.ts b/packages/utils/src/logger/index.ts index ea605c9920..39798473fc 100644 --- a/packages/utils/src/logger/index.ts +++ b/packages/utils/src/logger/index.ts @@ -1,6 +1,4 @@ -import { getWindow } from '../globalConfig' - -const _win: any = getWindow() +const _win: any = globalThis /** 使用 logger.xxx 代替 window.console.xxx, 避免语法警告 */ export const logger = _win.console as Console From 39901e7af821f7635320e5b7daaa09602f3f704b Mon Sep 17 00:00:00 2001 From: shenjunjian <40288193@qq.com> Date: Sat, 25 Jan 2025 19:00:19 -0800 Subject: [PATCH 02/25] =?UTF-8?q?fix(utils):=20=E7=A7=BB=E9=99=A4isSerer?= =?UTF-8?q?=E5=88=B0globalConfig,=20=E5=88=A0=E9=99=A4isBrowser=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderless/src/base-select/index.ts | 5 +- .../src/cascader-select/column-index.ts | 4 +- packages/renderless/src/cascader/index.ts | 4 +- packages/renderless/src/common/browser.ts | 2 - .../src/common/deps/clickoutside.ts | 3 +- packages/renderless/src/common/string.ts | 4 +- packages/renderless/src/image-viewer/index.ts | 5 +- packages/renderless/src/input/index.ts | 10 +- packages/renderless/src/milestone/index.ts | 4 +- packages/renderless/src/nav-menu/index.ts | 4 +- packages/renderless/src/picker/index.ts | 4 - .../renderless/src/select-dropdown/vue.ts | 4 +- packages/renderless/src/select/index.ts | 4 +- packages/renderless/src/select/vue.ts | 4 +- packages/renderless/src/split/index.ts | 9 +- packages/renderless/src/tabs-mf/wheel.ts | 6 +- packages/renderless/src/time-spinner/index.ts | 4 +- packages/renderless/src/upload-list/vue.ts | 4 +- packages/utils/src/bigInt/index.ts | 3 - packages/utils/src/browser/index.ts | 100 ------------------ packages/utils/src/dom/index.ts | 2 +- packages/utils/src/espace-ctrl/index.ts | 6 +- packages/utils/src/fastdom/singleton.ts | 4 +- packages/utils/src/fullscreen/screenfull.ts | 14 +-- packages/utils/src/globalConfig/index.ts | 95 +++++++++++++++++ packages/utils/src/index.ts | 6 +- packages/utils/src/popper/index.ts | 7 +- packages/utils/src/popup-manager/index.ts | 3 +- packages/utils/src/resize-event/index.ts | 2 +- packages/utils/src/resize-observer/index.ts | 10 +- packages/utils/src/scroll-into-view/index.ts | 2 +- packages/utils/src/scroll-width/index.ts | 3 +- packages/utils/src/string/index.ts | 6 +- packages/utils/src/touch-emulator/index.ts | 8 +- packages/vue-common/src/breakpoint.ts | 2 +- packages/vue-directive/src/clickoutside.ts | 3 +- packages/vue-hooks/src/vue-popper.ts | 4 +- packages/vue-hooks/src/vue-popup.ts | 2 +- packages/vue/src/float-button/src/index.ts | 6 +- packages/vue/src/grid/src/table/src/table.ts | 4 +- packages/vue/src/image/src/index.ts | 4 +- 41 files changed, 179 insertions(+), 201 deletions(-) delete mode 100644 packages/utils/src/browser/index.ts diff --git a/packages/renderless/src/base-select/index.ts b/packages/renderless/src/base-select/index.ts index da71ddb6a6..b9f7ad0e48 100644 --- a/packages/renderless/src/base-select/index.ts +++ b/packages/renderless/src/base-select/index.ts @@ -15,7 +15,8 @@ import { isNull } from '../common/type' import { fastdom } from '../common/deps/fastdom' import { deepClone } from '../picker-column' import { escapeRegexpString } from '../option' -import { isBrowser } from '../common/browser' + +import { isServer } from '@opentiny/utils' export const handleComposition = ({ api, nextTick, state }) => @@ -1864,7 +1865,7 @@ export const watchInitValue = export const watchShowClose = ({ nextTick, state, parent }) => () => { - if (!isBrowser) return + if (isServer) return nextTick(() => { const parentEl = parent.$el const inputEl = parentEl.querySelector('input[data-tag="tiny-input-inner"]') diff --git a/packages/renderless/src/cascader-select/column-index.ts b/packages/renderless/src/cascader-select/column-index.ts index c4ec7ab6ab..a3932c062c 100644 --- a/packages/renderless/src/cascader-select/column-index.ts +++ b/packages/renderless/src/cascader-select/column-index.ts @@ -1,4 +1,4 @@ -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' const DEFAULT_DURATION = 200 @@ -42,7 +42,7 @@ export const setRollerStyle = export const onTouchStart = ({ state, props, touch, vm }) => (event) => { - if (!isBrowser) return + if (isServer) return touch.start(event) if (state.moving) { const dom = vm.$refs.roller diff --git a/packages/renderless/src/cascader/index.ts b/packages/renderless/src/cascader/index.ts index bb9bde622f..272122d815 100644 --- a/packages/renderless/src/cascader/index.ts +++ b/packages/renderless/src/cascader/index.ts @@ -10,7 +10,7 @@ * */ -import browser, { isBrowser } from '../common/browser' +import { isServer, browser } from '@opentiny/utils' import { isNull } from '../common/type' import debounce from '../common/deps/debounce' import { isEqual } from '../common/object' @@ -356,7 +356,7 @@ export const focusFirstNode = export const computePresentText = ({ props, state }: { props: ICascaderProps; state: ICascaderState }) => () => { - if (isBrowser) { + if (!isServer) { if (!isEmpty(state.checkedValue)) { const node = state.panel.getNodeByValue(state.checkedValue) diff --git a/packages/renderless/src/common/browser.ts b/packages/renderless/src/common/browser.ts index 0725dc366b..30ad81a76e 100644 --- a/packages/renderless/src/common/browser.ts +++ b/packages/renderless/src/common/browser.ts @@ -38,8 +38,6 @@ const isEdge = (browser) => { export const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document -export const globalEnvironment = isBrowser ? window : global - export default (() => { const browser = { name: undefined, diff --git a/packages/renderless/src/common/deps/clickoutside.ts b/packages/renderless/src/common/deps/clickoutside.ts index 5809d4a631..2b43edff7c 100644 --- a/packages/renderless/src/common/deps/clickoutside.ts +++ b/packages/renderless/src/common/deps/clickoutside.ts @@ -12,7 +12,8 @@ import { on } from './dom' -const isServer = typeof window === 'undefined' +import { isServer } from '@opentiny/utils' + const nodeList = [] const nameSpace = '@@clickoutsideContext' let startClick diff --git a/packages/renderless/src/common/string.ts b/packages/renderless/src/common/string.ts index 1ef505b2f8..ebe379bbef 100644 --- a/packages/renderless/src/common/string.ts +++ b/packages/renderless/src/common/string.ts @@ -13,7 +13,7 @@ import { isPlainObject, isNumber, isNumeric, isNull } from './type' import { getObj, toJsonStr } from './object' import { toFixed, Decimal } from './decimal' -import { globalEnvironment, isBrowser } from './browser' +import { isBrowser } from './browser' /** * 文本替换格式类型 @@ -243,7 +243,7 @@ export const fillChar = (string, length, append, chr = '0') => { export const random = () => { let MAX_UINT32_PLUS_ONE = 4294967296 - return globalEnvironment.crypto.getRandomValues(new globalEnvironment.Uint32Array(1))[0] / MAX_UINT32_PLUS_ONE + return globalThis.crypto.getRandomValues(new Uint32Array(1))[0] / MAX_UINT32_PLUS_ONE } /** diff --git a/packages/renderless/src/image-viewer/index.ts b/packages/renderless/src/image-viewer/index.ts index 48a110f8bf..b2f0c78d78 100644 --- a/packages/renderless/src/image-viewer/index.ts +++ b/packages/renderless/src/image-viewer/index.ts @@ -14,11 +14,8 @@ import { on, off } from '../common/deps/dom' import { KEY_CODE } from '../common' import PopupManager from '../common/deps/popup-manager' import { xss } from '@opentiny/utils' -import { isBrowser } from '../common/browser' -const isFirefox = () => (isBrowser ? !!window.navigator.userAgent.match(/firefox/i) : false) - -const mousewheelEventName = isFirefox() ? 'DOMMouseScroll' : 'mousewheel' +const mousewheelEventName = 'mousewheel' export const rafThrottle = (fn) => { let locked = false diff --git a/packages/renderless/src/input/index.ts b/packages/renderless/src/input/index.ts index 5e7510db6f..99a2bcc723 100644 --- a/packages/renderless/src/input/index.ts +++ b/packages/renderless/src/input/index.ts @@ -11,6 +11,7 @@ */ import { omitText } from '../common/string' +import { isServer } from '@opentiny/utils' import type { IInputApi, IInputRenderlessParamUtils, IInputRenderlessParams, IInputState } from 'types/input.type' const HIDDEN_STYLE = ` @@ -46,7 +47,6 @@ const STYLE = { BorderBottomWidth: 'border-bottom-width' } -const isServer = typeof window === 'undefined' const isKorean = (text: string): boolean => /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi.test(text) export const showBox = (state: IInputState) => (): void => { @@ -455,10 +455,10 @@ export const handleEnterDisplayOnlyContent = const rect = target.getBoundingClientRect() const iconWidth = 16 + 15 // 减去图标的宽度加上右边距 /* - 1、omitText使用canvas来计算文字渲染后宽度来计算有没有文本超长 - 2、html标签换行情况下,会导致textContent比原文本多出前后空格,导致canvas计算宽度比html实际渲染宽度大,最终误判 - 3、将文本内容去除前后空格,再交给canvas计算宽度,消除空格带来的误差 - */ + 1、omitText使用canvas来计算文字渲染后宽度来计算有没有文本超长 + 2、html标签换行情况下,会导致textContent比原文本多出前后空格,导致canvas计算宽度比html实际渲染宽度大,最终误判 + 3、将文本内容去除前后空格,再交给canvas计算宽度,消除空格带来的误差 + */ const calcText = text?.trim() || '' isOverTextWhenMask = omitText(calcText, font, rect.width - iconWidth).o } diff --git a/packages/renderless/src/milestone/index.ts b/packages/renderless/src/milestone/index.ts index 6ea0e78165..c25272a1d2 100644 --- a/packages/renderless/src/milestone/index.ts +++ b/packages/renderless/src/milestone/index.ts @@ -19,10 +19,10 @@ import type { IMilestoneIconStyle, IMilestoneFlagOperateParams } from '@/types' -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' export const hexToRgb = (hex: string): { r: number; g: number; b: number } => { - if (hex.includes('var') && isBrowser) { + if (hex.includes('var') && !isServer) { hex = hex.replace(/var\(|\)/g, '') hex = getComputedStyle(document.documentElement).getPropertyValue(hex) } diff --git a/packages/renderless/src/nav-menu/index.ts b/packages/renderless/src/nav-menu/index.ts index 962e01ffed..aeb2b01652 100644 --- a/packages/renderless/src/nav-menu/index.ts +++ b/packages/renderless/src/nav-menu/index.ts @@ -24,7 +24,7 @@ import { mapTree } from '../grid/static' import { transformTreeData } from '../common/array' import { on, off } from '../common/deps/dom' import { xss } from '@opentiny/utils' -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' const { nextZIndex } = PopupManager @@ -491,7 +491,7 @@ export const skip = export const getPoint = ({ api, parent }: Pick) => (): number => { - if (!isBrowser) return 0 + if (isServer) return 0 else { const items = parent.$el.querySelectorAll('.menu>li') as NodeListOf let index = 0 diff --git a/packages/renderless/src/picker/index.ts b/packages/renderless/src/picker/index.ts index b30e676704..ccd2101ab9 100644 --- a/packages/renderless/src/picker/index.ts +++ b/packages/renderless/src/picker/index.ts @@ -1034,10 +1034,6 @@ export const hidePicker = export const showPicker = ({ api, nextTick, updatePopper, state }) => () => { - if (state.$isServer) { - return - } - if (!state.picker) { api.mountPicker() } diff --git a/packages/renderless/src/select-dropdown/vue.ts b/packages/renderless/src/select-dropdown/vue.ts index 0a1b5da1fb..6afe9af532 100644 --- a/packages/renderless/src/select-dropdown/vue.ts +++ b/packages/renderless/src/select-dropdown/vue.ts @@ -24,7 +24,7 @@ import { import userPopper from '../common/deps/vue-popper' import PopupManager from '../common/deps/popup-manager' import debounce from '../common/deps/debounce' -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' export const api = [ 'state', @@ -96,7 +96,7 @@ const initApi = ({ api, popper, state, selectEmitter, constants, selectVm, paren const initWatch = ({ watch, selectVm, state, nextTick }) => { watch( - () => (isBrowser ? selectVm.state.inputWidth : undefined), + () => (!isServer ? selectVm.state.inputWidth : undefined), (val) => { nextTick(() => { state.minWidth = ((selectVm && selectVm.$el && selectVm.$el.getBoundingClientRect().width) || val) + 'px' diff --git a/packages/renderless/src/select/index.ts b/packages/renderless/src/select/index.ts index 33d779c806..77c8dbfeaf 100644 --- a/packages/renderless/src/select/index.ts +++ b/packages/renderless/src/select/index.ts @@ -16,7 +16,7 @@ import { fastdom } from '../common/deps/fastdom' import { deepClone } from '../picker-column' import { escapeRegexpString } from '../option' import { correctTarget } from '../common/event' -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' export const handleComposition = ({ api, nextTick, state }) => @@ -2398,7 +2398,7 @@ export const watchInitValue = export const watchShowClose = ({ nextTick, state, parent }) => () => { - if (!isBrowser) return + if (isServer) return nextTick(() => { const parentEl = parent.$el const inputEl = parentEl.querySelector('input[data-tag="tiny-input-inner"]') diff --git a/packages/renderless/src/select/vue.ts b/packages/renderless/src/select/vue.ts index 76cd4966dd..88399f6bf6 100644 --- a/packages/renderless/src/select/vue.ts +++ b/packages/renderless/src/select/vue.ts @@ -115,7 +115,7 @@ import { import debounce from '../common/deps/debounce' import { isNumber } from '../common/type' import { useUserAgent } from '../common/deps/useUserAgent' -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' export const api = [ 'state', @@ -206,7 +206,7 @@ const initState = ({ reactive, computed, props, api, emitter, parent, constants, optionsAllDisabled: computed(() => api.computedOptionsAllDisabled()), collapseTagSize: computed(() => api.computedCollapseTagSize()), showNewOption: computed(() => api.computedShowNewOption()), - selectSize: computed(() => (isBrowser ? props.size || state.formItemSize : 0)), + selectSize: computed(() => (!isServer ? props.size || state.formItemSize : 0)), optimizeOpts: computed(() => api.computeOptimizeOpts()), optimizeStore: { valueIndex: 0, recycleScrollerHeight: computed(() => api.recycleScrollerHeight()) }, diff --git a/packages/renderless/src/split/index.ts b/packages/renderless/src/split/index.ts index bdab7bb708..4b52f8260b 100644 --- a/packages/renderless/src/split/index.ts +++ b/packages/renderless/src/split/index.ts @@ -8,8 +8,7 @@ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * - */ -import { isBrowser } from '../common/browser' + */ import { isServer } from '@opentiny/utils' export const px2percent = ({ numerator, denominator }) => parseFloat(numerator) / parseFloat(denominator) @@ -43,8 +42,8 @@ export const getAnotherOffset = return isPercent ? 100 - value : state.valueIsPx - ? `${vm.$refs.outerWrapper[state.offsetSize] - parseFloat(value)}px` - : 1 - value + ? `${vm.$refs.outerWrapper[state.offsetSize] - parseFloat(value)}px` + : 1 - value } export const handleMove = @@ -173,7 +172,7 @@ export const computeOffset = () => { setTimeout(() => { // 防止当split组件销毁时,state为undefined导致的报错 - if (state && isBrowser) { + if (state && !isServer) { state.totalPane = vm.$refs.outerWrapper[state.offsetSize] state.leftTopPane = state.totalPane * (state.offset / 100) } diff --git a/packages/renderless/src/tabs-mf/wheel.ts b/packages/renderless/src/tabs-mf/wheel.ts index cf6f67bda9..9cfc9c2726 100644 --- a/packages/renderless/src/tabs-mf/wheel.ts +++ b/packages/renderless/src/tabs-mf/wheel.ts @@ -1,4 +1,4 @@ -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' export const getAddWheelListener = (window, document) => { const { addApiName, removeApiName, prefix } = detectEventModel(window) @@ -22,7 +22,7 @@ export const getAddWheelListener = (window, document) => { } const detectEventModel = (window) => { - const flag = isBrowser ? window.addEventListener : null + const flag = !isServer ? window.addEventListener : null const addApiName = flag ? 'addEventListener' : 'attachEvent' const removeApiName = flag ? 'removeEventListener' : 'detachEvent' @@ -32,7 +32,7 @@ const detectEventModel = (window) => { } const detectAvailableWheelEvent = (document) => { - if (!isBrowser) return null + if (isServer) return null else { let support if ('onwheel' in document.createElement('div')) { diff --git a/packages/renderless/src/time-spinner/index.ts b/packages/renderless/src/time-spinner/index.ts index f3899767e3..58a5998dcc 100644 --- a/packages/renderless/src/time-spinner/index.ts +++ b/packages/renderless/src/time-spinner/index.ts @@ -13,7 +13,7 @@ import { modifyTime } from '../common/deps/date-util' import { DATEPICKER } from '../common' -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' export const getArrowHourList = (state) => () => { const hours = state.hours @@ -205,7 +205,7 @@ export const adjustCurrentSpinner = export const adjustSpinner = ({ api, props, vm, state }) => (type, value) => { - if (props.arrowControl || !isBrowser) { + if (props.arrowControl || isServer) { return } diff --git a/packages/renderless/src/upload-list/vue.ts b/packages/renderless/src/upload-list/vue.ts index a2c18413df..1595c9d715 100644 --- a/packages/renderless/src/upload-list/vue.ts +++ b/packages/renderless/src/upload-list/vue.ts @@ -33,7 +33,7 @@ import { import { getToken, initService } from '../file-upload' import { formatFileSize } from '../common/string' import { getApi } from '../file-upload/vue' -import { isBrowser } from '../common/browser' +import { isServer } from '@opentiny/utils' export const api = [ 't', @@ -66,7 +66,7 @@ export const renderless = ( ): IUploadListApi => { const api = { getApi } as IUploadListApi parent = inject('uploader').$children[0] - const constants = isBrowser ? (parent.$constants as IFileUploadConstants) : null + const constants = !isServer ? (parent.$constants as IFileUploadConstants) : null const $service = initService({ props, service }) const { current } = useBreakpoint() diff --git a/packages/utils/src/bigInt/index.ts b/packages/utils/src/bigInt/index.ts index 6def08f417..d6baddb1b2 100644 --- a/packages/utils/src/bigInt/index.ts +++ b/packages/utils/src/bigInt/index.ts @@ -11,9 +11,6 @@ */ import { fillChar } from '../string' -import { isBrowser } from '../browser' - -const BigInt = isBrowser ? window.BigInt : global.BigInt export function supportBigInt() { return typeof BigInt === 'function' diff --git a/packages/utils/src/browser/index.ts b/packages/utils/src/browser/index.ts deleted file mode 100644 index e8e8654690..0000000000 --- a/packages/utils/src/browser/index.ts +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright (c) 2022 - present TinyVue Authors. - * Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. - * - * Use of this source code is governed by an MIT-style license. - * - * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, - * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR - * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. - * - */ - -const getIEVersion = () => { - let version = 8 - if (!!document.addEventListener && !!window.performance) { - version = 9 - if (!!window.atob && !!window.matchMedia) { - version = 10 - if (!window.attachEvent && !document.all) { - version = 11 - } - } - } - return version -} - -const isEdge = (browser) => { - if (browser.chrome && ~navigator.userAgent.indexOf('Edg')) { - browser.name = 'edge' - browser.edge = true - delete browser.chrome - } else if (!document.documentMode && !!window.StyleMedia) { - browser.name = 'edge' - browser.edge = true - } -} - -export const isBrowser = - typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document - -export const globalEnvironment = isBrowser ? window : global - -export const browser = (() => { - const browser = { - name: undefined, - version: undefined, - isDoc: typeof document !== 'undefined', - isMobile: false, - isPC: true, - isNode: typeof window === 'undefined' - } - - if (isBrowser) { - const isMobile = /(Android|webOS|iPhone|iPad|iPod|SymbianOS|BlackBerry|Windows Phone)/.test(navigator.userAgent) - - browser.isMobile = isMobile - browser.isPC = !isMobile - - let matches - - if (!!window.chrome && (!!window.chrome.webstore || /^Google\b/.test(window.navigator.vendor))) { - browser.name = 'chrome' - browser.chrome = true - matches = navigator.userAgent.match(/chrome\/(\d+)/i) - browser.version = !!matches && !!matches[1] && parseInt(matches[1], 10) - matches = undefined - } else if (!!document.all || !!document.documentMode) { - browser.name = 'ie' - browser.version = getIEVersion() - browser.ie = true - } else if (typeof window.InstallTrigger !== 'undefined') { - browser.name = 'firefox' - browser.firefox = true - } else if (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0) { - browser.name = 'safari' - browser.safari = true - } else if ((!!window.opr && !!window.opr.addons) || !!window.opera) { - browser.name = 'opera' - browser.opera = true - } - - isEdge(browser) - - if (!~['ie', 'chrome'].indexOf(browser.name)) { - const reg = browser.name + '/(\\d+)' - matches = navigator.userAgent.match(new RegExp(reg, 'i')) - browser.version = !!matches && !!matches[1] && parseInt(matches[1], 10) - matches = undefined - } - - if (browser.isDoc) { - const bodyEl = document.body || document.documentElement - ;['webkit', 'khtml', 'moz', 'ms', 'o'].forEach((core) => { - browser['-' + core] = !!bodyEl[core + 'MatchesSelector'] - }) - } - } - - return browser -})() diff --git a/packages/utils/src/dom/index.ts b/packages/utils/src/dom/index.ts index 7b5ec4ed76..34c8695248 100644 --- a/packages/utils/src/dom/index.ts +++ b/packages/utils/src/dom/index.ts @@ -12,8 +12,8 @@ import { hasOwn, isNull } from '../type' import { globalConfig } from '../globalConfig' +import { isServer } from '../globalConfig' -export const isServer = typeof window === 'undefined' const SPECIAL_CHARS_REGEXP = /([:\-_]+(.))/g const MOZ_HACK_REGEXP = /^moz([A-Z])/ diff --git a/packages/utils/src/espace-ctrl/index.ts b/packages/utils/src/espace-ctrl/index.ts index fdf7adb6f7..77f15fd9b1 100644 --- a/packages/utils/src/espace-ctrl/index.ts +++ b/packages/utils/src/espace-ctrl/index.ts @@ -9,7 +9,7 @@ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. * */ -import { isBrowser } from '../browser' +import { isServer } from '../globalConfig' let ws = null const url = 'ws://localhost' @@ -381,7 +381,7 @@ out.addContactList = function (account, cb) { ) } -if (!isBrowser || !window.WebSocket) { +if (isServer || !window.WebSocket) { const notFn = function () { return undefined } @@ -400,7 +400,7 @@ if (!isBrowser || !window.WebSocket) { let initialized = false export function init() { - if (!initialized && isBrowser) { + if (!initialized && !isServer) { localStorage.setItem('eSpaceCtrl_initialized', 0) out.init({ timeout: 3000, pollingInterval: 1000 }) out.ready(() => { diff --git a/packages/utils/src/fastdom/singleton.ts b/packages/utils/src/fastdom/singleton.ts index 1f765b14c6..d926c3dc04 100644 --- a/packages/utils/src/fastdom/singleton.ts +++ b/packages/utils/src/fastdom/singleton.ts @@ -8,10 +8,10 @@ * @author Wilson Page * @author Kornel Lesinski */ -import { isBrowser } from '../browser' +import { isServer } from '../globalConfig' const RAF = (function () { - if (isBrowser) { + if (!isServer) { return window.requestAnimationFrame.bind(window) } return function (callback) { diff --git a/packages/utils/src/fullscreen/screenfull.ts b/packages/utils/src/fullscreen/screenfull.ts index e808c1a2bd..0162b71f17 100644 --- a/packages/utils/src/fullscreen/screenfull.ts +++ b/packages/utils/src/fullscreen/screenfull.ts @@ -11,7 +11,7 @@ */ import { on, off } from '../dom' -import { isBrowser } from '../browser' +import { isServer } from '../globalConfig' const fullscreenApi = [ 'fullscreenElement', @@ -56,7 +56,7 @@ const document = typeof window !== 'undefined' && typeof window.document !== 'un let fullscreenEvents = null const getFullScreenEvents = () => { - if (!isBrowser) return + if (isServer) return for (let i = 0, len = fullscreenApiMap.length; i < len; i++) { let eventName = fullscreenApiMap[i] @@ -90,7 +90,7 @@ const screenfull = { this.on('change', onFullscreenEntered) - element = element || (isBrowser ? document.documentElement : null) + element = element || (!isServer ? document.documentElement : null) if (element && fullscreenEvents && element[fullscreenEvents.requestFullscreen]) { const promiseReturn = element[fullscreenEvents.requestFullscreen](options) @@ -117,7 +117,7 @@ const screenfull = { this.on('change', onFullscreenExit) - if (isBrowser && fullscreenEvents && document[fullscreenEvents.exitFullscreen]) { + if (!isServer && fullscreenEvents && document[fullscreenEvents.exitFullscreen]) { const promiseReturn = document[fullscreenEvents.exitFullscreen]() if (promiseReturn instanceof Promise) { @@ -140,14 +140,14 @@ const screenfull = { on(event, callback) { const eventName = eventNameMap[event] - if (eventName && isBrowser) { + if (eventName && !isServer) { on(document, eventName, callback) } }, off(event, callback) { const eventName = eventNameMap[event] - if (eventName && isBrowser) { + if (eventName && !isServer) { off(document, eventName, callback) } }, @@ -155,7 +155,7 @@ const screenfull = { } // 处理屏幕全屏状态的方法 -if (isBrowser) { +if (!isServer) { Object.defineProperties(screenfull, { isFullscreen: { get() { diff --git a/packages/utils/src/globalConfig/index.ts b/packages/utils/src/globalConfig/index.ts index cb1fc3f3fd..bef9347444 100644 --- a/packages/utils/src/globalConfig/index.ts +++ b/packages/utils/src/globalConfig/index.ts @@ -4,3 +4,98 @@ export const globalConfig = { } export const getViewportWindow = () => globalConfig.viewportWindow || window + +export const isServer = typeof window === 'undefined' + +const getIEVersion = () => { + let version = 8 + if (!!document.addEventListener && !!window.performance) { + version = 9 + if (!!window.atob && !!window.matchMedia) { + version = 10 + if (!window.attachEvent && !document.all) { + version = 11 + } + } + } + return version +} + +const isEdge = (browser) => { + if (browser.chrome && ~navigator.userAgent.indexOf('Edg')) { + browser.name = 'edge' + browser.edge = true + delete browser.chrome + } else if (!document.documentMode && !!window.StyleMedia) { + browser.name = 'edge' + browser.edge = true + } +} + +/** 分析浏览器的版本信息 */ +export const browser = (() => { + if (isServer) return null + + const browser = { + name: '', + version: 0, + isDoc: typeof document !== 'undefined', + isMobile: false, + isPC: true, + isNode: isServer, + chrome: false, + ie: false, + firefox: false, + safari: false, + opera: false, + edge: false + } + + const isMobile = /(Android|webOS|iPhone|iPad|iPod|SymbianOS|BlackBerry|Windows Phone)/.test(navigator.userAgent) + + browser.isMobile = isMobile + browser.isPC = !isMobile + + let matches + + // 整体的浏览器判断标准已过时 + if (!!window.chrome && (!!window.chrome.webstore || /^Google\b/.test(window.navigator.vendor))) { + browser.name = 'chrome' + browser.chrome = true + matches = navigator.userAgent.match(/chrome\/(\d+)/i) + browser.version = !!matches && !!matches[1] && parseInt(matches[1], 10) + matches = undefined + } else if (!!document.all || !!document.documentMode) { + browser.name = 'ie' + browser.version = getIEVersion() + browser.ie = true + } else if (typeof window.InstallTrigger !== 'undefined') { + // 过时的判断条件, 最新的ff中已经没有该属性。 + browser.name = 'firefox' + browser.firefox = true + } else if (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0) { + browser.name = 'safari' + browser.safari = true + } else if ((!!window.opr && !!window.opr.addons) || !!window.opera) { + browser.name = 'opera' + browser.opera = true + } + + isEdge(browser) + + if (!~['ie', 'chrome'].indexOf(browser.name)) { + const reg = browser.name + '/(\\d+)' + matches = navigator.userAgent.match(new RegExp(reg, 'i')) + browser.version = !!matches && !!matches[1] && parseInt(matches[1], 10) + matches = undefined + } + + if (browser.isDoc) { + const bodyEl = document.body || document.documentElement + ;['webkit', 'khtml', 'moz', 'ms', 'o'].forEach((core) => { + browser['-' + core] = !!bodyEl[core + 'MatchesSelector'] + }) + } + + return browser +})() diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index a273b3fe04..9b4dcb020a 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -5,7 +5,7 @@ import ResizeObserver from './resize-observer' export { xss, logger, ResizeObserver } export { sha256 } from './crypt' -export { globalConfig, getViewportWindow } from './globalConfig' +export { globalConfig, getViewportWindow, isServer, browser } from './globalConfig' export { getDays, getWeek, lastMonth, nextMonth, getCalendar, transformArray, parseDate } from './calendar' @@ -71,9 +71,6 @@ export { omitText } from './string' -// 待转移到globalConfig -export { isBrowser, globalEnvironment, browser } from './browser' - export { roundFixed, Decimal, toFixed as toFixedDecimal, formatNumber, recoverNumber } from './decimal' export { each, getObj, setObj, copyField, copyArray, isEqual, isEachEqual, extend, toJsonStr, merge } from './object' @@ -188,7 +185,6 @@ export { debounce } from './debounce' export { throttle } from './throttle' export { - isServer, on, off, once, diff --git a/packages/utils/src/popper/index.ts b/packages/utils/src/popper/index.ts index f72916cbdf..6157faed57 100644 --- a/packages/utils/src/popper/index.ts +++ b/packages/utils/src/popper/index.ts @@ -12,9 +12,8 @@ import { on, off, isDisplayNone } from '../dom' import { PopupManager } from '../popup-manager' -import { globalConfig } from '../globalConfig' +import { globalConfig, isServer } from '../globalConfig' import { typeOf } from '../type' -import { isBrowser } from '../browser' const positions = ['left', 'right', 'top', 'bottom'] const modifiers = ['shift', 'offset', 'preventOverflow', 'keepTogether', 'arrow', 'flip', 'applyStyle'] @@ -275,7 +274,7 @@ const stopFn = (ev: Event) => { /** 全局的resize观察器, 监听popper的大小改变 */ const resizeOb = - isBrowser && typeof ResizeObserver === 'function' + !isServer && typeof ResizeObserver === 'function' ? new ResizeObserver((entries) => { entries.forEach((entry) => { if (entry.target.popperVm && entry.contentRect.height > 50) { @@ -377,7 +376,7 @@ export class Popper { return this[modifier] }) - if (isBrowser) { + if (!isServer) { this._popper.setAttribute('x-placement', this._options.placement) this.state.position = this._getPopperPositionByRefernce(this._reference) setStyle(this._popper, { position: this.state.position, top: 0 }) diff --git a/packages/utils/src/popup-manager/index.ts b/packages/utils/src/popup-manager/index.ts index 289b93560d..2f3df16f8e 100644 --- a/packages/utils/src/popup-manager/index.ts +++ b/packages/utils/src/popup-manager/index.ts @@ -12,8 +12,7 @@ import { KEY_CODE } from '../common' import { addClass, removeClass, on } from '../dom' - -const isServer = typeof window === 'undefined' +import { isServer } from '../globalConfig' const instances = {} as Record diff --git a/packages/utils/src/resize-event/index.ts b/packages/utils/src/resize-event/index.ts index 36538261a7..0f932ddb35 100644 --- a/packages/utils/src/resize-event/index.ts +++ b/packages/utils/src/resize-event/index.ts @@ -11,8 +11,8 @@ */ import ResizeObserver from '../resize-observer' +import { isServer } from '../globalConfig' -const isServer = typeof window === 'undefined' const cacheKey = '__resizeListeners__' /* istanbul ignore next */ diff --git a/packages/utils/src/resize-observer/index.ts b/packages/utils/src/resize-observer/index.ts index 81c1ae31c3..dd0cd9fb08 100644 --- a/packages/utils/src/resize-observer/index.ts +++ b/packages/utils/src/resize-observer/index.ts @@ -12,7 +12,7 @@ */ import { on, off } from '../dom' -import { isBrowser } from '../browser' +import { isServer } from '../globalConfig' const MapShim = (function () { if (typeof Map !== 'undefined') { @@ -97,7 +97,7 @@ const MapShim = (function () { })() })() -const func = isBrowser ? window.Function : global.Function +const func = globalThis.Function const global$1 = (function () { const isMath = (val) => val.Math === Math @@ -216,7 +216,7 @@ const ResizeObserverController = (function () { } ResizeObserverController.prototype.connect_ = function () { - if (!isBrowser || this.connected_) { + if (isServer || this.connected_) { return } @@ -243,7 +243,7 @@ const ResizeObserverController = (function () { } ResizeObserverController.prototype.disconnect_ = function () { - if (!isBrowser || !this.connected_) { + if (isServer || !this.connected_) { return } @@ -397,7 +397,7 @@ const isSVGGraphicsElement = (function () { })() const getContentRect = function (target) { - if (!isBrowser) { + if (isServer) { return emptyRect } diff --git a/packages/utils/src/scroll-into-view/index.ts b/packages/utils/src/scroll-into-view/index.ts index b7c101b8d8..6114cd43e7 100644 --- a/packages/utils/src/scroll-into-view/index.ts +++ b/packages/utils/src/scroll-into-view/index.ts @@ -10,7 +10,7 @@ * */ -const isServer = typeof window === 'undefined' +import { isServer } from '../globalConfig' export const scrollIntoView = (container, selected) => { if (isServer) { diff --git a/packages/utils/src/scroll-width/index.ts b/packages/utils/src/scroll-width/index.ts index 9c4ec0b56d..d99a5f153b 100644 --- a/packages/utils/src/scroll-width/index.ts +++ b/packages/utils/src/scroll-width/index.ts @@ -10,8 +10,9 @@ * */ +import { isServer } from '../globalConfig' + let scrollBarWidth: number -const isServer = typeof window === 'undefined' // 通过构造2层div,计算出来滚动条的宽度,并全局缓存值 export function scrollWidth() { diff --git a/packages/utils/src/string/index.ts b/packages/utils/src/string/index.ts index 2be9f35b35..4f6f02ecd3 100644 --- a/packages/utils/src/string/index.ts +++ b/packages/utils/src/string/index.ts @@ -13,7 +13,7 @@ import { isPlainObject, isNumber, isNumeric, isNull } from '../type' import { getObj, toJsonStr } from '../object' import { toFixed, Decimal } from '../decimal' -import { globalEnvironment, isBrowser } from '../browser' +import { isServer } from '../globalConfig' /** * 文本替换格式类型 @@ -243,7 +243,7 @@ export const fillChar = (string, length, append, chr = '0') => { export const random = () => { let MAX_UINT32_PLUS_ONE = 4294967296 - return globalEnvironment.crypto.getRandomValues(new globalEnvironment.Uint32Array(1))[0] / MAX_UINT32_PLUS_ONE + return globalThis.crypto.getRandomValues(new Uint32Array(1))[0] / MAX_UINT32_PLUS_ONE } /** @@ -811,7 +811,7 @@ export const isKorean = (text) => /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi.test( */ export const omitText = (text: string, font: string, w: number) => { let t: string - if (!isBrowser) return { t: text, o: false } + if (isServer) return { t: text, o: false } const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') diff --git a/packages/utils/src/touch-emulator/index.ts b/packages/utils/src/touch-emulator/index.ts index bc890f9dcc..3f6ee8fe40 100644 --- a/packages/utils/src/touch-emulator/index.ts +++ b/packages/utils/src/touch-emulator/index.ts @@ -1,14 +1,14 @@ -import { isBrowser } from '../browser' +import { isServer } from '../globalConfig' let emulated = false let initiated = false let eventTarget = null let mouseTarget = null -const matches = isBrowser ? Element.prototype.matches : null +const matches = !isServer ? Element.prototype.matches : null const closest = (el, s) => { - if (isBrowser) { + if (!isServer) { do { if (matches.call(el, s)) return el el = el.parentElement || el.parentNode @@ -114,7 +114,7 @@ const touchEmulator = () => { } export const emulate = () => { - if (isBrowser) { + if (!isServer) { const supportTouch = 'ontouchstart' in window if (!emulated && !supportTouch) { emulated = true diff --git a/packages/vue-common/src/breakpoint.ts b/packages/vue-common/src/breakpoint.ts index 4ea063e77d..62b5677b9a 100644 --- a/packages/vue-common/src/breakpoint.ts +++ b/packages/vue-common/src/breakpoint.ts @@ -1,5 +1,5 @@ import hooks from './adapter' -import { isServer } from '@opentiny/vue-renderless/common/deps/dom' +import { isServer } from '@opentiny/utils' import debounce from '@opentiny/vue-renderless/common/deps/debounce' /** diff --git a/packages/vue-directive/src/clickoutside.ts b/packages/vue-directive/src/clickoutside.ts index 129ee8b451..e87cac6877 100644 --- a/packages/vue-directive/src/clickoutside.ts +++ b/packages/vue-directive/src/clickoutside.ts @@ -10,9 +10,8 @@ * */ -import { on } from '@opentiny/utils' +import { on, isServer } from '@opentiny/utils' -const isServer = typeof window === 'undefined' const nodeList = [] const nameSpace = '@@clickoutsideContext' let startClick diff --git a/packages/vue-hooks/src/vue-popper.ts b/packages/vue-hooks/src/vue-popper.ts index b0b213ca1f..beffe6c9c9 100644 --- a/packages/vue-hooks/src/vue-popper.ts +++ b/packages/vue-hooks/src/vue-popper.ts @@ -15,6 +15,8 @@ import { PopupManager, Popper as PopperJS, on, off, isDisplayNone } from '@opent // todo import type { ISharedRenderlessFunctionParams } from 'types/shared.type' +import { isServer } from '@opentiny/utils' + export interface IPopperState { popperJS: Popper appended: boolean @@ -33,8 +35,6 @@ type IPopperInputParams = ISharedRenderlessFunctionParams & { /** 给 popper 的click添加stop, 阻止冒泡 */ const stop = (e: Event) => e.stopPropagation() -const isServer = typeof window === 'undefined' - // 由于多个组件传入reference元素的方式不同,所以这里从多处查找。 const getReference = ({ state, props, vm, slots }: Pick) => { let reference = diff --git a/packages/vue-hooks/src/vue-popup.ts b/packages/vue-hooks/src/vue-popup.ts index 23100757c7..6f129f107f 100644 --- a/packages/vue-hooks/src/vue-popup.ts +++ b/packages/vue-hooks/src/vue-popup.ts @@ -14,9 +14,9 @@ import { merge, PopupManager, addClass } from '@opentiny/utils' // todo import type { ISharedRenderlessFunctionParams } from 'types/shared.type' +import { isServer } from '@opentiny/utils' let idSeed = 1 -const isServer = typeof window === 'undefined' export interface IPopupState { opened: boolean diff --git a/packages/vue/src/float-button/src/index.ts b/packages/vue/src/float-button/src/index.ts index 83d6e81818..be395276fe 100644 --- a/packages/vue/src/float-button/src/index.ts +++ b/packages/vue/src/float-button/src/index.ts @@ -11,7 +11,7 @@ */ import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common' import template from 'virtual-template?pc' -import { isBrowser } from '@opentiny/vue-renderless/common/browser' +import { isServer } from '@opentiny/utils' export const floatButtonProps = { ...$props, @@ -95,8 +95,8 @@ export const floatButtonProps = { }, // 设置需要监听其滚动事件的元素 element: { - default: isBrowser ? document.body : null, - type: isBrowser ? HTMLElement : Object + default: !isServer ? document.body : null, + type: !isServer ? HTMLElement : Object } } diff --git a/packages/vue/src/grid/src/table/src/table.ts b/packages/vue/src/grid/src/table/src/table.ts index ed812e71ca..5b2c17b1eb 100644 --- a/packages/vue/src/grid/src/table/src/table.ts +++ b/packages/vue/src/grid/src/table/src/table.ts @@ -41,7 +41,7 @@ import { error } from '../../tools' import { clearOnTableUnmount } from './strategy' import MfTable from '../../mobile-first/index.vue' import { useDrag, useRowGroup } from '../../composable' -import { isBrowser } from '@opentiny/vue-renderless/common/browser' +import { isServer } from '@opentiny/utils' const { themes, viewConfig, columnLevelKey, defaultColumnName } = GlobalConfig const { TINY: T_TINY, SAAS: T_SAAS } = themes @@ -1011,7 +1011,7 @@ export default defineComponent({ useRelation({ relationKey: `${columnLevelKey}-${id.value}`, childrenKey: 'childColumns', - relationContainer: () => (isBrowser ? $table.$el.querySelector(`.${hiddenContainerClass}`) : null), + relationContainer: () => (!isServer ? $table.$el.querySelector(`.${hiddenContainerClass}`) : null), onChange: () => { const collectKey = $table.computeCollectKey() diff --git a/packages/vue/src/image/src/index.ts b/packages/vue/src/image/src/index.ts index ddc3f2a19c..761ef06adc 100644 --- a/packages/vue/src/image/src/index.ts +++ b/packages/vue/src/image/src/index.ts @@ -12,7 +12,7 @@ import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common' import type { IImageApi } from '@opentiny/vue-renderless/types/image.type' import template from 'virtual-template?pc|mobile-first' -import { isBrowser } from '@opentiny/vue-renderless/common/browser' +import { isServer } from '@opentiny/utils' export const $constants = { NONE: 'none', @@ -36,7 +36,7 @@ export const imageProps = { default: () => [] }, scrollContainer: { - type: isBrowser ? [String, HTMLElement] : null, + type: !isServer ? [String, HTMLElement] : null, default: null }, src: String, From 6e7aacd4abf139af6d3389f286970514f84873d8 Mon Sep 17 00:00:00 2001 From: shenjunjian <40288193@qq.com> Date: Sat, 25 Jan 2025 19:27:00 -0800 Subject: [PATCH 03/25] =?UTF-8?q?fix(utils):=20=E7=A7=BB=E9=99=A4=20prop-u?= =?UTF-8?q?til=20=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/utils/src/index.ts | 13 ------- packages/utils/src/prop-util/index.ts | 39 ------------------- .../vue/src/virtual-scroll-box/src/index.ts | 25 ++++++------ packages/vue/src/virtual-tree/src/index.ts | 17 +++++--- 4 files changed, 23 insertions(+), 71 deletions(-) delete mode 100644 packages/utils/src/prop-util/index.ts diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 9b4dcb020a..9e66487519 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -118,19 +118,6 @@ export { emitEvent, getActualTarget, correctTarget } from './event' export { noop, callInterceptor } from './function' -// 当真有人这么用的吗? 待移除 -export { - unknownProp, - numericProp, - truthProp, - makeRequiredProp, - makeArrayProp, - makeNumberProp, - makeNumericProp, - makeStringProp, - makeStringValidProp -} from './prop-util' - export { fastdom, fastdomAsync, fastdomSandbox } from './fastdom' // 待移除。 移到fullscreen组件 内部去, 或起个更好的名字 diff --git a/packages/utils/src/prop-util/index.ts b/packages/utils/src/prop-util/index.ts deleted file mode 100644 index 4cb818c755..0000000000 --- a/packages/utils/src/prop-util/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -export const unknownProp = null - -export const numericProp = [Number, String] - -export const truthProp = { - type: Boolean, - default: true -} - -export const makeRequiredProp = (type) => ({ - type, - required: true -}) - -export const makeArrayProp = () => ({ - type: Array, - default: () => [] -}) - -export const makeNumberProp = (defaultVal) => ({ - type: Number, - default: defaultVal -}) - -export const makeNumericProp = (defaultVal) => ({ - type: numericProp, - default: defaultVal -}) - -export const makeStringProp = (defaultVal) => ({ - type: String, - default: defaultVal -}) - -export const makeStringValidProp = (defaultVal, optionals = []) => ({ - type: String, - default: defaultVal, - validator: (val) => optionals.includes(val) -}) diff --git a/packages/vue/src/virtual-scroll-box/src/index.ts b/packages/vue/src/virtual-scroll-box/src/index.ts index f7b19a522f..6c5d555be2 100644 --- a/packages/vue/src/virtual-scroll-box/src/index.ts +++ b/packages/vue/src/virtual-scroll-box/src/index.ts @@ -1,5 +1,4 @@ import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common' -import { numericProp, makeNumericProp, makeArrayProp } from '@opentiny/vue-renderless/common/prop-util' import template from 'virtual-template?pc' @@ -7,18 +6,18 @@ export default defineComponent({ name: $prefix + 'VirtualScrollBox', props: { ...$props, - width: numericProp, // 区域的宽度 - height: numericProp, // 区域的高度 - rowBuffer: makeNumericProp(200), // 行缓冲区高度 - columnBuffer: makeNumericProp(200), // 列缓冲区宽度 - scrollbarSize: numericProp, // 滚动条尺寸 - columns: makeArrayProp(), // 所有的列 - columnSizes: makeArrayProp(), // 每个列对应的宽度 - rows: makeArrayProp(), // 所有的行 - rowSizes: makeArrayProp(), // 每个行对应的高度 - fixedRows: makeArrayProp(), // 行固定配置 - fixedColumns: makeArrayProp(), // 列固定配置 - spanConfig: makeArrayProp() // 单元格合并配置 + width: [Number, String], // 区域的宽度 + height: [Number, String], // 区域的高度 + rowBuffer: { type: [Number, String], default: 200 }, // 行缓冲区高度 + columnBuffer: { type: [Number, String], default: 200 }, // 列缓冲区宽度 + scrollbarSize: [Number, String], // 滚动条尺寸 + columns: { type: Array, default: () => [] }, // 所有的列 + columnSizes: { type: Array, default: () => [] }, // 每个列对应的宽度 + rows: { type: Array, default: () => [] }, // 所有的行 + rowSizes: { type: Array, default: () => [] }, // 每个行对应的高度 + fixedRows: { type: Array, default: () => [] }, // 行固定配置 + fixedColumns: { type: Array, default: () => [] }, // 列固定配置 + spanConfig: { type: Array, default: () => [] } // 单元格合并配置 }, setup(props, context) { return $setup({ props, context, template }) diff --git a/packages/vue/src/virtual-tree/src/index.ts b/packages/vue/src/virtual-tree/src/index.ts index d7d8b013eb..09109870e3 100644 --- a/packages/vue/src/virtual-tree/src/index.ts +++ b/packages/vue/src/virtual-tree/src/index.ts @@ -1,5 +1,4 @@ import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common' -import { numericProp, makeNumericProp, unknownProp } from '@opentiny/vue-renderless/common/prop-util' import template from 'virtual-template?pc' @@ -7,11 +6,17 @@ export default defineComponent({ name: $prefix + 'VirtualTree', props: { ...$props, - width: numericProp, - height: numericProp, - rowHeight: makeNumericProp(36), - scrollbarSize: makeNumericProp(6), - treeOp: unknownProp + width: [Number, String], + height: [Number, String], + rowHeight: { + type: Number, + default: 36 + }, + scrollbarSize: { + type: Number, + default: 6 + }, + treeOp: null }, setup(props, context) { return $setup({ props, context, template }) From dba8c929714fa9e09b4b0e2031ada4f53186a475 Mon Sep 17 00:00:00 2001 From: shenjunjian <40288193@qq.com> Date: Sun, 26 Jan 2025 22:45:57 -0800 Subject: [PATCH 04/25] =?UTF-8?q?fix(utils):=20=E6=9B=B4=E6=96=B0date,=20c?= =?UTF-8?q?alendar,date-utils,=20type=E5=9B=9B=E4=B8=AA=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderless/src/calendar-bar/index.ts | 2 +- .../renderless/src/calendar-view/index.ts | 2 +- packages/renderless/src/calendar/index.ts | 2 +- packages/renderless/src/date-panel/index.ts | 20 +- packages/renderless/src/date-panel/vue.ts | 4 +- packages/renderless/src/date-range/index.ts | 60 +-- packages/renderless/src/date-range/vue.ts | 4 +- packages/utils/src/date-util/fecha.ts | 343 ++++++++++++++++++ packages/utils/src/date-util/index.ts | 2 +- packages/utils/src/index.ts | 79 ++-- packages/vue/src/date-table/src/index.ts | 4 +- packages/vue/src/grid-toolbar/src/index.ts | 2 +- packages/vue/src/grid/src/body/src/body.tsx | 3 +- .../vue/src/grid/src/footer/src/footer.ts | 2 +- .../vue/src/grid/src/header/src/header.ts | 2 +- .../vue/src/grid/src/table/src/methods.ts | 3 +- packages/vue/src/grid/src/table/src/table.ts | 3 +- packages/vue/src/grid/src/tools/formatter.ts | 2 +- .../vue/src/image-viewer/src/mobileTouch.ts | 17 +- packages/vue/src/month-table/package.json | 19 +- packages/vue/src/month-table/src/pc.vue | 6 +- .../vue/src/recycle-scroller/src/idState.ts | 2 +- packages/vue/src/year-table/src/index.ts | 4 +- 23 files changed, 466 insertions(+), 121 deletions(-) create mode 100644 packages/utils/src/date-util/fecha.ts diff --git a/packages/renderless/src/calendar-bar/index.ts b/packages/renderless/src/calendar-bar/index.ts index d4771279c7..e0a03eb8ce 100644 --- a/packages/renderless/src/calendar-bar/index.ts +++ b/packages/renderless/src/calendar-bar/index.ts @@ -1,4 +1,4 @@ -import { lastMonth, nextMonth } from '../common/calendar/calendar' +import { lastMonth, nextMonth } from '@opentiny/utils' import { getDirection } from '../common/deps/touch' const normalConfig = (config, state) => { diff --git a/packages/renderless/src/calendar-view/index.ts b/packages/renderless/src/calendar-view/index.ts index 6137dc3c73..dd5f182228 100644 --- a/packages/renderless/src/calendar-view/index.ts +++ b/packages/renderless/src/calendar-view/index.ts @@ -1,6 +1,6 @@ import { cloneDeep } from '../chart-core/deps/utils' import { getDirection } from '../common/deps/touch' -import { getDays, lastMonth, nextMonth, getCalendar, transformArray } from '../common/calendar/calendar' +import { getDays, lastMonth, nextMonth, getCalendar, transformArray } from '@opentiny/utils' const getTime = (date) => new Date(date).getTime() diff --git a/packages/renderless/src/calendar/index.ts b/packages/renderless/src/calendar/index.ts index cf8bbb260d..2c593a7ff5 100644 --- a/packages/renderless/src/calendar/index.ts +++ b/packages/renderless/src/calendar/index.ts @@ -11,7 +11,7 @@ */ import { copyArray } from '../common/object' -import { lastMonth, nextMonth, getCalendar, transformArray, parseDate } from '../common/calendar/calendar' +import { lastMonth, nextMonth, getCalendar, transformArray, parseDate } from '@opentiny/utils' export const computedCalendar = ({ state }) => diff --git a/packages/renderless/src/date-panel/index.ts b/packages/renderless/src/date-panel/index.ts index 985d26e7ce..fe39d6ca15 100644 --- a/packages/renderless/src/date-panel/index.ts +++ b/packages/renderless/src/date-panel/index.ts @@ -13,22 +13,22 @@ import { getWeekData } from '../picker' import debounce from '../common/deps/debounce' import { - isDate, - parseDate, + isDate1, + parseDate1, modifyDate, modifyTime, clearTime, prevYear, nextYear, prevMonth, - nextMonth, + nextMonth1, timeWithinRange, clearMilliseconds, modifyWithTimeString, changeYearMonthAndClampDate, formatDate, extractTimeFormat -} from '../common/deps/date-util' +} from '@opentiny/utils' import { DATEPICKER } from '../common' import { on, off } from '../common/deps/dom' import { getDateWithNewTimezone, getLocalTimezone } from '../common/date' @@ -60,7 +60,7 @@ export const watchValue = return } - if (isDate(value)) { + if (isDate1(value)) { state.date = state.selectionMode === 'week' ? getWeekData(value) : new Date(value) } else { state.date = api.getDefaultValue() @@ -70,7 +70,7 @@ export const watchValue = export const watchDefaultValue = ({ state }) => (value) => { - if (!isDate(state.value)) { + if (!isDate1(state.value)) { state.date = value ? new Date(value) : new Date() } } @@ -192,7 +192,7 @@ export const cusPrevMonth = export const cusNextMonth = ({ state }) => () => - (state.date = nextMonth(state.date)) + (state.date = nextMonth1(state.date)) export const cusPrevYear = ({ state }) => @@ -238,7 +238,7 @@ export const doPick = (emit) => (date) => { export const handleTimePick = ({ api, state, t }) => (value, visible, first) => { - if (isDate(value)) { + if (isDate1(value)) { const newDate = state.value ? modifyTime(state.value, value.getHours(), value.getMinutes(), value.getSeconds()) : modifyWithTimeString(api.getDefaultValue(), state.defaultTime, t) @@ -487,7 +487,7 @@ export const handleKeyControl = export const handleVisibleTimeChange = ({ api, vm, state, t }) => (value) => { - const time = parseDate(value, state.timeFormat, t) + const time = parseDate1(value, state.timeFormat, t) if (time && api.checkDateWithinRange(time)) { state.date = modifyDate(time, state.year, state.month, state.monthDate) @@ -505,7 +505,7 @@ export const handleVisibleTimeChange = export const handleVisibleDateChange = ({ api, state, t }) => (value) => { - const date = parseDate(value, state.dateFormat, t) + const date = parseDate1(value, state.dateFormat, t) if (date) { if (typeof state.disabledDate === 'function' && state.disabledDate(date)) { diff --git a/packages/renderless/src/date-panel/vue.ts b/packages/renderless/src/date-panel/vue.ts index e54062b479..c0c348e59e 100644 --- a/packages/renderless/src/date-panel/vue.ts +++ b/packages/renderless/src/date-panel/vue.ts @@ -58,7 +58,7 @@ import { getDisabledConfirm, getNowTime } from './index' -import { toDate, getWeekNumber, modifyDate, extractDateFormat } from '../common/deps/date-util' +import { toDate1, getWeekNumber, modifyDate, extractDateFormat } from '@opentiny/utils' import { DATEPICKER, DATE } from '../common' export const api = [ @@ -146,7 +146,7 @@ const initWatch = ({ watch, state, api, nextTick, props }) => { watch( () => props.modelValue, (value) => { - let newVal = toDate(value) + let newVal = toDate1(value) if (newVal) { const newDate = modifyDate(newVal, newVal.getFullYear(), newVal.getMonth(), newVal.getUTCDate()) state.date = newDate diff --git a/packages/renderless/src/date-range/index.ts b/packages/renderless/src/date-range/index.ts index e148c02b3b..e529e4eac6 100644 --- a/packages/renderless/src/date-range/index.ts +++ b/packages/renderless/src/date-range/index.ts @@ -11,18 +11,18 @@ */ import { - isDate, + toDate1, nextDate, - parseDate, + parseDate1, formatDate, modifyDate, modifyTime, nextYear, prevYear, - nextMonth, + nextMonth1, prevMonth, modifyWithTimeString -} from '../common/deps/date-util' +} from '@opentiny/utils' export const calcDefaultValue = (defaultVal) => { if (Array.isArray(defaultVal)) { @@ -115,7 +115,7 @@ export const watchMinDate = const format = 'HH:mm:ss' minTimePicker.state.selectableRange = [ - [parseDate(formatDate(state.minDate, format, t), format, t), parseDate('23:59:59', format, t)] + [parseDate1(formatDate(state.minDate, format, t), format, t), parseDate1('23:59:59', format, t)] ] } @@ -164,8 +164,8 @@ export const watchValue = state.minDate = null state.maxDate = null } else if (Array.isArray(value)) { - state.minDate = isDate(value[0]) ? new Date(value[0]) : null - state.maxDate = isDate(value[1]) ? new Date(value[1]) : null + state.minDate = toDate1(value[0]) ? new Date(value[0]) : null + state.maxDate = toDate1(value[1]) ? new Date(value[1]) : null if (state.minDate) { state.leftDate = state.minDate @@ -177,13 +177,13 @@ export const watchValue = const maxDateMonth = state.maxDate.getMonth() state.rightDate = - minDateYear === maxDateYear && minDateMonth === maxDateMonth ? nextMonth(state.maxDate) : state.maxDate + minDateYear === maxDateYear && minDateMonth === maxDateMonth ? nextMonth1(state.maxDate) : state.maxDate } else { - state.rightDate = nextMonth(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) } } else { state.leftDate = calcDefaultValue(state.defaultValue)[0] - state.rightDate = nextMonth(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) } } } @@ -195,7 +195,7 @@ export const watchDefault = const [left, right] = calcDefaultValue(value) state.leftDate = left - state.rightDate = value && value[1] && state.unlinkPanels ? right : nextMonth(state.leftDate) + state.rightDate = value && value[1] && state.unlinkPanels ? right : nextMonth1(state.leftDate) } } @@ -205,7 +205,7 @@ export const handleClear = state.minDate = null state.maxDate = null state.leftDate = calcDefaultValue(state.defaultValue)[0] - state.rightDate = nextMonth(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) state.rangeState.selecting = false // tiny 新增下面行 state.rangeState.endDate = null @@ -228,7 +228,7 @@ export const handleDateInput = return } - const parsedValue = parseDate(value, state.dateFormat, t) + const parsedValue = parseDate1(value, state.dateFormat, t) if (parsedValue) { if (typeof state.disabledDate === 'function' && state.disabledDate(new Date(parsedValue))) { @@ -246,7 +246,7 @@ export const handleDateInput = state.leftDate = new Date(parsedValue) if (!state.unlinkPanels) { - state.rightDate = nextMonth(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) } } else { state.maxDate = modifyDate( @@ -268,7 +268,7 @@ export const handleDateInput = export const handleDateChange = ({ state, t }) => (value, type) => { - const parsedValue = parseDate(value, state.dateFormat, t) + const parsedValue = parseDate1(value, state.dateFormat, t) if (parsedValue) { if (type === 'min') { @@ -306,7 +306,7 @@ export const handleTimeInput = return } - const parsedValue = parseDate(value, state.timeFormat, t) + const parsedValue = parseDate1(value, state.timeFormat, t) if (parsedValue) { if (type === 'min') { @@ -330,7 +330,7 @@ export const handleTimeInput = export const handleTimeChange = ({ state, t, vm }) => (value, type) => { - const parsedValue = parseDate(value, state.timeFormat, t) + const parsedValue = parseDate1(value, state.timeFormat, t) if (parsedValue) { if (type === 'min') { @@ -410,10 +410,10 @@ export const handleShortcutClick = (state, api) => (shortcut) => { state.shortcutType = shortcut.type state.shortcutText = shortcut.text - if (shortcut.type === 'startFrom' && shortcut.endDate && isDate(shortcut.endDate)) { + if (shortcut.type === 'startFrom' && shortcut.endDate && toDate1(shortcut.endDate)) { state.maxRangeDate = shortcut.endDate } - if (shortcut.type === 'endAt' && shortcut.startDate && isDate(shortcut.startDate)) { + if (shortcut.type === 'endAt' && shortcut.startDate && toDate1(shortcut.startDate)) { state.minRangeDate = shortcut.startDate } @@ -480,7 +480,7 @@ export const leftPrevYear = state.leftDate = prevYear(state.leftDate) if (!state.unlinkPanels) { - state.rightDate = nextMonth(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) } } @@ -490,7 +490,7 @@ export const leftPrevMonth = state.leftDate = prevMonth(state.leftDate) if (!state.unlinkPanels) { - state.rightDate = nextMonth(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) } } @@ -501,7 +501,7 @@ export const rightNextYear = if (!unlinkPanels) { state.leftDate = nextYear(leftDate) - state.rightDate = nextMonth(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) } else { state.rightDate = nextYear(rightDate) } @@ -511,10 +511,10 @@ export const rightNextMonth = ({ state }) => () => { if (!state.unlinkPanels) { - state.leftDate = nextMonth(state.leftDate) - state.rightDate = nextMonth(state.leftDate) + state.leftDate = nextMonth1(state.leftDate) + state.rightDate = nextMonth1(state.leftDate) } else { - state.rightDate = nextMonth(state.rightDate) + state.rightDate = nextMonth1(state.rightDate) } } @@ -526,7 +526,7 @@ export const leftNextYear = export const leftNextMonth = ({ state }) => () => - (state.leftDate = nextMonth(state.leftDate)) + (state.leftDate = nextMonth1(state.leftDate)) export const rightPrevYear = ({ state }) => @@ -553,16 +553,16 @@ export const isValidValue = value && value[0] && value[1] && - isDate(value[0]) && - isDate(value[1]) && + toDate1(value[0]) && + toDate1(value[1]) && value[0].getTime() <= value[1].getTime() && (typeof state.disabledDate === 'function' ? !state.disabledDate(value[0]) && !state.disabledDate(value[1]) : true) export const resetView = ({ state }) => () => { - state.minDate = state.value && isDate(state.value[0]) ? new Date(state.value[0]) : null - state.maxDate = state.value && isDate(state.value[0]) ? new Date(state.value[1]) : null + state.minDate = state.value && toDate1(state.value[0]) ? new Date(state.value[0]) : null + state.maxDate = state.value && toDate1(state.value[0]) ? new Date(state.value[1]) : null } export const setTimeFormat = diff --git a/packages/renderless/src/date-range/vue.ts b/packages/renderless/src/date-range/vue.ts index 3cce39cec5..0ffa7f8ed7 100644 --- a/packages/renderless/src/date-range/vue.ts +++ b/packages/renderless/src/date-range/vue.ts @@ -52,7 +52,7 @@ import { computerEnableYearArrow, watchPickerVisible } from './index' -import { nextMonth, extractDateFormat, extractTimeFormat } from '../common/deps/date-util' +import { nextMonth1, extractDateFormat, extractTimeFormat } from '@opentiny/utils' export const api = [ 'state', @@ -95,7 +95,7 @@ const initState = ({ reactive, computed, api, constants, designConfig }) => { minRangeDate: constants.startDate, maxRangeDate: constants.endDate, leftDate: new Date(), - rightDate: nextMonth(new Date()), + rightDate: nextMonth1(new Date()), rangeState: { endDate: null, selecting: false, row: null, column: null }, showTime: false, format: '', diff --git a/packages/utils/src/date-util/fecha.ts b/packages/utils/src/date-util/fecha.ts new file mode 100644 index 0000000000..9dd32ce951 --- /dev/null +++ b/packages/utils/src/date-util/fecha.ts @@ -0,0 +1,343 @@ +/** + * Copyright (c) 2022 - present TinyVue Authors. + * Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. + * + * Use of this source code is governed by an MIT-style license. + * + * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, + * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR + * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. + * + */ + +import { DATEPICKER } from '../common' +import { isNull, isDate } from '../type' + +/** 西班牙语的“日期,日子”,此处为日期辅助对象,其下有i18n,masks,format,parse等辅助方法 */ +const fecha = {} +const digitsReg = ['\\d\\d?', '\\d{3}', '\\d{4}'] +const twoDigits = digitsReg[0] +const threeDigits = digitsReg[1] +const fourDigits = digitsReg[2] +const word = '[^\\s]+' +const literal = /\[([^]*?)\]/gm +const noop = () => undefined +const formats = { + shortDate: 'M/D/yy', + mediumDate: 'MMM d, yyyy', + longDate: 'MMMM d, yyyy', + fullDate: 'dddd, MMMM d, yyyy', + default: 'ddd MMM dd yyyy HH:mm:ss', + shortTime: 'HH:mm', + mediumTime: 'HH:mm:ss', + longTime: 'HH:mm:ss.SSS' +} + +const shorten = (arr, sLen) => { + let newArr = [] + + for (let i = 0, len = arr.length; i < len; i++) { + newArr.push(arr[i].substr(0, sLen)) + } + + return newArr +} + +const monthUpdate = (arrName) => (date, value, i18n) => { + const index = i18n[arrName].indexOf(value.charAt(0).toUpperCase() + value.substr(1).toLowerCase()) + + if (~index) { + date.month = index + } +} + +const pad = (val, len) => { + val = String(val) + len = len || 2 + + while (val.length < len) { + val = '0' + val + } + + return val +} + +const regexEscape = (str) => str.replace(/[|\\{()[^$+*?.-]/g, '\\$&') + +const fullTimeReg = /d{1,4}|M{1,4}|yy(?:yy)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g +const dayNames = DATEPICKER.fullWeeks +const monthNames = DATEPICKER.fullMonths +const monthNamesShort = shorten(monthNames, 3) +const dayNamesShort = shorten(dayNames, 3) +const parts = ['th', 'st', 'nd', 'rd'] + +fecha.i18n = { + dayNames, + monthNames, + dayNamesShort, + monthNamesShort, + amPm: ['am', 'pm'], + doFn: (D) => D + parts[D % 10 > 3 ? 0 : ((D - (D % 10) !== 10) * D) % 10] +} + +const formatFlags = { + D: (dateObj) => dateObj.getDay(), + DD: (dateObj) => pad(dateObj.getDay()), + Do: (dateObj, i18n) => i18n.doFn(dateObj.getDate()), + d: (dateObj) => dateObj.getDate(), + dd: (dateObj) => pad(dateObj.getDate()), + ddd: (dateObj, i18n) => i18n.dayNamesShort[dateObj.getDay()], + dddd: (dateObj, i18n) => i18n.dayNames[dateObj.getDay()], + M: (dateObj) => dateObj.getMonth() + 1, + MM: (dateObj) => pad(dateObj.getMonth() + 1), + MMM: (dateObj, i18n) => i18n.monthNamesShort[dateObj.getMonth()], + MMMM: (dateObj, i18n) => i18n.monthNames[dateObj.getMonth()], + yy: (dateObj) => pad(String(dateObj.getFullYear()), 4).substr(2), + yyyy: (dateObj) => pad(dateObj.getFullYear(), 4), + h: (dateObj) => dateObj.getHours() % 12 || 12, + hh: (dateObj) => pad(dateObj.getHours() % 12 || 12), + H: (dateObj) => dateObj.getHours(), + HH: (dateObj) => pad(dateObj.getHours()), + m: (dateObj) => dateObj.getMinutes(), + mm: (dateObj) => pad(dateObj.getMinutes()), + s: (dateObj) => dateObj.getSeconds(), + ss: (dateObj) => pad(dateObj.getSeconds()), + S: (dateObj) => Math.round(dateObj.getMilliseconds() / 100), + SS: (dateObj) => pad(Math.round(dateObj.getMilliseconds() / 10), 2), + SSS: (dateObj) => pad(dateObj.getMilliseconds(), 3), + a: (dateObj, i18n) => (dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1]), + A: (dateObj, i18n) => (dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase()), + ZZ: (dateObj) => { + const offset = dateObj.getTimezoneOffset() + return (offset > 0 ? '-' : '+') + pad(Math.floor(Math.abs(offset) / 60) * 100 + (Math.abs(offset) % 60), 4) + } +} + +const parseFlags = { + d: [ + twoDigits, + (date, value) => { + date.day = value + } + ], + Do: [ + twoDigits + word, + (date, value) => { + date.day = parseInt(value, 10) + } + ], + M: [ + twoDigits, + (date, value) => { + date.month = value - 1 + } + ], + yy: [ + twoDigits, + (date, value) => { + const now = new Date() + const cent = Number(String(now.getFullYear()).substr(0, 2)) + date.year = String(value > 68 ? cent - 1 : cent) + value + } + ], + h: [ + twoDigits, + (date, value) => { + date.hour = value + } + ], + m: [ + twoDigits, + (date, value) => { + date.minute = value + } + ], + s: [ + twoDigits, + (date, value) => { + date.second = value + } + ], + yyyy: [ + fourDigits, + (date, value) => { + date.year = value + } + ], + S: [ + '\\d', + (date, value) => { + date.millisecond = value * 100 + } + ], + SS: [ + '\\d{2}', + (date, value) => { + date.millisecond = value * 10 + } + ], + SSS: [ + threeDigits, + (date, value) => { + date.millisecond = value + } + ], + D: [twoDigits, noop], + ddd: [word, noop], + MMM: [word, monthUpdate('monthNamesShort')], + MMMM: [word, monthUpdate('monthNames')], + a: [ + word, + (date, value, i18n) => { + const val = value.toLowerCase() + if (val === i18n.amPm[0]) { + date.isPm = false + } else if (val === i18n.amPm[1]) { + date.isPm = true + } + } + ], + ZZ: [ + '[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z', + (date, value) => { + let parts = String(value).match(/([+-]|\d\d)/gi) + let minutes + + if (parts) { + minutes = Number(parts[1] * 60) + parseInt(parts[2], 10) + date.timezoneOffset = parts[0] === '+' ? minutes : -minutes + } + } + ] +} + +const fmts = ['A', 'DD', 'dd', 'mm', 'hh', 'MM', 'ss', 'hh', 'H', 'HH'] + +fecha.masks = formats +parseFlags.dddd = parseFlags.ddd + +fmts.forEach((name) => { + if (name === 'MM') { + parseFlags[name] = parseFlags[name.substr(0, 1)] + } else { + parseFlags[name] = parseFlags[name.substr(0, 1).toLowerCase()] + } +}) + +fecha.format = (dateObj, mask, i18nSettings) => { + const i18n = i18nSettings || fecha.i18n + + if (typeof dateObj === 'number') { + dateObj = new Date(dateObj) + } + + if (!isDate(dateObj) || isNaN(dateObj.getTime())) { + throw new Error('Invalid Date in fecha.format') + } + + mask = fecha.masks[mask] || mask || fecha.masks.default + + let literals = [] + + mask = mask.replace(literal, ($0, $1) => { + literals.push($1) + return '@@@' + }) + + mask = mask.replace(fullTimeReg, ($0) => + $0 in formatFlags ? formatFlags[$0](dateObj, i18n) : $0.slice(1, $0.length - 1) + ) + + return mask.replace(/@@@/g, () => literals.shift()) +} + +const getNewFormat = (format, parseInfo) => { + let literals = [] + + let newFormat = regexEscape(format).replace(fullTimeReg, ($0) => { + if (parseFlags[$0]) { + const info = parseFlags[$0] + parseInfo.push(info[1]) + + return '(' + info[0] + ')' + } + + return $0 + }) + + newFormat = newFormat.replace(/@@@/g, () => literals.shift()) + + return newFormat +} + +const getDate = (dateInfo) => { + let date + const today = new Date() + + if (!isNull(dateInfo.timezoneOffset)) { + dateInfo.minute = Number(dateInfo.minute || 0) - Number(dateInfo.timezoneOffset) + + const { year, month, day, hour, minute, second, millisecond } = dateInfo + + date = new Date( + Date.UTC(year || today.getFullYear(), month || 0, day || 1, hour || 0, minute || 0, second || 0, millisecond || 0) + ) + } else { + const { year, month, day, hour, minute, second, millisecond } = dateInfo + + date = new Date( + year || today.getFullYear(), + month || 0, + day || 1, + hour || 0, + minute || 0, + second || 0, + millisecond || 0 + ) + } + return date +} + +fecha.parse = (dateStr, format, i18nSettings) => { + const i18n = i18nSettings || fecha.i18n + + if (typeof format !== 'string') { + throw new TypeError('Invalid format in fecha.parse') + } + + format = fecha.masks[format] || format + + if (dateStr.length > 1000) { + return null + } + + let dateInfo = {} + let parseInfo = [] + let literals = [] + + format = format.replace(literal, ($0, $1) => { + literals.push($1) + return '@@@' + }) + + const newFormat = getNewFormat(format, parseInfo) + const matches = dateStr.match(new RegExp(newFormat, 'i')) + + if (!matches) { + return null + } + + for (let i = 1, len = matches.length; i < len; i++) { + parseInfo[i - 1](dateInfo, matches[i], i18n) + } + + if (dateInfo.isPm === true && !isNull(dateInfo.hour) && Number(dateInfo.hour) !== 12) { + dateInfo.hour = Number(dateInfo.hour) + 12 + } else if (dateInfo.isPm === false && Number(dateInfo.hour) === 12) { + dateInfo.hour = 0 + } + + return getDate(dateInfo) +} + +export { fecha } diff --git a/packages/utils/src/date-util/index.ts b/packages/utils/src/date-util/index.ts index 49fe6ee084..ab4b1a31b6 100644 --- a/packages/utils/src/date-util/index.ts +++ b/packages/utils/src/date-util/index.ts @@ -10,7 +10,7 @@ * */ -import { fecha } from '../fecha' +import { fecha } from './fecha' import { isNull } from '../type' import { isLeapYear } from '../date' import { DATEPICKER } from '../index' diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 9e66487519..a8bbbcea7d 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -12,7 +12,7 @@ export { getDays, getWeek, lastMonth, nextMonth, getCalendar, transformArray, pa export { isLeapYear, toDate, - format as formatDate, + format as formatDateByPattern, getDateWithNewTimezone, toDateStr, getWeekOfFirstDay, @@ -20,6 +20,43 @@ export { getStrTimezone } from './date' +// 与 date.ts 合并一下, 有几个重名变量,待整理, 如果功能一致就合并 +export { + getI18nSettings, + isDate as isDate1, + toDate as toDate1, + isDateObject, + formatDate, + parseDate as parseDate1, + getDayCountOfMonth, + getDayCountOfYear, + getFirstDayOfMonth, + prevDate, + nextDate, + getStartDateOfMonth, + getWeekNumber, + getRangeHours, + range, + getMonthDays, + getPrevMonthLastDays, + getRangeMinutes, + modifyDate, + modifyTime, + modifyWithTimeString, + clearTime, + clearMilliseconds, + limitTimeRange, + timeWithinRange, + changeYearMonthAndClampDate, + nextMonth as nextMonth1, + prevMonth, + nextYear, + prevYear, + extractTimeFormat, + extractDateFormat, + validateRangeInOneMonth +} from './date-util' + export { toString, hasOwn, @@ -128,46 +165,6 @@ export { NODE_KEY, getNodeKey, markNodeData, getChildState, Node, TreeStore } fr // 待移除, 移到loading中去, 或起个更好的名字 export { afterLeave } from './after-leave' -// 原来位置 common/deps/data.ts -export { fecha } from './fecha' - -// 与 date.ts 合并一下, 有几个重名变量,待整理, 如果功能一致就合并 -export { - getI18nSettings, - isDate as isDate1, - toDate as toDate1, - isDateObject, - formatDate as formatDate1, - parseDate as parseDate1, - getDayCountOfMonth, - getDayCountOfYear, - getFirstDayOfMonth, - prevDate, - nextDate, - getStartDateOfMonth, - getWeekNumber, - getRangeHours, - range, - getMonthDays, - getPrevMonthLastDays, - getRangeMinutes, - modifyDate, - modifyTime, - modifyWithTimeString, - clearTime, - clearMilliseconds, - limitTimeRange, - timeWithinRange, - changeYearMonthAndClampDate, - nextMonth as nextMonth1, - prevMonth, - nextYear, - prevYear, - extractTimeFormat, - extractDateFormat, - validateRangeInOneMonth -} from './date-util' - export { debounce } from './debounce' export { throttle } from './throttle' diff --git a/packages/vue/src/date-table/src/index.ts b/packages/vue/src/date-table/src/index.ts index b46eac45bd..e44ac3bd6d 100644 --- a/packages/vue/src/date-table/src/index.ts +++ b/packages/vue/src/date-table/src/index.ts @@ -1,6 +1,6 @@ import { $prefix, $props, $setup, defineComponent } from '@opentiny/vue-common' import template from 'virtual-template?pc|mobile-first' -import { isDate } from '@opentiny/vue-renderless/common/deps/date-util' +import { isDate1 } from '@opentiny/utils' export default defineComponent({ name: $prefix + 'DateTable', @@ -11,7 +11,7 @@ export default defineComponent({ date: {}, defaultValue: { validator(val) { - return val === null || isDate(val) || (Array.isArray(val) && val.every(isDate)) + return val === null || isDate1(val) || (Array.isArray(val) && val.every(isDate1)) } }, disabledDate: {}, diff --git a/packages/vue/src/grid-toolbar/src/index.ts b/packages/vue/src/grid-toolbar/src/index.ts index d758794f4c..3e43b1b197 100644 --- a/packages/vue/src/grid-toolbar/src/index.ts +++ b/packages/vue/src/grid-toolbar/src/index.ts @@ -22,7 +22,7 @@ * SOFTWARE. * */ -import { isNumber } from '@opentiny/vue-renderless/common/type' +import { isNumber } from '@opentiny/utils' import { iconMinscreen, iconFullscreen } from '@opentiny/vue-icon' import { h, hooks, $prefix, defineComponent, appProperties, $props } from '@opentiny/vue-common' import { toStringJSON, isEmpty, isPlainObject, toJSONString, find } from '@opentiny/vue-renderless/grid/static/' diff --git a/packages/vue/src/grid/src/body/src/body.tsx b/packages/vue/src/grid/src/body/src/body.tsx index c6b7ec9680..376adb574f 100644 --- a/packages/vue/src/grid/src/body/src/body.tsx +++ b/packages/vue/src/grid/src/body/src/body.tsx @@ -1,3 +1,4 @@ +/* eslint-disable unused-imports/no-unused-vars */ /** * MIT License * @@ -24,7 +25,7 @@ */ import { isFunction, find } from '@opentiny/vue-renderless/grid/static/' -import { isNull } from '@opentiny/vue-renderless/common/type' +import { isNull } from '@opentiny/utils' import { updateCellTitle, emitEvent, diff --git a/packages/vue/src/grid/src/footer/src/footer.ts b/packages/vue/src/grid/src/footer/src/footer.ts index 81477190e3..6d462f6555 100644 --- a/packages/vue/src/grid/src/footer/src/footer.ts +++ b/packages/vue/src/grid/src/footer/src/footer.ts @@ -25,7 +25,7 @@ import { isFunction } from '@opentiny/vue-renderless/grid/static/' import { getClass, emitEvent, formatText, updateCellTitle } from '@opentiny/vue-renderless/grid/utils' -import { isNull } from '@opentiny/vue-renderless/common/type' +import { isNull } from '@opentiny/utils' import { h, $prefix, defineComponent } from '@opentiny/vue-common' const classMap = { diff --git a/packages/vue/src/grid/src/header/src/header.ts b/packages/vue/src/grid/src/header/src/header.ts index 31433b72db..8940a677b1 100644 --- a/packages/vue/src/grid/src/header/src/header.ts +++ b/packages/vue/src/grid/src/header/src/header.ts @@ -23,7 +23,7 @@ * */ -import { isObject, isNull } from '@opentiny/vue-renderless/common/type' +import { isObject, isNull } from '@opentiny/utils' import { removeClass, addClass } from '@opentiny/vue-renderless/common/deps/dom' import { isBoolean, isFunction } from '@opentiny/vue-renderless/grid/static/' import { updateCellTitle, emitEvent, getClass } from '@opentiny/vue-renderless/grid/utils' diff --git a/packages/vue/src/grid/src/table/src/methods.ts b/packages/vue/src/grid/src/table/src/methods.ts index b97546746d..e95c065fde 100644 --- a/packages/vue/src/grid/src/table/src/methods.ts +++ b/packages/vue/src/grid/src/table/src/methods.ts @@ -1,3 +1,4 @@ +/* eslint-disable unused-imports/no-unused-vars */ /** * MIT License * @@ -25,7 +26,7 @@ import { getColumnList, assemColumn } from '@opentiny/vue-renderless/grid/utils' import { toDecimal } from '@opentiny/vue-renderless/common/string' import { addClass, removeClass, isDisplayNone } from '@opentiny/vue-renderless/common/deps/dom' -import { isNull } from '@opentiny/vue-renderless/common/type' +import { isNull } from '@opentiny/utils' import debounce from '@opentiny/vue-renderless/common/deps/debounce' import { fastdom } from '@opentiny/vue-renderless/common/deps/fastdom' import { diff --git a/packages/vue/src/grid/src/table/src/table.ts b/packages/vue/src/grid/src/table/src/table.ts index 5b2c17b1eb..229149c982 100644 --- a/packages/vue/src/grid/src/table/src/table.ts +++ b/packages/vue/src/grid/src/table/src/table.ts @@ -1,3 +1,4 @@ +/* eslint-disable unused-imports/no-unused-vars */ /** * MIT License * @@ -25,7 +26,7 @@ import { h, hooks, $prefix, resolveTheme, defineComponent, useInstanceSlots, useRelation } from '@opentiny/vue-common' import Tooltip from '@opentiny/vue-tooltip' import { extend } from '@opentiny/vue-renderless/common/object' -import { isEmptyObject, isObject, isNull } from '@opentiny/vue-renderless/common/type' +import { isEmptyObject, isObject, isNull } from '@opentiny/utils' import { uniqueId, template, toNumber, isBoolean } from '@opentiny/vue-renderless/grid/static/' import { getRowkey, GlobalEvent, hasChildrenList, getListeners } from '@opentiny/vue-renderless/grid/utils' import TINYGrid from '../../adapter' diff --git a/packages/vue/src/grid/src/tools/formatter.ts b/packages/vue/src/grid/src/tools/formatter.ts index 5bef0f4846..10b90c6616 100644 --- a/packages/vue/src/grid/src/tools/formatter.ts +++ b/packages/vue/src/grid/src/tools/formatter.ts @@ -35,7 +35,7 @@ import { toBoolValue } from '@opentiny/vue-renderless/common/string' import { find } from '@opentiny/vue-renderless/grid/static/' -import { isNumber, isDate, isNull } from '@opentiny/vue-renderless/common/type' +import { isNumber, isDate, isNull } from '@opentiny/utils' import { toDateStr, getDateWithNewTimezone, toDate, format } from '@opentiny/vue-renderless/common/date' import { iconClose, iconYes } from '@opentiny/vue-icon' import { warn } from './logger' diff --git a/packages/vue/src/image-viewer/src/mobileTouch.ts b/packages/vue/src/image-viewer/src/mobileTouch.ts index 4c6940fe28..e3bb82e435 100644 --- a/packages/vue/src/image-viewer/src/mobileTouch.ts +++ b/packages/vue/src/image-viewer/src/mobileTouch.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-new */ /** * Copyright (c) 2022 - present TinyVue Authors. * Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd. @@ -10,7 +11,7 @@ * */ import { directive } from '@opentiny/vue-common' -import { isObject } from '@opentiny/vue-renderless/common/type' +import { isObject } from '@opentiny/utils' class TinyTouch { constructor(element, tinyBinding, type) { @@ -49,7 +50,7 @@ class TinyTouch { this.time = setTimeout(() => { if (this.tinyVueLeave && this.tinyVueMoves) { - this.touchType == 'longtap' && this.tinyVueCallBack(this.tinyBinding.value, e) + this.touchType === 'longtap' && this.tinyVueCallBack(this.tinyBinding.value, e) this.tinyLongTouch = false } }, 1000) @@ -66,28 +67,28 @@ class TinyTouch { clearTimeout(this.time) if (Math.abs(disX) > 10 || Math.abs(disY) > 100) { - this.touchType == 'swipe' && this.tinyVueCallBack(this.tinyBinding.value, e) + this.touchType === 'swipe' && this.tinyVueCallBack(this.tinyBinding.value, e) if (Math.abs(disX) > Math.abs(disY)) { if (disX > 10) { - this.touchType == 'swiperight' && this.tinyVueCallBack(this.tinyBinding.value, e) + this.touchType === 'swiperight' && this.tinyVueCallBack(this.tinyBinding.value, e) } if (disX < -10) { - this.touchType == 'swipeleft' && this.tinyVueCallBack(this.tinyBinding.value, e) + this.touchType === 'swipeleft' && this.tinyVueCallBack(this.tinyBinding.value, e) } } else { if (disY > 10) { - this.touchType == 'swipedown' && this.tinyVueCallBack(this.tinyBinding.value, e) + this.touchType === 'swipedown' && this.tinyVueCallBack(this.tinyBinding.value, e) } if (disY < -10) { - this.touchType == 'swipeup' && this.tinyVueCallBack(this.tinyBinding.value, e) + this.touchType === 'swipeup' && this.tinyVueCallBack(this.tinyBinding.value, e) } } } else { if (this.tinyLongTouch && this.tinyVueMoves) { - this.touchType == 'tap' && this.tinyVueCallBack(this.tinyBinding.value, e) + this.touchType === 'tap' && this.tinyVueCallBack(this.tinyBinding.value, e) this.tinyVueLeave = false } } diff --git a/packages/vue/src/month-table/package.json b/packages/vue/src/month-table/package.json index 312770e6ce..46af2409bf 100644 --- a/packages/vue/src/month-table/package.json +++ b/packages/vue/src/month-table/package.json @@ -1,23 +1,24 @@ { "name": "@opentiny/vue-month-table", + "type": "module", "version": "3.21.0", "description": "", + "license": "MIT", + "sideEffects": false, "main": "lib/index.js", "module": "index.ts", - "sideEffects": false, - "type": "module", - "devDependencies": { - "@opentiny-internal/vue-test-utils": "workspace:*", - "vitest": "catalog:" - }, "scripts": { "build": "pnpm -w build:ui $npm_package_name", "//postversion": "pnpm build" }, "dependencies": { - "@opentiny/vue-renderless": "workspace:~", + "@opentiny/utils": "workspace:~", "@opentiny/vue-common": "workspace:~", + "@opentiny/vue-renderless": "workspace:~", "@opentiny/vue-theme": "workspace:~" }, - "license": "MIT" -} + "devDependencies": { + "@opentiny-internal/vue-test-utils": "workspace:*", + "vitest": "catalog:" + } +} \ No newline at end of file diff --git a/packages/vue/src/month-table/src/pc.vue b/packages/vue/src/month-table/src/pc.vue index 7e1626c630..2d17b7caea 100644 --- a/packages/vue/src/month-table/src/pc.vue +++ b/packages/vue/src/month-table/src/pc.vue @@ -13,7 +13,7 @@ -
+
@@ -26,7 +26,7 @@ diff --git a/examples/sites/demos/pc/app/time-line-new/custom-normal-step.vue b/examples/sites/demos/pc/app/time-line-new/custom-normal-step.vue deleted file mode 100644 index 3409599642..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/custom-normal-step.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/custom-vertical-step.vue b/examples/sites/demos/pc/app/time-line-new/custom-vertical-step.vue deleted file mode 100644 index ee003d54ee..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/custom-vertical-step.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/different-data1.vue b/examples/sites/demos/pc/app/time-line-new/different-data1.vue deleted file mode 100644 index fe33cddcc2..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/different-data1.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/different-data2.vue b/examples/sites/demos/pc/app/time-line-new/different-data2.vue deleted file mode 100644 index 40e64015ba..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/different-data2.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/event.vue b/examples/sites/demos/pc/app/time-line-new/event.vue deleted file mode 100644 index 7afd9b7099..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/event.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/node-toset1.vue b/examples/sites/demos/pc/app/time-line-new/node-toset1.vue deleted file mode 100644 index e6b30c9fef..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/node-toset1.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/node-toset2.vue b/examples/sites/demos/pc/app/time-line-new/node-toset2.vue deleted file mode 100644 index 14861f2c59..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/node-toset2.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/set-start-value.vue b/examples/sites/demos/pc/app/time-line-new/set-start-value.vue deleted file mode 100644 index 87b0227661..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/set-start-value.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/show-number.vue b/examples/sites/demos/pc/app/time-line-new/show-number.vue deleted file mode 100644 index c76fee2ef2..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/show-number.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/show-status.vue b/examples/sites/demos/pc/app/time-line-new/show-status.vue deleted file mode 100644 index 5c4ba546ba..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/show-status.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/vertical1.vue b/examples/sites/demos/pc/app/time-line-new/vertical1.vue deleted file mode 100644 index 16f042a1a7..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/vertical1.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/vertical2.vue b/examples/sites/demos/pc/app/time-line-new/vertical2.vue deleted file mode 100644 index 7afd9b7099..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/vertical2.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - diff --git a/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.cn.md b/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.cn.md deleted file mode 100644 index 1ea36f9022..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.cn.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Timeline 时间线 ---- - -# Timeline 时间线 - -
可视化时间流信息
diff --git a/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.en.md b/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.en.md deleted file mode 100644 index 93235ce817..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.en.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: TimeLine ---- - -# TimeLine - -
Visualize time flow information.
diff --git a/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.js b/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.js deleted file mode 100644 index 531555ebbf..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/webdoc/time-line-new.js +++ /dev/null @@ -1,184 +0,0 @@ -export default { - column: '2', - owner: '', - demos: [ - { - demoId: 'basic-usage', - name: { - 'zh-CN': '基本用法', - 'en-US': 'Basic Usage' - }, - desc: { - 'zh-CN': '通过 data 属性设置时间线步骤条数据,通过 active 属性设置步骤条的选中步骤。', - 'en-US': - '

Use the data attribute to set data, the active attribute to set the selected node, and click to listen to click event on node.

\n' - }, - codeFiles: ['basic-usage.vue'] - }, - { - demoId: 'vertical1', - name: { - 'zh-CN': '竖向时间线 1', - 'en-US': 'Timeline Node Component' - }, - desc: { - 'zh-CN': '通过 vertical 属性设置竖向时间线。', - 'en-US': - '

Customize the attributes, events, and slots of individual nodes through the timeline-item component of the Timeline node component.

\n' - }, - codeFiles: ['vertical1.vue'] - }, - { - demoId: 'vertical2', - name: { - 'zh-CN': '竖向时间线 2', - 'en-US': 'Vertical Timeline' - }, - desc: { - 'zh-CN': '通过 reverse 属性设置竖向步骤条的方向。', - 'en-US': - '

Use the vertical attribute to set the vertical timeline and reverse to set whether display data in reverse order.

\n' - }, - codeFiles: ['vertical2.vue'] - }, - { - demoId: 'width', - name: { - 'zh-CN': '宽度设置', - 'en-US': 'Status of Node' - }, - desc: { - 'zh-CN': '通过 space 属性设置步骤条的宽度。', - 'en-US': - '

Specify the state of timeline nodes by setting the autoColor or type attribute, and use the disabled attribute to enable or disable them.

' - }, - codeFiles: ['width.vue'] - }, - { - demoId: 'different-data1', - name: { - 'zh-CN': '数据映射 1', - 'en-US': 'Node name position' - }, - desc: { - 'zh-CN': - '通过 name-field 属性设置节点信息中名称对应的字段名,通过 time-field 属性设置节点时间信息对应的字段名。', - 'en-US': - '

Set the position of the node name using the text-position attribute, which applies only to horizontal timelines.

' - }, - codeFiles: ['different-data1.vue'] - }, - { - demoId: 'different-data2', - name: { - 'zh-CN': '数据映射 2', - 'en-US': 'Appearance of Node' - }, - desc: { - 'zh-CN': '通过 auto-color-field 属性设置节点信息图标对应的字段名。', - 'en-US': '

Use the shape attribute to set the appearance of a vertical time line node.

' - }, - codeFiles: ['different-data2.vue'] - }, - { - demoId: 'set-start-value', - name: { - 'zh-CN': '设置序号起始值', - 'en-US': 'Width Setting' - }, - desc: { - 'zh-CN': '通过 start 属性设置步骤条序号起始值。', - 'en-US': '

Use the space attribute to set the width of timeline node.

\n' - }, - codeFiles: ['set-start-value.vue'] - }, - { - demoId: 'show-status', - name: { - 'zh-CN': '显示组件内部状态', - 'en-US': 'Custom Icon' - }, - desc: { - 'zh-CN': '通过 show-status 属性设置是否显示组件内部状态。默认为 false,表示不显示。', - 'en-US': '

Customize icon by using the auto-color attribute.

' - }, - codeFiles: ['show-status.vue'] - }, - { - demoId: 'node-toset1', - name: { - 'zh-CN': '节点配置图标 1', - 'en-US': 'Custom Field' - }, - desc: { - 'zh-CN': '通过在 data 里面的属性 autoColor 设置自定义状态', - 'en-US': - '

The name-field attribute is used to set the field name corresponding to the node name in the node information, the time-field attribute is used to set the field name corresponding to the node time information and the auto-color-field attribute is used to set the field name corresponding to the icon.

' - }, - codeFiles: ['node-toset1.vue'] - }, - { - demoId: 'node-toset2', - name: { - 'zh-CN': '节点配置图标 2', - 'en-US': 'Start value of the sequence number' - }, - desc: { - 'zh-CN': '通过在 data 里面的属性 autoColor 设置自定义图标', - 'en-US': '

Set the start sequence number through the start attribute.

\n' - }, - codeFiles: ['node-toset2.vue'] - }, - { - demoId: 'show-number', - name: { - 'zh-CN': '未完成的序号显示', - 'en-US': 'Bottom indicator triangle' - }, - desc: { - 'zh-CN': '通过 show-number 属性设置未完成的状态是否显示序号。', - 'en-US': - 'The show-divider attribute is used to set whether to display the indicator triangle at the bottom. This parameter is valid only when the node text is on the right of the sequence number.' - }, - codeFiles: ['show-number.vue'] - }, - { - demoId: 'custom-normal-step', - name: { - 'zh-CN': '自定义横向时间线', - 'en-US': 'Customizing a Horizontal Timeline' - }, - desc: { - 'zh-CN': 'slot 为 top 可以自定义步骤条顶部内容,slot 为 bottom 可以自定义步骤条底部内容。', - 'en-US': - 'If

slot is top, you can customize the top content of the timeline. If

slot is slot, you can customize the bottom content of the timeline.

\n' - }, - codeFiles: ['custom-normal-step.vue'] - }, - { - demoId: 'custom-vertical-step', - name: { - 'zh-CN': '自定义竖向时间线', - 'en-US': 'Customized Vertical Timeline' - }, - desc: { - 'zh-CN': 'slot 为 left 可以自定义步骤条左侧内容,slot 为 right 可以自定义步骤条右侧内容。', - 'en-US': - 'If

slot is set to left, you can customize the content on the left of the timeline. If

slot is set to right, you can customize the content on the right of the timeline.

\n' - }, - codeFiles: ['custom-vertical-step.vue'] - }, - { - demoId: 'event', - name: { - 'zh-CN': 'click 事件', - 'en-US': 'Node Description' - }, - desc: { - 'zh-CN': '单击时触发 click 事件', - 'en-US': '

Add description information for a single node through the description slot.

' - }, - codeFiles: ['event.vue'] - } - ] -} diff --git a/examples/sites/demos/pc/app/time-line-new/width.vue b/examples/sites/demos/pc/app/time-line-new/width.vue deleted file mode 100644 index cb1c85507b..0000000000 --- a/examples/sites/demos/pc/app/time-line-new/width.vue +++ /dev/null @@ -1,28 +0,0 @@ - - - From aaacca69f008f513f91757cf0891b33fe3154dfd Mon Sep 17 00:00:00 2001 From: shenjunjian <40288193@qq.com> Date: Thu, 6 Feb 2025 17:31:14 -0800 Subject: [PATCH 23/25] fix(utils): adjust import orders --- packages/vue-directive/index.ts | 4 ++-- packages/vue-hooks/index.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vue-directive/index.ts b/packages/vue-directive/index.ts index 312f7290a9..baca57adf8 100644 --- a/packages/vue-directive/index.ts +++ b/packages/vue-directive/index.ts @@ -11,10 +11,10 @@ */ import AutoTip from './src/auto-tip' -import HighlightQuery from './src/highlight-query' import Clickoutside from './src/clickoutside' -import RepeatClick from './src/repeat-click' +import HighlightQuery from './src/highlight-query' import ObserveVisibility from './src/observe-visibility' +import RepeatClick from './src/repeat-click' export { InfiniteScroll, getScrollContainer } from './src/infinite-scroll' export { AutoTip, HighlightQuery, Clickoutside, RepeatClick, ObserveVisibility } diff --git a/packages/vue-hooks/index.ts b/packages/vue-hooks/index.ts index 691d3cf363..4c8e1bd425 100644 --- a/packages/vue-hooks/index.ts +++ b/packages/vue-hooks/index.ts @@ -12,12 +12,12 @@ export { useFloating } from './src/use-floating' export { useLazyShow } from './src/use-lazy-show' -export { userPopper } from './src/vue-popper' -export { usePopup } from './src/vue-popup' -export { useInstanceSlots } from './src/useInstanceSlots' -export { useRelation } from './src/useRelation' export { useEventListener } from './src/useEventListener' +export { useInstanceSlots } from './src/useInstanceSlots' export { useRect } from './src/useRect' +export { useRelation } from './src/useRelation' export { useTouch } from './src/useTouch' export { useUserAgent } from './src/useUserAgent' export { useWindowSize } from './src/useWindowSize' +export { userPopper } from './src/vue-popper' +export { usePopup } from './src/vue-popup' From 1baade3f7975174081e2a946fa283bafcd067957 Mon Sep 17 00:00:00 2001 From: shenjunjian <40288193@qq.com> Date: Thu, 6 Feb 2025 22:13:27 -0800 Subject: [PATCH 24/25] =?UTF-8?q?fix(utils):=20=E6=9B=BF=E6=8D=A2=E8=B7=AF?= =?UTF-8?q?=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/nuxt/playground/package.json | 5 ++++- examples/nuxt/playground/pages/InfiniteScroll.vue | 2 +- .../mobile-first/app/select/memoize-usage.vue | 2 +- .../basic-usage-composition-api.vue | 2 +- .../demos/pc/app/infinite-scroll/basic-usage.vue | 2 +- .../infinite-scroll/disabled-composition-api.vue | 2 +- .../demos/pc/app/infinite-scroll/disabled.vue | 2 +- .../demos/pc/app/query-builder/basic-usage.vue | 2 +- .../pc/app/query-builder/display-only-field.vue | 2 +- .../demos/pc/app/query-builder/max-height.vue | 2 +- .../pc/app/query-builder/sub-component-param.vue | 2 +- .../demos/pc/app/query-builder/tree-field.vue | 2 +- .../app/select/memoize-usage-composition-api.vue | 2 +- .../sites/demos/pc/app/select/memoize-usage.vue | 2 +- examples/sites/demos/pc/webdoc/faq-en.md | 2 +- examples/sites/demos/pc/webdoc/faq.md | 2 +- packages/renderless/src/cascader/index.ts | 4 ++-- packages/utils/src/globalConfig/index.ts | 2 +- packages/vue/src/fullscreen/package.json | 15 ++++++++------- 19 files changed, 30 insertions(+), 26 deletions(-) diff --git a/examples/nuxt/playground/package.json b/examples/nuxt/playground/package.json index daa7157e4a..5b3ddf9444 100644 --- a/examples/nuxt/playground/package.json +++ b/examples/nuxt/playground/package.json @@ -16,8 +16,11 @@ }, "devDependencies": { "@opentiny-internal/unplugin-virtual-template": "workspace:*", + "@opentiny/utils": "workspace:~", "@opentiny/vue": "workspace:~", "@opentiny/vue-common": "workspace:~", + "@opentiny/vue-directive": "workspace:~", + "@opentiny/vue-hooks": "workspace:~", "@opentiny/vue-icon": "workspace:~", "@opentiny/vue-locale": "workspace:~", "@opentiny/vue-renderless": "workspace:~", @@ -33,4 +36,4 @@ "vite-plugin-dynamic-import": "^1.2.4", "vite-svg-loader": "^3.6.0" } -} \ No newline at end of file +} diff --git a/examples/nuxt/playground/pages/InfiniteScroll.vue b/examples/nuxt/playground/pages/InfiniteScroll.vue index 373c03d4f3..7425f4a7b1 100644 --- a/examples/nuxt/playground/pages/InfiniteScroll.vue +++ b/examples/nuxt/playground/pages/InfiniteScroll.vue @@ -5,7 +5,7 @@