@himakarinv/nativex 1.0.0

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.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/images.d.ts +14 -0
  4. package/index.js +8 -0
  5. package/nativewind-preset.js +18 -0
  6. package/package.json +120 -0
  7. package/src/assets/branding/logo.jpg +0 -0
  8. package/src/assets/branding/softech-logo.png +0 -0
  9. package/src/assets/icons/2-layers.svg +3 -0
  10. package/src/assets/icons/Forbidden.svg +211 -0
  11. package/src/assets/icons/Internal-server-error.svg +119 -0
  12. package/src/assets/icons/Log-out-nav.svg +4 -0
  13. package/src/assets/icons/Not-Found.svg +282 -0
  14. package/src/assets/icons/Unauthorized.svg +314 -0
  15. package/src/assets/icons/User-Frame.svg +5 -0
  16. package/src/assets/icons/alert.svg +4 -0
  17. package/src/assets/icons/arrow-right.svg +3 -0
  18. package/src/assets/icons/avatar-female.svg +10 -0
  19. package/src/assets/icons/avatar-male.svg +10 -0
  20. package/src/assets/icons/bell.svg +3 -0
  21. package/src/assets/icons/calendar-event.svg +11 -0
  22. package/src/assets/icons/calendar.svg +6 -0
  23. package/src/assets/icons/card.svg +4 -0
  24. package/src/assets/icons/caret-right.svg +3 -0
  25. package/src/assets/icons/chat.svg +11 -0
  26. package/src/assets/icons/check.svg +3 -0
  27. package/src/assets/icons/checkbox-minus.svg +3 -0
  28. package/src/assets/icons/checkmark.svg +3 -0
  29. package/src/assets/icons/chevron-down.svg +3 -0
  30. package/src/assets/icons/chevron-left.svg +9 -0
  31. package/src/assets/icons/chevron-right.svg +9 -0
  32. package/src/assets/icons/circle-radio-active.svg +10 -0
  33. package/src/assets/icons/circle-radio.svg +10 -0
  34. package/src/assets/icons/clock.svg +3 -0
  35. package/src/assets/icons/close.svg +3 -0
  36. package/src/assets/icons/code.svg +3 -0
  37. package/src/assets/icons/country.svg +20 -0
  38. package/src/assets/icons/dot.svg +3 -0
  39. package/src/assets/icons/download.svg +1 -0
  40. package/src/assets/icons/dropdown-arrow.svg +3 -0
  41. package/src/assets/icons/dropdown-avatar.svg +3 -0
  42. package/src/assets/icons/email.svg +3 -0
  43. package/src/assets/icons/error.svg +3 -0
  44. package/src/assets/icons/eye-off.svg +1 -0
  45. package/src/assets/icons/eye.svg +1 -0
  46. package/src/assets/icons/hashtag-icon.svg +3 -0
  47. package/src/assets/icons/help-circle.svg +10 -0
  48. package/src/assets/icons/help.svg +4 -0
  49. package/src/assets/icons/hide-checkbox.svg +3 -0
  50. package/src/assets/icons/home-smile.svg +3 -0
  51. package/src/assets/icons/home.svg +3 -0
  52. package/src/assets/icons/info.svg +5 -0
  53. package/src/assets/icons/left-arrow.svg +3 -0
  54. package/src/assets/icons/log-out.svg +3 -0
  55. package/src/assets/icons/notification-box.svg +4 -0
  56. package/src/assets/icons/pencil.svg +1 -0
  57. package/src/assets/icons/plus.svg +3 -0
  58. package/src/assets/icons/radio-dot.svg +3 -0
  59. package/src/assets/icons/right-arrow.svg +3 -0
  60. package/src/assets/icons/search.svg +3 -0
  61. package/src/assets/icons/settings.svg +11 -0
  62. package/src/assets/icons/slack.svg +17 -0
  63. package/src/assets/icons/slash.svg +3 -0
  64. package/src/assets/icons/success.svg +3 -0
  65. package/src/assets/icons/successicon.svg +5 -0
  66. package/src/assets/icons/three-dot-vertical.svg +5 -0
  67. package/src/assets/icons/trash.svg +1 -0
  68. package/src/assets/icons/trend-down-01.svg +3 -0
  69. package/src/assets/icons/trend-up-01.svg +3 -0
  70. package/src/assets/icons/up-arrow.svg +3 -0
  71. package/src/assets/icons/user-plus.svg +10 -0
  72. package/src/assets/icons/user.svg +3 -0
  73. package/src/assets/icons/users.svg +3 -0
  74. package/src/assets/icons/vertical-dots-true-icon.svg +5 -0
  75. package/src/assets/icons/vertical-line.svg +3 -0
  76. package/src/assets/icons/vertical-three-dots-icon.svg +5 -0
  77. package/src/assets/icons/warning.svg +3 -0
  78. package/src/assets/icons/zap.svg +3 -0
  79. package/src/components/ActionsMenu/ActionsMenu.tsx +314 -0
  80. package/src/components/ActionsMenu/index.ts +2 -0
  81. package/src/components/Alert/Alert.tsx +291 -0
  82. package/src/components/Alert/index.ts +2 -0
  83. package/src/components/Badge/Badge.tsx +230 -0
  84. package/src/components/Badge/index.ts +2 -0
  85. package/src/components/Breadcrumb/Breadcrumb.tsx +364 -0
  86. package/src/components/Breadcrumb/index.ts +7 -0
  87. package/src/components/Button/Button.tsx +584 -0
  88. package/src/components/Button/index.ts +9 -0
  89. package/src/components/Checkbox/Checkbox.tsx +336 -0
  90. package/src/components/Checkbox/index.ts +2 -0
  91. package/src/components/CreatePassword/CreatePassword.tsx +161 -0
  92. package/src/components/CreatePassword/index.ts +2 -0
  93. package/src/components/DataTable/DataTable.tsx +822 -0
  94. package/src/components/DataTable/index.ts +10 -0
  95. package/src/components/Datepicker/Datepicker.tsx +797 -0
  96. package/src/components/Datepicker/index.ts +2 -0
  97. package/src/components/Dropdown/Dropdown.tsx +277 -0
  98. package/src/components/Dropdown/index.ts +7 -0
  99. package/src/components/DropdownMenu/DropdownMenu.tsx +471 -0
  100. package/src/components/DropdownMenu/index.ts +11 -0
  101. package/src/components/DynamicForm/DynamicForm.tsx +741 -0
  102. package/src/components/DynamicForm/index.ts +13 -0
  103. package/src/components/ErrorPages/ErrorPages.tsx +135 -0
  104. package/src/components/ErrorPages/index.ts +2 -0
  105. package/src/components/ForgotPassword/ForgotPassword.tsx +121 -0
  106. package/src/components/ForgotPassword/index.ts +2 -0
  107. package/src/components/HintError/HintError.tsx +37 -0
  108. package/src/components/HintError/index.ts +2 -0
  109. package/src/components/Icon/Icon.tsx +43 -0
  110. package/src/components/Icon/icon-registry.ts +227 -0
  111. package/src/components/Icon/index.ts +3 -0
  112. package/src/components/InputDropdown/InputDropdown.tsx +662 -0
  113. package/src/components/InputDropdown/index.ts +9 -0
  114. package/src/components/InputField/InputField.tsx +527 -0
  115. package/src/components/InputField/index.ts +2 -0
  116. package/src/components/Label/Label.tsx +88 -0
  117. package/src/components/Label/index.ts +2 -0
  118. package/src/components/LoginForm/LoginForm.tsx +158 -0
  119. package/src/components/LoginForm/index.ts +2 -0
  120. package/src/components/LoginShell/LoginShell.tsx +97 -0
  121. package/src/components/LoginShell/RoleCard.tsx +24 -0
  122. package/src/components/LoginShell/SoftechLogo.tsx +24 -0
  123. package/src/components/LoginShell/branding-assets.ts +2 -0
  124. package/src/components/LoginShell/index.ts +20 -0
  125. package/src/components/LoginShell/login-copy.ts +45 -0
  126. package/src/components/LoginShell/loginPageStyles.ts +210 -0
  127. package/src/components/Modals/Modals.tsx +313 -0
  128. package/src/components/Modals/index.ts +2 -0
  129. package/src/components/Offcanvas/Offcanvas.tsx +404 -0
  130. package/src/components/Offcanvas/index.ts +13 -0
  131. package/src/components/PageHeader/PageHeader.tsx +128 -0
  132. package/src/components/PageHeader/index.ts +2 -0
  133. package/src/components/Pagination/Pagination.tsx +540 -0
  134. package/src/components/Pagination/index.ts +8 -0
  135. package/src/components/ResetPassword/ResetPassword.tsx +172 -0
  136. package/src/components/ResetPassword/index.ts +2 -0
  137. package/src/components/RoleSelection/RoleSelection.tsx +111 -0
  138. package/src/components/RoleSelection/index.ts +2 -0
  139. package/src/components/SendOtp/SendOtp.tsx +149 -0
  140. package/src/components/SendOtp/index.ts +2 -0
  141. package/src/components/Sidenavbar/Sidenavbar.tsx +358 -0
  142. package/src/components/Sidenavbar/index.ts +2 -0
  143. package/src/components/StatCard/StatCard.tsx +393 -0
  144. package/src/components/StatCard/index.ts +6 -0
  145. package/src/components/Tabs/Tabs.tsx +239 -0
  146. package/src/components/Tabs/index.ts +2 -0
  147. package/src/components/Textarea/Textarea.tsx +217 -0
  148. package/src/components/Textarea/index.ts +2 -0
  149. package/src/components/Timepicker/Timepicker.tsx +384 -0
  150. package/src/components/Timepicker/index.ts +2 -0
  151. package/src/components/Toast/Toast.tsx +278 -0
  152. package/src/components/Toast/index.ts +2 -0
  153. package/src/components/Toggle/Toggle.tsx +296 -0
  154. package/src/components/Toggle/index.ts +2 -0
  155. package/src/components/Typeahead/Typeahead.tsx +521 -0
  156. package/src/components/Typeahead/index.ts +2 -0
  157. package/src/components/Verification/Verification.tsx +374 -0
  158. package/src/components/Verification/index.ts +2 -0
  159. package/src/index.ts +39 -0
  160. package/src/theme/borders.ts +19 -0
  161. package/src/theme/button.ts +41 -0
  162. package/src/theme/colors.ts +273 -0
  163. package/src/theme/index.ts +14 -0
  164. package/src/theme/nativewind-theme.js +182 -0
  165. package/src/theme/radius.ts +12 -0
  166. package/src/theme/shadows.ts +40 -0
  167. package/src/theme/spacing.ts +18 -0
  168. package/src/theme/typography.ts +35 -0
  169. package/src/utils/a11y.ts +21 -0
  170. package/svg.d.ts +7 -0
