Closed jabakochashvilisunrun closed 2 days ago
Hello @jabakochashvilisunrun,
While TSS doesn't currently allow a complete override of the algorithm that generates class names, it still offers a high degree of customization.
Let’s break down the structure of the generated class names:
css-1fsy1xq-FeatureItems-features
css
: This is the Emotion cache key, which you can customize. Learn more about cache customization here. 1fsy1xq
: This is an automatically generated hash. It’s necessary for technical reasons and cannot be controlled directly. FeatureItems
: This is the name of the useStyles
instance, typically matching the React component it’s used with. You can set it using .withName()
. features
: This is the rule name you've defined. For example:const useStyles = tss.create({ features: { /* your styles */ } });
// Then
const { classes } = useStyles();
<div className={classes.features} />
Let me know if this customization level meets your needs or if you’d like more granular control.
Thanks, ideally we'd like to have control over the automatically generated hash, but I understand that it cannot be controlled directly. that's what I wanted to check with you.
Thanks for the quick reply! closing this issue now
Well TSS has a plugin system that you could levrage. You could overwrite the classes object so that it returns your extact desired class on top of the class required.
You could have:
const useStyles = tss.withName("FeatureItems")create({ features: { /* your styles */ } });
// Then
const { classes } = useStyles();
<div className={classes.features} />
Be rendered as:
<div class="css-1fsy1xq-FeatureItems-features featureItems-features" />
For example.
Let me know if you're intrested, I can provide more details.
@garronej thanks for the example. Unfortunately that's not something we're looking for.
we'd like to change the algorithm that's used to generate automatically generated hash (1fsy1xq
)
I think you can acheive this with a stylisPlugins plugin:
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import stylis from 'stylis';
// Example of a custom hash plugin
const customHashPlugin = (element) => {
if (element.type === 'rule') {
element.props = element.props.map((selector) => {
// Replace the hash generation with your custom logic
// For example, prepend a custom prefix or apply a different hashing function
return selector.replace(/css-[a-z0-9]+/, 'custom-prefix-' + generateCustomHash(selector));
});
}
};
// Your custom hashing function
function generateCustomHash(input) {
// Implement your custom hash function here
return input.length.toString(16); // This is a simple example; replace with a real hash
}
// Set up Emotion cache with the custom stylis plugin
const cache = createCache({
key: 'custom',
stylisPlugins: [customHashPlugin],
});
// Then wrap your app with CacheProvider and the custom cache
function App() {
return (
<CacheProvider value={cache}>
{/* Your application */}
</CacheProvider>
);
}
(It's chatGPT so it probably need to be ajusted)
Thank you so much! I'll play with this code. I really appreciate this!
@garronej I've played with this code, and I'm able to modify the hash value:
import createCache, { StylisElement } from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
const hashOverridePlugin = (element: StylisElement) => {
const props = element.props;
const propsArr = typeof props === 'string' ? [props] : props;
if (element.type === 'rule') {
element.value = element.value.replace(/jest-[a-z0-9]+/, 'jest-uuid');
element.props = propsArr.map((selector: string) => {
return selector.replace(/jest-[a-z0-9]+/, 'jest-uuid');
});
}
};
const cache = createCache({
key: 'jest',
stylisPlugins: [hashOverridePlugin, console.log],
});
const customJestRenderer = (ui: ReactNode) => {
function Wrapper({ children }: { children: ReactNode }) {
return (
<CacheProvider value={cache}>
<ThemeProvider theme={customTheme}>{children}</ThemeProvider>
</CacheProvider>
);
}
return rtlRender(ui, { wrapper: Wrapper });
};
I'm able to verify with console.log
plugin that the classnames are updating. Issue is that looks like this only updates the class names in generated stylesheet. DOM nodes still have the old classnames with hashes in it.
Do you have any suggestions on how to override that easily? To add more context, we're trying to remove hashes from the jest snapshots.
Thank you
Hello,
I’m curious if there’s a way to change the naming of the class names that are automatically generated by TSS. Before we upgraded MUI and switched to TSS, we used the
createGenerateClassname
(https://mui.com/system/styles/api/#creategenerateclassname-options-class-name-generator) function to override class names for our specific project needs. I couldn’t find anything similar for classes generated by TSS.For example, this class name was generated by TSS: "css-1fsy1xq-FeatureItems-features". I'd like to be able to change the algorithm that's used to generate it if that's possible.
Thanks!