-
Notifications
You must be signed in to change notification settings - Fork 90
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(NumberInput): add new component #1826
base: main
Are you sure you want to change the base?
Conversation
Preview is ready. |
Visual Tests Report is ready. |
68cd582
to
f529fed
Compare
f529fed
to
af30ed7
Compare
517519a
to
c7425bd
Compare
e86d5d6
to
fc7fce7
Compare
be77a52
to
29bfffd
Compare
cd9c3bd
to
cc9165b
Compare
onKeyPress: () => {}, | ||
}; | ||
|
||
const DefaultTemplate: StoryFn<NumberInputProps> = (args) => { |
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.
Let's use newer format of stories (CSF3), see Button as a reference. Right now controls are unusable. The idea is that one single story should show particular prop behavior and be altered with controls. For example, Size
- variants of sizes, View
- variants of views, Error
- variants of how error can be displayed, Step
- how step works, Min/Max
- how minimum and maximum works and so on.
await expectScreenshot(); | ||
}); | ||
|
||
test('render story: <Showcase>', async ({mount, expectScreenshot}) => { |
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.
Let's keep only default story screenshot for now, current stories are not suitable for such kind of tests
onInput: handleInput, | ||
...props.controlProps, | ||
onWheel: allowMouseWheel && active ? handleWheel : undefined, | ||
role: 'spinbutton', |
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.
Not sure if it's correct. It's an input for numeric text, not spinbutton.
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.
Native input type number has spinbutton role
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.
Ok, let's keep it.
@@ -94,7 +104,7 @@ export const TextInput = React.forwardRef<HTMLSpanElement, TextInputProps>( | |||
note, | |||
onUpdate, | |||
onChange, | |||
} = props; | |||
} = propsWithDefaults; |
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.
Why we need this? Defaults eventually will be aplied anyway.
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.
Because some of these TextInput defaults (which were moved to a separate object) are also required in NumberInput
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.
Can we use it in React way then? TextInput.defaultProps = {...}
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.
defaultProps for function components is deprecated in React 19. https://react.dev/blog/2024/04/25/react-19-upgrade-guide#removed-deprecated-react-apis
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.
If you'd help me to deal with fc typings with defaultProps^ then I'll change it to react way
I would really appreciate you help
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.
From default props only size and view are needed, right? Let's set default only for them ('m'
, and 'normal'
) in NumberInput.
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.
@ValeraS
Also disabled
is used in NumberInput directly.
But, wouldn't it be better to store default props in one object to be sure that they wouldn't differ in different controls one day? And what if we'll need to use more default props from TextInput in NumberInput itself?
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.
Ok, I've checked that other controls define default values of these props themselves, so I reverted these changes in TextInput
value, | ||
defaultValue, | ||
shiftMultiplier, | ||
} = getInternalVariables({ |
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.
getInternalState
seems to be more descriptive name
onBlur?.(e); | ||
}; | ||
|
||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { |
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.
We can only use onUpdate
for updating the value. onChange
handler is redundant
); | ||
|
||
--_--border-width: var(--g-text-input-border-width, 1px); | ||
border-style: solid; |
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 like these styles are duplicated
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.
Which styles and where is their duplicate is located?
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.
border styles between NumericArrows.scss and NumberInput.scss
@use '../../../../../styles/mixins'; | ||
@use '../../../variables'; | ||
@use '../../../controls/mixins.scss' as control-mixins; | ||
@use '../../../controls/variables.scss' as control-variables; |
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.
We don't use any of these in the file
export {getNumericInputValidator} from './utils'; | ||
export type {GetNumericInputValidatorParams} from './utils'; |
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.
Aren't these internal helpers? Why we export them?
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.
No, they are not used in component. This utility function is for external use only. NumberInput itself doesn't show any validation errors
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.
Then why keep this code? We cannot maintain it properly without specific usecases
return clampedValue; | ||
} | ||
|
||
export function warnAboutInvalidProps({ |
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.
This will span a lot. What's the benefit of this? Component won't allow invalid value anyway.
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.
It will spam only with invalid props passed.
I think it would be better to notify programmer about invalid component usage6 but not just fix props silently
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.
Ok then it should use warnOnce
function from utils in format of [NumberInput] <message>
instead of console.warn
, see usages across the codebase
b7b173b
to
faf3eaa
Compare
255d426
to
feac75f
Compare
…es to divisible numbers
…orwardRef&comment in N-Arrows
2174b81
to
f54c958
Compare
f54c958
to
ddfd727
Compare
} | ||
|
||
&_view_normal { | ||
--_-g-number-input-numeric-arrows-border-color: var(--g-color-line-generic); |
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.
--_-g-number-input-numeric-arrows-border-color: var(--g-color-line-generic); | |
--_--arrows-border-color: var(--g-color-line-generic); |
It's a private var so no need to specify full name
--_--border-color-hover: var(--g-color-line-generic-hover); | ||
--_--border-color-active: var(--g-color-line-generic-active); |
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.
What these variables for? They duplicate TextInput styles
--_-g-number-input-numeric-arrows-border-color: transparent; | ||
} | ||
|
||
&__numeric-arrows { |
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.
&__numeric-arrows { | |
&__arrows { |
Let's be compact here
/** An optional element displayed under the lower right corner of the control and sharing the place with the error container */ | ||
note?: React.ReactNode; | ||
/**Describes the validation state */ | ||
validationState?: 'invalid' | undefined; |
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.
This prop already in the BaseInputControlProps
, no need to specify it again
/** Enables changing value by scrolling mousewheel on with cursor on the input | ||
* @default false | ||
*/ | ||
allowMouseWheel?: boolean; |
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.
We've decided to remove the wheel behaviour completely. It turned out that currently it brings a lot of bugs and inconsistency between mouse and touchpad devices. Maybe we reimplement it in the future.
onInput: handleInput, | ||
...props.controlProps, | ||
onWheel: allowMouseWheel && active ? handleWheel : undefined, | ||
role: 'spinbutton', |
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.
Ok, let's keep it.
...props.controlProps, | ||
onWheel: allowMouseWheel && active ? handleWheel : undefined, | ||
role: 'spinbutton', | ||
inputMode: 'numeric', |
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.
when allowDecimal = true
, we should pass decimal
here to have correct keyborad on mobile devices
$block: '.#{variables.$ns}numeric-arrows'; | ||
|
||
#{$block} { | ||
--_--numeric-arrows-border-color: var( |
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.
--_--numeric-arrows-border-color: var( | |
--_--arrows-border-color: var( |
view: 'flat-secondary', | ||
disabled, | ||
tabIndex: -1, | ||
width: 'max', |
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.
Let's hide the buttons from screenreaders via aria-hidden="true"
export {getNumericInputValidator} from './utils'; | ||
export type {GetNumericInputValidatorParams} from './utils'; |
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.
Then why keep this code? We cannot maintain it properly without specific usecases
Extra zero digits not deleted on blur: 2024-10-15.20.41.16.movTyping dot when 2024-10-15.20.41.37.movLeading dot not deleted on blur: 2024-10-15.20.42.29.mov |
No description provided.