Skip to content

Commit

Permalink
feat(core): edit button-group 调整 button-group 组件
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemeras246 committed May 10, 2024
1 parent 7c108d0 commit 8e37350
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 58 deletions.
42 changes: 20 additions & 22 deletions packages/core/src/components/button-group/button-group.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,27 @@
@click.stop="clickDelegate($event, 'wb-button', handleGroupClick)"
>
<slot>
<wb-button
v-for="(item, index) in options"
v-bind="item"
:key="item.key || index"
:data-key="item.key || index"
:size="size"
:type="type"
:shape="shape"
flex="1"
/>
<component :is="ContentNode" v-if="!options?.length" />
<template v-else>
<wb-button
v-for="(item, index) in options"
v-bind="item"
:key="item.key || index"
:data-key="item.key || index"
:size="size"
:type="type"
:shape="shape"
flex="1"
/>
</template>
</slot>
</div>
</template>
<script setup lang="ts">
import { getComponentSizeStyles, clickDelegate } from '@/utils'
import { computed, getCurrentInstance } from 'vue'
import { useNode } from '@/composables'
import { clickDelegate, getComponentSizeStyles } from '@/utils'
import { computed } from 'vue'
import { FormElementDefaultProps, FormElementProps } from '../api'
import WbButton from '../button/button.vue'
import DefaultProps, { Emits, Props, Slots } from './api'
Expand All @@ -37,13 +41,6 @@ const props = withDefaults(defineProps<Props & FormElementProps>(), {
const emits = defineEmits<Emits>()
defineSlots<Slots>()
const instance = getCurrentInstance()
// getChildrens()
console.log(instance)
console.log(instance?.slots?.default?.())
// TODO: 判断是否指定类型,获取children信息
const propsClasses = computed(() => {
const result = ['wb-button-group']
const displayProps = ['type', 'size', 'shape']
Expand All @@ -70,11 +67,12 @@ const propsStyles = computed(() => {
return result
})
const renderNode = useNode()
const ContentNode = () => renderNode('default', { nodeType: 'WbButton' })
function handleGroupClick(dataset: Record<string, any>) {
// index -> key 等其他信息? 获取slot时注入data-key?
const { key } = dataset
debugger
if (key !== undefined) {
if (key) {
emits('click', key)
}
}
Expand Down
33 changes: 27 additions & 6 deletions packages/core/src/components/button-group/examples/event.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
<template>
<wb-button-group @click="clickHandler">
<wb-button type="plain" key="1">button1</wb-button>
<wb-button type="plain" key="2">button2</wb-button>
<wb-button type="plain" key="3">button3</wb-button>
<div>111</div>
</wb-button-group>
<wb-space vertical>
<wb-button-group @click="clickHandler">
<wb-button type="plain" key="1">button1</wb-button>
<wb-button type="plain" key="2">button2</wb-button>
<wb-button type="plain" key="3">button3</wb-button>
<div>111</div>
</wb-button-group>
<wb-button-group :options="options" @click="clickHandler" />
</wb-space>
</template>

<script setup lang="ts">
const options = [
{
key: '1',
content: 'button1',
type: 'plain'
},
{
key: '2',
content: 'button2',
type: 'plain'
},
{
key: '3',
content: 'button3',
type: 'plain'
}
]
function clickHandler(key: string) {
console.log(`click: button${key}`)
}
Expand Down
14 changes: 5 additions & 9 deletions packages/core/src/components/button/button.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<component
:is="tag"
:data-key="nodeKey"
v-bind="$attrs"
:disabled="loading || disabled"
:aria-disabled="loading || disabled"
Expand Down Expand Up @@ -49,10 +50,10 @@
</template>

<script setup lang="tsx">
import { useNode, useNodes } from '@/composables'
import { useNode, useNodeKey, useNodes } from '@/composables'
import { getComponentSizeStyles } from '@/utils'
import Color from 'color'
import { computed, onMounted } from 'vue'
import { computed } from 'vue'
import {
WithElementDefaultProps,
WithElementProps,
Expand All @@ -69,7 +70,6 @@ const props = withDefaults(defineProps<Props & WithElementProps & WithStateProps
...WithStateDefaultProps,
...DefaultProps
})
defineEmits<Emits>()
defineSlots<Slots>()
Expand Down Expand Up @@ -111,15 +111,11 @@ const propsStyles = computed(() => {
return result
})
const nodeKey = useNodeKey()
const renderNodes = useNodes()
const ContentNode = () => renderNodes(['content', 'default'])
const renderNode = useNode()
const renderPrefixNode = renderNode('prefix')
const PrefixNode = () => renderPrefixNode
const PrefixNode = () => renderNode('prefix')
const SuffixNode = () => renderNode('suffix')
onMounted(() => {
console.log(renderPrefixNode)
})
</script>
60 changes: 40 additions & 20 deletions packages/core/src/composables/node.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
import { ComponentInternalInstance, getCurrentInstance, h } from 'vue'
// import type { VNode } from 'vue'

function getSlotNode(instance: ComponentInternalInstance, name: string) {
const node = instance.slots[name]?.()
// TODO: 获取子组件信息
if (node && node.filter(t => t.type.toString() !== 'Symbol(v-cmt)').length) return node
function getSlotNode(
instance: ComponentInternalInstance,
name: string,
targetNodeType = ''
) {
const nodes = instance.slots[name]?.()
if (nodes) {
console.log(nodes)
const resolveNodes = nodes.filter((n: any) => {
const type =
Object.prototype.toString.call(n.type) === '[object Object]'
? n.type.name
: n.type.toString()
const isTargetType = ['Symbol(v-cmt)', targetNodeType].includes(type)
if (!isTargetType) {
// eslint-disable-next-line no-console
console.warn(
`[white-block]: Detected invalid type: \`${type}\` child inside \`button-group\` which only allowed \`button\`.`
)
}
return isTargetType
})
console.log(resolveNodes)
if (resolveNodes.length) return resolveNodes
}
return null
}

export interface UseNodeOptions {
prior: string
nodeType: string
}
/**
* Get node from `props` or `slots`.
Expand All @@ -36,34 +57,27 @@ export interface UseNodeOptions {
*/
export function useNode() {
const instance = getCurrentInstance()
return function (name: string, options?: UseNodeOptions) {
return function (name: string, options?: Partial<UseNodeOptions>) {
if (!instance) return null

const { prior = 'slots' } = options || {}
const { prior = 'slots', nodeType } = options || {}

// slot first
// Slots First
let slotNode: any = null
if (instance.slots[name]) {
// slotNode = getSlotNode(instance, name)
const nodes = instance.slots[name]?.()
// TODO: 获取子组件信息
if (nodes && nodes.filter(t => t.type.toString() !== 'Symbol(v-cmt)').length) {
slotNode = nodes
}
slotNode = getSlotNode(instance, name, nodeType)
}
if (nodeType) {
console.log(slotNode)
}
if (prior === 'slots' && slotNode) return slotNode

// props
// Then Props
let propNode: any = null
if (instance.props[name]) {
propNode = instance.props[name]
}

// if ([false, null].includes(propNode)) {
// propNode = null
// } else if (propNode === true) {
// propNode = getSlotNode(instance, name)
// } else
if (typeof propNode === 'function') {
propNode = propNode(h, {})
}
Expand All @@ -84,3 +98,9 @@ export function useNodes() {
return null
}
}

export function useNodeKey() {
const instance = getCurrentInstance()
if (!instance) return null
return instance.vnode.key
}
1 change: 0 additions & 1 deletion packages/core/src/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export function clickDelegate(
(dom: HTMLElement) => dom.className && dom.className.includes(className)
)
if (target) {
debugger
handler(target.dataset, e)
return
}
Expand Down

0 comments on commit 8e37350

Please sign in to comment.