Skip to content

Commit

Permalink
fix(InputMasked): inherit of provider/context props
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker committed Dec 16, 2021
1 parent dec57cb commit 89db309
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 47 deletions.
19 changes: 16 additions & 3 deletions packages/dnb-eufemia/src/components/input-masked/InputMasked.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,33 @@

import React from 'react'
import PropTypes from 'prop-types'
import { registerElement } from '../../shared/component-helper'
import {
registerElement,
extendPropsWithContext,
} from '../../shared/component-helper'
import InputMaskedContext from './InputMaskedContext'
import InputMaskedElement from './InputMaskedElement'
import Input, { inputPropTypes } from '../input/Input'
import Context from '../../shared/Context'

const InputMasked = React.forwardRef((props, ref) => {
const context = React.useContext(Context)

const contextAndProps = React.useCallback(
extendPropsWithContext(
props,
InputMasked.defaultProps,
context?.InputMasked
),
[props, InputMasked.defaultProps, context?.InputMasked]
)

return (
<InputMaskedContext.Provider
value={{
inner_ref: ref,
props,
...context,
props: contextAndProps,
context,
}}
>
<InputMaskedElement />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
isTrue,
dispatchCustomElementEvent,
} from '../../shared/component-helper'
import Context from '../../shared/Context'

import TextMask from './TextMask'
import createNumberMask from './addons/createNumberMask'
Expand Down Expand Up @@ -84,8 +83,7 @@ export const useInputElementRef = () => {
* @returns string
*/
export const useLocale = () => {
const { props } = React.useContext(InputMaskedContext)
const context = React.useContext(Context)
const { props, context } = React.useContext(InputMaskedContext)

let { locale } = props
if (!locale && context?.locale) {
Expand All @@ -104,16 +102,14 @@ export const useLocale = () => {
* @returns object with internal value state and state setter
*/
export const useLocalValue = () => {
const { props } = React.useContext(InputMaskedContext)
const context = React.useContext(Context)
const { props, context } = React.useContext(InputMaskedContext)
const maskParams = useNumberMaskParams() || {}
const locale = useLocale()

const [localValue, setLocalValue] = React.useState(() =>
correctNumberValue({
props,
context,
locale,
props,
maskParams,
})
)
Expand All @@ -125,9 +121,8 @@ export const useLocalValue = () => {
React.useEffect(() => {
const value = correctNumberValue({
localValue,
props,
context,
locale,
props,
maskParams,
})

Expand All @@ -146,8 +141,9 @@ export const useLocalValue = () => {
*/
export const useNumberMask = () => {
const maskParams = useNumberMaskParams()
const { props } = React.useContext(InputMaskedContext)

if (!maskParams) {
if (!maskParams || !isRequestingNumberMask(props)) {
return null
}

Expand All @@ -163,7 +159,7 @@ export const useNumberMask = () => {
*
* @returns mask function
*/
export const useInternalMask = () => {
export const useMask = () => {
const { props } = React.useContext(InputMaskedContext)

const numberMask = useNumberMask()
Expand All @@ -190,7 +186,7 @@ export const useMaskParams = () => {
placeholder,
} = props

const mask = useInternalMask()
const mask = useMask()
const maskParams = useNumberMaskParams() || {}

maskParams.showMask = !placeholder && isTrue(show_mask)
Expand Down Expand Up @@ -225,7 +221,7 @@ export const useInputElement = () => {

const { pipe } = props

const mask = useInternalMask()
const mask = useMask()
const { showMask, showGuide, placeholderChar, keepCharPositions } =
useMaskParams()

Expand Down Expand Up @@ -353,7 +349,6 @@ const useCallEvent = ({ setLocalValue }) => {

if (/^0/.test(testValue)) {
event.preventDefault()
return // stop here
}
}

Expand Down Expand Up @@ -457,11 +452,10 @@ const useCallEvent = ({ setLocalValue }) => {
*/
const useNumberMaskParams = () => {
const { props } = React.useContext(InputMaskedContext)
const context = React.useContext(Context)
const locale = useLocale()

if (!isRequestingNumberMask(props)) {
return null
return { ...fromJSON(props.mask_options) }
}

let { number_mask, currency_mask, mask_options } = props
Expand Down Expand Up @@ -506,7 +500,6 @@ const useNumberMaskParams = () => {

if (number_mask) {
maskParams = handleNumberMask({
context,
mask_options,
number_mask,
})
Expand All @@ -516,7 +509,6 @@ const useNumberMaskParams = () => {
}
} else if (currency_mask) {
maskParams = handleCurrencyMask({
context,
mask_options,
currency_mask,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export const isRequestingNumberMask = (props) => {
export const correctNumberValue = ({
localValue = null,
props,
context,
locale,
maskParams,
}) => {
Expand All @@ -85,13 +84,11 @@ export const correctNumberValue = ({
/**
* This only runs IF "number_format" is set – we do not use it else
*/
const numberFormatFromContext = context?.InputMasked?.number_format
if (props.number_format || numberFormatFromContext) {
if (props.number_format) {
const options = {
locale,
decimals: 0,
...fromJSON(props.number_format),
...numberFormatFromContext,
...props.number_format,
}
if (shouldHaveDecimals) {
options.decimals = maskParams.decimalLimit
Expand Down Expand Up @@ -245,19 +242,13 @@ export const handlePercentMask = ({ props, locale, maskParams }) => {
* @property {object} currency_mask Component property for change the currency parameters
* @returns object maskParams
*/
export const handleCurrencyMask = ({
context,
mask_options,
currency_mask,
}) => {
export const handleCurrencyMask = ({ mask_options, currency_mask }) => {
const maskParams = {
showMask: true,
placeholderChar: null,
allowDecimal: true,
decimalLimit: 2,
decimalSymbol: ',',
...context?.InputMasked?.mask_options,
...context?.InputMasked?.currency_mask,
...mask_options,
...currency_mask,
}
Expand All @@ -283,15 +274,9 @@ export const handleCurrencyMask = ({
* @property {object} number_mask Component property for change the number parameters
* @returns object maskParams
*/
export const handleNumberMask = ({
context,
mask_options,
number_mask,
}) => {
export const handleNumberMask = ({ mask_options, number_mask }) => {
const maskParams = {
decimalSymbol: ',',
...context?.InputMasked?.mask_options,
...context?.InputMasked?.number_mask,
...mask_options,
...number_mask,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ describe('InputMasked component', () => {
preventDefault,
})
expect(preventDefault).toHaveBeenCalledTimes(0)
expect(onKeyDown).toHaveBeenCalledTimes(1)
expect(onKeyDown.mock.calls[0][0].value).toBe('NOK 1 234,56 kr')
expect(onKeyDown.mock.calls[0][0].numberValue).toBe(1234.56)

Expand All @@ -207,7 +208,7 @@ describe('InputMasked component', () => {
preventDefault,
})
expect(preventDefault).toHaveBeenCalledTimes(1)
expect(onKeyDown).toHaveBeenCalledTimes(1)
expect(onKeyDown).toHaveBeenCalledTimes(2)

Comp.setProps({
number_mask: {
Expand Down Expand Up @@ -244,8 +245,8 @@ describe('InputMasked component', () => {
},
preventDefault,
})
expect(preventDefault).toHaveBeenCalledTimes(2)
expect(onKeyDown).toHaveBeenCalledTimes(2)
expect(preventDefault).toHaveBeenCalledTimes(3)
expect(onKeyDown).toHaveBeenCalledTimes(4)
})

it('should allow leading zero when removing first letter', () => {
Expand Down Expand Up @@ -445,7 +446,7 @@ describe('InputMasked component', () => {
preventDefault,
})
expect(preventDefault).toHaveBeenCalledTimes(1)
expect(onKeyDown).toHaveBeenCalledTimes(0)
expect(onKeyDown).toHaveBeenCalledTimes(1)

Comp.setProps({
number_mask: {
Expand All @@ -461,12 +462,13 @@ describe('InputMasked component', () => {
},
preventDefault,
})
expect(onKeyDown.mock.calls[0][0].value).toBe('0 kr')
expect(onKeyDown).toHaveBeenCalledTimes(1)

expect(onKeyDown).toHaveBeenCalledTimes(2)
expect(onKeyDown.mock.calls[1][0].value).toBe('0 kr')
expect(preventDefault).toHaveBeenCalledTimes(1)
})

it('should accept mask only (ssn)', () => {
it('should accept custom mask only', () => {
const onKeyDown = jest.fn()
const preventDefault = jest.fn()
const newValue = '010203 12345'
Expand Down Expand Up @@ -507,6 +509,51 @@ describe('InputMasked component', () => {
expect(preventDefault).toHaveBeenCalledTimes(0)
expect(onKeyDown).toHaveBeenCalledTimes(1)
expect(onKeyDown.mock.calls[0][0].value).toBe('010203 12345')

Comp.setProps({
mask_options: {
allowLeadingZeroes: false,
},
})

Comp.find('input').simulate('keydown', {
key: '0',
keyCode: 48, // zero
target: {
value: newValue,
selectionStart: 0, // set it to be a leading zero
},
preventDefault,
})

expect(preventDefault).toHaveBeenCalledTimes(1)
expect(onKeyDown).toHaveBeenCalledTimes(2)
})

it('should accept provider props with custom mask', () => {
const Comp = mount(
<Provider value={{ InputMasked: { value: '00020300000' } }}>
<Component
value="11020312345"
mask={() => [
/[0-9]/,
/\d/,
/\d/,
/\d/,
/\d/,
/\d/,
' ',
/\d/,
/\d/,
/\d/,
/\d/,
/\d/,
]}
/>
</Provider>
)

expect(Comp.find('input').instance().value).toBe('110203 12345')
})

it('should show placeholder chars when show_mask is true', () => {
Expand Down

0 comments on commit 89db309

Please sign in to comment.