Skip to content

Commit

Permalink
feat: add BTree
Browse files Browse the repository at this point in the history
  • Loading branch information
YunYouJun committed Dec 23, 2023
1 parent 50403ab commit f167fb5
Show file tree
Hide file tree
Showing 7 changed files with 475 additions and 187 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts" setup>
import { svg } from '../../styles/icons'
import BIconButton from './BIconButton.vue'
const icons = Object.keys(svg).map(icon => ({
icon,
muted: false,
hint: icon,
}))
</script>

<template>
<Story
title="BIconButton"
>
<template v-for="icon in icons" :key="icon.icon">
<BIconButton
:icon="icon.icon"
:muted="icon.muted"
:hint="icon.hint"
/>
</template>
</Story>
</template>
56 changes: 56 additions & 0 deletions packages/blender-ui/client/components/BIconButton/BIconButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script lang="ts" setup>
import { computed } from 'vue'
// Props
const props = withDefaults(defineProps<{
icon: string
muted?: boolean
hint?: string
}>(), {
muted: false,
hint: '',
})
// Computed style for background image
const backgroundImageStyle = computed(() => ({
backgroundImage: `var(--b-icon-${props.icon})`,
}))
// Double click event handler
function handleDoubleClick() {
// Your double click logic here
}
</script>

<template>
<button
class="toggle"
:class="{ muted }"
:style="backgroundImageStyle"
:title="hint"
@click.stop
@dblclick.stop="handleDoubleClick"
/>
</template>

<style scoped>
.toggle {
appearance: none;
background: transparent no-repeat center center;
border: none;
width: 20px;
height: 20px;
opacity: 0.6;
flex-shrink: 0;
cursor: pointer;
}
.toggle:active,
.toggle:hover {
opacity: 0.8;
}
.toggle.muted {
opacity: 0.3;
}
</style>
79 changes: 62 additions & 17 deletions packages/blender-ui/client/components/BTree/BTree.story.vue
Original file line number Diff line number Diff line change
@@ -1,70 +1,115 @@
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import type { Tree } from './BTree.vue'
import { ref } from 'vue'
import type { TreeNode, Trees } from './types'
import BTree from './BTree.vue'
const data: Tree[] = [
const treeData = ref<Trees>([
{
label: 'Level one 1',
name: 'Level one 1',
children: [
{
label: 'Level two 1-1',
name: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
name: 'Level three 1-1-1',
},
],
},
],
},
{
label: 'Level one 2',
name: 'Level one 2',
visible: true,
children: [
{
label: 'Level two 2-1',
name: 'Level two 2-1',
visible: true,
children: [
{
label: 'Level three 2-1-1',
name: 'Level three 2-1-1',
},
],
},
{
label: 'Level two 2-2',
name: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
name: 'Level three 2-2-1',
},
],
},
],
},
{
label: 'Level one 3',
name: 'Level one 3',
expanded: true,
children: [
{
label: 'Level two 3-1',
name: 'Level two 3-1',
expanded: true,
children: [
{
label: 'Level three 3-1-1',
name: 'Level three 3-1-1',
selectable: true,
},
],
},
{
label: 'Level two 3-2',
name: 'Level two 3-2',
visible: false,
children: [
{
label: 'Level three 3-2-1',
name: 'Level three 3-2-1',
},
],
},
],
},
]
])
function onSelect(nodes: Trees) {
console.log('onSelect', nodes)
}
function onUnselected(nodes: Trees) {
console.log('onUnselected', nodes)
}
function hide(nodes: Trees) {
console.log('hide', nodes)
}
function show(nodes: Trees) {
console.log('show', nodes)
}
function collapse(nodes: Trees) {
console.log('collapse', nodes)
}
function expand(nodes: Trees) {
console.log('expand', nodes)
}
function activate(node: TreeNode) {
console.log('activate', node)
}
</script>

<template>
<Story
title="BTree"
>
<BTree :data="data" />
<BTree
:data="treeData"
@node-selected="onSelect"
@node-unselected="onUnselected"
@node-hide="hide"
@node-show="show"
@node-collapse="collapse"
@node-expand="expand"
@node-activate="activate"
/>
</Story>
</template>
122 changes: 106 additions & 16 deletions packages/blender-ui/client/components/BTree/BTree.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,113 @@
<script lang="ts" setup>
export interface Tree {
label: string
children?: Tree[]
<!-- eslint-disable vue/custom-event-name-casing -->
<script setup lang="ts">
import { ref } from 'vue'
import type { TreeNode, Trees } from './types'
import BTreeNode from './BTreeNode.vue'
withDefaults(defineProps<{
data: Trees | TreeNode
depth?: number
}>(), {
depth: 0,
})
const emit = defineEmits([
'node-activate',
'node-collapse',
'node-expand',
'node-selected',
'node-unselected',
'node-show',
'node-hide',
'log',
],
)
const currentNode = ref<TreeNode>({
name: 'root',
})
function expand(nodes: TreeNode[]) {
nodes.forEach((node) => {
node.expanded = true
})
emit('node-expand', nodes)
}
function collapse(nodes: TreeNode[]) {
nodes.forEach((node) => {
node.expanded = false
})
emit('node-collapse', nodes)
}
function onSelected(nodes: Trees) {
nodes.forEach((node) => {
node.selectable = true
})
emit('node-selected', nodes)
}
defineProps<{
data: Tree[]
}>()
function onUnselected(nodes: Trees) {
nodes.forEach((node) => {
node.selectable = false
})
emit('node-unselected', nodes)
}
function show(nodes: Trees) {
nodes.forEach((node) => {
node.visible = true
})
emit('node-show', nodes)
}
function hide(nodes: Trees) {
nodes.forEach((node) => {
node.visible = false
})
emit('node-hide', nodes)
}
function activate(node: TreeNode) {
currentNode.value = node
}
</script>

<template>
<div class="tree">
<div v-for="item in data" :key="item.label" class="tree-item">
<div class="tree-item-label">
{{ item.label }}
</div>
<div class="tree-item-children">
<Tree :data="item.children" />
</div>
</div>
<div class="b-tree">
<template v-if="Array.isArray(data)">
<template v-for="(tree, i) in data" :key="tree.id || tree.name || i">
<BTreeNode
:current-node="currentNode"
:node="tree"
:depth="depth || 0"

@node-activate="activate"
@node-collapse="collapse"
@node-expand="expand"
@node-show="show"
@node-hide="hide"
@node-selected="onSelected"
@node-unselected="onUnselected"
/>
</template>
</template>
<template v-else>
<BTreeNode
:current-node="currentNode"
:node="data"
:depth="depth || 0"

@node-activate="activate"
@node-collapse="collapse"
@node-expand="expand"
@node-show="show"
@node-hide="hide"
@node-selected="onSelected"
@node-unselected="onUnselected"
/>
</template>
</div>
</template>
Loading

0 comments on commit f167fb5

Please sign in to comment.