react-date-select icon indicating copy to clipboard operation
react-date-select copied to clipboard

Ability to supply custom classes

Open ojame opened this issue 10 years ago • 0 comments

Firstly, I realise this component is still under development and may change a lot - I'm just interested in some general direction and to see if the ability to supply custom classes is possible.

We've gone through a massive shift at Macropod with how we write and manage our css. We're finally starting to get it consistent and manageable through css-loader and css-modules with local scoping on by default. This means we don't like to do any global styling.

We're using react-widgets to generate dropdowns, tag inputs and date pickers. This was chosen because it was really the only option at the time (a year ago, ish). We've ran into a few issues, and generally, both this component and the select component are written much better (to our tastes) anyway - so we'd love to use them.

One major issue we've come across (in general) is how to override third-party component styling. With react-widgets, everything is namespaced (much like this component) with .rw-, which we targeted in a rw.scss stylesheet. As mentioned before - we no longer want to pollute the globals in css.


Would it be possible to have a set of defaults, which is then extended by a prop classNames and then used throughout the components partials? I haven't really seen this done before in any external components so I'm not sure on best practices.

Take for example, the button in the Footer:

<button
   onClick={this.props.onSelect}
   className="DateSelectFooter__button DateSelectFooter__button--primary"
>
   Confirm
</button>

If we passed DateSelect a prop of classnames:

import styles from './custom.css';

<DateSelect
   classNames={
      footerButton: styles.footerButton,
      footerButtonPrimary: styles.footerButtonPrimary,
   }
/>

src/DateSelect.js

let classNames = {
   footerButton: 'DateSelectFooter__button',
   footerButtonPrimary: 'DateSelectFooter__button--primary',
}

var DateSelect = React.createClass({
   componentWillReceiveProps(props) {
      classNames = Object.assign({}, classNames, props.classNames);
   }

   render() {
      return (
          <DateSelectDialog classNames={classNames} />
      )
   }
});

And then you'd pass it through all of the components (or you could use context, but it's hard to trace), and the initial button would become:

const buttonClass = classnames(this.props.classNames.footerButton, this.props.classNames.footerButtonPrimary);

<button
   onClick={this.props.onSelect}
   className={buttonClass}
>
   Confirm
</button>

Obviously this has a chance to get unwieldily quite fast, and the initial prop could have quite a few keys (not sure how many classes there are all up) - but i feel containing them is probably the cleanest.

I'm more than happy to work on this and put up a PR. Although i'm not sure if this is just a problem I need to shim on our end, or if an idea like the above would be useful to others.

ojame avatar Aug 07 '15 10:08 ojame