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 8e37350 commit 24749c5
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 65 deletions.
10 changes: 9 additions & 1 deletion docs/.vitepress/components/layout/overview/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@
transform="hover:translate-y-[-1px]"
transition="all duration-300 ease-in-out"
>
<div w="full" aspect-ratio-1 m="b-2" rounded="1.5">
<div
w="full"
aspect-ratio-1
m="b-2"
rounded="1.5"
flex
justify="center"
items="center"
>
<img
v-if="sub.image"
:src="
Expand Down
11 changes: 10 additions & 1 deletion docs/content/components/button-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ button-group/examples/usage.json

## Properties
:::tip
Property setted on the `ButtonGroup` will have greater priority than `Button` inside it.
If use property `options`.

Properties set on the `ButtonGroup` will have greater priority than `Button` inside it.
:::

## Slots
:::tip
If use `Slot`.

Properties set on the `ButtonGroup` will be ignore.
:::

## Events
Expand Down
12 changes: 9 additions & 3 deletions packages/core/src/components/button-group/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ButtonGroupOptions, ButtonGroupShape, ButtonGroupType } from './types'
import type { Props as ButtonProps } from '../button/api'
import { Props as ButtonProps } from '../button/api'
import { ButtonTheme, ButtonType } from '../button/types'
import { ButtonGroupOptions, ButtonGroupShape } from './types'

