With CSS Modules and webpack I can configure pattern of generated CSS class names like this:
localIdentName=[name]__[local]___[hash:base64:5]
Can I do that with JSS?..
Not yet, tell me why you want to be able to do that, then we can think about a solution.
@kof, sure.
I'm investigating into direction of using both CSS Modules and JSS on the project.
Like this:
At this point everything is ok.
(btw, i'm using webpack, react, react-jss)
What I need here is consistent css class names for both approaches.
So with CSS Modules I can specify pattern like {ComponentName}_{LocalCssClassName}
With JSS I have ComponentName_LocalCssClassName--jss-0-27
I do not need that --jss-x-x postfix...
I don't quite understand how are you going to use those "consistent" class names. They are generated and are not ment to be used directly.
Yes, usually we do not care about generated class names.
But I need to allow users ability to customize UI through rewriting css rules through their custom css files.
So I cannot have random hash part in class names (component styles isolation still achieved by adding {ComponentName}_ at the start).
Thats why there is a generated hash on a class name. Its a security against somebody using this selector to overwrite styles from the outside.
What you are going to do is bad. Rethink your design.
Yep, rewriting styles is bad.
Sometimes we have old projects and compatibility issues.
For this case you way want to add additional class names to elements.
Also I don't have enough insides to your project, maybe there is a better approach.
also as a hack, you can overwrite the function responsible for class generation in jss and use whatever pattern you want. Your use case just doesn't justify a public api change.
@kof, sure. Additional class names will result in too many classes on each element.
And I'm sure, some of users will add rewrite on some random class like 'component-jss-45-168'. And that binding will break on next update...
Honestly, I do not see any good approach to allow users to customize styles of your app, consider this app as template app, which is usually customized to needs of concrete customer.
On one hand I need styles isolation for my components to make sure I have no collision with other components. On the other hand, I have to provide customization of those styles to customers...
Odd, and not the case web developers usually have.
Thanks anyway!
Thats your task as an engineer to find a proper solution for your project, in general there are approaches for theaming. It has nothing to do with jss itself.
For e.g. take a look at
https://github.com/markdalgleish/react-themeable
And this discussion:
Looks promising. Will go deep into that later. Thanks.
Just a quick question. Does this approach allows me to dynamically change custom themes? Like, put one styles definition, reload page, put another one... without rebuilding?..
sure.
nice
@kof another use case to override class name generation is for selenium unit testing where the test case attempts to traverse the DOM to find certain elements for condition assertion.
We would like to prefix the classname with certain keyword while still retaining the generated numeric id.
how can we do that?
@Korayem see: http://cssinjs.org/js-api?v=v9.8.7#generate-your-own-class-names
I keep seeing this link (http://cssinjs.org/js-api?v=v9.8.7#generate-your-own-class-names) wherever I search for an answer to creating custom class names using JSS, but that link is 404ing. Can the solution be found somewhere else?
Yes: this is now located here: https://cssinjs.org/jss-api?v=v10.0.0-alpha.9#generate-your-class-names
Yeah we broke URLs with v10 of the lib and new site structure. We should do it better in the future ... not sure how though.
@Korayem like this:
import React from 'react';
import classnames from 'classnames';
import injectSheet from 'react-jss';
import {merge} from 'lodash';
function Foo ({
classes = {},
className,
isBar,
name,
value,
...props
}) {
return (
<div className={classnames(
'static-foo-classname',
isBar && 'static-foo-classname--is-bar',
className,
classes.container,
isBar && classes.containerIsBar
)}>
<div className={classnames(
'static-foo-classname__name',
className,
classes.name
)}>
{title}
</div>
<div className={classnames(
'static-foo-classname__value',
className,
classes.value
)}>
{value}
</div>
</div>
)
}
Foo.styles = (theme) => {
return merge({
container: {},
containerIsBar: {},
name: {},
value: {}
}, theme.Foo)
}
export default injectSheet(Foo.styles)(Foo);
Most helpful comment
@kof another use case to override class name generation is for selenium unit testing where the test case attempts to traverse the DOM to find certain elements for condition assertion.
We would like to prefix the classname with certain keyword while still retaining the generated numeric id.
how can we do that?