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

[Question || Feature request]How to override class in virtual component from layer? #281

Open
lna1989 opened this issue Sep 26, 2024 · 8 comments

Comments

@lna1989
Copy link

lna1989 commented Sep 26, 2024

The project consists of three layers.
First layer VBtn defaults:

VBtn: {
      class: ['first-layer'],
    },

Second layer VBtn defaults:

VBtn: {
      class: ['second-layer'],
    },

In project layer VBtn defaults:

VBtn: {
      class: ['project-layer'],
    },

Example:
https://stackblitz.com/edit/nuxt-starter-dk197v?file=layers%2Ffirst%2Fvuetify.config.ts,layers%2Fsecond%2Fvuetify.config.ts,vuetify.config.ts,pages%2Findex.vue

Actual result:
image
And this is normal, since there is an interlayer gluing of classes.

Question:
How can I undo the gluing of styles towards rewriting at the project or second layer level?

Additional info:
In nuxt.config.ts the arrow function is used to overwrite the layer values, I tried it, but it didn't work in vuetify.config.ts

@lna1989 lna1989 changed the title How to override class in virtual component from layer? [Question || Feature request]How to override class in virtual component from layer? Sep 26, 2024
@userquin
Copy link
Member

userquin commented Sep 26, 2024

There are a lot of options, the module will merge layers using defu, since the entry is an array the merge will not replace the value (we should add a custom handler to defu here: https://github.com/vuetifyjs/nuxt-module/blob/main/src/utils/layers.ts#L65).

We had similar problem with some other options like merging icon sets: you can check #214 and #217 (https://github.com/vuetifyjs/nuxt-module/blob/main/src/utils/layers.ts#L85C11-L85C21)

@lna1989
Copy link
Author

lna1989 commented Sep 26, 2024

Thanks for the quick response!

Can we add a rule, if the value is an arrow function, () => ['project-layer'], then overwrite the value, and not merge with the previous ones?

Now I'm bypassing this point by writing the class value in the project with a string, but such an entry will be inconvenient, for example, when writing the value for style with a string.

@userquin
Copy link
Member

userquin commented Sep 26, 2024

Merging options is not easy, Nuxt will merge configured layers (I'll check the layer.ts module here, maybe we can simplify the logic) and the module requires merging again for custom vuetify:registerModule Nuxt hook.

We need to dedupe some options, some options should be fine others no, detecting all the options we need to dedupe would require a lot of work, we can do it progresivelly.

EDIT: your use case requires deduping, some other users may want to merge classes (with your same configuration)

@userquin
Copy link
Member

userquin commented Sep 26, 2024

Maybe we can add a new hook to dedupe options before resolving the configuration (providing merged configuration and the layers configuration, similar to https://github.com/vuetifyjs/nuxt-module/blob/main/src/utils/layers.ts#L85C11-L85C21).

For example, adding before returning here:

await nuxt.callHook('vuetify:dedupeOptions', {  configuration, moduleOptions })

@userquin
Copy link
Member

userquin commented Oct 7, 2024

@lna1989 looks like we can use a merger function to override the value instead merging: this will require to change a lot of types.

// In project layer VBtn defaults
VBtn: {
  class: () => ['project-layer'],
}

@userquin
Copy link
Member

userquin commented Oct 8, 2024

@lna1989 since we have this:

type DefaultsInstance = undefined | {
    [key: string]: undefined | Record<string, unknown>;
    global?: Record<string, unknown>;
};
type DefaultsOptions = Partial<DefaultsInstance>;

can you try using previous code in your app? The VBtn class should result in ['project-layer']

@lna1989
Copy link
Author

lna1989 commented Oct 8, 2024

@userquin I have already been there, I have not achieved the expected result, but now I will try again.

@lna1989
Copy link
Author

lna1989 commented Oct 8, 2024

@userquin
When using the arrow function, no additional class appears.

defaults: {
    VBtn: {
      variant: 'outlined',
      class: () => ['project-layer'],
    },
  },

Result:

<button type="button" class="v-btn v-theme--light text-error v-btn--density-default v-btn--size-default v-btn--variant-outlined" style=""><!--[--><span class="v-btn__overlay"></span><span class="v-btn__underlay"></span><!--]--><!----><span class="v-btn__content" data-no-activator=""><!--[--><!--[--> VBtn <!--]--><!--]--></span><!----><!----></button>

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

No branches or pull requests

2 participants