Skip to content

Commit 003d882

Browse files
authored
fix(password): pass all scale props for internally wrapped components (#732)
* fix(scale): add dunamic functions to export all props related to scale * fix(password): pass all scale props for internally wrapped components
1 parent 88f1b41 commit 003d882

File tree

7 files changed

+118
-68
lines changed

7 files changed

+118
-68
lines changed

components/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ export { default as useClasses } from './use-classes'
200200
export { default as useScale } from './use-scale'
201201
export { withScale, ScalePropKeys, ScaleContext } from './use-scale'
202202
export type {
203-
ScalePropsAndInvalid,
204203
ScaleProps,
205204
ScaleConfig,
206205
GetScalePropsFunction,
206+
GetAllScalePropsFunction,
207207
} from './use-scale'

components/input/__tests__/password.test.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react'
2-
import { mount } from 'enzyme'
2+
import { mount, shallow } from 'enzyme'
33
import { Input } from 'components'
44
import { nativeEvent } from 'tests/utils'
55

@@ -23,4 +23,13 @@ describe('InputPassword', () => {
2323
const wrapper = mount(<Input.Password hideToggle />)
2424
expect(wrapper.find('.input-icon').length).toBe(0)
2525
})
26+
27+
it('should be pass all native scale props', () => {
28+
const width = 'calc(100% - 10px)'
29+
const height = Math.random().toString(16).slice(-8)
30+
const wrapper = shallow(<Input.Password w={width} h={height} />)
31+
const html = wrapper.html()
32+
expect(html).toContain(width)
33+
expect(html).toContain(height)
34+
})
2635
})

components/input/password.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { useImperativeHandle, useMemo, useRef, useState } from 'react'
22
import { Props, defaultProps } from './input-props'
33
import PasswordIcon from './password-icon'
44
import Input from './input'
5-
import { withScale } from '../use-scale'
5+
import { useScale, withScale } from '../use-scale'
66

77
interface PasswordProps extends Props {
88
hideToggle?: boolean
@@ -28,6 +28,7 @@ const InputPasswordComponent = React.forwardRef<
2828
}: React.PropsWithChildren<InputPasswordProps> & typeof defaultProps,
2929
ref: React.Ref<HTMLInputElement | null>,
3030
) => {
31+
const { getAllScaleProps } = useScale()
3132
const inputRef = useRef<HTMLInputElement>(null)
3233
const [visible, setVisible] = useState<boolean>(false)
3334
useImperativeHandle(ref, () => inputRef.current)
@@ -56,7 +57,7 @@ const InputPasswordComponent = React.forwardRef<
5657
}, [hideToggle, visible])
5758

5859
return (
59-
<Input iconRight={icon} {...inputProps}>
60+
<Input iconRight={icon} {...getAllScaleProps()} {...inputProps}>
6061
{children}
6162
</Input>
6263
)

components/use-scale/__tests__/scale.test.tsx

+26
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,30 @@ describe('UseScale', () => {
167167
inner = wrapper.find('#inner').getDOMNode()
168168
expect(inner.hasAttribute('scale')).not.toBe(true)
169169
})
170+
171+
it('should be update all native scale props', () => {
172+
const wrapper: React.FC<any> = ({ children, ...props }) => (
173+
<ScaleComponent {...props}>{children}</ScaleComponent>
174+
)
175+
const { result, rerender } = renderHook<any, ScaleConfig>(() => useScale(), {
176+
wrapper,
177+
initialProps: {},
178+
})
179+
let { SCALES, getAllScaleProps } = result.current
180+
expect(typeof SCALES).toEqual('object')
181+
expect(typeof getAllScaleProps).toEqual('function')
182+
expect(typeof getAllScaleProps()).toEqual('object')
183+
184+
rerender({ width: '1em', height: '2em' })
185+
getAllScaleProps = result.current.getAllScaleProps
186+
expect(getAllScaleProps().width).toEqual('1em')
187+
expect(getAllScaleProps().height).toEqual('2em')
188+
expect(typeof getAllScaleProps().font).toEqual('undefined')
189+
190+
rerender({ px: '10px', mx: '20px' })
191+
getAllScaleProps = result.current.getAllScaleProps
192+
expect(getAllScaleProps().px).toEqual('10px')
193+
expect(getAllScaleProps().mx).toEqual('20px')
194+
expect(typeof getAllScaleProps().paddingTop).toEqual('undefined')
195+
})
170196
})

components/use-scale/scale-context.ts

+36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
import React from 'react'
22

