@hero-design/rn 7.10.2 → 7.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +8 -8
- package/es/index.js +353 -79
- package/lib/assets/fonts/hero-icons.ttf +0 -0
- package/lib/index.js +352 -77
- package/package.json +2 -2
- package/src/components/FAB/ActionGroup/__tests__/__snapshots__/index.spec.tsx.snap +4 -0
- package/src/components/FAB/ActionGroup/index.tsx +16 -5
- package/src/components/PinInput/PinCell.tsx +34 -0
- package/src/components/PinInput/StyledPinInput.tsx +88 -0
- package/src/components/PinInput/__tests__/PinCell.spec.tsx +48 -0
- package/src/components/PinInput/__tests__/StyledPinInput.spec.tsx +22 -0
- package/src/components/PinInput/__tests__/__snapshots__/PinCell.spec.tsx.snap +186 -0
- package/src/components/PinInput/__tests__/__snapshots__/StyledPinInput.spec.tsx.snap +58 -0
- package/src/components/PinInput/__tests__/__snapshots__/index.spec.tsx.snap +1028 -0
- package/src/components/PinInput/__tests__/index.spec.tsx +91 -0
- package/src/components/PinInput/index.tsx +173 -0
- package/src/components/TextInput/__tests__/index.spec.tsx +15 -0
- package/src/components/TextInput/index.tsx +20 -16
- package/src/components/Typography/Text/StyledText.tsx +1 -1
- package/src/components/Typography/Text/__tests__/StyledText.spec.tsx +1 -0
- package/src/components/Typography/Text/__tests__/__snapshots__/StyledText.spec.tsx.snap +22 -0
- package/src/components/Typography/Text/index.tsx +1 -1
- package/src/index.ts +2 -0
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +35 -0
- package/src/theme/components/pinInput.ts +45 -0
- package/src/theme/components/typography.ts +2 -0
- package/src/theme/global/colors.ts +1 -1
- package/src/theme/global/space.ts +10 -10
- package/src/theme/index.ts +6 -3
- package/types/components/Alert/StyledAlert.d.ts +0 -0
- package/types/components/Alert/__tests__/index.spec.d.ts +0 -0
- package/types/components/Alert/index.d.ts +0 -0
- package/types/components/Avatar/StyledAvatar.d.ts +0 -0
- package/types/components/Avatar/__tests__/StyledAvatar.spec.d.ts +0 -0
- package/types/components/Avatar/__tests__/index.spec.d.ts +0 -0
- package/types/components/Avatar/index.d.ts +0 -0
- package/types/components/Badge/Status.d.ts +0 -0
- package/types/components/Badge/StyledBadge.d.ts +0 -0
- package/types/components/Badge/__tests__/Badge.spec.d.ts +0 -0
- package/types/components/Badge/__tests__/Status.spec.d.ts +0 -0
- package/types/components/Badge/index.d.ts +0 -0
- package/types/components/BottomNavigation/StyledBottomNavigation.d.ts +0 -0
- package/types/components/BottomNavigation/__tests__/index.spec.d.ts +0 -0
- package/types/components/BottomNavigation/index.d.ts +0 -0
- package/types/components/BottomSheet/Footer.d.ts +0 -0
- package/types/components/BottomSheet/Header.d.ts +0 -0
- package/types/components/BottomSheet/StyledBottomSheet.d.ts +0 -0
- package/types/components/BottomSheet/__tests__/index.spec.d.ts +0 -0
- package/types/components/BottomSheet/index.d.ts +0 -0
- package/types/components/Button/Button.d.ts +0 -0
- package/types/components/Button/IconButton.d.ts +0 -0
- package/types/components/Button/LoadingIndicator/StyledLoadingIndicator.d.ts +0 -0
- package/types/components/Button/LoadingIndicator/__tests__/StyledLoadingIndicator.spec.d.ts +0 -0
- package/types/components/Button/LoadingIndicator/__tests__/index.spec.d.ts +0 -0
- package/types/components/Button/LoadingIndicator/index.d.ts +0 -0
- package/types/components/Button/StyledButton.d.ts +0 -0
- package/types/components/Button/UtilityButton/__tests__/index.spec.d.ts +0 -0
- package/types/components/Button/UtilityButton/index.d.ts +0 -0
- package/types/components/Button/UtilityButton/styled.d.ts +0 -0
- package/types/components/Button/__tests__/Button.spec.d.ts +0 -0
- package/types/components/Button/__tests__/IconButton.spec.d.ts +0 -0
- package/types/components/Button/__tests__/StyledButton.spec.d.ts +0 -0
- package/types/components/Button/index.d.ts +0 -0
- package/types/components/Card/DataCard/StyledDataCard.d.ts +0 -0
- package/types/components/Card/DataCard/__tests__/StyledDataCard.spec.d.ts +0 -0
- package/types/components/Card/DataCard/__tests__/index.spec.d.ts +0 -0
- package/types/components/Card/DataCard/index.d.ts +0 -0
- package/types/components/Card/StyledCard.d.ts +0 -0
- package/types/components/Card/__tests__/StyledCard.spec.d.ts +0 -0
- package/types/components/Card/__tests__/index.spec.d.ts +0 -0
- package/types/components/Card/index.d.ts +0 -0
- package/types/components/Checkbox/StyledCheckbox.d.ts +0 -0
- package/types/components/Checkbox/__tests__/StyledCheckbox.spec.d.ts +0 -0
- package/types/components/Checkbox/__tests__/index.spec.d.ts +0 -0
- package/types/components/Checkbox/index.d.ts +0 -0
- package/types/components/Collapse/StyledCollapse.d.ts +0 -0
- package/types/components/Collapse/__tests__/StyledCollapse.spec.d.ts +0 -0
- package/types/components/Collapse/__tests__/index.spec.d.ts +0 -0
- package/types/components/Collapse/index.d.ts +0 -0
- package/types/components/ContentNavigator/StyledContentNavigator.d.ts +0 -0
- package/types/components/ContentNavigator/__tests__/StyledContentNavigator.spec.d.ts +0 -0
- package/types/components/ContentNavigator/__tests__/index.spec.d.ts +0 -0
- package/types/components/ContentNavigator/index.d.ts +0 -0
- package/types/components/Divider/StyledDivider.d.ts +0 -0
- package/types/components/Divider/__tests__/StyledDivider.spec.d.ts +0 -0
- package/types/components/Divider/index.d.ts +0 -0
- package/types/components/Drawer/StyledDrawer.d.ts +0 -0
- package/types/components/Drawer/__tests__/index.spec.d.ts +0 -0
- package/types/components/Drawer/index.d.ts +0 -0
- package/types/components/FAB/ActionGroup/ActionItem.d.ts +0 -0
- package/types/components/FAB/ActionGroup/StyledActionGroup.d.ts +0 -0
- package/types/components/FAB/ActionGroup/StyledActionItem.d.ts +0 -0
- package/types/components/FAB/ActionGroup/__tests__/index.spec.d.ts +0 -0
- package/types/components/FAB/ActionGroup/index.d.ts +0 -0
- package/types/components/FAB/AnimatedFABIcon.d.ts +0 -0
- package/types/components/FAB/FAB.d.ts +0 -0
- package/types/components/FAB/StyledFAB.d.ts +0 -0
- package/types/components/FAB/__tests__/AnimatedFABIcon.spec.d.ts +0 -0
- package/types/components/FAB/__tests__/StyledFAB.spec.d.ts +0 -0
- package/types/components/FAB/__tests__/index.spec.d.ts +0 -0
- package/types/components/FAB/index.d.ts +0 -0
- package/types/components/Icon/HeroIcon/index.d.ts +0 -0
- package/types/components/Icon/IconList.d.ts +0 -0
- package/types/components/Icon/__tests__/index.spec.d.ts +0 -0
- package/types/components/Icon/index.d.ts +0 -0
- package/types/components/Icon/utils.d.ts +0 -0
- package/types/components/List/BasicListItem.d.ts +0 -0
- package/types/components/List/ListItem.d.ts +0 -0
- package/types/components/List/StyledBasicListItem.d.ts +0 -0
- package/types/components/List/StyledListItem.d.ts +0 -0
- package/types/components/List/__tests__/BasicListItem.spec.d.ts +0 -0
- package/types/components/List/__tests__/ListItem.spec.d.ts +0 -0
- package/types/components/List/__tests__/StyledBasicListItem.spec.d.ts +0 -0
- package/types/components/List/__tests__/StyledListItem.spec.d.ts +0 -0
- package/types/components/List/index.d.ts +0 -0
- package/types/components/PinInput/PinCell.d.ts +8 -0
- package/types/components/PinInput/StyledPinInput.d.ts +73 -0
- package/types/components/PinInput/__tests__/PinCell.spec.d.ts +1 -0
- package/types/components/PinInput/__tests__/StyledPinInput.spec.d.ts +1 -0
- package/types/components/PinInput/__tests__/index.spec.d.ts +1 -0
- package/types/components/PinInput/index.d.ts +48 -0
- package/types/components/Progress/ProgressBar.d.ts +0 -0
- package/types/components/Progress/ProgressCircle.d.ts +0 -0
- package/types/components/Progress/StyledProgressBar.d.ts +0 -0
- package/types/components/Progress/StyledProgressCircle.d.ts +0 -0
- package/types/components/Progress/__tests__/index.spec.d.ts +0 -0
- package/types/components/Progress/index.d.ts +0 -0
- package/types/components/Progress/types.d.ts +0 -0
- package/types/components/Radio/Radio.d.ts +0 -0
- package/types/components/Radio/RadioGroup.d.ts +0 -0
- package/types/components/Radio/StyledRadio.d.ts +0 -0
- package/types/components/Radio/__tests__/Radio.spec.d.ts +0 -0
- package/types/components/Radio/__tests__/RadioGroup.spec.d.ts +0 -0
- package/types/components/Radio/__tests__/StyledRadio.spec.d.ts +0 -0
- package/types/components/Radio/index.d.ts +0 -0
- package/types/components/Radio/types.d.ts +0 -0
- package/types/components/SectionHeading/StyledHeading.d.ts +0 -0
- package/types/components/SectionHeading/__tests__/StyledHeading.spec.d.ts +0 -0
- package/types/components/SectionHeading/__tests__/index.spec.d.ts +0 -0
- package/types/components/SectionHeading/index.d.ts +0 -0
- package/types/components/Select/Footer.d.ts +0 -0
- package/types/components/Select/MultiSelect/Option.d.ts +0 -0
- package/types/components/Select/MultiSelect/OptionList.d.ts +0 -0
- package/types/components/Select/MultiSelect/__tests__/Option.spec.d.ts +0 -0
- package/types/components/Select/MultiSelect/__tests__/OptionList.spec.d.ts +0 -0
- package/types/components/Select/MultiSelect/__tests__/index.spec.d.ts +0 -0
- package/types/components/Select/MultiSelect/index.d.ts +0 -0
- package/types/components/Select/SingleSelect/Option.d.ts +0 -0
- package/types/components/Select/SingleSelect/OptionList.d.ts +0 -0
- package/types/components/Select/SingleSelect/__tests__/Option.spec.d.ts +0 -0
- package/types/components/Select/SingleSelect/__tests__/OptionList.spec.d.ts +0 -0
- package/types/components/Select/SingleSelect/__tests__/index.spec.d.ts +0 -0
- package/types/components/Select/SingleSelect/index.d.ts +0 -0
- package/types/components/Select/StyledSelect.d.ts +0 -0
- package/types/components/Select/__tests__/StyledSelect.spec.d.ts +0 -0
- package/types/components/Select/helpers.d.ts +0 -0
- package/types/components/Select/index.d.ts +0 -0
- package/types/components/Select/types.d.ts +0 -0
- package/types/components/Spinner/AnimatedSpinner.d.ts +0 -0
- package/types/components/Spinner/StyledSpinner.d.ts +0 -0
- package/types/components/Spinner/__tests__/AnimatedSpinner.spec.d.ts +0 -0
- package/types/components/Spinner/__tests__/StyledSpinner.spec.d.ts +0 -0
- package/types/components/Spinner/__tests__/index.spec.d.ts +0 -0
- package/types/components/Spinner/index.d.ts +0 -0
- package/types/components/Switch/StyledSwitch.d.ts +0 -0
- package/types/components/Switch/__tests__/StyledHeading.spec.d.ts +0 -0
- package/types/components/Switch/__tests__/index.spec.d.ts +0 -0
- package/types/components/Switch/index.d.ts +0 -0
- package/types/components/Tabs/ActiveTabIndicator.d.ts +0 -0
- package/types/components/Tabs/ScrollableTabs.d.ts +0 -0
- package/types/components/Tabs/StyledScrollableTabs.d.ts +0 -0
- package/types/components/Tabs/StyledTabs.d.ts +0 -0
- package/types/components/Tabs/__tests__/ScrollableTabs.spec.d.ts +0 -0
- package/types/components/Tabs/__tests__/index.spec.d.ts +0 -0
- package/types/components/Tabs/index.d.ts +0 -0
- package/types/components/Tabs/utils.d.ts +0 -0
- package/types/components/Tag/StyledTag.d.ts +0 -0
- package/types/components/Tag/__tests__/Tag.spec.d.ts +0 -0
- package/types/components/Tag/index.d.ts +0 -0
- package/types/components/TextInput/StyledTextInput.d.ts +0 -0
- package/types/components/TextInput/__tests__/StyledTextInput.spec.d.ts +0 -0
- package/types/components/TextInput/__tests__/index.spec.d.ts +0 -0
- package/types/components/TextInput/index.d.ts +0 -0
- package/types/components/Toast/StyledToast.d.ts +0 -0
- package/types/components/Toast/Toast.d.ts +0 -0
- package/types/components/Toast/ToastContainer.d.ts +0 -0
- package/types/components/Toast/ToastContext.d.ts +0 -0
- package/types/components/Toast/ToastProvider.d.ts +0 -0
- package/types/components/Toast/__tests__/Toast.spec.d.ts +0 -0
- package/types/components/Toast/__tests__/ToastContainer.spec.d.ts +0 -0
- package/types/components/Toast/index.d.ts +0 -0
- package/types/components/Toast/types.d.ts +0 -0
- package/types/components/Toolbar/StyledToolbar.d.ts +0 -0
- package/types/components/Toolbar/ToolbarGroup.d.ts +0 -0
- package/types/components/Toolbar/ToolbarItem.d.ts +0 -0
- package/types/components/Toolbar/__tests__/ToolbarGroup.spec.d.ts +0 -0
- package/types/components/Toolbar/__tests__/ToolbarItem.spec.d.ts +0 -0
- package/types/components/Toolbar/index.d.ts +0 -0
- package/types/components/Typography/Text/StyledText.d.ts +1 -1
- package/types/components/Typography/Text/__tests__/StyledText.spec.d.ts +0 -0
- package/types/components/Typography/Text/__tests__/index.spec.d.ts +0 -0
- package/types/components/Typography/Text/index.d.ts +1 -1
- package/types/components/Typography/index.d.ts +0 -0
- package/types/index.d.ts +2 -1
- package/types/testHelpers/renderWithTheme.d.ts +0 -0
- package/types/theme/__tests__/index.spec.d.ts +0 -0
- package/types/theme/components/alert.d.ts +0 -0
- package/types/theme/components/avatar.d.ts +0 -0
- package/types/theme/components/badge.d.ts +0 -0
- package/types/theme/components/bottomNavigation.d.ts +0 -0
- package/types/theme/components/bottomSheet.d.ts +0 -0
- package/types/theme/components/button.d.ts +0 -0
- package/types/theme/components/card.d.ts +0 -0
- package/types/theme/components/checkbox.d.ts +0 -0
- package/types/theme/components/contentNavigator.d.ts +0 -0
- package/types/theme/components/divider.d.ts +0 -0
- package/types/theme/components/drawer.d.ts +0 -0
- package/types/theme/components/fab.d.ts +0 -0
- package/types/theme/components/icon.d.ts +0 -0
- package/types/theme/components/list.d.ts +0 -0
- package/types/theme/components/pinInput.d.ts +35 -0
- package/types/theme/components/progress.d.ts +0 -0
- package/types/theme/components/radio.d.ts +0 -0
- package/types/theme/components/sectionHeading.d.ts +0 -0
- package/types/theme/components/select.d.ts +0 -0
- package/types/theme/components/spinner.d.ts +0 -0
- package/types/theme/components/switch.d.ts +0 -0
- package/types/theme/components/tabs.d.ts +0 -0
- package/types/theme/components/tag.d.ts +0 -0
- package/types/theme/components/textInput.d.ts +0 -0
- package/types/theme/components/toast.d.ts +0 -0
- package/types/theme/components/toolbar.d.ts +0 -0
- package/types/theme/components/typography.d.ts +2 -0
- package/types/theme/global/borders.d.ts +0 -0
- package/types/theme/global/colors.d.ts +0 -0
- package/types/theme/global/index.d.ts +0 -0
- package/types/theme/global/scale.d.ts +0 -0
- package/types/theme/global/space.d.ts +0 -0
- package/types/theme/global/typography.d.ts +0 -0
- package/types/theme/index.d.ts +4 -2
- package/types/types.d.ts +0 -0
- package/types/utils/__tests__/scale.spec.d.ts +0 -0
- package/types/utils/helpers.d.ts +0 -0
- package/types/utils/hooks.d.ts +0 -0
- package/types/utils/scale.d.ts +0 -0
- package/src/components/TextInput/__tests__/.log/ti-10343.log +0 -62
- package/src/components/TextInput/__tests__/.log/tsserver.log +0 -15584
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { fireEvent } from '@testing-library/react-native';
|
|
3
|
+
import renderWithTheme from '../../../testHelpers/renderWithTheme';
|
|
4
|
+
import PinInput, { getState } from '..';
|
|
5
|
+
|
|
6
|
+
describe('rendering', () => {
|
|
7
|
+
it('renders correctly', () => {
|
|
8
|
+
const wrapper = renderWithTheme(
|
|
9
|
+
<PinInput value="12" onChangeText={jest.fn()} />
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
13
|
+
expect(wrapper.queryAllByTestId('pin-cell-filled-mask')).toHaveLength(2);
|
|
14
|
+
expect(wrapper.queryAllByTestId('pin-cell-mask')).toHaveLength(2);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders correctly when length is 6 and secure is false', () => {
|
|
18
|
+
const wrapper = renderWithTheme(
|
|
19
|
+
<PinInput
|
|
20
|
+
length={6}
|
|
21
|
+
value="123"
|
|
22
|
+
onChangeText={jest.fn()}
|
|
23
|
+
secure={false}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
expect(wrapper.queryAllByText('1')).toHaveLength(1);
|
|
28
|
+
expect(wrapper.queryAllByText('2')).toHaveLength(1);
|
|
29
|
+
expect(wrapper.queryAllByText('3')).toHaveLength(1);
|
|
30
|
+
expect(wrapper.queryAllByTestId('pin-cell-mask')).toHaveLength(3);
|
|
31
|
+
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('renders correctly when there is error', () => {
|
|
35
|
+
const wrapper = renderWithTheme(
|
|
36
|
+
<PinInput
|
|
37
|
+
value="12"
|
|
38
|
+
onChangeText={jest.fn()}
|
|
39
|
+
error="PIN is not correct"
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(wrapper.queryAllByText('PIN is not correct')).toHaveLength(1);
|
|
44
|
+
expect(wrapper.queryAllByTestId('pin-error-icon')).toHaveLength(1);
|
|
45
|
+
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('renders correctly when disabled', () => {
|
|
49
|
+
const wrapper = renderWithTheme(
|
|
50
|
+
<PinInput value="12" onChangeText={jest.fn()} disabled />
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
expect(wrapper.toJSON()).toMatchSnapshot();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('behaviors', () => {
|
|
58
|
+
it('calls onChangeText, onFulfill with correct params', () => {
|
|
59
|
+
const onChangeText = jest.fn();
|
|
60
|
+
const onFulfill = jest.fn();
|
|
61
|
+
const { getByTestId } = renderWithTheme(
|
|
62
|
+
<PinInput value="123" onChangeText={onChangeText} onFulfill={onFulfill} />
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const hiddenInput = getByTestId('pin-hidden-input');
|
|
66
|
+
fireEvent.changeText(hiddenInput, '123.4'); // 123.4 is intended to test regex behavior
|
|
67
|
+
|
|
68
|
+
expect(onChangeText).toHaveBeenCalledWith('1234');
|
|
69
|
+
expect(onFulfill).toHaveBeenCalledWith('1234');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('getState', () => {
|
|
74
|
+
it.each`
|
|
75
|
+
disabled | error | state
|
|
76
|
+
${true} | ${'PIN is not correct'} | ${'disabled'}
|
|
77
|
+
${true} | ${undefined} | ${'disabled'}
|
|
78
|
+
${false} | ${'This field is required'} | ${'error'}
|
|
79
|
+
${false} | ${undefined} | ${'default'}
|
|
80
|
+
`(
|
|
81
|
+
'returns $state when disabled is $disabled, error is $error',
|
|
82
|
+
({ disabled, error, state }) => {
|
|
83
|
+
expect(
|
|
84
|
+
getState({
|
|
85
|
+
disabled,
|
|
86
|
+
error,
|
|
87
|
+
})
|
|
88
|
+
).toBe(state);
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
});
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
InteractionManager,
|
|
4
|
+
StyleProp,
|
|
5
|
+
TextInput,
|
|
6
|
+
ViewStyle,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import Icon from '../Icon';
|
|
9
|
+
import PinCell from './PinCell';
|
|
10
|
+
import {
|
|
11
|
+
StyledErrorContainer,
|
|
12
|
+
StyledErrorMessage,
|
|
13
|
+
StyledHiddenInput,
|
|
14
|
+
StyledSpacer,
|
|
15
|
+
StyledPinWrapper,
|
|
16
|
+
StyledWrapper,
|
|
17
|
+
State,
|
|
18
|
+
} from './StyledPinInput';
|
|
19
|
+
|
|
20
|
+
interface PinInputProps {
|
|
21
|
+
/**
|
|
22
|
+
* The value to show for the input.
|
|
23
|
+
*/
|
|
24
|
+
value?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Callback function that's called when the text changed.
|
|
27
|
+
*/
|
|
28
|
+
onChangeText: (value: string) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Callback function that's called when the input is completely filled.
|
|
31
|
+
*/
|
|
32
|
+
onFulfill?: (value: string) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Number of character for the input.
|
|
35
|
+
*/
|
|
36
|
+
length?: number;
|
|
37
|
+
/*
|
|
38
|
+
* Whether the input is disabled.
|
|
39
|
+
*/
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the pin value is secured using masks.
|
|
43
|
+
* By default, this is true, meaning that masks are shown to hide pin value.
|
|
44
|
+
*/
|
|
45
|
+
secure?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* If true, focuses the input on componentDidMount.
|
|
48
|
+
*/
|
|
49
|
+
autoFocus?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Error message.
|
|
52
|
+
*/
|
|
53
|
+
error?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Additional style.
|
|
56
|
+
*/
|
|
57
|
+
style?: StyleProp<ViewStyle>;
|
|
58
|
+
/**
|
|
59
|
+
* Testing id of the component.
|
|
60
|
+
*/
|
|
61
|
+
testID?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getState({
|
|
65
|
+
disabled,
|
|
66
|
+
error,
|
|
67
|
+
}: {
|
|
68
|
+
disabled?: boolean;
|
|
69
|
+
error?: string;
|
|
70
|
+
}): State {
|
|
71
|
+
if (disabled) {
|
|
72
|
+
return 'disabled';
|
|
73
|
+
}
|
|
74
|
+
if (error) {
|
|
75
|
+
return 'error';
|
|
76
|
+
}
|
|
77
|
+
return 'default';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function PinInput({
|
|
81
|
+
value = '',
|
|
82
|
+
onChangeText,
|
|
83
|
+
onFulfill,
|
|
84
|
+
length = 4,
|
|
85
|
+
disabled = false,
|
|
86
|
+
secure = true,
|
|
87
|
+
autoFocus = false,
|
|
88
|
+
error,
|
|
89
|
+
style,
|
|
90
|
+
testID,
|
|
91
|
+
}: PinInputProps) {
|
|
92
|
+
const inputRef = useRef<TextInput>(null);
|
|
93
|
+
const [focused, setFocused] = useState(autoFocus);
|
|
94
|
+
const state = getState({ disabled, error });
|
|
95
|
+
|
|
96
|
+
const focus = useCallback(() => {
|
|
97
|
+
if (inputRef?.current) {
|
|
98
|
+
inputRef.current.focus();
|
|
99
|
+
setFocused(true);
|
|
100
|
+
}
|
|
101
|
+
}, []);
|
|
102
|
+
|
|
103
|
+
const blur = useCallback(() => {
|
|
104
|
+
if (inputRef?.current) {
|
|
105
|
+
inputRef.current.blur();
|
|
106
|
+
setFocused(false);
|
|
107
|
+
}
|
|
108
|
+
}, []);
|
|
109
|
+
|
|
110
|
+
const changeText = useCallback((text: string) => {
|
|
111
|
+
const pin = (text.match(/[0-9]/g) || []).join('');
|
|
112
|
+
if (onChangeText) {
|
|
113
|
+
onChangeText(pin);
|
|
114
|
+
}
|
|
115
|
+
if (pin.length === length && onFulfill) {
|
|
116
|
+
onFulfill(pin);
|
|
117
|
+
}
|
|
118
|
+
}, []);
|
|
119
|
+
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
// Must run after animations for keyboard to automatically open
|
|
122
|
+
if (autoFocus) {
|
|
123
|
+
InteractionManager.runAfterInteractions(focus);
|
|
124
|
+
}
|
|
125
|
+
}, [inputRef]);
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<StyledWrapper style={style} testID={testID}>
|
|
129
|
+
<StyledPinWrapper>
|
|
130
|
+
{[...Array(length).keys()].map(index => (
|
|
131
|
+
<React.Fragment key={index}>
|
|
132
|
+
{index !== 0 && <StyledSpacer />}
|
|
133
|
+
<PinCell
|
|
134
|
+
value={value.charAt(index)}
|
|
135
|
+
secure={secure}
|
|
136
|
+
focused={focused && index === value.length}
|
|
137
|
+
state={state}
|
|
138
|
+
/>
|
|
139
|
+
</React.Fragment>
|
|
140
|
+
))}
|
|
141
|
+
</StyledPinWrapper>
|
|
142
|
+
{state === 'error' && (
|
|
143
|
+
<StyledErrorContainer>
|
|
144
|
+
<Icon
|
|
145
|
+
icon="circle-info"
|
|
146
|
+
size="xsmall"
|
|
147
|
+
intent="danger"
|
|
148
|
+
testID="pin-error-icon"
|
|
149
|
+
/>
|
|
150
|
+
<StyledErrorMessage>{error}</StyledErrorMessage>
|
|
151
|
+
</StyledErrorContainer>
|
|
152
|
+
)}
|
|
153
|
+
<StyledHiddenInput
|
|
154
|
+
themePinLength={length}
|
|
155
|
+
ref={inputRef}
|
|
156
|
+
value={value}
|
|
157
|
+
onChangeText={changeText}
|
|
158
|
+
secureTextEntry={secure}
|
|
159
|
+
editable={!disabled}
|
|
160
|
+
autoFocus={autoFocus}
|
|
161
|
+
onFocus={focus}
|
|
162
|
+
onBlur={blur}
|
|
163
|
+
maxLength={length}
|
|
164
|
+
keyboardType="numeric"
|
|
165
|
+
contextMenuHidden
|
|
166
|
+
caretHidden
|
|
167
|
+
testID="pin-hidden-input"
|
|
168
|
+
/>
|
|
169
|
+
</StyledWrapper>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export default PinInput;
|
|
@@ -60,6 +60,21 @@ describe('TextInput', () => {
|
|
|
60
60
|
).toHaveLength(1);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
+
it('should not render input-label if label is empty', () => {
|
|
64
|
+
const { getByTestId } = renderWithTheme(
|
|
65
|
+
<TextInput
|
|
66
|
+
prefix="dollar-sign"
|
|
67
|
+
suffix="arrow-down"
|
|
68
|
+
testID="idle-text-input"
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
expect(getByTestId('idle-text-input')).toBeTruthy();
|
|
73
|
+
expect(
|
|
74
|
+
within(getByTestId('idle-text-input')).queryAllByTestId('input-label')
|
|
75
|
+
).toHaveLength(0);
|
|
76
|
+
});
|
|
77
|
+
|
|
63
78
|
it('onChangeText, onBlur, onFocus', () => {
|
|
64
79
|
const onChangeText = jest.fn();
|
|
65
80
|
const onBlur = jest.fn();
|
|
@@ -171,14 +171,16 @@ const TextInput = ({
|
|
|
171
171
|
*
|
|
172
172
|
</StyledAsteriskLabel>
|
|
173
173
|
)}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
174
|
+
{!!label && (
|
|
175
|
+
<StyledLabel
|
|
176
|
+
nativeID={accessibilityLabelledBy}
|
|
177
|
+
testID="input-label"
|
|
178
|
+
fontSize="small"
|
|
179
|
+
themeVariant={variant}
|
|
180
|
+
>
|
|
181
|
+
{label}
|
|
182
|
+
</StyledLabel>
|
|
183
|
+
)}
|
|
182
184
|
</StyledLabelContainer>
|
|
183
185
|
)}
|
|
184
186
|
{typeof prefix === 'string' ? (
|
|
@@ -200,14 +202,16 @@ const TextInput = ({
|
|
|
200
202
|
*
|
|
201
203
|
</StyledAsteriskLabelInsideTextInput>
|
|
202
204
|
)}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
{!!label && (
|
|
206
|
+
<StyledLabelInsideTextInput
|
|
207
|
+
nativeID={accessibilityLabelledBy}
|
|
208
|
+
testID="input-label"
|
|
209
|
+
fontSize="medium"
|
|
210
|
+
themeVariant={variant}
|
|
211
|
+
>
|
|
212
|
+
{label}
|
|
213
|
+
</StyledLabelInsideTextInput>
|
|
214
|
+
)}
|
|
211
215
|
</StyledLabelContainerInsideTextInput>
|
|
212
216
|
)}
|
|
213
217
|
<StyledTextInput
|
|
@@ -8,7 +8,7 @@ const FONTWEIGHT_MAP = {
|
|
|
8
8
|
} as const;
|
|
9
9
|
|
|
10
10
|
const StyledText = styled(Text)<{
|
|
11
|
-
themeFontSize: 'small' | 'medium' | 'large' | 'xlarge';
|
|
11
|
+
themeFontSize: 'small' | 'medium' | 'large' | 'xlarge' | 'xxxxxlarge';
|
|
12
12
|
themeFontWeight: 'light' | 'regular' | 'semi-bold';
|
|
13
13
|
themeIntent:
|
|
14
14
|
| 'body'
|
|
@@ -307,3 +307,25 @@ exports[`StyledText has xlarge fontSize style 1`] = `
|
|
|
307
307
|
This is a test
|
|
308
308
|
</Text>
|
|
309
309
|
`;
|
|
310
|
+
|
|
311
|
+
exports[`StyledText has xxxxxlarge fontSize style 1`] = `
|
|
312
|
+
<Text
|
|
313
|
+
style={
|
|
314
|
+
Array [
|
|
315
|
+
Object {
|
|
316
|
+
"color": "#292a2b",
|
|
317
|
+
"fontFamily": "BeVietnamPro-Regular",
|
|
318
|
+
"fontSize": 32,
|
|
319
|
+
"letterSpacing": 0.96,
|
|
320
|
+
"lineHeight": 40,
|
|
321
|
+
},
|
|
322
|
+
undefined,
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
themeFontSize="xxxxxlarge"
|
|
326
|
+
themeFontWeight="regular"
|
|
327
|
+
themeIntent="body"
|
|
328
|
+
>
|
|
329
|
+
This is a test
|
|
330
|
+
</Text>
|
|
331
|
+
`;
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ import Drawer from './components/Drawer';
|
|
|
16
16
|
import FAB from './components/FAB';
|
|
17
17
|
import Icon from './components/Icon';
|
|
18
18
|
import List from './components/List';
|
|
19
|
+
import PinInput from './components/PinInput';
|
|
19
20
|
import Progress from './components/Progress';
|
|
20
21
|
import Spinner from './components/Spinner';
|
|
21
22
|
import Radio from './components/Radio';
|
|
@@ -50,6 +51,7 @@ export {
|
|
|
50
51
|
FAB,
|
|
51
52
|
Icon,
|
|
52
53
|
List,
|
|
54
|
+
PinInput,
|
|
53
55
|
Progress,
|
|
54
56
|
Spinner,
|
|
55
57
|
Radio,
|
|
@@ -354,6 +354,39 @@ Object {
|
|
|
354
354
|
"leadingStatus": 8,
|
|
355
355
|
},
|
|
356
356
|
},
|
|
357
|
+
"pinInput": Object {
|
|
358
|
+
"borderWidths": Object {
|
|
359
|
+
"default": 1,
|
|
360
|
+
"focused": 2,
|
|
361
|
+
},
|
|
362
|
+
"colors": Object {
|
|
363
|
+
"default": "#292a2b",
|
|
364
|
+
"disabled": "#bfc1c5",
|
|
365
|
+
"error": "#de350b",
|
|
366
|
+
"mask": "#727478",
|
|
367
|
+
},
|
|
368
|
+
"fontSizes": Object {
|
|
369
|
+
"cellText": 28,
|
|
370
|
+
"errorMessage": 12,
|
|
371
|
+
},
|
|
372
|
+
"fonts": Object {
|
|
373
|
+
"cellText": "BeVietnamPro-SemiBold",
|
|
374
|
+
"errorMessage": "BeVietnamPro-Regular",
|
|
375
|
+
},
|
|
376
|
+
"radii": Object {
|
|
377
|
+
"cell": 8,
|
|
378
|
+
"mask": 999,
|
|
379
|
+
},
|
|
380
|
+
"sizes": Object {
|
|
381
|
+
"cellHeight": 48,
|
|
382
|
+
"cellWidth": 40,
|
|
383
|
+
"mask": 16,
|
|
384
|
+
},
|
|
385
|
+
"space": Object {
|
|
386
|
+
"errorMessagePadding": 4,
|
|
387
|
+
"spacer": 16,
|
|
388
|
+
},
|
|
389
|
+
},
|
|
357
390
|
"progress": Object {
|
|
358
391
|
"colors": Object {
|
|
359
392
|
"background": "#dadbde",
|
|
@@ -655,6 +688,7 @@ Object {
|
|
|
655
688
|
"medium": 14,
|
|
656
689
|
"small": 12,
|
|
657
690
|
"xlarge": 18,
|
|
691
|
+
"xxxxxlarge": 32,
|
|
658
692
|
},
|
|
659
693
|
"fonts": Object {
|
|
660
694
|
"light": "BeVietnamPro-Light",
|
|
@@ -666,6 +700,7 @@ Object {
|
|
|
666
700
|
"medium": 22,
|
|
667
701
|
"small": 20,
|
|
668
702
|
"xlarge": 26,
|
|
703
|
+
"xxxxxlarge": 40,
|
|
669
704
|
},
|
|
670
705
|
},
|
|
671
706
|
},
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { GlobalTheme } from '../global';
|
|
2
|
+
|
|
3
|
+
const getPinInputTheme = (theme: GlobalTheme) => {
|
|
4
|
+
const borderWidths = {
|
|
5
|
+
default: theme.borderWidths.base,
|
|
6
|
+
focused: theme.borderWidths.medium,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const colors = {
|
|
10
|
+
default: theme.colors.text,
|
|
11
|
+
mask: theme.colors.subduedText, // should be Maastricht Blue light 50
|
|
12
|
+
error: theme.colors.danger, // using this so that the color is the same as danger Icon, should be Vermilion
|
|
13
|
+
disabled: theme.colors.archivedDark,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const fonts = {
|
|
17
|
+
cellText: theme.fonts.semiBold,
|
|
18
|
+
errorMessage: theme.fonts.regular,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const fontSizes = {
|
|
22
|
+
cellText: theme.fontSizes.xxxxlarge,
|
|
23
|
+
errorMessage: theme.fontSizes.small,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const sizes = {
|
|
27
|
+
cellWidth: theme.space.xxlarge,
|
|
28
|
+
cellHeight: theme.space.xxxlarge,
|
|
29
|
+
mask: theme.space.medium,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const space = {
|
|
33
|
+
spacer: theme.space.medium,
|
|
34
|
+
errorMessagePadding: theme.space.xsmall,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const radii = {
|
|
38
|
+
cell: theme.radii.medium,
|
|
39
|
+
mask: theme.radii.rounded,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return { borderWidths, colors, fonts, fontSizes, sizes, space, radii };
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default getPinInputTheme;
|
|
@@ -22,6 +22,7 @@ const getTypographyTheme = (theme: GlobalTheme) => {
|
|
|
22
22
|
medium: theme.fontSizes.medium,
|
|
23
23
|
large: theme.fontSizes.large,
|
|
24
24
|
xlarge: theme.fontSizes.xlarge,
|
|
25
|
+
xxxxxlarge: theme.fontSizes.xxxxxlarge,
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
const lineHeights = {
|
|
@@ -29,6 +30,7 @@ const getTypographyTheme = (theme: GlobalTheme) => {
|
|
|
29
30
|
medium: theme.lineHeights.medium,
|
|
30
31
|
large: theme.lineHeights.large,
|
|
31
32
|
xlarge: theme.lineHeights.xlarge,
|
|
33
|
+
xxxxxlarge: theme.lineHeights.xxxxxlarge,
|
|
32
34
|
};
|
|
33
35
|
|
|
34
36
|
return { colors, fonts, fontSizes, lineHeights };
|
|
@@ -28,7 +28,7 @@ const systemPalette = {
|
|
|
28
28
|
platformBackground: palette.white,
|
|
29
29
|
backgroundLight: palette.greyLight95,
|
|
30
30
|
backgroundDark: palette.greyDark75,
|
|
31
|
-
text: palette.greyDark75,
|
|
31
|
+
text: palette.greyDark75, // should be Maastricht Blue
|
|
32
32
|
subduedText: palette.greyDark30,
|
|
33
33
|
disabledText: palette.greyDark15,
|
|
34
34
|
disabledLightText: palette.greyLight45,
|
|
@@ -14,16 +14,16 @@ interface Space {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const getSpace = (baseSpace: number): Space => ({
|
|
17
|
-
xxsmall: scale(baseSpace * 0.25),
|
|
18
|
-
xsmall: scale(baseSpace * 0.5),
|
|
19
|
-
small: scale(baseSpace),
|
|
20
|
-
smallMedium: scale(baseSpace) * 1.5,
|
|
21
|
-
medium: scale(baseSpace * 2),
|
|
22
|
-
large: scale(baseSpace * 3),
|
|
23
|
-
xlarge: scale(baseSpace * 4),
|
|
24
|
-
xxlarge: scale(baseSpace * 5),
|
|
25
|
-
xxxlarge: scale(baseSpace * 6),
|
|
26
|
-
xxxxlarge: scale(baseSpace * 7),
|
|
17
|
+
xxsmall: scale(baseSpace * 0.25), // 2
|
|
18
|
+
xsmall: scale(baseSpace * 0.5), // 4
|
|
19
|
+
small: scale(baseSpace), // 8
|
|
20
|
+
smallMedium: scale(baseSpace) * 1.5, // 12
|
|
21
|
+
medium: scale(baseSpace * 2), // 16
|
|
22
|
+
large: scale(baseSpace * 3), // 24
|
|
23
|
+
xlarge: scale(baseSpace * 4), // 32
|
|
24
|
+
xxlarge: scale(baseSpace * 5), // 40
|
|
25
|
+
xxxlarge: scale(baseSpace * 6), // 48
|
|
26
|
+
xxxxlarge: scale(baseSpace * 7), // 56
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
export { Space, getSpace };
|
package/src/theme/index.ts
CHANGED
|
@@ -22,6 +22,8 @@ import getDividerTheme from './components/divider';
|
|
|
22
22
|
import getDrawerTheme from './components/drawer';
|
|
23
23
|
import getFABTheme from './components/fab';
|
|
24
24
|
import getIconTheme from './components/icon';
|
|
25
|
+
import getListTheme from './components/list';
|
|
26
|
+
import getPinInputTheme from './components/pinInput';
|
|
25
27
|
import getProgressTheme from './components/progress';
|
|
26
28
|
import getRadioTheme from './components/radio';
|
|
27
29
|
import getSectionHeadingTheme from './components/sectionHeading';
|
|
@@ -34,7 +36,6 @@ import getTextInputTheme from './components/textInput';
|
|
|
34
36
|
import getToastTheme from './components/toast';
|
|
35
37
|
import getToolbarTheme from './components/toolbar';
|
|
36
38
|
import getTypographyTheme from './components/typography';
|
|
37
|
-
import getListTheme from './components/list';
|
|
38
39
|
|
|
39
40
|
type Theme = GlobalTheme & {
|
|
40
41
|
__hd__: {
|
|
@@ -51,6 +52,8 @@ type Theme = GlobalTheme & {
|
|
|
51
52
|
drawer: ReturnType<typeof getDrawerTheme>;
|
|
52
53
|
fab: ReturnType<typeof getFABTheme>;
|
|
53
54
|
icon: ReturnType<typeof getIconTheme>;
|
|
55
|
+
list: ReturnType<typeof getListTheme>;
|
|
56
|
+
pinInput: ReturnType<typeof getPinInputTheme>;
|
|
54
57
|
progress: ReturnType<typeof getProgressTheme>;
|
|
55
58
|
radio: ReturnType<typeof getRadioTheme>;
|
|
56
59
|
sectionHeading: ReturnType<typeof getSectionHeadingTheme>;
|
|
@@ -63,7 +66,6 @@ type Theme = GlobalTheme & {
|
|
|
63
66
|
toast: ReturnType<typeof getToastTheme>;
|
|
64
67
|
toolbar: ReturnType<typeof getToolbarTheme>;
|
|
65
68
|
typography: ReturnType<typeof getTypographyTheme>;
|
|
66
|
-
list: ReturnType<typeof getListTheme>;
|
|
67
69
|
};
|
|
68
70
|
};
|
|
69
71
|
|
|
@@ -88,6 +90,8 @@ const getTheme = (
|
|
|
88
90
|
drawer: getDrawerTheme(globalTheme),
|
|
89
91
|
fab: getFABTheme(globalTheme),
|
|
90
92
|
icon: getIconTheme(globalTheme),
|
|
93
|
+
list: getListTheme(globalTheme),
|
|
94
|
+
pinInput: getPinInputTheme(globalTheme),
|
|
91
95
|
progress: getProgressTheme(globalTheme),
|
|
92
96
|
radio: getRadioTheme(globalTheme),
|
|
93
97
|
sectionHeading: getSectionHeadingTheme(globalTheme),
|
|
@@ -100,7 +104,6 @@ const getTheme = (
|
|
|
100
104
|
toast: getToastTheme(globalTheme),
|
|
101
105
|
toolbar: getToolbarTheme(globalTheme),
|
|
102
106
|
typography: getTypographyTheme(globalTheme),
|
|
103
|
-
list: getListTheme(globalTheme),
|
|
104
107
|
},
|
|
105
108
|
};
|
|
106
109
|
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|