Skip to content

feat(module): define neutral utilities #3629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: v3
Choose a base branch
from
Open

feat(module): define neutral utilities #3629

wants to merge 21 commits into from

Conversation

benjamincanac
Copy link
Member

@benjamincanac benjamincanac commented Mar 19, 2025

πŸ”— Linked issue

Resolves #3628

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

This is a proposal to define tailwind utilities to avoid writing CSS variables:

  1. Colors: feat(module): dynamic rounded-* utilitiesΒ #3906

For each of our color aliases (design system), we define a --color-primary: var(--ui-primary) in Tailwind CSS @theme which lets us write:

  • text-(--ui-primary) -> text-primary
  • bg-(--ui-error)/10 -> bg-error/10
  • ...
  1. Radius: feat(module): define default color shadesΒ #3916

It is a pain at the moment to write rounded classes so my suggestion is to override the default Tailwind CSS rounded-sm, rounded-md, etc. to use our --ui-radius CSS variable (which keeps the flexibility to change all of them at once):

  • rounded-(--ui-radius) -> rounded-sm
  • rounded-[calc(var(--ui-radius)*1.5)] -> rounded-md
  • ...
  1. Neutral

By adding an @utility for each variable, this let us write:

  • text-(--ui-text-muted) -> text-muted
  • border-(--ui-border) -> border-default
  • ...

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

Copy link

pkg-pr-new bot commented Mar 19, 2025

npm i https://pkg.pr.new/@nuxt/ui@3629

commit: 852dc4f

Copy link
Contributor

nuxthub-admin bot commented Mar 19, 2025

βœ… Deployed ui3

Deployed ui3 852dc4f to preview

πŸ”— pr-3628.ui-6q2.pages.dev
πŸ“Œ 93cfdbfb.ui-6q2.pages.dev
πŸ“±
View QR Code QR code linking to deployment URL.

πŸ“‹ View deployment logs

@moshetanzer
Copy link
Contributor

This is great. Will make migration easier and code cleaner.

@stijns96
Copy link
Contributor

I think I even asked this already somewhere in one of my issues, but this would be so helpful. I really hate the fact that I constantly somehow have to remember what is available.

