@hero-design/rn 8.25.1 → 8.25.3

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.
@@ -1,4 +1,11 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
1
+ import React, {
2
+ forwardRef,
3
+ useCallback,
4
+ useEffect,
5
+ useImperativeHandle,
6
+ useRef,
7
+ useState,
8
+ } from 'react';
2
9
  import { InteractionManager, TextInput } from 'react-native';
3
10
  import type { StyleProp, ViewStyle } from 'react-native';
4
11
  import Icon from '../Icon';
@@ -73,98 +80,122 @@ export function getState({
73
80
  return 'default';
74
81
  }
75
82
 
76
- function PinInput({
77
- value = '',
78
- onChangeText,
79
- onFulfill,
80
- length = 4,
81
- disabled = false,
82
- secure = true,
83
- autoFocus = false,
84
- error,
85
- style,
86
- testID,
87
- }: PinInputProps) {
88
- const inputRef = useRef<TextInput>(null);
89
- const [focused, setFocused] = useState(autoFocus);
90
- const state = getState({ disabled, error });
83
+ export interface PinInputHandler {
84
+ /**
85
+ * focus into input
86
+ */
87
+ focus: () => void;
88
+ /**
89
+ * blur text input
90
+ */
91
+ blur: () => void;
92
+ }
91
93
 
92
- const focus = useCallback(() => {
93
- if (inputRef?.current) {
94
- inputRef.current.focus();
95
- setFocused(true);
96
- }
97
- }, []);
94
+ const PinInput = forwardRef<PinInputHandler, PinInputProps>(
95
+ (
96
+ {
97
+ value = '',
98
+ onChangeText,
99
+ onFulfill,
100
+ length = 4,
101
+ disabled = false,
102
+ secure = true,
103
+ autoFocus = false,
104
+ error,
105
+ style,
106
+ testID,
107
+ },
108
+ ref
109
+ ) => {
110
+ const inputRef = useRef<TextInput>(null);
111
+ const [focused, setFocused] = useState(autoFocus);
112
+ const state = getState({ disabled, error });
98
113
 
99
- const blur = useCallback(() => {
100
- if (inputRef?.current) {
101
- inputRef.current.blur();
102
- setFocused(false);
103
- }
104
- }, []);
114
+ const focus = useCallback(() => {
115
+ if (inputRef?.current) {
116
+ inputRef.current.focus();
117
+ setFocused(true);
118
+ }
119
+ }, []);
105
120
 
106
- const changeText = useCallback((text: string) => {
107
- const pin = (text.match(/[0-9]/g) || []).join('');
108
- if (onChangeText) {
109
- onChangeText(pin);
110
- }
111
- if (pin.length === length && onFulfill) {
112
- onFulfill(pin);
113
- }
114
- }, []);
121
+ const blur = useCallback(() => {
122
+ if (inputRef?.current) {
123
+ inputRef.current.blur();
124
+ setFocused(false);
125
+ }
126
+ }, []);
115
127
 
116
- useEffect(() => {
117
- // Must run after animations for keyboard to automatically open
118
- if (autoFocus) {
119
- InteractionManager.runAfterInteractions(focus);
120
- }
121
- }, [inputRef]);
128
+ const changeText = useCallback(
129
+ (text: string) => {
130
+ const pin = (text.match(/[0-9]/g) || []).join('');
122
131
 
123
- return (
124
- <StyledWrapper style={style} testID={testID}>
125
- <StyledPinWrapper>
126
- {[...Array(length).keys()].map((index) => (
127
- <React.Fragment key={index}>
128
- {index !== 0 && <StyledSpacer />}
129
- <PinCell
130
- value={value.charAt(index)}
131
- secure={secure}
132
- focused={focused && index === value.length}
133
- state={state}
132
+ onChangeText?.(pin);
133
+
134
+ if (pin.length === length) {
135
+ onFulfill?.(pin);
136
+ }
137
+ },
138
+ [length, onChangeText, onFulfill]
139
+ );
140
+
141
+ useEffect(() => {
142
+ // Must run after animations for keyboard to automatically open
143
+ if (autoFocus) {
144
+ InteractionManager.runAfterInteractions(focus);
145
+ }
146
+ }, [inputRef]);
147
+
148
+ useImperativeHandle(ref, () => ({
149
+ focus,
150
+ blur,
151
+ }));
152
+
153
+ return (
154
+ <StyledWrapper style={style} testID={testID}>
155
+ <StyledPinWrapper>
156
+ {[...Array(length).keys()].map((index) => (
157
+ <React.Fragment key={index}>
158
+ {index !== 0 && <StyledSpacer />}
159
+ <PinCell
160
+ value={value.charAt(index)}
161
+ secure={secure}
162
+ focused={focused && index === value.length}
163
+ state={state}
164
+ />
165
+ </React.Fragment>
166
+ ))}
167
+ </StyledPinWrapper>
168
+ {state === 'error' && (
169
+ <StyledErrorContainer>
170
+ <Icon
171
+ icon="circle-info"
172
+ size="xsmall"
173
+ intent="danger"
174
+ testID="pin-error-icon"
134
175
  />
135
- </React.Fragment>
136
- ))}
137
- </StyledPinWrapper>
138
- {state === 'error' && (
139
- <StyledErrorContainer>
140
- <Icon
141
- icon="circle-info"
142
- size="xsmall"
143
- intent="danger"
144
- testID="pin-error-icon"
145
- />
146
- <StyledErrorMessage>{error}</StyledErrorMessage>
147
- </StyledErrorContainer>
148
- )}
149
- <StyledHiddenInput
150
- themePinLength={length}
151
- ref={inputRef}
152
- value={value}
153
- onChangeText={changeText}
154
- secureTextEntry={secure}
155
- editable={!disabled}
156
- autoFocus={autoFocus}
157
- onFocus={focus}
158
- onBlur={blur}
159
- maxLength={length}
160
- keyboardType="numeric"
161
- contextMenuHidden
162
- caretHidden
163
- pointerEvents="box-only"
164
- testID="pin-hidden-input"
165
- />
166
- </StyledWrapper>
167
- );
168
- }
176
+ <StyledErrorMessage>{error}</StyledErrorMessage>
177
+ </StyledErrorContainer>
178
+ )}
179
+ <StyledHiddenInput
180
+ themePinLength={length}
181
+ ref={inputRef}
182
+ value={value}
183
+ onChangeText={changeText}
184
+ secureTextEntry={secure}
185
+ editable={!disabled}
186
+ autoFocus={autoFocus}
187
+ onFocus={focus}
188
+ onBlur={blur}
189
+ maxLength={length}
190
+ keyboardType="numeric"
191
+ contextMenuHidden
192
+ caretHidden
193
+ pointerEvents="box-only"
194
+ testID="pin-hidden-input"
195
+ />
196
+ </StyledWrapper>
197
+ );
198
+ }
199
+ );
169
200
 
170
201
  export default PinInput;
@@ -16,8 +16,4 @@ declare const StyledFABText: import("@emotion/native").StyledComponent<import(".
16
16
  theme?: import("@emotion/react").Theme | undefined;
17
17
  as?: import("react").ElementType<any> | undefined;
18
18
  } & TextProps, {}, {}>;
19
- declare const StyledFABContainer: import("@emotion/native").StyledComponent<import("../Box").BoxProps & {
20
- theme?: import("@emotion/react").Theme | undefined;
21
- as?: import("react").ElementType<any> | undefined;
22
- }, {}, {}>;
23
- export { StyledFAB, StyledFABIcon, StyledFABText, StyledFABContainer };
19
+ export { StyledFAB, StyledFABIcon, StyledFABText };
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import type { StyleProp, ViewStyle } from 'react-native';
2
3
  import type { State } from './StyledPinInput';
3
4
  interface PinInputProps {
@@ -44,5 +45,15 @@ export declare function getState({ disabled, error, }: {
44
45
  disabled?: boolean;
45
46
  error?: string;
46
47
  }): State;
47
- declare function PinInput({ value, onChangeText, onFulfill, length, disabled, secure, autoFocus, error, style, testID, }: PinInputProps): JSX.Element;
48
+ export interface PinInputHandler {
49
+ /**
50
+ * focus into input
51
+ */
52
+ focus: () => void;
53
+ /**
54
+ * blur text input
55
+ */
56
+ blur: () => void;
57
+ }
58
+ declare const PinInput: React.ForwardRefExoticComponent<PinInputProps & React.RefAttributes<PinInputHandler>>;
48
59
  export default PinInput;