export type Slots = {
/*
Expand Down Expand Up @@ -28,7 +29,12 @@ export type Props = {
* Display style of the button-group.
* 'base' | 'plain' | 'outline' | 'ghost' | 'dashed' | 'link' | 'text'
*/
type?: ButtonGroupType
type?: ButtonType
/*
* Display color of the button-group.
* 'default' | 'primary' | 'success' | 'warning' | 'danger'
*/
theme?: ButtonTheme
/*
* Shape of the button in button-group.
* 'rectangle' | 'square' | 'round' | 'circle'
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/components/button-group/button-group.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
:key="item.key || index"
:data-key="item.key || index"
:size="size"
:theme="theme"
:type="type"
:shape="shape"
flex="1"
Expand All @@ -24,7 +25,7 @@
</template>
<script setup lang="ts">
import { useNode } from '@/composables'
import { useNode, useSlotNodeType } from '@/composables'
import { clickDelegate, getComponentSizeStyles } from '@/utils'
import { computed } from 'vue'
import { FormElementDefaultProps, FormElementProps } from '../api'
Expand Down Expand Up @@ -67,8 +68,9 @@ const propsStyles = computed(() => {
return result
})
useSlotNodeType('default', 'WbButton')
const renderNode = useNode()
const ContentNode = () => renderNode('default', { nodeType: 'WbButton' })
const ContentNode = () => renderNode('default')
function handleGroupClick(dataset: Record<string, any>) {
const { key } = dataset
Expand Down
33 changes: 15 additions & 18 deletions packages/core/src/components/button-group/examples/event.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
<template>
<wb-space vertical>
<wb-button-group @click="clickHandler">
<wb-button key="1">button1</wb-button>
<wb-button key="2">button2</wb-button>
<wb-button key="3">button3</wb-button>
</wb-button-group>
<wb-button-group
type="outline"
theme="default"
:options="options"
@click="clickHandler"
/>
<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 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'
}
{ key: '1', content: 'button1' },
{ key: '2', content: 'button2' },
{ key: '3', content: 'button3' }
]
function clickHandler(key: string) {
Expand Down
19 changes: 10 additions & 9 deletions packages/core/src/components/button/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,19 @@
--wb-button-color-main: rgb(var(--vc-danger));
}

/* TODO: 提取重复CSS变量,如 rgb(var(--wb-button-vc-main) / 18%); */
/* -------------------------------------------- type -------------------------------------------- */
.wb-button--base {
--wb-button-background: var(--wb-button-color-main);
--wb-button-background-hover: color-mix(
in srgb,
var(--wb-button-color-main) 75%,
white
var(--wb-button-color-main) 85%,
var(--wb-color-background)
);
--wb-button-background-active: color-mix(
in srgb,
var(--wb-button-color-main) 75%,
black
var(--wb-color-background)
);
--wb-button-border: rgb(var(--wb-button-vc-main) / 30%);
--wb-button-border-hover: var(--wb-button-background-hover);
Expand All @@ -82,8 +83,8 @@
--wb-button-text-active: var(--wb-color-background);
}
.wb-button--plain {
--wb-button-background: rgb(var(--wb-button-vc-main) / 15%);
--wb-button-background-hover: rgb(var(--wb-button-vc-main) / 30%);
--wb-button-background: rgb(var(--wb-button-vc-main) / 10%);
--wb-button-background-hover: rgb(var(--wb-button-vc-main) / 18%);
--wb-button-background-active: color-mix(
in srgb,
var(--wb-button-background-hover) 75%,
Expand All @@ -98,18 +99,18 @@
}
.wb-button--outline {
--wb-button-background: transparent;
--wb-button-background-hover: rgb(var(--wb-button-vc-main) / 30%);
--wb-button-background-hover: rgb(var(--wb-button-vc-main) / 18%);
--wb-button-background-active: rgb(var(--wb-button-vc-main) / 20%);
--wb-button-border: rgb(var(--wb-button-vc-main) / 30%);
--wb-button-border-hover: rgb(var(--wb-button-vc-main) / 80%);
--wb-button-border: rgb(var(--wb-button-vc-main) / 15%);
--wb-button-border-hover: rgb(var(--wb-button-vc-main) / 30%);
--wb-button-border-active: color-mix(in srgb, var(--wb-button-border-hover) 75%, black);
--wb-button-text: var(--wb-button-color-main);
--wb-button-text-hover: color-mix(in srgb, var(--wb-button-text) 90%, white);
--wb-button-text-active: color-mix(in srgb, var(--wb-button-text) 90%, black);
}
.wb-button--ghost {
--wb-button-border: transparent;
--wb-button-border-hover: rgb(var(--wb-button-vc-main) / 80%);
--wb-button-border-hover: rgb(var(--wb-button-vc-main) / 30%);
--wb-button-border-active: color-mix(in srgb, var(--wb-button-border-hover) 75%, black);
--wb-button-text: var(--wb-button-color-main);
--wb-button-text-hover: color-mix(in srgb, var(--wb-button-text) 75%, white);
Expand Down
64 changes: 33 additions & 31 deletions packages/core/src/composables/node.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,15 @@
import { ComponentInternalInstance, getCurrentInstance, h } from 'vue'

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
function getSlotNode(instance: ComponentInternalInstance, name: string) {
const nodes = instance.slots[name]?.(instance.props)
if (nodes && nodes.filter(n => n.type.toString() !== 'Symbol(v-cmt)').length) {
return nodes
}
return null
}

export interface UseNodeOptions {
prior: string
nodeType: string
}
/**
* Get node from `props` or `slots`.
Expand All @@ -40,7 +19,7 @@ export interface UseNodeOptions {
*
*```
* const renderNode = useNode()
* const Node = renderNode('propsOrSlots')
* const Node = () => renderNode('propsOrSlots')
*
* From `slots`
* ```
Expand All @@ -60,15 +39,12 @@ export function useNode() {
return function (name: string, options?: Partial<UseNodeOptions>) {
if (!instance) return null

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

// Slots First
let slotNode: any = null
if (instance.slots[name]) {
slotNode = getSlotNode(instance, name, nodeType)
}
if (nodeType) {
console.log(slotNode)
slotNode = getSlotNode(instance, name)
}
if (prior === 'slots' && slotNode) return slotNode

Expand Down Expand Up @@ -104,3 +80,29 @@ export function useNodeKey() {
if (!instance) return null
return instance.vnode.key
}

export function useSlotNodeType(slot: string, allowed: string) {
const instance = getCurrentInstance()

if (!instance) return

if (instance.slots[slot]) {
const nodes = instance.slots[slot]?.()
if (nodes) {
// @ts-ignore
const nodeType = instance.vnode.type.name
nodes.forEach((n: any) => {
const type =
Object.prototype.toString.call(n.type) === '[object Object]'
? n.type.name
: n.type.toString()
if (type !== allowed) {
// eslint-disable-next-line no-console
console.warn(
`[white-block]: Detected invalid child element type: \`${type}\` inside \`${nodeType}\` which only allowed \`${allowed}\`.`
)
}
})
}
}
}

0 comments on commit 24749c5

Please sign in to comment.