diff --git a/packages/opendesign/package.json b/packages/opendesign/package.json index 96b2b10ce254cd8b86ed8437c2616e50a2cbcf9e..eeb5c5077196fa3ed34d4d00317b1f012410643e 100644 --- a/packages/opendesign/package.json +++ b/packages/opendesign/package.json @@ -1,6 +1,6 @@ { "name": "@opensig/opendesign", - "version": "0.0.14", + "version": "0.0.19", "main": "lib/index.js", "module": "es/index.mjs", "types": "es/index.d.ts", diff --git a/packages/opendesign/src/components/_shared/vue-utils.ts b/packages/opendesign/src/components/_shared/vue-utils.ts index 73e401acc48e857f195f4efeaa9741b34045058d..107577a3ed07dc97c414f2b415c3798a6c07f8a4 100644 --- a/packages/opendesign/src/components/_shared/vue-utils.ts +++ b/packages/opendesign/src/components/_shared/vue-utils.ts @@ -14,7 +14,7 @@ export const enum ShapeFlags { SUSPENSE = 1 << 7, //suspense组件 COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8, //需要被keep-live的有状态组件 COMPONENT_KEPT_ALIVE = 1 << 9, //已经被keep-alive的有状态组件 - COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT//有状态或函数式组件 + COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT, //有状态或函数式组件 } /** * 判断vnode是不是element @@ -57,8 +57,8 @@ export function useSlotElement(componentName?: string) { const components = []; onMounted(() => { - children?.forEach(child => { - console.log(child, isComponent(child)); + children?.forEach((child) => { + // console.log(child, isComponent(child)); if (isComponent(child, child.type)) { if (componentName && child.type.name === componentName) { components.push(child); @@ -71,7 +71,7 @@ export function useSlotElement(componentName?: string) { if (nodes) { children = nodes; } - } + }, }; } export function getFirstComponent(vn: VNode | VNode[]): VNode | null { @@ -103,7 +103,6 @@ export function getFirstComponent(vn: VNode | VNode[]): VNode | null { return null; } - export const getFirstElement = (vn: VNode | VNode[]): HTMLElement | null => { if (isArray(vn)) { for (const child of vn) { @@ -122,7 +121,7 @@ export const getFirstElement = (vn: VNode | VNode[]): HTMLElement | null => { const result = getFirstElement(vn.component.subTree); if (result) { return result; - }; + } } } else if (isArrayChildren(vn, vn.children)) { for (const child of vn.children) { @@ -142,18 +141,16 @@ export function useSlotFirstElement() { onMounted(() => { if (children) { fistElement.value = getFirstElement(children); - console.log(fistElement.value); - + // console.log(fistElement.value); } }); return { setSlot(nodes: VNode[] | undefined) { if (nodes) { children = nodes; - console.log(children); - + // console.log(children); } }, - fistElement + fistElement, }; -} \ No newline at end of file +} diff --git a/packages/opendesign/src/components/dialog/style/index.scss b/packages/opendesign/src/components/dialog/style/index.scss index 8274de6ee3785c27c3f991746faa330470c283d1..0c2a977c7f6c14e470c95dcd9696574559bc4b00 100644 --- a/packages/opendesign/src/components/dialog/style/index.scss +++ b/packages/opendesign/src/components/dialog/style/index.scss @@ -1,7 +1,7 @@ @use './var.scss'; .o-dialog { - position: absolute; + position: var(--dlg-position, 'fixed'); left: 0; right: 0; top: 0; diff --git a/packages/opendesign/src/components/dialog/style/var.scss b/packages/opendesign/src/components/dialog/style/var.scss index 1d0c641c5529914684ab31da59616ba1ae28da78..a36fe7028d25dd03e23694a9988ae571be0394a9 100644 --- a/packages/opendesign/src/components/dialog/style/var.scss +++ b/packages/opendesign/src/components/dialog/style/var.scss @@ -1,4 +1,6 @@ .o-dialog { + --dlg-position: fixed; + --dlg-close-size: var(--o-icon_size-xs); --dlg-close-color: var(--o-color-info2); --dlg-close-color-hover: var(--o-color-primary2); diff --git a/packages/opendesign/src/components/dropdown/ODropdownItem.vue b/packages/opendesign/src/components/dropdown/ODropdownItem.vue index 85f49e8571949fce6fdd1ac51e85b9c4a685d284..54c0ca1cc8eaccb15ecf14bcf4e7cac95d70f539 100644 --- a/packages/opendesign/src/components/dropdown/ODropdownItem.vue +++ b/packages/opendesign/src/components/dropdown/ODropdownItem.vue @@ -7,7 +7,6 @@ const props = defineProps(dropdownItemProps); const dropdownInjection = inject(dropdownInjectKey, null); const onItemClick = () => { - console.log(1); if (props.disabled) { return; } diff --git a/packages/opendesign/src/components/pagination/OPagination.vue b/packages/opendesign/src/components/pagination/OPagination.vue index 4b2a90bd4b665c98065e4ae8a888efa8c90099af..82e59d33f755f61d2a59ad2be04cd466252713ad 100644 --- a/packages/opendesign/src/components/pagination/OPagination.vue +++ b/packages/opendesign/src/components/pagination/OPagination.vue @@ -103,7 +103,7 @@ const pageSizeChange = (val: string | number) => { currentPageSize.value = Number(val); nextTick(() => { currentPage.value = Math.floor(currentIndex / currentPageSize.value) + 1; - console.log(currentIndex, totalPage.value, currentPage.value, currentPageSize.value); + // console.log(currentIndex, totalPage.value, currentPage.value, currentPageSize.value); pages.value = getPagerItem(totalPage.value, currentPage.value, props.showPageCount); diff --git a/packages/opendesign/src/components/popover/OPopover.vue b/packages/opendesign/src/components/popover/OPopover.vue index 16ef118bdbb95d0c450d4d337c4b63687468c81b..6da4722905596780f05a85957bb75debef716ca0 100644 --- a/packages/opendesign/src/components/popover/OPopover.vue +++ b/packages/opendesign/src/components/popover/OPopover.vue @@ -32,6 +32,7 @@ const targetElRef = ref(null); :wrap-class="props.wrapClass ?? 'o-popover-wrap'" :anchor-class="props.anchor ? props.anchorClass ?? 'o-popover-anchor' : ''" :unmount-on-hide="props.unmountOnHide" + :auto-hide="props.autoHide" @update:visible="updateVisible" >
diff --git a/packages/opendesign/src/components/popover/types.ts b/packages/opendesign/src/components/popover/types.ts index 73166c378a6a4a5b4c503aa8fe651669a4ac6377..6df240900ec5750996401cb560d8a268048d364d 100644 --- a/packages/opendesign/src/components/popover/types.ts +++ b/packages/opendesign/src/components/popover/types.ts @@ -2,7 +2,7 @@ import { ExtractPropTypes } from 'vue'; import { popupProps } from '../popup/types'; -const { position, trigger, target, visible, wrapper, unmountOnHide, anchorClass, wrapClass } = popupProps; +const { position, trigger, target, visible, wrapper, unmountOnHide, anchorClass, wrapClass, autoHide } = popupProps; export const popoverProps = { position, @@ -13,6 +13,7 @@ export const popoverProps = { unmountOnHide, anchorClass, wrapClass, + autoHide, /** * 距离触发元素的偏移量 */ diff --git a/packages/opendesign/src/components/popup/OPopup.vue b/packages/opendesign/src/components/popup/OPopup.vue index 82b50585ebce11116561ae08ac965827d6dc2155..a625016d34ae89f7b63ee40a5042668275cc63ae 100644 --- a/packages/opendesign/src/components/popup/OPopup.vue +++ b/packages/opendesign/src/components/popup/OPopup.vue @@ -104,6 +104,7 @@ const bindTargetEvent = (el: HTMLElement | null) => { triggerListener = bindTrigger(el, popupRef, triggers, { updateFn: updateVisible, hoverDelay: props.hoverDelay, + autoHide: props.autoHide, }); if (props.hideWhenTargetInvisible) { @@ -134,7 +135,7 @@ const updatePopupStyle = () => { if (!targetEl || !popupRef.value || !wrapperEl.value) { return; } - console.log('calc popup position...'); + // console.log('calc popup position...'); const { popupStyle: pStyle, @@ -333,7 +334,7 @@ const onPopupHoverIn = () => { } }; const onPopupHoverOut = () => { - if (triggers.includes('hover')) { + if (triggers.includes('hover') && props.autoHide) { updateVisible(false, props.hoverDelay); } }; diff --git a/packages/opendesign/src/components/popup/__demo__/PopupTarget.vue b/packages/opendesign/src/components/popup/__demo__/PopupTarget.vue index dd4ea8de3e4ad15383548e14b7f276399b9e4c36..248c1fea74678f08edb0684b4902fe0b438dde9d 100644 --- a/packages/opendesign/src/components/popup/__demo__/PopupTarget.vue +++ b/packages/opendesign/src/components/popup/__demo__/PopupTarget.vue @@ -8,8 +8,20 @@ const content = 'this is popup content';

Popup Target

- - + + + + + + + + + + + + + + diff --git a/packages/opendesign/src/components/popup/popup.ts b/packages/opendesign/src/components/popup/popup.ts index 268a52d5358c49502355342e3e4a92b806de6404..09be760b4fb803959b81acae8295cb70e0247e02 100644 --- a/packages/opendesign/src/components/popup/popup.ts +++ b/packages/opendesign/src/components/popup/popup.ts @@ -394,6 +394,7 @@ export function calcPopupStyle( } // 监听元素的触发事件 +// eslint-disable-next-line max-lines-per-function export function bindTrigger( el: HTMLElement | null, popupRef: Ref, @@ -401,9 +402,11 @@ export function bindTrigger( { updateFn, hoverDelay = 100, + autoHide = true, }: { updateFn: (isVisible?: boolean, delay?: number) => void; hoverDelay?: number; + autoHide?: boolean; } ) { if (!el) { @@ -433,35 +436,46 @@ export function bindTrigger( const triggerHandlers: Record void> = { hover: () => { el?.addEventListener('mouseover', enterFn); - el?.addEventListener('mouseleave', leavefn); - const removeFn = () => { + listeners.push(() => { el?.removeEventListener('mouseover', enterFn); - el?.removeEventListener('mouseleave', leavefn); - }; - listeners.push(removeFn); + }); + + if (autoHide) { + el?.addEventListener('mouseleave', leavefn); + listeners.push(() => { + el?.removeEventListener('mouseleave', leavefn); + }); + } }, click: () => { el?.addEventListener('click', toggleFn); - outClick.addListener(el, hideFn, (e: MouseEvent) => { - return !!popupRef.value?.contains(e.target as HTMLElement); - }); - listeners.push(() => { el?.removeEventListener('click', toggleFn); }); - listeners.push(() => { - outClick.removeListener(el, hideFn); - }); + + if (autoHide) { + outClick.addListener(el, hideFn, (e: MouseEvent) => { + return !!popupRef.value?.contains(e.target as HTMLElement); + }); + + listeners.push(() => { + outClick.removeListener(el, hideFn); + }); + } }, focus: () => { el?.addEventListener('focusin', showFn); - el?.addEventListener('focusout', hideFn); - const removeFn = () => { + listeners.push(() => { el?.removeEventListener('focusin', showFn); - el?.removeEventListener('focusout', hideFn); - }; - listeners.push(removeFn); + }); + + if (autoHide) { + el?.addEventListener('focusout', hideFn); + listeners.push(() => { + el?.removeEventListener('focusout', hideFn); + }); + } }, contextmenu: () => { const fn = (e: Event) => { @@ -470,19 +484,37 @@ export function bindTrigger( }; el?.addEventListener('contextmenu', fn); - outClick.addListener(el, hideFn, (e: MouseEvent) => { - return !!popupRef.value?.contains(e.target as HTMLElement); - }); - listeners.push(() => { el?.removeEventListener('contextmenu', fn); }); + if (autoHide) { + outClick.addListener(el, hideFn, (e: MouseEvent) => { + return !!popupRef.value?.contains(e.target as HTMLElement); + }); + listeners.push(() => { + outClick.removeListener(el, hideFn); + }); + } + }, + none: () => {}, + // hover 显示 outclick隐藏 + 'hover-outclick': () => { + el?.addEventListener('mouseover', enterFn); + listeners.push(() => { - outClick.removeListener(el, hideFn); + el?.removeEventListener('mouseover', enterFn); }); + + if (autoHide) { + outClick.addListener(el, hideFn, (e: MouseEvent) => { + return !!popupRef.value?.contains(e.target as HTMLElement); + }); + listeners.push(() => { + outClick.removeListener(el, hideFn); + }); + } }, - none: () => {}, }; triggers.forEach((tr: PopupTriggerT) => { diff --git a/packages/opendesign/src/components/popup/types.ts b/packages/opendesign/src/components/popup/types.ts index 63cf4470df0b9b939ef3f2bbe2c8c3e5cbeacef0..8c1a5b97fa90a0136f3718888e0d89264ceca6a7 100644 --- a/packages/opendesign/src/components/popup/types.ts +++ b/packages/opendesign/src/components/popup/types.ts @@ -2,7 +2,7 @@ import { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'; export type PopupPositionT = 'top' | 'tl' | 'tr' | 'bottom' | 'bl' | 'br' | 'left' | 'lt' | 'lb' | 'right' | 'rt' | 'rb'; -export type PopupTriggerT = 'hover' | 'click' | 'focus' | 'contextmenu' | 'none'; +export type PopupTriggerT = 'hover' | 'click' | 'focus' | 'contextmenu' | 'none' | 'hover-outclick'; export const popupProps = { /** @@ -111,6 +111,13 @@ export const popupProps = { type: String, default: 'o-zoom-fade', }, + /** + * 是否自动隐藏 + */ + autoHide: { + type: Boolean, + default: true, + }, }; export type PopupPropsT = ExtractPropTypes; diff --git a/packages/opendesign/src/components/select/OSelect.vue b/packages/opendesign/src/components/select/OSelect.vue index 2afc2448f602a05d88352f12aba57e8da82c459c..2139586815a996e895bfad26a15e2736d936e692 100644 --- a/packages/opendesign/src/components/select/OSelect.vue +++ b/packages/opendesign/src/components/select/OSelect.vue @@ -51,7 +51,7 @@ provide(selectOptionInjectKey, { if (activeVal.value !== val.value) { emits('change', val.value); activeVal.value = val.value; - console.log('选中change', val.value, activeLabel.value); + // console.log('选中change', val.value, activeLabel.value); } emits('update:modelValue', val.value); showOption.value = false; diff --git a/packages/opendesign/src/components/slides/OSlides.vue b/packages/opendesign/src/components/slides/OSlides.vue index a15f9cc1bbc5c185ecd4cd59f9e2848af4f1306d..404f9157281367a761e44bd60f4b0137704c1170 100644 --- a/packages/opendesign/src/components/slides/OSlides.vue +++ b/packages/opendesign/src/components/slides/OSlides.vue @@ -46,23 +46,25 @@ const fixIndex = (idx: number) => { // gallery let slidesInstance: GallerySlidesT | null = null; -const activeSlideByIndex = (index: number) => { - const to = fixIndex(index); - const from = activeIndex.value; - if (to === from) { - return; - } - emits('before-change', to, activeIndex.value); +const activeSlideByIndex = (to: number): Promise => { + return new Promise((resolve) => { + const from = activeIndex.value; + if (to === from || !slideElList.value) { + resolve(false); + } - switch (props.type) { - case 'gallery': { - (slidesInstance as GallerySlidesT)?.active(to).then(() => { - emits('change', to, from); - }); - activeIndex.value = to; - break; + switch (props.type) { + case 'gallery': { + (slidesInstance as GallerySlidesT)?.active(to).then(() => { + resolve(true); + }); + break; + } + default: { + resolve(false); + } } - } + }); }; let timer: number | null = null; @@ -81,19 +83,39 @@ const startPlay = () => { // 激活slide const activeSlide = (index: number) => { - if (isChanging) { - return; + if (isChanging || !slideElList.value) { + return Promise.resolve(); } isChanging = true; // 停止自动播放 stopPlay(); - activeSlideByIndex(index); - // 恢复自动播放 - if (props.autoPlay) { - startPlay(); - } - isChanging = false; + const to = fixIndex(index); + const from = activeIndex.value; + + emits('before-change', to, activeIndex.value); + + return activeSlideByIndex(to).then((success) => { + if (!success) { + return; + } + + const toSlideEl = (slideElList.value as HTMLElement[])[to]; + const fromSlideEl = (slideElList.value as HTMLElement[])[from]; + + fromSlideEl.classList.remove('o-slide-active'); + toSlideEl.classList.add('o-slide-active'); + + emits('change', to, from); + + activeIndex.value = to; + + // 恢复自动播放 + if (props.autoPlay) { + startPlay(); + } + isChanging = false; + }); }; const initSlides = () => { @@ -140,6 +162,12 @@ onUnmounted(() => { provide(slidesInjectKey, { type: props.type, }); + +defineExpose({ + play: startPlay, + stop: startPlay, + active: activeSlide, +});