Browse Source

fix: fix the issue with NoobButton rendering its icon off center when in `circle` mode.

dev
hechang27-sprt 6 months ago
parent
commit
aa5369efc1
  1. 6
      .claude/settings.local.json
  2. 25
      packages/base/item/button.vue
  3. 35
      packages/base/item/buttonWithTooltip.vue

6
.claude/settings.local.json

@ -17,7 +17,11 @@
"mcp__chrome-devtools__list_console_messages", "mcp__chrome-devtools__list_console_messages",
"Bash(dir:*)", "Bash(dir:*)",
"Bash(curl:*)", "Bash(curl:*)",
"Bash(xargs cat:*)" "Bash(xargs cat:*)",
"mcp__chrome-devtools__fill_form",
"Bash(npm run build:lib:*)",
"Bash(bun run build:lib:*)",
"Bash(bun run dev)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

25
packages/base/item/button.vue

@ -1,14 +1,15 @@
<template> <template>
<el-button :class="type || state.style.name" :size="state.size.size" :type="type" :icon="icon" :disabled="disabled" <el-button :class="type || state.style.name" :size="state.size.size" :type="type" :icon="icon" :disabled="disabled"
:plain="plain" :round="round" :circle="circle" :loading="loading" :text="text" :link="link"> :plain="plain" :round="round" :circle="circle" :loading="loading" :text="text" :link="link">
<slot /> <slot v-if="hasSlotContent" />
</el-button> </el-button>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { useStore } from "vuex"; import { useStore } from "vuex";
import { reactive, onMounted, ref } from "vue"; import { reactive, onMounted, ref, useSlots, computed } from "vue";
const { state } = useStore(); const { state } = useStore();
const slots = useSlots();
const prop = defineProps({ const prop = defineProps({
type: { type: {
@ -49,6 +50,20 @@ const prop = defineProps({
} }
}); });
const hasSlotContent = computed(() => {
if (!slots.default) return false;
const content = slots.default();
// Filter out comments and empty text nodes
const meaningfulContent = content.filter(vnode => {
// Comment nodes
if (vnode.type === Symbol.for('v-cmt')) return false;
// Text nodes that are empty or whitespace only
if (vnode.type === Symbol.for('v-txt') && (!vnode.children || String(vnode.children).trim() === '')) return false;
return true;
});
return meaningfulContent.length > 0;
});
onMounted(() => { }); onMounted(() => { });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -62,3 +77,9 @@ onMounted(() => { });
--el-button-hover-text-color: v-bind('state.style.color'); --el-button-hover-text-color: v-bind('state.style.color');
} }
</style> </style>
<style>
/* Global style to fix icon centering in circle buttons by hiding empty slot spans */
.el-button.is-circle > span[class=""] {
display: none !important;
}
</style>

35
packages/base/item/buttonWithTooltip.vue

@ -1,24 +1,21 @@
<template> <template>
<el-tooltip <el-tooltip
v-if="props.tooltip"
:content="props.tooltip" :content="props.tooltip"
:disabled="props.disabled" :disabled="props.disabled || !props.tooltip"
:show-after="0" :show-after="0"
:hide-after="0" :hide-after="0"
:popper-options="{ modifiers: [{ name: 'eventListeners', enabled: false }] }" :popper-options="{ modifiers: [{ name: 'eventListeners', enabled: false }] }"
popper-class="non-interactive-tooltip" popper-class="non-interactive-tooltip"
> >
<NoobButton :disabled="props.disabled" v-bind="buttonProps"> <NoobButton v-if="!hasSlotContent" :disabled="props.disabled" v-bind="buttonProps" />
<slot />
</NoobButton>
</el-tooltip>
<NoobButton v-else :disabled="props.disabled" v-bind="buttonProps"> <NoobButton v-else :disabled="props.disabled" v-bind="buttonProps">
<slot /> <slot />
</NoobButton> </NoobButton>
</el-tooltip>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useAttrs } from "vue"; import { useAttrs, useSlots } from "vue";
import { ElTooltip } from "element-plus"; import { ElTooltip } from "element-plus";
import { computed } from "vue"; import { computed } from "vue";
import { NoobButton } from "noob-mengyxu"; import { NoobButton } from "noob-mengyxu";
@ -32,15 +29,39 @@ interface Props {
const props = defineProps<Props>(); const props = defineProps<Props>();
const attrs = useAttrs(); const attrs = useAttrs();
const slots = useSlots();
const buttonProps = computed(() => { const buttonProps = computed(() => {
const { class: _, ...rest } = attrs; const { class: _, ...rest } = attrs;
return rest; return rest;
}); });
const hasSlotContent = computed(() => {
if (!slots.default) return false;
const content = slots.default();
// Filter out comments and empty text nodes
const meaningfulContent = content.filter(vnode => {
// Comment nodes
if (vnode.type === Symbol.for('v-cmt')) return false;
// Text nodes that are empty or whitespace only
if (vnode.type === Symbol.for('v-txt') && (!vnode.children || String(vnode.children).trim() === '')) return false;
return true;
});
return meaningfulContent.length > 0;
});
</script> </script>
<style> <style>
.non-interactive-tooltip { .non-interactive-tooltip {
pointer-events: none !important; pointer-events: none !important;
} }
/* Hide empty span in circle buttons - use !important to override element-plus styles */
.el-button.is-circle > span:empty,
.el-button.is-circle > span.el-button__text:empty,
.el-button.is-circle > span[class=""]:empty {
display: none !important;
width: 0 !important;
height: 0 !important;
}
</style> </style>

Loading…
Cancel
Save