primefaces / primevue

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

PrimeVue v4 styled mode doesn't work with Tailwind as documented #5762

Open minkyn opened 4 months ago

minkyn commented 4 months ago

Describe the bug

According to the v4 document, if I want to use the styled mode with Tailwind CSS, I need to first turn on the cssLayer option:

app.use(Prime Vue, {
  theme: {
    preset: Aura,
    options: {
      prefix: 'p',
      darkModeSelector: 'system',
      cssLayer: true,
    },
  },
}

Then create a css file (./assets/style.css) arranging the layer order:

@layer tailwind-base, primevue, tailwind-utilities;

@layer tailwind-base {
  @tailwind base;
}

@layer tailwind-utilities {
  @tailwind components;
  @tailwind utilities;
}

However, with this setup, when I experiment a simple page, the styles turn out to come all from Tailwind preflight including the button instead of PrimeVue:

<h1>Home</h1>
<p>Welcome to the Home Page</p>
<Button label="OK" />

I tried adjusting the order of importing the css file in main.ts:

import './assets/style.css'
import PrimeVue from 'primevue/config'
import Aura from 'primevue/themes/aura'

as well as

import PrimeVue from 'primevue/config'
import Aura from 'primevue/themes/aura'
import './assets/style.css'

but neither works.

Reproducer

https://stackblitz.com/edit/primevue-create-vue-typescript-issue-template

PrimeVue version

4.0.0-beta3

Vue version

3.x

Language

TypeScript

Build / Runtime

Vite

Browser(s)

No response

Steps to reproduce the behavior

  1. Create a style file at ./assets/style.css:
    
    @layer tailwind-base, primevue, tailwind-utilities;

@layer tailwind-base { @tailwind base; }

@layer tailwind-utilities { @tailwind components; @tailwind utilities; }


2. Setup PrimeVue config in `main.ts`:
```typescript
import { createApp } from 'vue'

import PrimeVue from 'primevue/config'
import Aura from 'primevue/themes/aura'
import './assets/style.css'

import App from './App.vue'

const pinia = createPinia()

const app = createApp(App)

app.use(PrimeVue, {
  theme: {
    preset: Aura,
    options: {
      prefix: 'p',
      darkModeSelector: 'system',
      cssLayer: true,
    },
  },
})

app.mount('#app')
  1. Create a simple page at App.vue:
    <template>
    <div>
    <h1>Home</h1>
    <p>Welcome to the Home Page</p>
    <Button label="OK" />
    </div>
    </template>

Expected behavior

The heading and paragraph should be rendered in Tailwind CSS preflight, and the button should be rendered in PrimeVue Aura theme.

minkyn commented 4 months ago

It looks like it works when I change from cssLayer: true to cssLayer: { name: "primevue" }

m-meier commented 4 months ago

At least in beta 1 (haven't tried it with the latest one yet) you could also specify the order directly in the configuration. It is not documented however, so I don't know if it will stay this way:

cssLayer: { name: "primeui", order: "tailwind-base, primeui, primevue, tailwind-utilities;", },

minkyn commented 4 months ago

I think the key question I'm asking is about consistency between the public documentation and the actual solution. Hope this can be fixed soon in the coming RC1 release.

flmn commented 4 months ago

when using cssLayer: true, you can check developer tools, you will find the layer name is primeui, consistency is the problem.

minkyn commented 4 months ago

Here is what I found:

  1. When I set cssLayer: true or cssLayer: { name: "primeui" }, the layer's name defaults to "primeui" instead of "primevue" as documented, but there is no way to rearrange its layer order. @layer tailwind-base, primeui, tailwind-utilities; doesn't work. "primeui" always comes at the bottom most layer.
  2. In order for the layer ordering to work, I have to use a different layer name (e.g. "primevue"). After @layer tailwind-base, primevue, tailwind-utilities;, the DevTools actually shows layer ordering as primeui, tailwind-base, primevue, tailwind-utilities; ugly but works. I assume "primeui" was set at the bottom layer by the framework and not able to be changed, so adding a new layer "primevue" is the only workaround I can find now.
minkyn commented 4 months ago

Here is what I found in the code:

if (cssLayer) {
  var order = themes.SharedUtils.object.getItemValue(cssLayer.order || 'primeui', params);
  return "@layer ".concat(order);
}

Maybe the solution is not to add a default @layer statement in the framework? Since developers will definitely write their own ordering in the css file when they try to enable cssLayer option.

f-r3d commented 3 months ago

I had the same problem using Vue 3 + Vite. I resolved with tailwind guide: https://tailwindcss.com/docs/guides/vite#vue

Basically I added postcss