-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Rewrite / 1.0 #568
Comments
Things are looking good so I've merged my progress into master. There are going to be a lot of PRs and Issues in the backlog that need review now :) The examples have all (except tags mode, see below) been rewritten for the new API and everything seems to be working correctly. There are two new In major terms, the things left to be done are:
|
react-select is very cool and I'm really excited to see the new version - thanks for all your hard work, and for sharing it with us. 👍 |
I've created a separate issue which I'll delete, but I found some problems with the build process. Specifically, example files weren't recompiling properly. If you're OK with it, I'd like to contribute the following changes. You could think of it as a complete re-write of the tooling around the project.
Other than all that, I'm working to make things more flexible, and friendly for developers. You know, DX!
You can do this:
This means the internal implementations of Option etc, should be exposed to the users. Additionally, later, I'll work to make it possible to override the inbuilt Option component altogether. As long as you create your own Option component, that has the same displayName, it will be used instead of the built in Option.
Please let me know things you want/don't want. The checked items here are partially done on my computer locally. |
Hey @nmn, thanks - excited to have you on board and contributing to the project!
Sounds good as long as the processes work on Windows as well as OS X / linux - I've had trouble before getting that right and don't want to exclude contributors who have a Windows development environment. Gulp's lasted as long as it has in my projects because it abstracts those difficulties, but I'd love to see what you come up with. Would be a big win if the process is encapsulated / reusable across multiple projects as the current gulp tasks are.
+1 but is having a build repo really cleaner? I'm almost more inclined to drop support for bower altogether. Elemental's had a rocky experience with this.
I'm happy for you to make the tests nicer but defer to @bruderstein - he's contributed the bulk of what's there and owns the current tests (is also a Wallaby fan ;) I like the look of this:
Just to clarify, are you suggesting we deprecate the existing APIs for The last 3 sound good. CSS has also been something @jossmac and I have been thinking about how to fix. We've been trending toward JSS - see his recent rewrite of https://github.com/jossmac/react-images |
Oooh nice, related to bower concerns: mjackson/npm-http-server#17 looks like @nkbt is on it 😀 |
wallaby is just a runner, and effectively doesn't play any role, just leave the file in the repo, then anyone with wallaby can have a great testing experience :) I've not got around to trying enzyme yet, although I've heard mixed reports, but it seems to be getting a lot of attention. It would certainly make some things easier. If you're mentioning expect-jsx, I assume you're also talking of moving the majority of the tests to the shallow renderer? Whilst I think the shallow renderer is excellent, it doesn't fit for some places, and I think the main The shallow renderer is however in use for the Select.Async component, where we we're really not interested what I would really like to stay away from expect-jsx. It only converts the ReactElements to strings, and thereafter produces string diffs. I'm biased, so I'll try and remain objective, but we're using unexpected-react for the shallow renderer tests for For example, the test it('should filter after entering some text', () => {
typeSearchText('T');
var node = ReactDOM.findDOMNode(instance);
expect(node, 'queried for', '.Select-option:nth-child(1)', 'to have items satisfying', 'to have text', 'Two');
expect(node, 'queried for', '.Select-option:nth-child(2)', 'to have items satisfying', 'to have text', 'Three');
expect(node, 'queried for', '.Select-option', 'to have length', 2);
}); Could be rewritten as it('should filter after entering some text', () => {
typeSearchText('T');
return expect(instance, 'to have rendered with all children',
<Select>
<span className="Select-option">Two</span>
<span className="Select-option">Three</span>
</Select>);
}); And if it fails, it will show a diff with exactly the issue, based on the tree, and not just on the JSX string. However, as I said, I'm biased, so open to comments & criticism! |
@bruderstein I'll do some more research on the testing front. My original goal, however is not to move everything to expect-jsx. It's more of an all-of-the-above approach that I'm thinking of. expect-jsx for simple shallow unit tests. enzyme for the jsdom based tests and behavior tests. I'll read up more about unexpected since I missed a lot of its capabilities. It's also familiar enough for future contributors. Build ProcessThe npm scripts that replace gulp will work on windows and *Nix environments alike. As long as you only use nom-based cli-tools everything works anyway. The common things that break are:
The build processes themselves should be easy to use across projects. It will however, probably not be a module that can be npm installed. Instead, I'll make something like a customizable boilerplate that sets up projects for you. removing built files
That's your call entirely. I don't like bower, and I would love to see it die completely. However, maintaining a separate repo for it can be pretty simple and self-contained. The repo can simply npm install react-select and run it's own scripts. In fact, if we set it up correctly, it should be possible to automate the process completely. A repo that auto pulls the newest version of react-select, bumps its own version number to the same, and runs a few scripts to generate standalone .js files. TestingI've written about this above. I'll come to testing. props.children APIThis will most definitely be in addition to the current props based API. But the documentation will probably de-prioritise that. Something I'm looking to do is to be able to mix-and-match sub components for Select. This is something I'm trying to achieve. This would use the normal optionList renderer:
But this would use the renderer with list culling for extremely long option lists:
This would mean that I have refactor these parts into their own components, which may be challenging. But I'm sure it's possible. CSSI'll hold off this for now. In general, my plan was to give each component down the tree to have a simple key name. And then Select should be able to take a deep option of either inline-styles OR classNames for CSS-modules. The module itself can ship with a few separate themes that way, but it's tricky to do it without inline-styles. If there wasn't a need for pseudo selectors like Lodash?What do you feel about adding a dependency on lodash? It would make like a little simpler when dealing with the child APIs. |
BTW, I'm creating a WIP Pull request now. |
In regards to styles, a pattern that makes things really nice is to rely on composition for it. Basically, have a core component that allows classnames or styles to be specified, but specifies nothing (or next to nothing) by default. Then wrap that in a presentational component that specifies either default classes or styles. This allows people to just use the component's logic and make the presentational layer themselves. For an example of this see react-modal2 which is the business logic and cf-component-modal which is an example presentational component that uses react-modal2 internally by simply specifying classnames. |
One more note on styling publishable UI components: https://github.com/istarkov/babel-plugin-webpack-loaders Using this plugin + css-loader + css-modules allows to publish UI components with internal styles (with unique clasnames by css-modules), meanwhile allowing to override any possible classname |
@JedWatson @nmn I would help convert this to Radium, need it for a project but don't want to include CSS in the pipeline. Let me know if you go that way. |
The CSS part was the major blocker for us. Trying to provide something that works for everyone is quite hard. |
@colinmegill we're leaning towards react-jss and possibly react-themeable. Would you still be interested in aiding conversion? |
I think its a really poor decision to use any of those. The best React components are the ones that don't have these kinds of opinions and advocate wrapping. |
Could you elaborate James? On Thu, Jan 28, 2016 at 5:09 PM James Kyle notifications@github.com wrote:
|
@colinmegill Sure, the React community certainly hasn't standardized around a particular way of authoring styles. You could argue that the standard is inline styles (which certainly doesn't describe everyone), but even then there are dozens of ways of doing that. When you pick one particular way of doing styles in a general purpose component then you are locking people out of doing what they want for very little gain. If you design your general purpose components to be wrapped in other components by users or more opinionated components it becomes far more pleasant to use (composition is a really nice pattern). With styles you do this by allowing the user to specify classnames or inline styles for your component, then the user can wrap it however they want and use the wrapped version (which also aids in being able to swap out the underlying component without changing your own interface). |
@thejameskyle I've been thinking along those lines, but I've been having a hard time figuring out the actual details. That said, I'm sure there's a way to keep things flexible and move forward with a solution that works for everyone. Just not there yet. |
I've written a module which I hope might help with this problem: https://github.com/thejameskyle/react-stylish |
@thejameskyle That's a great module, and mostly solves all the problems. The one edge case for me is Radium. How can we conditionally require Radium only when using inline styles? Without it pseudo selectors won't work. And it's a large enough library that requiring it for everyone is a No-No. That is basically the blocker for me right now. |
I'm just reading about how Radium works, I'll dive into it tonight but I think this might work: https://github.com/thejameskyle/react-stylish/issues/3 I also just published a blog post about this |
Radium has gained a lot of traction in the community, if you haven't read about it yet be sure to understand what's it's doing first - happy to jump on a google hangout with everyone if that's helpful. It has proven to be quite smooth for publishing consumable components. https://github.com/FormidableLabs/victory-pie/blob/master/src/components/victory-pie.jsx In a nutshell: styles passed in as props override default styles owned by the component. Object.assign({}, styles.ownedByComponent, styles.passedInByUser) Super simple |
@colinmegill This is probably not the best place to get into this discussion |
Fair enough I'll hold off - @jossmac I'm not crazy about them. Check out the comparisons of libs here: https://github.com/FormidableLabs/radium/tree/master/docs/comparison if you decide on Radium reach out and I'll pitch in. |
@colinmegill can I join you on that hangout if you don't mind! |
Does anyone know whats happening here? It's become a bit of a blocker for us... We're happy to spend some dev time on this if we understood what needs to be done. |
@nmn use the
|
Also, really really need the tags functionality. I was mildly shocked to see that the docs were there, and after spending an hour debugging my code, I found out that the |
Lads, I've been working for the past few week with React Select and I love it. I've sent a couple of PRs there. I am willing to pitch in some time to help close some issues, work on bugs, missing functionality, test builds, etc. I can also polish those examples, add new ones and update the docs if needs be. |
@JedWatson similar to @kumarharsh I'd love to bring back tagmode for v1.0. Is there any specific reason why this feature hasn't been implemented yet? I'd be happy to help out with implementing it for the upgrade. |
@jxodwyer tag mode is there, see the multiselect demos on http://jedwatson.github.io/react-select/ AFAIK, the only thing that isn't is an I looked at adding an allowCreate option back in with the new model, but it turned out it wasn't really doing anything other than what I've just explained. Maybe we should add this to the docs. |
@bruderstein thanks a lot for the response! You were right that the |
Sorry to write here @bruderstein but I have an issue with your method, maybe I'm missing a step. As a workaround I did this in the handleChange(option) {
if (option && option.create) {
this.refs.select.setState({
options: [{ value: option.value, label: option.value }]
});
}
this.props.onChange(option);
} Any better way to handle this case? |
The option has to be there - as it's a controlled component, the caller is responsible for ensuring that the option is created. So you'd just need to ensure that if you get the option with the |
I'm looking for a way to render customize label, I can copy and modify the "Value" component. But it will be hard if I want to update to further version. I think @nmn 's solution will be more flexible and can solve my problem. May I know which branch and progress which you guys are working on custom render label? After dig in to source code I found "valueRenderer" function and it solves my problems. |
@JedWatson Where are you guys with a stable 1.0.0 release? I would be more than willing to help. I've been using the old stable for a while now and would love to upgrade @nozzle to 1.0.0 |
Discussion continued: #1481 |
Is there any chance of #59 making it into 1.0.0? |
1.0.0 is out 🎉 |
@JedWatson is JSS supported? |
I'm midway through a massive rewrite of this library and wanted to open an issue so it's more visible. There will be several breaking changes to the API, all for the better.
WIP is visible on the
rebuild
branch.Aside from how we're bundling
lib
anddist
files (which won't change for now), it basically addresses all the things that @brianreavis raised in #227.I've been trying to split Select up into more granular components as suggested by @bruderstein in #396, but it's not obvious how to do this while also cleaning everything up and preserving a simple API so that can probably be the focus of another major version down the track.
The big improvements include:
onChange
.<input>
field is now optional and the component is better suited to use in a rich React.js app than it wasonInputChange
The other major change is that the whole async options loading piece has been split out into its own
Select.Async
component, which wrapsSelect
and passes most props through. This dramatically simplifies the select component itself, and plays nicely with the new "options and value are just props" changes. Props that were related toasyncOptions
have also been moved to the new component.Aside from the details of what's been changed, it just feels better to use, more solid. I don't have benchmarks to back this up, but it should be much faster too (and easier to optimise in subsequent versions)
The text was updated successfully, but these errors were encountered: