Skip to content

Commit

Permalink
✨ feat: 初步增加 tree 组件
Browse files Browse the repository at this point in the history
  • Loading branch information
GuoJikun committed Nov 8, 2023
1 parent 1aedfaf commit 1fc936b
Show file tree
Hide file tree
Showing 18 changed files with 416 additions and 93 deletions.
3 changes: 2 additions & 1 deletion .markdownlint.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"ivy-table-column",
"ivy-drawer",
"ivy-tooltip",
"ivy-details"
"ivy-details",
"ivy-tree"
]
}
}
4 changes: 4 additions & 0 deletions packages/docs/src/.vitepress/config/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ const components = [
text: "Carousel 轮播图",
link: "/components/carousel",
},
{
text: "Tree 树形控件",
link: "/components/tree",
},
],
},
{
Expand Down
72 changes: 72 additions & 0 deletions packages/docs/src/components/tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Tree 树形控件

## 基础用法

<ivy-tree ref="el1" node-key="id"></ivy-tree>

<script setup>
import { onMounted, ref } from 'vue'

const data = [
{
id: 1,
label: 'Level one 1',
children: [
{
id: 4,
label: 'Level two 1-1',
children: [
{
id: 9,
label: 'Level three 1-1-1',
},
{
id: 10,
label: 'Level three 1-1-2',
},
],
},
],
},
{
id: 2,
label: 'Level one 2',
children: [
{
id: 5,
label: 'Level two 2-1',
},
{
id: 6,
label: 'Level two 2-2',
},
],
},
{
id: 3,
label: 'Level one 3',
children: [
{
id: 7,
label: 'Level two 3-1',
},
{
id: 8,
label: 'Level two 3-2',
},
],
},
{
id: 9,
label: 'Level two 4',
},
]

const el1 = ref()
const setElData = (el, data) => {
el.value.setData(data)
}
onMounted(()=>{
setElData(el1, data)
})
</script>
4 changes: 2 additions & 2 deletions packages/ivy-design-wc/src/components/button/index.ce.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { genLoading } from '@/utils/icons'
import { Loading } from '@/utils/icons'
import type { IvySize, IvyType } from '@/utils/typescript'
export type ivyButtonType = IvyType | 'default'
Expand Down Expand Up @@ -38,7 +38,7 @@ const props = defineProps({
}
]"
>
<genLoading v-if="props.loading" class="ivy-loading" />
<Loading v-if="props.loading" class="ivy-loading" />
<slot></slot>
</button>
<div v-if="props.loading" class="is-loading"></div>
Expand Down
6 changes: 3 additions & 3 deletions packages/ivy-design-wc/src/components/carousel/index.ce.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="tsx">
import { type PropType, onMounted, ref, defineComponent, computed, Transition } from 'vue'
import { genArrowRight, genArrowLeft } from '../../utils/icons'
import { ArrowRight, ArrowLeft } from '../../utils/icons'
type Arrow = 'hover' | 'click'
type Trigger = 'hover' | 'always' | 'never'
Expand Down Expand Up @@ -167,13 +167,13 @@ export default defineComponent({
onMouseleave={handleMouseleaveHelper}
>
<div class="carousel-trigger-item" onClick={handlePrev}>
{genArrowLeft()}
{ArrowLeft()}
</div>
<div
class="carousel-trigger-item carousel-trigger-item-right"
onClick={handleNext}
>
{genArrowRight()}
{ArrowRight()}
</div>
</div>
</Transition>
Expand Down
4 changes: 2 additions & 2 deletions packages/ivy-design-wc/src/components/collapse/item.ce.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="tsx">
import { transition } from '@/utils/collapse-transition'
import { genArrowRight } from '@/utils/icons'
import { ArrowRight } from '@/utils/icons'
import { computed, defineComponent, inject, Transition } from 'vue'
Expand Down Expand Up @@ -35,7 +35,7 @@ export default defineComponent({
<div class={['ivy-collapse-item', { 'ivy-collapse-item-active': isActive.value }]}>
<div class="ivy-collapse-item__header" onClick={handleChange}>
<span class={['ivy-icon-right', `ivy-collapse-arrow-${arrowPosition}`]}>
<slot name="icon">{genArrowRight()}</slot>
<slot name="icon">{ArrowRight()}</slot>
</span>
<span>
Expand Down
4 changes: 2 additions & 2 deletions packages/ivy-design-wc/src/components/details/index.ce.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="tsx">
import { defineComponent, ref, Transition } from 'vue'
import { transition } from '@/utils/collapse-transition'
import { genArrowRight } from '@/utils/icons'
import { ArrowRight } from '@/utils/icons'
export default defineComponent({
name: `Details`,
Expand All @@ -23,7 +23,7 @@ export default defineComponent({
return () => (
<div class="details">
<div class="details-summary" onClick={handlerClick}>
{genArrowRight({ class: `details-icon ${visible.value ? 'is-open' : ''}` })}
{ArrowRight({ class: `details-icon ${visible.value ? 'is-open' : ''}` })}
<slot name="summary">{props.summary}</slot>
</div>
Expand Down
4 changes: 2 additions & 2 deletions packages/ivy-design-wc/src/components/loading/index.ce.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="tsx">
import { defineComponent, computed } from 'vue'
import { genLoading } from '@/utils/icons'
import { Loading } from '@/utils/icons'
export default defineComponent({
name: 'Loading',
Expand All @@ -17,7 +17,7 @@ export default defineComponent({
return [
<div class="loading" v-show={isLoading.value}>
<div class="icon">
<slot name="icon">{genLoading({ class: 'icon-loading' })}</slot>
<slot name="icon">{Loading({ class: 'icon-loading' })}</slot>
</div>
{props.text ? <div class="text">{props.text}</div> : null}
</div>,
Expand Down
2 changes: 1 addition & 1 deletion packages/ivy-design-wc/src/components/message/index.ce.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import useHostElement from '@/hooks/useHostElement'
import { curMessageIndex } from '@/utils/utils'
import useBroadCastChannel from '@/hooks/useBroadcastChannel'
// import { genSuccess } from '@/utils/icons'
// import { Success } from '@/utils/icons'
defineOptions({
name: 'Message',
Expand Down
4 changes: 2 additions & 2 deletions packages/ivy-design-wc/src/components/rate/index.ce.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="tsx">
import { computed, ref, defineComponent } from 'vue'
import { genStar, genStarFilled } from '@/utils/icons'
import { Star, StarFilled } from '@/utils/icons'
export default defineComponent({
name: 'Rate',
Expand Down Expand Up @@ -85,7 +85,7 @@ export default defineComponent({
onMouseleave={() => handleMouseleave(index + 1)}
onClick={() => handleClick(index + 1)}
>
{curIndex.value < index + 1 ? genStar() : genStarFilled()}
{curIndex.value < index + 1 ? Star() : StarFilled()}
</div>
)
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ const handleMousemove = useThrottleFn((ev: any) => {
scrollMap.value.y = ev.y - initMap.value.y + scrollMap.value.y
// initMap.value.y = 0
// scrollMap.value.y = ev.y - initMap.value.y + scrollMap.value.y
if (scrollbarView.value) scrollWrap.value.scrollTo(0, move)
if (scrollbarView.value) scrollWrap.value?.scrollTo(0, move)
}, 10)
const { setExpose } = useExpose()
Expand Down
2 changes: 1 addition & 1 deletion packages/ivy-design-wc/src/components/table/index.ce.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import useExpose from '@/hooks/useExpose'
import { genLoading } from '@/utils/icons'
import { Loading } from '@/utils/icons'
defineOptions({
name: 'Table',
Expand Down
40 changes: 40 additions & 0 deletions packages/ivy-design-wc/src/components/tree/child.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { type SetupContext } from 'vue'
import CollapseTransition from '@/utils/collapse-transition'
import { CaretRight } from '@/utils/icons'

const TreeItem = (props: Record<string, any>, { emit }: SetupContext) => {
const { data, props: childProps } = props

const handleClick = () => {
data.isOpen = !data.isOpen
emit('item-click', data)
}
return (
<div class="tree-item">
<div class="tree-item__label" onClick={handleClick}>
{data.isLeaf ? (
<span class="tree-item__icon">&nbsp;</span>
) : (
<CaretRight
class="tree-item__icon"
style={{ transform: `rotate(${data.isOpen ? 90 : 0}deg)` }}
></CaretRight>
)}
<span>{data[childProps.label]}</span>
</div>
{data.isLeaf ? null : (
<CollapseTransition>
<div class="tree-item__children" v-show={data.isOpen}>
{data[childProps.children].map((c: any) => (
<TreeItem data={c} props={childProps}></TreeItem>
))}
</div>
</CollapseTransition>
)}
</div>
)
}

TreeItem.emits = ['item-click']

export { TreeItem }
107 changes: 107 additions & 0 deletions packages/ivy-design-wc/src/components/tree/index.ce.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { TreeItem } from './child'
import useExpose from '@/hooks/useExpose'
defineOptions({
name: 'Tree',
inheritAttrs: false
})
const props = defineProps({
nodeKey: String,
propLabel: {
type: String,
default: 'label'
},
propChildren: {
type: String,
default: 'children'
}
})
const keyMap = ref({
label: props.propLabel,
children: props.propChildren
}) // key 映射
type DataSources = Array<{
[key: string]: any
}>
const dataSources = ref<DataSources>([]) // 数据源
// const checkedKeys = ref([]) // 选中的 key
const parseData = (data: DataSources) => {
return data.map((item) => {
const { [props.propChildren]: children } = item
if (children) {
item.isOpen = false
item.isLeaf = false
item.children = parseData(children)
} else {
item.isLeaf = true
}
return item
})
}
const { setExposes } = useExpose()
onMounted(() => {
setExposes({
setCheckedKeys: (keys: string[]) => {
console.log(keys)
},
setData(data: DataSources) {
dataSources.value = parseData(data)
}
})
})
</script>

<template>
<div class="tree">
<template
v-for="(item, index) in dataSources"
:key="props.nodeKey ? item[props.nodeKey] : index"
>
<TreeItem :data="item" :props="keyMap" />
</template>
</div>
</template>

<style lang="scss">
:host {
display: block;
--ivy-tree-font-size: 14px;
--ivy-tree-line-height: 1.5;
}
.tree {
font-size: var(--ivy-tree-font-size);
line-height: var(--ivy-tree-line-height);
&-item {
cursor: default;
&__label {
display: flex;
align-items: center;
}
&__icon {
display: inline-flex;
font-size: 14px;
width: 1em;
height: 1em;
transition: transform 0.3s;
}
&__children {
padding-left: 20px;
box-sizing: border-box;
}
}
}
.collapse-transition {
transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out,
0.3s padding-bottom ease-in-out;
}
</style>
Loading

0 comments on commit 1fc936b

Please sign in to comment.