on bd7ed64 help sign in
bridge/src/form/Inputs.js
230 lines 5.0 kB history raw
1import React from 'react';
2import { Input, AccessoryIcon } from 'indigo-react';
3import { useField } from 'react-final-form';
5import {
6 convertToNumber,
7 buildFormatter,
8 downcase,
9 ensurePatFormat,
10 stripHexPrefix,
11 ensureHexPrefix,
12} from 'form/formatters';
13import { DEFAULT_HD_PATH } from 'lib/constants';
14import InputSigil from 'components/InputSigil';
15import { StatelessTextInput } from '@tlon/indigo-react';
17const PLACEHOLDER_POINT = '~sampel-ponnym';
18const PLACEHOLDER_HD_PATH = DEFAULT_HD_PATH;
19const PLACEHOLDER_MNEMONIC =
20 'example crew supreme gesture quantum web media hazard theory mercy wing kitten';
21export const PLACEHOLDER_TICKET = '~sampel-ticlyt-migfun-falmel';
22const PLACEHOLDER_PASSWORD = '••••••-••••••-••••••-••••••';
23const PLACEHOLDER_ADDRESS = '0x';
24const PLACEHOLDER_HEX = '0x';
25const PLACEHOLDER_PRIVATE_KEY =
26 'a44de2416ee6beb2f323fab48b432925c9785808d33a6ca6d7ba00b45e9370c3';
27const PLACEHOLDER_EMAIL = 'email@example.com';
29const formatPat = buildFormatter([downcase, ensurePatFormat]);
31export function TicketInput({ name, hidden, ...rest }) {
32 const {
33 meta: { valid, error, validating, touched, active },
34 } = useField(name, {
35 subscription: {
36 valid: true,
37 error: true,
38 validating: true,
39 touched: true,
40 active: true,
41 },
42 });
44 return (
45 <Input
46 type={hidden ? 'password' : 'text'}
47 name={name}
48 obscure={value => value.replace(/[^~-]+/g, '••••••')}
49 placeholder={hidden ? PLACEHOLDER_PASSWORD : PLACEHOLDER_TICKET}
50 autoCapitalize="none"
51 autoCorrect="off"
52 accessory={
53 touched && !active && error ? (
54 <AccessoryIcon.Failure />
55 ) : validating ? (
56 <AccessoryIcon.Pending />
57 ) : valid ? (
58 <AccessoryIcon.Success />
59 ) : null
60 }
61 config={{ parse: formatPat }}
62 mono
63 {...rest}
64 />
65 );
68export function MnemonicInput({ ...rest }) {
69 return (
70 <Input
71 type="textarea"
72 placeholder={PLACEHOLDER_MNEMONIC}
73 autoCapitalize="none"
74 autoComplete="off"
75 mono
76 {...rest}
77 />
78 );
81export function HdPathInput({ ...rest }) {
82 return (
83 <Input
84 type="text"
85 placeholder={PLACEHOLDER_HD_PATH}
86 autoCapitalize="none"
87 autoComplete="off"
88 autoCorrect="off"
89 {...rest}
90 />
91 );
94export function PassphraseInput({ ...rest }) {
95 return (
96 <Input
97 type="password"
98 placeholder="Passphrase"
99 autoCapitalize="none"
100 autoCorrect="off"
101 {...rest}
102 />
103 );
106export function PointInput({ name, size = 4, ...rest }) {
107 const {
108 input: { value },
109 meta: { active, valid, error },
110 } = useField(name, {
111 subscription: { value: true, active: true, valid: true, error: true },
112 });
114 return (
115 <Input
116 type="text"
117 label="Urbit ID"
118 name={name}
119 placeholder={PLACEHOLDER_POINT}
120 autoCapitalize="none"
121 autoComplete="off"
122 autoCorrect="off"
123 accessory={
124 value ? (
125 <InputSigil
126 patp={value}
127 size={44}
128 valid={valid}
129 error={error}
130 active={active}
131 />
132 ) : null
133 }
134 config={{ parse: formatPat }}
135 mono
136 {...rest}
137 />
138 );
141export function HexInput({ ...rest }) {
142 return (
143 <Input
144 type="text"
145 placeholder={PLACEHOLDER_HEX}
146 autoCapitalize="none"
147 autoComplete="off"
148 autoCorrect="off"
149 mono
150 config={{ parse: ensureHexPrefix }}
151 {...rest}
152 />
153 );
156export function PrivateKeyInput({ ...rest }) {
157 return (
158 <HexInput
159 type="password"
160 placeholder={PLACEHOLDER_PRIVATE_KEY}
161 config={{ parse: stripHexPrefix }}
162 {...rest}
163 />
164 );
167export function PsbtInput({ ...rest }) {
168 return (
169 <HexInput
170 type="text"
171 placeholder=""
172 config={{ parse: stripHexPrefix }}
173 {...rest}
174 />
175 );
178export function AddressInput({ ...rest }) {
179 return (
180 <Input
181 type="text"
182 placeholder={PLACEHOLDER_ADDRESS}
183 autoCapitalize="none"
184 autoCorrect="off"
185 mono
186 {...rest}
187 />
188 );
191export function NumberInput({ ...rest }) {
192 return (
193 <Input
194 type="number"
195 label="Number"
196 config={{ format: convertToNumber }}
197 {...rest}
198 />
199 );
202export function EmailInput({ ...rest }) {
203 return (
204 <Input
205 type="email"
206 placeholder={PLACEHOLDER_EMAIL}
207 autoCapitalize="none"
208 {...rest}
209 />
210 );
213export function TicketSegmentInput({ name, ...rest }) {
214 const { input } = useField(name);
216 return (
217 <StatelessTextInput
218 autoCapitalize="none"
219 autoCorrect="off"
220 type="text"
221 maxLength="6"
222 {...input}
223 {...rest}
224 />
225 );
228export const HiddenInput = ({ ...rest }) => {
229 return <StatelessTextInput type="hidden" {...rest} />;
230};