primefaces / primevue

Next Generation Vue UI Component Library
https://primevue.org
MIT License
10.19k stars 1.21k forks source link

Button: Icon position prop does not work as expected when use slot #5623

Open manjindersinghsarkaria opened 5 months ago

manjindersinghsarkaria commented 5 months ago

Describe the bug

When using a slot to provide an icon, the iconPos prop does not have any effect. I noticed this behavior while using Font Awesome icons. Even when testing with PrimeVue icons, the position remained unchanged. Below is the code snippet, and I'll also attach a screenshot for reference. Screenshot_4

Reproducer

https://stackblitz.com/edit/voekuq?file=src%2FApp.vue

PrimeVue version

3.51.0

Vue version

3.x

Language

TypeScript

Build / Runtime

Vue CLI App

Browser(s)

No response

Steps to reproduce the behavior

Add an icon inside the button using the icon slot, and give a position right via prop called iconPos, and you will see that the icon remain on left.

Expected behavior

Icon position should moved to right when the iconPos is right

Rekl0w commented 5 months ago

https://stackblitz.com/edit/voekuq-khdt1t?file=src%2FApp.vue

Try this, this should do.

manjindersinghsarkaria commented 5 months ago

@Rekl0w In the PrimeVue component library, when using a slot to provide an icon instead of utilizing PrimeIcons, the iconPos prop does not function as expected. This issue arises specifically when utilizing the icon slot with non-PrimeIcons, such as Font Awesome.

shaynekasai commented 5 months ago

Can confirm, we ran into the same issue using Hero icons

<Button iconPos="right">
  <template #icon><QuestionMarkCircleIcon class="w-5 h-5"/></template>
</Button>

The first workaround that comes to mind is to not use the template but then you lose other capabilities like label

jason-nabooki commented 5 months ago

Run into the same issue as well, trying to use FontAwesome. Padding is also lost between the label and icon. Of course we can add our own but ideally the template is for drop in replacement of the icon.

jhillacre commented 2 months ago

I'm running into this with v3.52.0.

I have a wrapping component (ButtonIcon.vue) around the PrimeVue Button where I use computed properties to determine a custom font awesome icon based on passed props. I'm also using Tailwind CSS with PrimeVue's Lara theme, customized using usePassThrough.

If someone is looking for a workaround, I've used the theme's icon function directly with a fake set of prop defaults.

...
const attrs = useAttrs();
const iconProps = computed(()=> CustomizedLara.value.button.icon({ props: {
    // hard-coded defaults for the Button
    ...{
        iconPos: "left",
        loading: false,
        link: false,
        raised: false,
        text: false,
        outlined: false,
        plain: false,
    },
    // local override default
    ...{
        iconPos: "right",
    },
    ...attrs
}}));
</script>
<template>
    <Button icon-pos="right">
        <template #icon="slotProps" v-if="autoIcon">
            <span :class="iconProps.class">
                <font-awesome-icon fixed-width :icon="autoIcon" />
            </span>
        </template>
    </Button>
</template>

It seems like getting the processed passthrough icon.class as a slot prop would make the slot more useful for simpler custom icons customization.

BenJackGill commented 2 weeks ago

Can confirm, we ran into the same issue using Hero icons

<Button iconPos="right">
  <template #icon><QuestionMarkCircleIcon class="w-5 h-5"/></template>
</Button>

The first workaround that comes to mind is to not use the template but then you lose other capabilities like label

I am also having this exact same issue.