diff --git a/.eslintrc.js b/.eslintrc.js index 6b40df4027e25d491ec4c4f524f3819c91550097..113afb5f541ab27d30c926389e52250aa6d12f25 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -40,7 +40,11 @@ module.exports = { 'prefer-template': 'error', 'prefer-spread': 'error', 'no-var': 'error', - 'max-lines-per-function': ['error', 100], + 'max-lines-per-function': ['error', { + max: 100, + skipComments: true, + skipBlankLines: true + }], complexity: ['warn', 20], 'max-depth': ['warn', 4], 'max-len': ['warn', { diff --git a/packages/opendesign/package.json b/packages/opendesign/package.json index 038394c8255f34fb734866c2d16e006fac94aee5..24cb1ca243fec7ae65470dc00e932d3205f360e0 100644 --- a/packages/opendesign/package.json +++ b/packages/opendesign/package.json @@ -26,11 +26,15 @@ }, "devDependencies": { "@opensig/opensig-scripts": "workspace:^0.0.1", + "@types/lodash-es": "^4.17.6", "typescript": "^4.6.4", "vue": "^3.2.41", "vue-tsc": "^1.0.13" }, "dependencies": { - "@vue/shared": "^3.2.45" + "@vue/shared": "^3.2.45", + "intersection-observer-polyfill": "^0.1.0", + "lodash-es": "^4.17.21", + "resize-observer-polyfill": "^1.5.1" } } \ No newline at end of file diff --git a/packages/opendesign/src/components/_shared/dom.ts b/packages/opendesign/src/components/_shared/dom.ts index 4ecdbd952874bc729c4d81604ece92242352be1a..879a065f0636a417251ba79cdbf67afc8f688622 100644 --- a/packages/opendesign/src/components/_shared/dom.ts +++ b/packages/opendesign/src/components/_shared/dom.ts @@ -1,28 +1,53 @@ +export type DirectionT = 'left' | 'right' | 'top' | 'bottom'; + export function isElement(el: any) { return (typeof HTMLElement === 'object') ? (el instanceof HTMLElement) : !!(el && typeof el === 'object' && (el.nodeType === 1 || el.nodeType === 9) && typeof el.nodeName === 'string'); } -export function isRootEl(el: HTMLElement | Window) { - return el === window || ['BODY', 'HTML'].includes((el as HTMLElement).tagName); +export function isDocumentElement(el: HTMLElement | Window) { + return el === window || ['HTML'].includes((el as HTMLElement).tagName); } - +// 获取真实相对父元素 当body没有设置position时,返回html +export function getOffsetElement(el: HTMLElement) { + let offsetEl = el.offsetParent; + if (offsetEl && offsetEl.tagName === 'BODY') { + const stylePosition = window.getComputedStyle(document.body).getPropertyValue('position'); + if (stylePosition === 'static') { + return document.documentElement; + } + } + return offsetEl; +} +// 获取元素scroll值 export function getScroll(el: HTMLElement | Window = window) { if (!el) { return { - left: 0, - top: 0 + scrollLeft: 0, + scrollTop: 0 }; } - const isroot = isRootEl(el); + const isroot = isDocumentElement(el); return { - left: isroot ? window.scrollX : (el as HTMLElement).scrollLeft, - top: isroot ? window.scrollY : (el as HTMLElement).scrollTop, + scrollLeft: isroot ? window.scrollX : (el as HTMLElement).scrollLeft, + scrollTop: isroot ? window.scrollY : (el as HTMLElement).scrollTop, }; } -export function getRelativeBounding(el: HTMLElement, c: DOMRect) { - const e = el.getBoundingClientRect(); +// 获取元素的可滚动的父元素 +export function getScrollParents(el: HTMLElement) { + const parents: Array = []; + let ele: HTMLElement | null = el; + while (ele && ele !== document.documentElement) { + const { offsetHeight, offsetWidth, scrollHeight, scrollWidth } = ele; + if (offsetHeight < scrollHeight || offsetWidth < scrollWidth) { + parents.push(ele); + } + ele = ele.parentElement; + } + return parents; +} +export function getRelativeBounding(e: DOMRect, c: DOMRect) { return { top: e.top, bottom: e.bottom, @@ -35,4 +60,35 @@ export function getRelativeBounding(el: HTMLElement, c: DOMRect) { offsetRight: e.right - c.left, offsetBottom: e.bottom - c.top, }; +} +export type RelativeRect = ReturnType + +export function getElementSize(el: HTMLElement | Window) { + return { + width: (el as Window).innerWidth || (el as HTMLElement).clientWidth, + height: (el as Window).innerHeight || (el as HTMLElement).clientHeight, + offsetWidth: (el as Window).innerWidth || (el as HTMLElement).offsetWidth, + offsetHeight: (el as Window).innerHeight || (el as HTMLElement).offsetHeight, + }; +} + +export function getElementBorder(el: HTMLElement, dir?: DirectionT | DirectionT[]) { + const style = window.getComputedStyle(el); + let d: DirectionT[] = []; + + if (typeof dir === 'string') { + d = [dir]; + } else { + d = Array.isArray(dir) ? dir : ['left', 'right', 'bottom', 'top']; + } + const rlt: { + left?: number, + right?: number, + top?: number, + bottom?: number, + } = {}; + d.forEach(k => { + rlt[k] = parseFloat(style.getPropertyValue(`border-${k}-width`)); + }); + return rlt; } \ No newline at end of file diff --git a/packages/opendesign/src/components/_shared/global.ts b/packages/opendesign/src/components/_shared/global.ts index 05782af61103190c990046b7e0b463c2025126bf..e5603c89502cb44ee429b5ed1dcd65eac7d18093 100644 --- a/packages/opendesign/src/components/_shared/global.ts +++ b/packages/opendesign/src/components/_shared/global.ts @@ -6,10 +6,11 @@ export enum Size { NORMAL = 'normal', SMALL = 'small' } +export type SizeT = 'large' | 'normal' | 'small' -export const defaultSize = ref(Size.NORMAL); +export const defaultSize = ref('normal'); -export function initSize(type: Size) { +export function initSize(type: SizeT) { defaultSize.value = type; } @@ -18,9 +19,11 @@ export enum Shape { ROUND = 'round', NORMAL = 'normal' } -export const defaultShape = ref(Shape.NORMAL); +export type ShapeT = 'round' | 'normal' -export function initShape(shape: Shape) { +export const defaultShape = ref('normal'); + +export function initShape(shape: ShapeT) { defaultShape.value = shape; } diff --git a/packages/opendesign/src/components/_shared/utils.ts b/packages/opendesign/src/components/_shared/utils.ts index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0759120407e6fc38c666dc4c205679ec479dd955 100644 --- a/packages/opendesign/src/components/_shared/utils.ts +++ b/packages/opendesign/src/components/_shared/utils.ts @@ -0,0 +1,50 @@ +import { throttle as _throttle, debounce as _debounce } from 'lodash-es'; +import type { ThrottleSettings, DebounceSettings } from 'lodash-es'; + +export function isFunction(fn: any) { + return typeof fn === 'function'; +} +// 防抖 +export function debounce any>(fn: T, wait?: number, ctx?: any | null, opts?: ThrottleSettings) { + return _debounce.apply(ctx, [fn, wait, opts]); +} +// 节流 +export function throttle any>(fn: T, wait?: number, ctx?: any | null, opts?: DebounceSettings) { + return _throttle.apply(ctx, [fn, wait, opts]); +} +// 防抖 时间为一个一帧 +export function debounceRAF any>(fn: T) { + let handle = 0; + const rlt = (...args: any[]) => { + if (handle) { + cancelAnimationFrame(handle); + } + handle = requestAnimationFrame(() => { + fn(...args); + handle = 0; + }); + }; + rlt.cancel = () => { + cancelAnimationFrame(handle); + handle = 0; + }; + return rlt; +} +// 节流 时间为一个一帧 +export function throttleRAF any>(fn: T) { + let handle = 0; + const rlt = (...args: any[]) => { + if (handle) { + return; + } + handle = requestAnimationFrame(() => { + fn(...args); + handle = 0; + }); + }; + rlt.cancel = () => { + cancelAnimationFrame(handle); + handle = 0; + }; + return rlt; +} \ No newline at end of file diff --git a/packages/opendesign/src/components/button/OButton.vue b/packages/opendesign/src/components/button/OButton.vue index cc9f1dd1f52eed702f63fdd101bcd32a877f9613..e5e97e041f85563b64b8a70126a9cc45f57049a6 100644 --- a/packages/opendesign/src/components/button/OButton.vue +++ b/packages/opendesign/src/components/button/OButton.vue @@ -1,14 +1,15 @@ diff --git a/packages/opendesign/src/components/button/__demo__/BtnIcon.vue b/packages/opendesign/src/components/button/__demo__/BtnIcon.vue index c56dce8ab1916d597034789357bd4d06df3147a5..120a943ece38e547fd741843f1b25ea71ab4da5b 100644 --- a/packages/opendesign/src/components/button/__demo__/BtnIcon.vue +++ b/packages/opendesign/src/components/button/__demo__/BtnIcon.vue @@ -1,44 +1,44 @@