Skip to content
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

feat: support extendTheme return to override #2258

Merged
merged 20 commits into from
Apr 9, 2023

Conversation

Dunqing
Copy link
Member

@Dunqing Dunqing commented Feb 25, 2023

close: #2242

Currently theme and extendTheme have the same effect. I think this behavior is not correct.

In fact, we should allow theme to override the preset's theme, and if we want to add configuration to the original theme, we should use extendTheme. This improvement is similar to the way Tailwind is handled.

So I have made some changes.

  1. theme configuration is not merged, if we provide theme, we only use it.
  2. The return value of extendTheme will be merged
  3. It is no longer necessary to determine whether userConfig.theme.breakpoints exists or not, just use config.theme.breakpoints instead.

@netlify
Copy link

netlify bot commented Feb 25, 2023

Deploy Preview for unocss ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit a38e55e
🔍 Latest deploy log https://app.netlify.com/sites/unocss/deploys/64322b356df8760008b0cbfb
😎 Deploy Preview https://deploy-preview-2258--unocss.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@Dunqing Dunqing marked this pull request as ready for review February 25, 2023 08:53
Comment on lines 85 to 90
let theme = [
...sortedPresets.map(p => p.theme),
config.theme,
].reverse().find(Boolean) as Theme
theme = (mergePresets('extendTheme') as ThemeExtender<Theme>[])
.reduce((mergedTheme, extendTheme) => mergeDeep(mergedTheme, extendTheme(mergedTheme) || {}), theme)
Copy link
Member

Choose a reason for hiding this comment

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

I think the logic here is wrong, you need to consider the existence of other preset theme configurations.

And I switched to your branch and did a simple test and found that none of the results were what I wanted.Dunqing#1.

And you'd better add more test case for it, thanks.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you for your review.

In my opinion the result what i wanted. Because i think preset should respect this rule. most presets should not set theme, but rather use extendTheme to expand the theme.

I will add test cases later to show the intent of this change.

@chu121su12
Copy link
Collaborator

Considering some theme key may require proper ordering (see container), whats the cons of being able to provide callback in theme object?

@endigma
Copy link
Contributor

endigma commented Feb 26, 2023

This doesn't quite close #2242, the desire of which is to disable the colors emanated by preset-mini specifically. I have another preset that adds colors from a different palette that I don't want to re-add as overrides in theme.

@Dunqing
Copy link
Member Author

Dunqing commented Feb 27, 2023

This doesn't quite close #2242, the desire of which is to disable the colors emanated by preset-mini specifically. I have another preset that adds colors from a different palette that I don't want to re-add as overrides in theme.

In your case, you can use extendTheme to override the colors.

extendTheme(theme) {
   theme.colors = {}
}

@Dunqing
Copy link
Member Author

Dunqing commented Feb 27, 2023

Considering some theme key may require proper ordering (see container), whats the cons of being able to provide callback in theme object?

For theme keys that depend on order, you can use extendTheme to replace the whole theme key.
I think callbacks are also good, i just want to be as consistent as possible with tailwind's

@antfu
Copy link
Member

antfu commented Feb 27, 2023

No, I don't think this breaking change is worth it. It's how it works by design from the beginning. It's a trade-off between two usages, this reverts the prioritizes, which to me, makes no difference from the current behavior (deep-merge over overrides, or overrides over deep-merge).

I would suggest we introduce a new option, say:

defineConfig({
  theme: {
    colors: { ... }
  },
  themeResolved(mergedTheme) {
	// by default
    return mergedTheme
    
    // completely ignore the theme, override with a custom one
    return { ... }
    
    // partially overrides, with reference to the resolved theme
    return {
       ...mergeTheme,
       colors: { ... } // override colors, but keep the rest of the theme,
       breakpoints: {
         large: mergeTheme.breakpoints.xl,
         small: mergeTheme.breakpoints.xl
       }
    }
  }
})

Copy link
Member

@antfu antfu left a comment

Choose a reason for hiding this comment

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

Changes requested

@Dunqing Dunqing changed the title refactor(core)!: improve the handling of the config of the theme and extendTheme feat: support themeResolved option Mar 3, 2023
@Dunqing
Copy link
Member Author

Dunqing commented Mar 3, 2023

Do we need to support themeResolved in Preset?

@endigma
Copy link
Contributor

endigma commented Mar 3, 2023

This doesn't quite close #2242, the desire of which is to disable the colors emanated by preset-mini specifically. I have another preset that adds colors from a different palette that I don't want to re-add as overrides in theme.

In your case, you can use extendTheme to override the colors.

extendTheme(theme) {
   theme.colors = {}
}

Let's say you have 3 presets, preset1..3. All 3 add colors/breakpoints/whatever, theme items. If you, the user of the presets, wanted to include only the colors from presets 1 and 3, extendTheme() with a hard override doesn't do anything to help you.

Perhaps a configuration option for all presets like:

include:
    theme:
        colors: false

with defaulting to just include all true?

include: true

or

include:
    theme: true

or

include:
    rules: false

all working how you might expect

@@ -42,6 +42,7 @@
"dependencies": {
"@unocss/config": "workspace:*",
"@unocss/core": "workspace:*",
"@unocss/preset-mini": "workspace:*",
Copy link
Member

Choose a reason for hiding this comment

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

I think we should avoid introducing this, as well as in the transformer directives

@antfu antfu changed the title feat: support themeResolved option feat: support extendTheme return to override Apr 8, 2023
@antfu
Copy link
Member

antfu commented Apr 8, 2023

Thanks! Pushed a change to merge those two APIs into extendTheme so that it has the full power to mutate / replace the theme object entirely.

@antfu
Copy link
Member

antfu commented Apr 8, 2023

This PR aims to be shipped with next minor

@antfu antfu merged commit aae131b into unocss:main Apr 9, 2023
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Completely override presetMini's color palette
5 participants