-
Notifications
You must be signed in to change notification settings - Fork 1.9k
feat(PresentationalNumberInput): introduction #2427
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
feat(PresentationalNumberInput): introduction #2427
Conversation
`<PresentationalNumberInput>` is presentational-only version of `<NumberInput>` to let application handle its state rather than handling it internally. Refs carbon-design-system/carbon-components-react#2207.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me!
Co-Authored-By: emyarod <[email protected]>
Deploy preview for the-carbon-components ready! Built with commit 4fbf21d https://deploy-preview-2427--the-carbon-components.netlify.com |
Deploy preview for carbon-components-react ready! Built with commit 39a9130 https://deploy-preview-2427--carbon-components-react.netlify.com |
Deploy preview for carbon-components-react ready! Built with commit 4fbf21d https://deploy-preview-2427--carbon-components-react.netlify.com |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PresentationalNumberInput
feels verbose to type out, I would think for controlled/uncontrolled we should try and keep the same component and change depending on stuff passed in (similar to libs like downshift)
Leaving a note; The notion of switching controlled/uncontrolled behavior upon props has been considered, stemming from easier implementation. The notion of separate component came along as a alternative for putting precedence on separation-of-concern and clear differentiation in behavior. The controlled version can be accessed in a similar manner as filtered-version of our multi-select component. The argument wrt verbose name may still be fair enough. Depending on users' feedback we can consider flipping the switch. |
What are some possible alternative component names we could use? |
@tw15egan Thank you for asking! The current choice is |
Is this something like a Another question, is there an issue related to this with more use case explanations? Thanks! |
@shixiedesign "View" is as-in traditional MVC (technical pattern). Sorry for the confusion 🙇 |
Created Redux Form example as discussed internally: https://codesandbox.io/s/github/asudoh/carbon-components/tree/redux-form-example/packages/react/examples/redux-form https://github.com/asudoh/carbon-components/blob/a66a284/packages/react/examples/redux-form/src/FieldLevelValidationForm.js#L25-L43 shows the gist of it. |
I'd be a little worried about introducing the view nomenclature here, particularly because in the traditional MVC sense the view most often represents a model and in our case we're just talking about stateless render method/functions. I think if we back up to first principles here, and take a look at where ideas of controlled/uncontrolled originate from, we can look at the Forms documentation on the React website: https://reactjs.org/docs/forms.html In these cases, the component itself is <form>
<label>
Name:
<input type="text" name="name" />
</label>
<input type="submit" value="Submit" />
</form>
The way we dip into controlled mode is by passing in render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
} Our component stays the same ( I think this would be a good thing to keep in mind with these decisions, and the closer we can get to this behavior the better 👍 If the goal here is to pull out stateful logic, then this would be a great opportunity to look at hooks as a natural way of separating out this logic to be re-used between components. |
Definitely agree, we need to be extremely consistent in our extraction, hooks are a great opportunity to share that logic. |
Interesting pattern from Dan that is basically what we were talking about yesterday in our Slack thread: https://twitter.com/dan_abramov/status/1065354652697444353 |
label: ' ', | ||
onChange: () => {}, | ||
onClick: () => {}, | ||
step: 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the step
prop here relevant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK it's for determining how many number increases by up/down arrow
ariaLabel: 'Numeric input field with increment and decrement buttons', | ||
helperText: '', | ||
light: false, | ||
allowEmpty: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be handled with invalid
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to have come from a contributor (#1352). invalid
explicitly makes the UI show the invalid state, whereas allowEmpty
does internal validation for user-entered empty string.
invalidText: 'Provide invalidText', | ||
ariaLabel: 'Numeric input field with increment and decrement buttons', | ||
helperText: '', | ||
light: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as we're making a new API can we switch to a variant
approach and away from boolean props? Something like variant="light"
to allow for future variations with props that don't conflict.
@@ -5,5 +5,10 @@ | |||
* LICENSE file in the root directory of this source tree. | |||
*/ | |||
|
|||
import NumberInput, { NumberInputView } from './NumberInput'; | |||
|
|||
NumberInput.View = NumberInputView; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While there's no inherent problem in also tacking it on here, I think we need to pick a usage method for our documentation and stick with it.
As far as naming is concerned, I think we can convey the distinction between the components better by sticking to react jargon. maybe |
@asudoh this is looks like a really powerful pattern worth considering |
While I wonder why Redux wasn't brought up in the tweet, @joshblack's point wrt following how React handles native |
<PresentationalNumberInput>
is presentational-only version of<NumberInput>
to let application handle its state rather than handling it internally.Refs carbon-design-system/carbon-components-react#2207.
Changelog
New
<PresentationalNumberInput>
, presentational-only version of<NumberInput>
to let application handle its state rather than handling it internally.Changed
<NumberInput>
to use<PresentationalNumberInput>
internally.Testing / Reviewing
Testing should make sure our
<NumberInput>
is not broken.