diff --git a/packages/docs/tab.md b/packages/docs/tab.md new file mode 100644 index 0000000000000000000000000000000000000000..5e0ff3b418a87df31f416c84f5718ca169820f12 --- /dev/null +++ b/packages/docs/tab.md @@ -0,0 +1,48 @@ +# Tab 页签 + +## props + +### OTabs + +| name | type | 默认值 | 说明 | +| :--------- | :-------------------------- | :----- | ------------------------------ | +| modelValue | string \| number(v-model) | '' | 开关状态 | +| lazy | boolean | false | 是否在首次激活标签时再挂载内容 | +| addable | boolean | false | 是否可以添加页签 | + +### OTabPane + +| name | type | 默认值 | 说明 | +| :------------ | :--------------- | :-------------- | ------------------------------ | +| value | string \| number | uid | tab id | +| label | string | undefined | 页签文本 | +| transition | string | o-fade-up-enter | 页签切换时过渡动画 | +| lazy | boolean | false | 是否在首次激活标签时再挂载内容 | +| unmountOnHide | boolean | false | 是否在未激活时卸载页签内容 | +| disabled | boolean | false | 是否禁用选中 | +| closable | boolean | false | 是否可以删除 | + +## event + +### OTabs + +| name | 参数 | 说明 | +| :----- | :-------------------------------------------------- | :------------- | +| change | value: string \| number, oldValue: string \| number | 页签切换后触发 | +| delete | value: string \| number | 页签删除后触发 | + +## expose + +## slot + +### OTabs + +| name | 说明 | +| :--- | :------------------- | +| act | 页签右侧额外内容插槽 | + +### OTabPane + +| name | 说明 | +| :--- | :------- | +| nav | 页签插槽 | diff --git a/packages/opendesign/src/components/_shared/icons.ts b/packages/opendesign/src/components/_shared/icons.ts index 27320a3ab9b3c2a25158422c09227d97e40b1ef9..f350b18c6ad2752d210d06ad9b12b8ce86bc18fd 100644 --- a/packages/opendesign/src/components/_shared/icons.ts +++ b/packages/opendesign/src/components/_shared/icons.ts @@ -5,7 +5,9 @@ import { Component, shallowRef } from 'vue'; import { IconLoading as _IconLoading, IconLink as IconLink, - IconArrowRight + IconArrowRight, + IconX, + IconAdd as _IconAdd, } from '../icons'; /** @@ -30,4 +32,18 @@ export function initLinkPrefixIcon(icon: Component) { export const IconLinkArrow = shallowRef(IconArrowRight); export function initLinkArrowIcon(icon: Component) { IconLinkArrow.value = icon; +} +/** + * close图标 + */ +export const IconClose = shallowRef(IconX); +export function initCloseIcon(icon: Component) { + IconClose.value = icon; +} +/** + * add图标 + */ +export const IconAdd = shallowRef(_IconAdd); +export function initAddIcon(icon: Component) { + IconAdd.value = icon; } \ No newline at end of file diff --git a/packages/opendesign/src/components/_shared/vue-utils.ts b/packages/opendesign/src/components/_shared/vue-utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..8a5dbc944e15c4b07030c6697891d35d0aa4389f --- /dev/null +++ b/packages/opendesign/src/components/_shared/vue-utils.ts @@ -0,0 +1,60 @@ +import { Component, onMounted, Slots, VNode, VNodeTypes } from 'vue'; + +// 来着vuejs/core +// https://github.com/vuejs/core/blob/main/packages/shared/src/shapeFlags.ts +export const enum ShapeFlags { + ELEMENT = 1, + FUNCTIONAL_COMPONENT = 1 << 1, + STATEFUL_COMPONENT = 1 << 2, + TEXT_CHILDREN = 1 << 3, + ARRAY_CHILDREN = 1 << 4, + SLOTS_CHILDREN = 1 << 5, + TELEPORT = 1 << 6, + SUSPENSE = 1 << 7, + COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8, + COMPONENT_KEPT_ALIVE = 1 << 9, + COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT +} +/** + * 判断vnode是不是element + */ +export const isElement = (vnode: VNode) => { + return Boolean(vnode && vnode.shapeFlag & ShapeFlags.ELEMENT); +}; + +/** + * 判断vnode是不是vue组件 + * @param vnode vnode节点 + * @param type 组件信息 + */ +export function isComponent(vnode: VNode, type?: VNodeTypes): type is Component { + return Boolean(vnode && vnode.shapeFlag & ShapeFlags.COMPONENT); +} +/** + * 判断vnode是不是vue组件 + */ +export const isSlotsChildren = (vnode: VNode, children: VNode['children']): children is Slots => { + return Boolean(vnode && vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN); +}; + +// TODO +export function useSlotElement(componentName?: string) { + let children: VNode[] | null = null; + const components = []; + // const + onMounted(() => { + children?.forEach(child => { + console.log(child, isComponent(child)); + if (isComponent(child, child.type)) { + if (componentName && child.type.name === componentName) { + components.push(child); + } + } + }); + }); + return { + setSlotChildren(nodes: VNode[]) { + children = nodes; + } + }; +} \ No newline at end of file diff --git a/packages/opendesign/src/components/popover/OPopover.vue b/packages/opendesign/src/components/popover/OPopover.vue index dd13980a4640fba19d0127417ed50c921ed92c36..174d39936566f5a4bc07e1af7e4fbfe0726beaf3 100644 --- a/packages/opendesign/src/components/popover/OPopover.vue +++ b/packages/opendesign/src/components/popover/OPopover.vue @@ -43,7 +43,7 @@ const props = defineProps({ /** * 是否在隐藏时卸载 */ - unmountOnClose: { + unmountOnHide: { type: Boolean, default: true, }, @@ -71,7 +71,7 @@ const updateVisible = (val: boolean) => { :target="props.target" :wrapper="props.wrapper" anchor-class="o-popover-anchor" - :unmount-on-close="props.unmountOnClose" + :unmount-on-hide="props.unmountOnHide" @update:visible="updateVisible" >
diff --git a/packages/opendesign/src/components/popup/OPopup.vue b/packages/opendesign/src/components/popup/OPopup.vue index 8f4c04d83c4a35eab21223b4615563fa477c77f2..7ef18ecc0d433cd93165591f1cde1cbbb77d2fc8 100644 --- a/packages/opendesign/src/components/popup/OPopup.vue +++ b/packages/opendesign/src/components/popup/OPopup.vue @@ -85,7 +85,7 @@ const props = defineProps({ /** * 是否在popup隐藏时unmout */ - unmountOnClose: { + unmountOnHide: { type: Boolean, default: true, }, @@ -117,6 +117,13 @@ const props = defineProps({ type: Boolean, default: true, }, + /** + * 过渡名称 + */ + transition: { + type: String, + default: 'o-zoom-fade', + }, }); const emits = defineEmits<{ (e: 'update:visible', val: boolean): void; (e: 'change', val: boolean): void }>(); @@ -307,7 +314,7 @@ const handleTransitionStart = () => { }; const handleTransitionEnd = () => { isAnimating.value = false; - if (!visible.value && props.unmountOnClose) { + if (!visible.value && props.unmountOnHide) { toMount.value = false; } }; @@ -424,7 +431,7 @@ onUnmounted(() => {