The only thing to keep in mind (what I still find a bit confusing) is adding custom styles, or get rid of the already existing tw colors. If I set colors to initial, the build is probably (thought I've tested it already, could be V2) going to break due to missing colors.

@jits
Copy link

jits commented Mar 20, 2025

This is an excellent proposal πŸŽ‰

daisyUI does something similar (example).

@XStarlink
Copy link

XStarlink commented Mar 20, 2025

This library has become a joy to use with v3, the updated components, and its design system!
Thanks @benjamincanac for taking my proposal into account so quicklyβ€”that was really fast!

@sandros94
Copy link
Member

The only thing to keep in mind (what I still find a bit confusing) is adding custom styles, or get rid of the already existing tw colors. If I set colors to initial, the build is probably (thought I've tested it already, could be V2) going to break due to missing colors.

The module requires a set of colors to be always defined to work properly (read more in theme's color section). Essentially it needs to know which are the new color values for them

@XStarlink
Copy link

XStarlink commented Mar 20, 2025

@benjamincanac Do you think it would be interesting to add shades for text-primary, like text-primary-50, text-primary-100, and text-primary-200... ?

Copy link
Member Author

benjamincanac commented Mar 20, 2025

@XStarlink We already have that in the 3.0.0, this PR adds the text-primary default without shade.

Here's where it's defined if you're interested: https://github.com/nuxt/ui/blob/v3/src/templates.ts#L90

@XStarlink
Copy link

@benjamincanac

Wow, excellent!
I hadn’t noticed that we could do that, I thought we had to access it using text-(--ui-color-primary-200) since the Theme page in the docs explained it with CSS variables. But I should have just tested it before asking...

Thanks for your incredible work!

@memic84
Copy link

memic84 commented Mar 20, 2025

@XStarlink We already have that in the 3.0.0, this PR adds the text-primary default without shade.

Here's where it's defined if you're interested: v3/src/templates.ts#L90

Sorry for asking this here, but i am a bit confused where to set the shades to work correctly.

I already have a tailwind setup v4 with --color-primary and with shades. Should these be added to app.config.ts to ui.colors.primary, as an object? Or just defined in my css file?

Does this mean, that in the current version bg-primary should also work as text-primary?

@sandros94
Copy link
Member

I already have a tailwind setup v4 with --color-primary and with shades. Should these be added to app.config.ts to ui.colors.primary, as an object? Or just defined in my css file?

you should define them in your css file (either by overriding one of tailwinds colors or creating your own) and then set in the app.config.ts which one to use:

Does this mean, that in the current version bg-primary should also work as text-primary?

This very PR adds the support for using the default color, so directly using text-primary or bg-primary.
What is already available is text-primary-500 and bg-primary-500, since we do already define all the shades for each color this module provides

@memic84
Copy link

memic84 commented Mar 20, 2025

I am a bit confused with the new tailwind v4 config and not sure what's happening inside nuxt/ui.

I do have the color reset for the tailwind colors, as i don't use those: --color-*: initial;

And combined with the theme(static), it seems that i don't have access to bg-primary-400 for example in nuxt itself. This did work before without the static part.

It doesn't seem right to define all the shades in app.config and nuxt.config as a separate color, right?

Is there maybe a example project with the new config for v3?

It seems that in my project the tailwindcss classes (spacing, height) aren't all created after switching to nuxt/ui.

I still have my initial installation of tailwindcss as a vite plugin, is that correct or should nuxt/ui handle all that?

Also i am using layers, i guess that nuxt/ui has support for that.

UPDATE:
Got it cleared up, there's is a issue with tailwind >= 4.0.8 as also known here: #3374

@import "tailwindcss" theme(static);
@import "@nuxt/ui";

@theme static {
	--color-*: initial;
    --color-black: #000000;
    --color-white: #FFFFFF;
    --color-gray-50: #f9f9f9;
    --color-gray-100: #ececeb;
    --color-gray-200: #dbdcdd;
    --color-gray-300: #d1d3d5;
    --color-gray-400: #b1b3b5;
    --color-gray-500: #878d91;
    --color-gray-600: #737b82;
    --color-gray-700: #676c71;
    --color-gray-800: #595d61;
    --color-gray-900: #3d4045;
    --color-gray-950: #25272a;
    --color-gray: #737b82;
    --color-primary-50: #fff7f0;
    --color-primary-100: #ffead7;
    --color-primary-200: #ffd5b3;
    --color-primary-300: #ffb380;
    --color-primary-400: #ff8c4d;
    --color-primary-500: #ff6000;
    --color-primary-600: #ff5800;
    --color-primary-700: #e1410d;
    --color-primary-800: #c43600;
    --color-primary-900: #a02d00;
    --color-primary-950: #541800;
    --color-primary: #ff5800;
    --body-bg: #ffffff;
    --body-text-primary: #595d61;
    --body-text-secondary: #676c71;
    --body-text-tertiary: #878d91;
}

:root {
  --ui-bg: var(--body-bg);
  --ui-text: var(--body-text-primary);
  --ui-primary: var(--color-primary);
  --ui-gray: var(--color-gray);
  --ui-black: var(--color-black);
  --ui-white: var(--color-white);
}

nuxt.config.ts

  ui: {
    theme: {
      colors: ['primary', 'gray']
    },
    colorMode: false
  },

app.config.ts

  ui: {
    colors: {
      primary: 'primary',
      gray: 'gray'
    }
  }

@benjamincanac benjamincanac added the v3 #1289 label Apr 4, 2025
@benjamincanac
Copy link
Member Author

benjamincanac commented Apr 15, 2025

I was in the middle of the refactor of the entire theme and I have second thoughts about those new utilities.

I'm ok for the default colors (text-primary, bg-error, etc.) and with the radius ones (rounded-md, etc.) but for the neutral ones it is a bit tricky because for example:

  1. the --ui-border can be used inside a border, ring, divide, outline, etc.

ring-(--ui-border) divide-(--ui-border-muted) focus-visible:outline-(--ui-border-inverted)

  1. the --ui-bg can be used inside a text, from, to, etc.

bg-gradient-to-b from-(--ui-bg-muted) to-(--ui-bg) text-(--ui-bg)

This would require defining lots of utilities and I'm not really sure it is worth it 😬 Also, the fact that you use a CSS variable instead of a Tailwind utility clearly state that it belongs to Nuxt UI vs to Tailwind CSS.

@benjamincanac
Copy link
Member Author

benjamincanac commented Apr 16, 2025

For the time being, I've splitted the work into different PRs until we figure out what is the best way to handle this:

@benjamincanac benjamincanac changed the title feat(module): define tailwind utilities feat(module): define neutral utilities Apr 17, 2025
Comment on lines 56 to 135
@utility text-dimmed {
@apply text-(--ui-text-dimmed);
}
@utility text-muted {
@apply text-(--ui-text-muted);
}
@utility text-toned {
@apply text-(--ui-text-toned);
}
@utility text-default {
@apply text-(--ui-text);
}
@utility text-highlighted {
@apply text-(--ui-text-highlighted);
}
@utility text-inverted {
@apply text-(--ui-text-inverted);
}

@utility bg-default {
@apply bg-(--ui-bg);
}
@utility bg-muted {
@apply bg-(--ui-bg-muted);
}
@utility bg-elevated {
@apply bg-(--ui-bg-elevated);
}
@utility bg-accented {
@apply bg-(--ui-bg-accented);
}
@utility bg-inverted {
@apply bg-(--ui-bg-inverted);
}

@utility border-default {
@apply border-(--ui-border);
}
@utility border-muted {
@apply border-(--ui-border-muted);
}
@utility border-accented {
@apply border-(--ui-border-accented);
}
@utility border-inverted {
@apply border-(--ui-border-inverted);
}

@utility ring-default {
@apply ring-(--ui-border);
}
@utility ring-muted {
@apply ring-(--ui-border-muted);
}
@utility ring-accented {
@apply ring-(--ui-border-accented);
}
@utility ring-inverted {
@apply ring-(--ui-border-inverted);
}

@utility divide-default {
@apply divide-(--ui-border);
}
@utility divide-muted {
@apply divide-(--ui-border-muted);
}
@utility divide-accented {
@apply divide-(--ui-border-accented);
}
@utility divide-inverted {
@apply divide-(--ui-border-inverted);
}

@utility outline-inverted {
@apply outline-(--ui-border-inverted);
}
@utility stroke-inverted {
@apply stroke-(--ui-border-inverted);
}
Copy link
Contributor

@hanneskuettner hanneskuettner Apr 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, Tailwind allows you to configure individual color variants for each of these color utilities, like

@theme {
  ...
  
  --text-color-default: var(--ui-text);
  --text-color-muted: var(--ui-text-muted);
  // generates .text-default and .text-muted but not .bg-default, etc

  --border-color-muted: var(--ui-border-muted);
}

which results in all of these utilities to be generated.

Copy link
Member Author

@benjamincanac benjamincanac Apr 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hanneskuettner This is exactly what I discovered an hour ago and am refactoring πŸ˜‚ Check latest commit!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was about to give up the refactor when I discovered that @utility don't work with opacity modifiers but this feature saved the day 😊

Co-Authored-By: SΓ©bastien Chopin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v3 #1289
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Simplified utility classes for text, bg, border
8 participants