@@ -0,0 +1,172 @@
1
+ import { useState } from 'react';
2
+ import { Text, View, type StyleProp, type ViewStyle } from 'react-native';
3
+
4
+ import { Button, ButtonSize, ButtonVariant, IconPosition } from '../Button';
5
+ import { IconName } from '../Icon';
6
+ import { InputField, InputState } from '../InputField';
7
+ import { LoginShell } from '../LoginShell/LoginShell';
8
+ import { RoleCard } from '../LoginShell/RoleCard';
9
+ import {
10
+ DEFAULT_BACK_AND_SELECT_ROLE,
11
+ DEFAULT_ROLE_DESCRIPTION,
12
+ DEFAULT_ROLE_TITLE,
13
+ } from '../LoginShell/login-copy';
14
+ import { loginPageStyles as styles } from '../LoginShell/loginPageStyles';
15
+
16
+ export type ResetPasswordProps = {
17
+ brandingAsideAriaLabel?: string;
18
+ logoSrc?: string;
19
+ logoAlt?: string;
20
+ quoteText?: string;
21
+ quoteAttribution?: string;
22
+ backButtonLabel?: string;
23
+ roleTitle?: string;
24
+ roleDescription?: string;
25
+ pageTitle?: string;
26
+ currentPasswordLabel?: string;
27
+ currentPasswordPlaceholder?: string;
28
+ currentPasswordHint?: string;
29
+ newPasswordLabel?: string;
30
+ newPasswordPlaceholder?: string;
31
+ newPasswordHint?: string;
32
+ confirmPasswordLabel?: string;
33
+ confirmPasswordPlaceholder?: string;
34
+ confirmPasswordHint?: string;
35
+ submitButtonLabel?: string;
36
+ minLengthPasswordError?: string;
37
+ passwordMismatchError?: string;
38
+ onBack?: () => void;
39
+ onSubmit?: (value: {
40
+ currentPassword: string;
41
+ newPassword: string;
42
+ confirmPassword: string;
43
+ }) => void;
44
+ style?: StyleProp<ViewStyle>;
45
+ };
46
+
47
+ export function ResetPassword({
48
+ brandingAsideAriaLabel,
49
+ logoSrc,
50
+ logoAlt,
51
+ quoteText,
52
+ quoteAttribution,
53
+ backButtonLabel = DEFAULT_BACK_AND_SELECT_ROLE,
54
+ roleTitle = DEFAULT_ROLE_TITLE,
55
+ roleDescription = DEFAULT_ROLE_DESCRIPTION,
56
+ pageTitle = 'Reset Password',
57
+ currentPasswordLabel = 'Current Password',
58
+ currentPasswordPlaceholder = 'Enter your current password',
59
+ currentPasswordHint = '',
60
+ newPasswordLabel = 'New Password',
61
+ newPasswordPlaceholder = 'Enter your new password',
62
+ newPasswordHint = '',
63
+ confirmPasswordLabel = 'Confirm Password',
64
+ confirmPasswordPlaceholder = 'Confirm your new password',
65
+ confirmPasswordHint = '',
66
+ submitButtonLabel = 'Reset Password',
67
+ minLengthPasswordError = 'Use at least 8 characters.',
68
+ passwordMismatchError = 'Passwords do not match.',
69
+ onBack,
70
+ onSubmit,
71
+ style,
72
+ }: ResetPasswordProps) {
73
+ const [currentPassword, setCurrentPassword] = useState('');
74
+ const [newPassword, setNewPassword] = useState('');
75
+ const [confirmPassword, setConfirmPassword] = useState('');
76
+ const [submitted, setSubmitted] = useState(false);
77
+
78
+ const newPasswordError =
79
+ submitted && newPassword.length < 8 ? minLengthPasswordError : '';
80
+ const confirmError =
81
+ submitted && confirmPassword && confirmPassword !== newPassword
82
+ ? passwordMismatchError
83
+ : submitted && !confirmPassword.trim()
84
+ ? passwordMismatchError
85
+ : '';
86
+
87
+ function submit() {
88
+ setSubmitted(true);
89
+ if (
90
+ !currentPassword.trim() ||
91
+ newPassword.length < 8 ||
92
+ !confirmPassword.trim() ||
93
+ confirmPassword !== newPassword
94
+ ) {
95
+ return;
96
+ }
97
+ onSubmit?.({ currentPassword, newPassword, confirmPassword });
98
+ }
99
+
100
+ return (
101
+ <LoginShell
102
+ brandingAsideAriaLabel={brandingAsideAriaLabel}
103
+ logoSrc={logoSrc}
104
+ logoAlt={logoAlt}
105
+ quoteText={quoteText}
106
+ quoteAttribution={quoteAttribution}
107
+ style={style}>
108
+ <View style={styles.form}>
109
+ <View style={styles.backWrap}>
110
+ <Button
111
+ variant={ButtonVariant.LinkGray}
112
+ size={ButtonSize.Small}
113
+ iconPosition={IconPosition.Before}
114
+ iconName={IconName.ChevronLeft}
115
+ iconDecorative
116
+ label={backButtonLabel}
117
+ onPress={onBack}
118
+ />
119
+ </View>
120
+ <RoleCard title={roleTitle} description={roleDescription} />
121
+ <Text accessibilityRole="header" style={[styles.pageTitle, styles.pageTitleVerify]}>
122
+ {pageTitle}
123
+ </Text>
124
+ <View style={styles.fields}>
125
+ <InputField
126
+ fullWidth
127
+ fieldType="password"
128
+ label={currentPasswordLabel}
129
+ placeholder={currentPasswordPlaceholder}
130
+ hint={currentPasswordHint}
131
+ value={currentPassword}
132
+ onValueChange={setCurrentPassword}
133
+ autoComplete="password"
134
+ />
135
+ <InputField
136
+ fullWidth
137
+ fieldType="password"
138
+ label={newPasswordLabel}
139
+ placeholder={newPasswordPlaceholder}
140
+ hint={newPasswordError ? '' : newPasswordHint}
141
+ value={newPassword}
142
+ error={newPasswordError}
143
+ state={newPasswordError ? InputState.Error : InputState.Default}
144
+ onValueChange={setNewPassword}
145
+ autoComplete="password"
146
+ />
147
+ <InputField
148
+ fullWidth
149
+ fieldType="password"
150
+ label={confirmPasswordLabel}
151
+ placeholder={confirmPasswordPlaceholder}
152
+ hint={confirmError ? '' : confirmPasswordHint}
153
+ value={confirmPassword}
154
+ error={confirmError}
155
+ state={confirmError ? InputState.Error : InputState.Default}
156
+ onValueChange={setConfirmPassword}
157
+ autoComplete="password"
158
+ />
159
+ <View style={styles.submit}>
160
+ <Button
161
+ fullWidth
162
+ variant={ButtonVariant.Primary}
163
+ size={ButtonSize.Large}
164
+ label={submitButtonLabel}
165
+ onPress={submit}
166
+ />
167
+ </View>
168
+ </View>
169
+ </View>
170
+ </LoginShell>
171
+ );
172
+ }
@@ -0,0 +1,2 @@
1
+ export { ResetPassword } from './ResetPassword';
2
+ export type { ResetPasswordProps } from './ResetPassword';
@@ -0,0 +1,111 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { Pressable, Text, View, type StyleProp, type ViewStyle } from 'react-native';
3
+
4
+ import { colors, spacing } from '../../theme';
5
+ import { Button, ButtonSize, ButtonVariant, IconPosition } from '../Button';
6
+ import { Icon, IconName } from '../Icon';
7
+ import { LoginShell } from '../LoginShell/LoginShell';
8
+ import { DEFAULT_ROLES, type LoginRoleOption } from '../LoginShell/login-copy';
9
+ import { loginPageStyles as styles } from '../LoginShell/loginPageStyles';
10
+
11
+ export type RoleSelectionProps = {
12
+ brandingAsideAriaLabel?: string;
13
+ logoSrc?: string;
14
+ logoAlt?: string;
15
+ quoteText?: string;
16
+ quoteAttribution?: string;
17
+ backButtonLabel?: string;
18
+ roleGroupAriaLabel?: string;
19
+ roles?: LoginRoleOption[];
20
+ selectedRoleId?: string;
21
+ onBack?: () => void;
22
+ onRoleSelected?: (id: string) => void;
23
+ style?: StyleProp<ViewStyle>;
24
+ };
25
+
26
+ export function RoleSelection({
27
+ brandingAsideAriaLabel,
28
+ logoSrc,
29
+ logoAlt,
30
+ quoteText,
31
+ quoteAttribution,
32
+ backButtonLabel = '',
33
+ roleGroupAriaLabel = 'Select your role',
34
+ roles = DEFAULT_ROLES,
35
+ selectedRoleId,
36
+ onBack,
37
+ onRoleSelected,
38
+ style,
39
+ }: RoleSelectionProps) {
40
+ const [selectedId, setSelectedId] = useState(selectedRoleId ?? '');
41
+
42
+ useEffect(() => {
43
+ if (selectedRoleId !== undefined) {
44
+ setSelectedId(selectedRoleId);
45
+ }
46
+ }, [selectedRoleId]);
47
+
48
+ function selectRole(id: string) {
49
+ setSelectedId(id);
50
+ onRoleSelected?.(id);
51
+ }
52
+
53
+ return (
54
+ <LoginShell
55
+ brandingAsideAriaLabel={brandingAsideAriaLabel}
56
+ logoSrc={logoSrc}
57
+ logoAlt={logoAlt}
58
+ quoteText={quoteText}
59
+ quoteAttribution={quoteAttribution}
60
+ style={style}>
61
+ <View style={styles.form}>
62
+ {backButtonLabel.trim() ? (
63
+ <View style={styles.backWrap}>
64
+ <Button
65
+ variant={ButtonVariant.LinkGray}
66
+ size={ButtonSize.Small}
67
+ iconPosition={IconPosition.Before}
68
+ iconName={IconName.ChevronLeft}
69
+ iconDecorative
70
+ label={backButtonLabel}
71
+ onPress={onBack}
72
+ />
73
+ </View>
74
+ ) : null}
75
+
76
+ <View accessibilityLabel={roleGroupAriaLabel} style={styles.roleList}>
77
+ {roles.map((role) => {
78
+ const selected = selectedId === role.id;
79
+ return (
80
+ <Pressable
81
+ key={role.id}
82
+ accessibilityRole="button"
83
+ accessibilityState={{ selected }}
84
+ accessibilityLabel={`${role.title}. ${role.description}`}
85
+ onPress={() => selectRole(role.id)}
86
+ style={styles.roleOption}>
87
+ <View style={styles.roleOptionIconWrap}>
88
+ <View style={styles.roleOptionIconInner}>
89
+ <Icon name={IconName.UserFrame} size={spacing['2xl']} decorative />
90
+ </View>
91
+ </View>
92
+ <View style={styles.roleOptionText}>
93
+ <Text style={styles.roleOptionTitle}>{role.title}</Text>
94
+ <Text style={styles.roleOptionDesc}>{role.description}</Text>
95
+ </View>
96
+ {selected ? (
97
+ <Icon
98
+ name={IconName.Checkmark}
99
+ size={spacing.lg}
100
+ color={colors.login.roleCardBorder}
101
+ decorative
102
+ />
103
+ ) : null}
104
+ </Pressable>
105
+ );
106
+ })}
107
+ </View>
108
+ </View>
109
+ </LoginShell>
110
+ );
111
+ }
@@ -0,0 +1,2 @@
1
+ export { RoleSelection } from './RoleSelection';
2
+ export type { RoleSelectionProps } from './RoleSelection';
@@ -0,0 +1,149 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { Text, View, type StyleProp, type ViewStyle } from 'react-native';
3
+
4
+ import { Button, ButtonSize, ButtonVariant, IconPosition } from '../Button';
5
+ import { IconName } from '../Icon';
6
+ import { InputField, InputState, InputVariant } from '../InputField';
7
+ import { LoginShell } from '../LoginShell/LoginShell';
8
+ import { RoleCard } from '../LoginShell/RoleCard';
9
+ import {
10
+ DEFAULT_BACK_AND_SELECT_ROLE,
11
+ DEFAULT_ROLE_DESCRIPTION,
12
+ DEFAULT_ROLE_TITLE,
13
+ isValidEmail,
14
+ } from '../LoginShell/login-copy';
15
+ import { loginPageStyles as styles } from '../LoginShell/loginPageStyles';
16
+ import { Verification, VerificationDigits, VerificationSize } from '../Verification';
17
+
18
+ export type SendOtpProps = {
19
+ brandingAsideAriaLabel?: string;
20
+ logoSrc?: string;
21
+ logoAlt?: string;
22
+ quoteText?: string;
23
+ quoteAttribution?: string;
24
+ backButtonLabel?: string;
25
+ roleTitle?: string;
26
+ roleDescription?: string;
27
+ pageTitle?: string;
28
+ emailLabel?: string;
29
+ emailPlaceholder?: string;
30
+ emailHint?: string;
31
+ emailInitialValue?: string;
32
+ otpVerificationLabel?: string;
33
+ resendPrefixText?: string;
34
+ resendButtonLabel?: string;
35
+ submitButtonLabel?: string;
36
+ onBack?: () => void;
37
+ onResendOtp?: () => void;
38
+ onSubmit?: (value: { email: string; code: string }) => void;
39
+ style?: StyleProp<ViewStyle>;
40
+ };
41
+
42
+ export function SendOtp({
43
+ brandingAsideAriaLabel,
44
+ logoSrc,
45
+ logoAlt,
46
+ quoteText,
47
+ quoteAttribution,
48
+ backButtonLabel = DEFAULT_BACK_AND_SELECT_ROLE,
49
+ roleTitle = DEFAULT_ROLE_TITLE,
50
+ roleDescription = DEFAULT_ROLE_DESCRIPTION,
51
+ pageTitle = 'Verify your Email',
52
+ emailLabel = 'What is your e-mail?',
53
+ emailPlaceholder = 'Alex.johnson@gmail.com',
54
+ emailHint = '',
55
+ emailInitialValue = '',
56
+ otpVerificationLabel = 'Enter the verification code',
57
+ resendPrefixText = "Didn't get a Code?",
58
+ resendButtonLabel = 'Click to resend',
59
+ submitButtonLabel = 'Confirm & Reset Password',
60
+ onBack,
61
+ onResendOtp,
62
+ onSubmit,
63
+ style,
64
+ }: SendOtpProps) {
65
+ const [email, setEmail] = useState(emailInitialValue);
66
+ const [code, setCode] = useState('');
67
+ const [submitted, setSubmitted] = useState(false);
68
+
69
+ useEffect(() => {
70
+ setEmail(emailInitialValue);
71
+ }, [emailInitialValue]);
72
+
73
+ const emailError = submitted && !isValidEmail(email) ? 'Enter a valid email address.' : '';
74
+
75
+ function submit() {
76
+ setSubmitted(true);
77
+ if (!isValidEmail(email)) {
78
+ return;
79
+ }
80
+ onSubmit?.({ email: email.trim(), code });
81
+ }
82
+
83
+ return (
84
+ <LoginShell
85
+ brandingAsideAriaLabel={brandingAsideAriaLabel}
86
+ logoSrc={logoSrc}
87
+ logoAlt={logoAlt}
88
+ quoteText={quoteText}
89
+ quoteAttribution={quoteAttribution}
90
+ style={style}>
91
+ <View style={styles.form}>
92
+ <View style={styles.backWrap}>
93
+ <Button
94
+ variant={ButtonVariant.LinkGray}
95
+ size={ButtonSize.Small}
96
+ iconPosition={IconPosition.Before}
97
+ iconName={IconName.ChevronLeft}
98
+ iconDecorative
99
+ label={backButtonLabel}
100
+ onPress={onBack}
101
+ />
102
+ </View>
103
+ <RoleCard title={roleTitle} description={roleDescription} />
104
+ <Text accessibilityRole="header" style={[styles.pageTitle, styles.pageTitleVerify]}>
105
+ {pageTitle}
106
+ </Text>
107
+ <View style={styles.fields}>
108
+ <InputField
109
+ fullWidth
110
+ variant={InputVariant.Email}
111
+ label={emailLabel}
112
+ placeholder={emailPlaceholder}
113
+ hint={emailError ? '' : emailHint}
114
+ value={email}
115
+ error={emailError}
116
+ state={emailError ? InputState.Error : InputState.Default}
117
+ onValueChange={setEmail}
118
+ autoComplete="email"
119
+ inputType="email"
120
+ />
121
+ <Verification
122
+ digits={VerificationDigits.Four}
123
+ size={VerificationSize.Medium}
124
+ label={otpVerificationLabel}
125
+ onValueChange={setCode}
126
+ />
127
+ <View style={styles.inlineRow}>
128
+ <Text style={styles.inlinePrefix}>{resendPrefixText}</Text>
129
+ <Button
130
+ variant={ButtonVariant.LinkPrimary}
131
+ size={ButtonSize.Small}
132
+ label={resendButtonLabel}
133
+ onPress={onResendOtp}
134
+ />
135
+ </View>
136
+ <View style={styles.submit}>
137
+ <Button
138
+ fullWidth
139
+ variant={ButtonVariant.Primary}
140
+ size={ButtonSize.Large}
141
+ label={submitButtonLabel}
142
+ onPress={submit}
143
+ />
144
+ </View>
145
+ </View>
146
+ </View>
147
+ </LoginShell>
148
+ );
149
+ }
@@ -0,0 +1,2 @@
1
+ export { SendOtp } from './SendOtp';
2
+ export type { SendOtpProps } from './SendOtp';