@toptal/picasso-number-input 1.0.1-alpha-fx-4861-find-missing-deep-imports-in-staff-portal-77646e396.4080 → 1.0.1-alpha-fx-4861-find-missing-deep-imports-in-staff-portal-25389459e.4083
Sign up to get free protection for your applications and to get access to all the features.
- package/dist-package/tsconfig.tsbuildinfo +1 -0
- package/package.json +11 -15
- package/src/NumberInput/NumberInput.tsx +152 -0
- package/src/NumberInput/__snapshots__/test.tsx.snap +73 -0
- package/src/NumberInput/index.ts +7 -0
- package/src/NumberInput/story/Default.example.tsx +25 -0
- package/src/NumberInput/story/Disabled.example.tsx +26 -0
- package/src/NumberInput/story/Sizes.example.tsx +57 -0
- package/src/NumberInput/story/Status.example.tsx +23 -0
- package/src/NumberInput/story/WithIcon.example.tsx +27 -0
- package/src/NumberInput/story/index.jsx +42 -0
- package/src/NumberInput/styles.ts +23 -0
- package/src/NumberInput/test.tsx +153 -0
- package/src/NumberInputEndAdornment/NumberInputEndAdornment.tsx +173 -0
- package/src/NumberInputEndAdornment/index.ts +2 -0
- package/src/NumberInputEndAdornment/styles.ts +58 -0
- package/src/index.ts +2 -0
- package/tsconfig.json +15 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
2
|
+
import type { RefObject } from 'react'
|
3
|
+
import React from 'react'
|
4
|
+
import type { Theme } from '@material-ui/core/styles'
|
5
|
+
import { makeStyles } from '@material-ui/core/styles'
|
6
|
+
import type { BaseProps, SizeType } from '@toptal/picasso-shared'
|
7
|
+
import { isBrowser } from '@toptal/picasso-shared'
|
8
|
+
import { ButtonBase } from '@material-ui/core'
|
9
|
+
import cx from 'classnames'
|
10
|
+
import { InputAdornment } from '@toptal/picasso-input-adornment'
|
11
|
+
import { Container } from '@toptal/picasso-container'
|
12
|
+
import {
|
13
|
+
ArrowDownMinor16,
|
14
|
+
ArrowUpMinor16,
|
15
|
+
ArrowDownMinor24,
|
16
|
+
ArrowUpMinor24,
|
17
|
+
} from '@toptal/picasso-icons'
|
18
|
+
|
19
|
+
import styles from './styles'
|
20
|
+
|
21
|
+
export interface Props extends BaseProps {
|
22
|
+
/** Value of the `input` element. */
|
23
|
+
value?: string | number
|
24
|
+
/** Minimum value for the `input` element */
|
25
|
+
min?: number | string
|
26
|
+
/** Maximum value for the `input` element */
|
27
|
+
max?: number | string
|
28
|
+
/** Next value of the `input` element will be calculated based on step */
|
29
|
+
step?: number | string
|
30
|
+
/** Indicates whether component is in disabled state */
|
31
|
+
disabled?: boolean
|
32
|
+
/** Component size */
|
33
|
+
size?: SizeType<'small' | 'medium' | 'large'>
|
34
|
+
/** Ref of the input element */
|
35
|
+
inputRef: RefObject<HTMLInputElement>
|
36
|
+
}
|
37
|
+
|
38
|
+
const useStyles = makeStyles<Theme, Props>(styles, {
|
39
|
+
name: 'NumberInputEndAdornment',
|
40
|
+
})
|
41
|
+
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
43
|
+
const nativeInputValueSetter = isBrowser()
|
44
|
+
? (
|
45
|
+
Object.getOwnPropertyDescriptor(
|
46
|
+
// eslint-disable-next-line ssr-friendly/no-dom-globals-in-module-scope
|
47
|
+
window.HTMLInputElement.prototype,
|
48
|
+
'value'
|
49
|
+
) as PropertyDescriptor
|
50
|
+
).set!
|
51
|
+
: undefined
|
52
|
+
|
53
|
+
export const NumberInputEndAdornment = (props: Props) => {
|
54
|
+
const {
|
55
|
+
step = 1,
|
56
|
+
min = -Infinity,
|
57
|
+
max = Infinity,
|
58
|
+
value,
|
59
|
+
disabled,
|
60
|
+
size = 'medium',
|
61
|
+
inputRef,
|
62
|
+
} = props
|
63
|
+
|
64
|
+
const classes = useStyles(props)
|
65
|
+
|
66
|
+
const normalizedStep = Number(step)
|
67
|
+
const normalizedValue = Number(value)
|
68
|
+
const normalizedMin = Number(min)
|
69
|
+
const normalizedMax = Number(max)
|
70
|
+
|
71
|
+
const fireEvent = (nextValue: number) => {
|
72
|
+
if (!nativeInputValueSetter) {
|
73
|
+
return
|
74
|
+
}
|
75
|
+
|
76
|
+
const input = inputRef?.current
|
77
|
+
|
78
|
+
nativeInputValueSetter.call(input, nextValue)
|
79
|
+
|
80
|
+
const event = new Event('input', {
|
81
|
+
bubbles: true,
|
82
|
+
cancelable: true,
|
83
|
+
})
|
84
|
+
|
85
|
+
if (input) {
|
86
|
+
input.dispatchEvent(event)
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
const handleUpClick = () => {
|
91
|
+
if (typeof value === 'undefined') {
|
92
|
+
return
|
93
|
+
}
|
94
|
+
|
95
|
+
let nextValue = normalizedValue + normalizedStep
|
96
|
+
|
97
|
+
if (nextValue <= max) {
|
98
|
+
if (normalizedValue < normalizedMin + normalizedStep) {
|
99
|
+
nextValue = normalizedMin + normalizedStep
|
100
|
+
}
|
101
|
+
|
102
|
+
fireEvent(nextValue)
|
103
|
+
} else if (normalizedValue !== normalizedMax) {
|
104
|
+
nextValue = normalizedMax
|
105
|
+
fireEvent(nextValue)
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
const handleDownClick = () => {
|
110
|
+
if (typeof value === 'undefined') {
|
111
|
+
return
|
112
|
+
}
|
113
|
+
|
114
|
+
let nextValue = normalizedValue - normalizedStep
|
115
|
+
|
116
|
+
if (nextValue >= min) {
|
117
|
+
if (normalizedValue > normalizedMax - normalizedStep) {
|
118
|
+
nextValue = normalizedMax - normalizedStep
|
119
|
+
}
|
120
|
+
|
121
|
+
fireEvent(nextValue)
|
122
|
+
} else if (normalizedValue !== normalizedMin) {
|
123
|
+
nextValue = normalizedMin
|
124
|
+
fireEvent(nextValue)
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
const rootClassName = cx(
|
129
|
+
{
|
130
|
+
[classes.disabled]: disabled,
|
131
|
+
},
|
132
|
+
classes[size],
|
133
|
+
classes.root
|
134
|
+
)
|
135
|
+
|
136
|
+
return (
|
137
|
+
<InputAdornment position='end'>
|
138
|
+
<Container flex direction='column' inline>
|
139
|
+
<ButtonBase
|
140
|
+
disabled={disabled}
|
141
|
+
classes={{
|
142
|
+
root: rootClassName,
|
143
|
+
}}
|
144
|
+
onClick={handleUpClick}
|
145
|
+
>
|
146
|
+
{size === 'large' ? <ArrowUpMinor24 /> : <ArrowUpMinor16 />}
|
147
|
+
</ButtonBase>
|
148
|
+
<ButtonBase
|
149
|
+
disabled={disabled}
|
150
|
+
classes={{
|
151
|
+
root: rootClassName,
|
152
|
+
}}
|
153
|
+
onClick={handleDownClick}
|
154
|
+
>
|
155
|
+
{size === 'large' ? <ArrowDownMinor24 /> : <ArrowDownMinor16 />}
|
156
|
+
</ButtonBase>
|
157
|
+
</Container>
|
158
|
+
</InputAdornment>
|
159
|
+
)
|
160
|
+
}
|
161
|
+
|
162
|
+
NumberInputEndAdornment.defaultProps = {
|
163
|
+
min: -Infinity,
|
164
|
+
max: Infinity,
|
165
|
+
value: 0,
|
166
|
+
step: 1,
|
167
|
+
disabled: false,
|
168
|
+
size: 'medium',
|
169
|
+
}
|
170
|
+
|
171
|
+
NumberInputEndAdornment.displayName = 'NumberInputEndAdornment'
|
172
|
+
|
173
|
+
export default NumberInputEndAdornment
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import type { Theme } from '@material-ui/core/styles'
|
2
|
+
import { createStyles } from '@material-ui/core/styles'
|
3
|
+
|
4
|
+
export default ({ palette, transitions, sizes: { borderRadius } }: Theme) =>
|
5
|
+
createStyles({
|
6
|
+
root: {
|
7
|
+
borderLeft: `1px solid ${palette.grey.light2}`,
|
8
|
+
borderRight: '1px solid transparent',
|
9
|
+
|
10
|
+
'&:hover': {
|
11
|
+
background: palette.grey.light2,
|
12
|
+
borderColor: palette.grey.light2,
|
13
|
+
},
|
14
|
+
|
15
|
+
'& + &': {
|
16
|
+
borderTop: `1px solid ${palette.grey.light2}`,
|
17
|
+
},
|
18
|
+
|
19
|
+
'&:active + &': {
|
20
|
+
borderTop: `1px solid ${palette.grey.main}`,
|
21
|
+
},
|
22
|
+
|
23
|
+
'&:active': {
|
24
|
+
background: palette.grey.main,
|
25
|
+
borderColor: palette.grey.main,
|
26
|
+
},
|
27
|
+
|
28
|
+
'&:first-child': {
|
29
|
+
borderTopRightRadius: borderRadius.small,
|
30
|
+
},
|
31
|
+
|
32
|
+
'&:last-child': {
|
33
|
+
borderBottomRightRadius: borderRadius.small,
|
34
|
+
},
|
35
|
+
|
36
|
+
transition: `all ${transitions.duration.short}ms ${transitions.easing.easeOut}`,
|
37
|
+
transitionProperty: 'border, color, background',
|
38
|
+
},
|
39
|
+
|
40
|
+
disabled: {
|
41
|
+
opacity: 0.48,
|
42
|
+
},
|
43
|
+
|
44
|
+
small: {
|
45
|
+
height: '0.75rem',
|
46
|
+
width: '1.375rem',
|
47
|
+
},
|
48
|
+
|
49
|
+
medium: {
|
50
|
+
height: '1rem',
|
51
|
+
width: '1.625rem',
|
52
|
+
},
|
53
|
+
|
54
|
+
large: {
|
55
|
+
height: '1.5rem',
|
56
|
+
width: '2.125rem',
|
57
|
+
},
|
58
|
+
})
|
package/src/index.ts
ADDED
package/tsconfig.json
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"extends": "../../../tsconfig.base.json",
|
3
|
+
"compilerOptions": { "outDir": "dist-package" },
|
4
|
+
"include": ["src"],
|
5
|
+
"references": [
|
6
|
+
{ "path": "../../shared" },
|
7
|
+
{ "path": "../Container" },
|
8
|
+
{ "path": "../Form" },
|
9
|
+
{ "path": "../Icons" },
|
10
|
+
{ "path": "../Input" },
|
11
|
+
{ "path": "../InputAdornment" },
|
12
|
+
{ "path": "../OutlinedInput" },
|
13
|
+
{ "path": "../Utils" }
|
14
|
+
]
|
15
|
+
}
|