Search code examples
vue.jsvuejs3primevueprimeflex

PrimeFlex margin not working inside Vue3 app


I want to apply some margin on PrimeVue elements inside my Vue3 app. Based on the example from the docs

https://www.primefaces.org/primevue/showcase/#/selectbutton

I have a working example with a margin between the icon and the text

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width,initial-scale=1.0" />

        <!-- PrimeVue -->
        <link href="https://unpkg.com/primevue@^3/resources/themes/saga-blue/theme.css" rel="stylesheet" />
        <link href="https://unpkg.com/primevue@^3/resources/primevue.min.css" rel="stylesheet" />
        <link href="https://unpkg.com/[email protected]/primeflex.min.css" rel="stylesheet" />
        <link href="https://unpkg.com/primeicons/primeicons.css" rel="stylesheet" />

        <!-- Dependencies -->
        <script src="https://unpkg.com/vue@next"></script>
        <script src="https://unpkg.com/primevue@^3/core/core.js"></script>

        <!-- Demo -->
        <script src="https://unpkg.com/primevue@^3/selectbutton/selectbutton.min.js"></script>
        <link href="./index.css" rel="stylesheet" />
    </head>
    <body>
        <div id="app">
            <p-selectbutton v-model="selectedValue" :options="options" dataKey="value">
                <template #option="slotProps">
                    <i class="pi pi-check-circle" />
                    <span class="p-ml-4">Some text</span>
                </template>
            </p-selectbutton>
        </div>

        <script type="module">
        const { createApp, ref } = Vue;

        const App = {
            setup() {
                const selectedValue = ref();
                
                const options = ref([
                    { value: 'left' },
                    { value: 'right' }
                ]);

                return { selectedValue, options }
            },
            components: {
                "p-selectbutton": primevue.selectbutton
            }
        };

        createApp(App)
            .use(primevue.config.default)
            .mount("#app");
        </script>

    </body>
</html>

But the margin does not work in my project. For reproduction:

vue create foo

# select default Vue3 app

cd foo

# based on https://primefaces.org/primevue/showcase/#/setup

npm install primevue

npm install primeicons

npm install primeflex

I change the main.js file to

import { createApp } from 'vue'
import PrimeVue from "primevue/config";
import "primevue/resources/themes/saga-blue/theme.css";
import "primevue/resources/primevue.min.css";
import "primeicons/primeicons.css";
import "primeflex/primeflex.css";
import SelectButton from "primevue/selectbutton";
import App from './App.vue'

createApp(App)
    .use(PrimeVue)
    .component("p-select-button", SelectButton)
    .mount('#app')

I change the App.vue file to

<template>
  <p-select-button v-model="selectedValue" :options="options" dataKey="value">
      <template #option>
          <i class="pi pi-check-circle" />
          <span class="p-ml-4">Some text</span>
      </template>
  </p-select-button>
</template>

<script>
import { ref } from "vue";

export default {
  setup() {
    const selectedValue = ref();
    
    const options = ref([
        { value: 'left' },
        { value: 'right' }
    ]);

    return { selectedValue, options }
  },
}
</script>

When running the app the result is

enter image description here

Does someone know why the margin works in the first sample but not in my code? What am I missing?


Solution

  • Your CDN demo uses PrimeFlex 2:

    <link href="https://unpkg.com/[email protected]/primeflex.min.css" rel="stylesheet" />
                                            👆
    

    But your app uses PrimeFlex 3 (i.e., npm install primeflex installs 3.1.0). The latest version has removed the p- prefix from all classnames for readability, so the class name is now ml-4.

    Solution 1: Update classname to ml-4

    You can use PrimeFlex 3's classname in App.vue:

    <!-- BEFORE -->
    <span class="p-ml-4">Some text</span>
    
    <!-- AFTER -->
    <span class="ml-4">Some text</span>
    

    demo 1

    Solution 2: Downgrade to PrimeFlex 2

    If you prefer to use the existing version (perhaps to minimize changes in a large app), install PrimeFlex 2 instead:

    npm install -S primeflex@2
    

    demo 2