[Discussion] Future of Styling/CSS and Theming
See original GitHub issueFirstly I would like to say I love this library my use case(s) have been really good. While using it I personally have come across issues with how to style and add some subtle changes to behaviour (such as variable height nodes). From looking through the issues I am not the only one.
Currently the core CSS is consumed internally by the source code as a css-module (compiled from scss
files), then when webpack bundles it, the classnames are prefixed with rst__
. There is “a lot of magic” going on here and a lot of the styling issues in this repo would be avoided if it wasn’t so magic.
It wouldn’t be much work (say for a version 2) to stop using css-modules
hardcode the “core” classnames in the jsx as strings such as ReactSortableTree__node, ReactSortableTree__row
and switch the webpack config to use ExtractTextPlugin
to co-locate the css instead. That way new users of this library can easily see which components use what classname from reading the source, at the same time this would prevent the need to distribute style-loader
logic making the bundle size smaller and more performant. The only difference to the end user is that they must import the css themselves but this is much more common (like react-virtualized
, react-select
, react-dates
etc)
Proposal: (Repo source):
tree-node.js
// Currently
import React from "react";
import styles from "./tree-node.scss";
class TreeNode extends Component {
/*...*/
render() {
/*...*/
// styles.node hides the final classname from the user,
// for devs who might not know webpack/css-modules
// this could cause confusion
return (<div className={styles.node} {/*...*/} />);
}
}
// Becomes
import React from "react"
import "./tree-node.scss"
class TreeNode extends Component {
/*...*/
render() {
/*...*/
// `"ReactSortableTree__node"` simpler to understand and override.
return (<div className="ReactSortableTree__node" {/*...*/} />);
}
}
tree-node.scss
/* Currrently */
.node {
min-width: 100%;
white-space: nowrap;
position: relative;
text-align: left;
}
/* Becomes */
.ReactSortableTree__node {
min-width: 100%;
white-space: nowrap;
position: relative;
text-align: left;
}
Proposal: (Usage):
import React, { Component } from 'react';
import SortableTree from 'react-sortable-tree';
// Now we just need to add the css into our project...
import 'react-sortable-tree/style.css';
export default class Tree extends Component {
constructor(props) {
super(props);
this.state = {
treeData: [{ title: 'Chicken', children: [ { title: 'Egg' } ] }],
};
}
render() {
return (
<div style={{ height: 400 }}>
<SortableTree
treeData={this.state.treeData}
onChange={treeData => this.setState({ treeData })}
/>
</div>
);
}
}
Bonus: (Usage):
import React, { Component } from 'react';
import SortableTree from 'react-sortable-tree';
// Now we just need to add the css into our project...
import 'react-sortable-tree/style.css';
// Importing here will cascade as expected, because no-more style-loader! :)
import './my-react-sortable-tree-override-styles.css';
/*...*/
I am keen to contribute towards this change if you also think it is a good idea. What do you think?
Issue Analytics
- State:
- Created 6 years ago
- Reactions:6
- Comments:5 (3 by maintainers)
Top GitHub Comments
Moving the css handling away from style-loader and into a css file you would import is an issue I’ve been mulling over for a long time now.
On the one hand, server side rendering becomes a lot more easy to handle, and overriding the styles also becomes easier, as you have demonstrated. On the other hand, the one drawback that I’ve been lingering on is the fact that importing a css file yourself can be an extra hurdle for someone just starting to use the library. At least it was for me when I was starting out with react and gulp/Webpack two years ago.
I think the best option is the one you have described. I would like to preserve the existing classnames, ugly as they are, in order to reduce the effort needed to migrate. This will be a breaking change, obviously, and the fact that all users will be affected kind of makes my stomach churn. But it will be worth it in the long run, I suppose.
resovle it by using