refactor: replace icon props with #icon slots in wrapper components

This commit is contained in:
kolaente 2026-02-19 14:57:52 +01:00
parent 70ada1d20b
commit 820ba348bb
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
4 changed files with 23 additions and 36 deletions

View File

@ -14,21 +14,17 @@
'--button-white-space': wrap ? 'break-spaces' : 'nowrap',
}"
>
<template v-if="icon">
<Icon
v-if="!$slots.default"
:icon="icon"
:style="{color: iconColor}"
/>
<template v-if="$slots.icon">
<span
v-else
v-if="$slots.default"
class="icon is-small"
>
<Icon
:icon="icon"
:style="{color: iconColor}"
/>
<slot name="icon" />
</span>
<slot
v-else
name="icon"
/>
</template>
<span>
<slot />
@ -39,7 +35,6 @@
<script setup lang="ts">
import {computed} from 'vue'
import BaseButton from '@/components/base/BaseButton.vue'
import type {IconProp} from '@fortawesome/fontawesome-svg-core'
const props = defineProps<ButtonProps>()
@ -53,8 +48,6 @@ export type ButtonTypes = keyof typeof VARIANT_CLASS_MAP
export interface ButtonProps {
variant?: ButtonTypes
icon?: IconProp
iconColor?: string
loading?: boolean
disabled?: boolean
shadow?: boolean
@ -64,7 +57,6 @@ export interface ButtonProps {
defineOptions({name: 'XButton'})
// @ts-expect-error - Complex union type from IconProp causes TS2590, but the code is correct
const variant = computed(() => (props.variant ?? 'primary') as ButtonTypes)
const shadow = computed(() => (props.shadow ?? true) as boolean)
const wrap = computed(() => (props.wrap ?? true) as boolean)

View File

@ -36,12 +36,19 @@
<XButton
v-if="hasPrimaryAction"
variant="primary"
:icon="primaryIcon"
:disabled="isBusy"
class="mis-2"
:loading="currentLoading"
@click.prevent.stop="primary"
>
<template
v-if="showPrimaryIcon"
#icon
>
<slot name="primary-icon">
<PhPlus />
</slot>
</template>
{{ primaryLabel || $t('misc.create') }}
</XButton>
</slot>
@ -51,14 +58,14 @@
</template>
<script setup lang="ts">
import type {IconProp} from '@fortawesome/fontawesome-svg-core'
import {PhPlus} from '@phosphor-icons/vue'
import {computed, ref, toRef, watch} from 'vue'
const props = withDefaults(defineProps<{
title: string,
primaryLabel?: string,
primaryIcon?: IconProp,
showPrimaryIcon?: boolean,
primaryDisabled?: boolean,
hasPrimaryAction?: boolean,
tertiary?: string,
@ -66,7 +73,7 @@ const props = withDefaults(defineProps<{
loading?: boolean,
}>(), {
primaryLabel: '',
primaryIcon: 'plus',
showPrimaryIcon: true,
primaryDisabled: false,
hasPrimaryAction: true,
tertiary: '',

View File

@ -15,10 +15,7 @@
class="dropdown-trigger is-flex"
@click="toggleOpen"
>
<Icon
:icon="triggerIcon"
class="icon"
/>
<PhDotsThree class="icon" />
</BaseButton>
</slot>
@ -42,17 +39,11 @@
import {ref, nextTick, watch, computed} from 'vue'
import {onClickOutside} from '@vueuse/core'
import {computePosition, autoPlacement, offset, shift} from '@floating-ui/dom'
import type {IconProp} from '@fortawesome/fontawesome-svg-core'
import {PhDotsThree} from '@phosphor-icons/vue'
import CustomTransition from '@/components/misc/CustomTransition.vue'
import BaseButton from '@/components/base/BaseButton.vue'
withDefaults(defineProps<{
triggerIcon?: IconProp
}>(), {
triggerIcon: 'ellipsis-h',
})
const emit = defineEmits<{
'close': [event: PointerEvent]
}>()

View File

@ -5,11 +5,11 @@
:class="{'is-disabled': disabled}"
>
<span
v-if="icon"
v-if="$slots.icon"
class="icon is-small"
:class="iconClass"
>
<Icon :icon="icon" />
<slot name="icon" />
</span>
<span>
<slot />
@ -18,12 +18,9 @@
</template>
<script lang="ts" setup>
import BaseButton, {type BaseButtonProps} from '@/components/base//BaseButton.vue'
import Icon from '@/components/misc/Icon'
import type {IconProp} from '@fortawesome/fontawesome-svg-core'
import BaseButton, {type BaseButtonProps} from '@/components/base/BaseButton.vue'
export interface DropDownItemProps extends /* @vue-ignore */ BaseButtonProps {
icon?: IconProp,
iconClass?: object | string,
disabled?: boolean,
}