3+
export const ScalePropKeys = [
4+
'width',
5+
'height',
6+
'padding',
7+
'margin',
8+
'w',
9+
'h',
10+
'paddingLeft',
11+
'paddingRight',
12+
'paddingTop',
13+
'paddingBottom',
14+
'pl',
15+
'pr',
16+
'pt',
17+
'pb',
18+
'marginLeft',
19+
'marginRight',
20+
'marginTop',
21+
'marginBottom',
22+
'ml',
23+
'mr',
24+
'mt',
25+
'mb',
26+
'px',
27+
'py',
28+
'mx',
29+
'my',
30+
'font',
31+
'unit',
32+
'scale',
33+
]
34+
335
export type ScaleProps = {
436
width?: string | number
537
height?: string | number
@@ -62,9 +94,12 @@ export type GetScalePropsFunction = (
6294
key: keyof ScaleProps | Array<keyof ScaleProps>,
6395
) => ScaleProps[keyof ScaleProps]
6496

97+
export type GetAllScalePropsFunction = () => ScaleProps
98+
6599
export interface ScaleConfig {
66100
SCALES: DynamicScales
67101
getScaleProps: GetScalePropsFunction
102+
getAllScaleProps: GetAllScalePropsFunction
68103
unit: string
69104
}
70105

@@ -74,6 +109,7 @@ const defaultDynamicLayoutPipe: DynamicLayoutPipe = scale1x => {
74109

75110
const defaultContext: ScaleConfig = {
76111
getScaleProps: () => undefined,
112+
getAllScaleProps: () => ({}),
77113
SCALES: {
78114
pl: defaultDynamicLayoutPipe,
79115
pr: defaultDynamicLayoutPipe,

components/use-scale/utils.ts

+37-44
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,39 @@
1-
import { ScaleProps } from './scale-context'
1+
import {
2+
GetAllScalePropsFunction,
3+
GetScalePropsFunction,
4+
ScaleProps,
5+
ScalePropKeys,
6+
} from './scale-context'
27

3-
export type ScalePropsAndInvalid = keyof ScaleProps | 'size'
8+
export const generateGetScaleProps = <P>(
9+
props: P & ScaleProps,
10+
): GetScalePropsFunction => {
11+
const getScaleProps: GetScalePropsFunction = keyOrKeys => {
12+
if (!Array.isArray(keyOrKeys)) return props[keyOrKeys as keyof ScaleProps]
13+
let value = undefined
14+
for (const key of keyOrKeys) {
15+
const currentValue = props[key]
16+
if (typeof currentValue !== 'undefined') {
17+
value = currentValue
18+
}
19+
}
20+
return value
21+
}
22+
return getScaleProps
23+
}
424

5-
export const ScalePropKeys: Array<ScalePropsAndInvalid> = [
6-
'paddingLeft',
7-
'pl',
8-
'paddingRight',
9-
'pr',
10-
'paddingTop',
11-
'pt',
12-
'paddingBottom',
13-
'pb',
14-
'marginTop',
15-
'mt',
16-
'marginRight',
17-
'mr',
18-
'marginBottom',
19-
'mb',
20-
'marginLeft',
21-
'ml',
22-
'px',
23-
'py',
24-
'mx',
25-
'my',
26-
'width',
27-
'height',
28-
'font',
29-
'unit',
30-
'scale',
31-
'size',
32-
]
33-
34-
// export const withPureProps = <T extends Record<any, any>>(
35-
// props: T,
36-
// ): Omit<T, ScalePropsAndInvalid> => {
37-
// if (!props) return {} as Omit<T, ScalePropsAndInvalid>
38-
// const keys = Object.keys(props).filter(key => key !== '')
39-
// const nextProps: any = {}
40-
// for (const key of keys) {
41-
// if (!(ScalePropKeys as string[]).includes(key)) {
42-
// nextProps[key] = props[key]
43-
// }
44-
// }
45-
// return nextProps
46-
// }
25+
export const generateGetAllScaleProps = <P>(
26+
props: P & ScaleProps,
27+
): GetAllScalePropsFunction => {
28+
const getAllScaleProps: GetAllScalePropsFunction = () => {
29+
let scaleProps: ScaleProps = {}
30+
for (const key of ScalePropKeys) {
31+
const value = props[key as keyof ScaleProps]
32+
if (typeof value !== 'undefined') {
33+
scaleProps[key as keyof ScaleProps] = value as any
34+
}
35+
}
36+
return scaleProps
37+
}
38+
return getAllScaleProps
39+
}

components/use-scale/with-scale.tsx

+5-20
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
import React, { forwardRef } from 'react'
2-
import {
3-
DynamicLayoutPipe,
4-
GetScalePropsFunction,
5-
ScaleConfig,
6-
ScaleContext,
7-
ScaleProps,
8-
} from './scale-context'
2+
import { DynamicLayoutPipe, ScaleConfig, ScaleContext, ScaleProps } from './scale-context'
93
import useTheme from '../use-theme'
104
import { isCSSNumberValue } from '../utils/collections'
5+
import { generateGetAllScaleProps, generateGetScaleProps } from './utils'
116

127
const reduceScaleCoefficient = (scale: number) => {
138
if (scale === 1) return scale
@@ -70,20 +65,9 @@ const withScale = <T, P = {}>(
7065
const customFactor = factor * Number(attrValue)
7166
return `calc(${customFactor} * ${unit})`
7267
}
73-
const getScaleProps: GetScalePropsFunction = keyOrKeys => {
74-
if (!Array.isArray(keyOrKeys)) return props[keyOrKeys as keyof ScaleProps]
75-
let value = undefined
76-
for (const key of keyOrKeys) {
77-
const currentValue = props[key]
78-
if (typeof currentValue !== 'undefined') {
79-
value = currentValue
80-
}
81-
}
82-
return value
83-
}
8468

8569
const value: ScaleConfig = {
86-
unit,
70+
unit: unit,
8771
SCALES: {
8872
pt: makeScaleHandler(paddingTop ?? pt ?? py ?? padding),
8973
pr: makeScaleHandler(paddingRight ?? pr ?? px ?? padding),
@@ -101,7 +85,8 @@ const withScale = <T, P = {}>(
10185
height: makeScaleHandler(height ?? h),
10286
font: makeScaleHandler(font),
10387
},
104-
getScaleProps,
88+
getScaleProps: generateGetScaleProps(props),
89+
getAllScaleProps: generateGetAllScaleProps(props),
10590
}
10691

10792
return (

0 commit comments

Comments
 (0)