panelui-native 0.14.0 → 0.19.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.
- package/README.md +2 -0
- package/lib/module/components/bottom-sheet/index.js +38 -10
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/checkbox/index.js +24 -11
- package/lib/module/components/checkbox/index.js.map +1 -1
- package/lib/module/components/direction/index.js +86 -0
- package/lib/module/components/direction/index.js.map +1 -0
- package/lib/module/components/field/index.js +337 -0
- package/lib/module/components/field/index.js.map +1 -0
- package/lib/module/components/flow/flow-paths.js +378 -0
- package/lib/module/components/flow/flow-paths.js.map +1 -0
- package/lib/module/components/flow/index.js +1598 -0
- package/lib/module/components/flow/index.js.map +1 -0
- package/lib/module/components/form/index.js +77 -0
- package/lib/module/components/form/index.js.map +1 -0
- package/lib/module/components/form/use-field.js +50 -0
- package/lib/module/components/form/use-field.js.map +1 -0
- package/lib/module/components/form/use-form.js +217 -0
- package/lib/module/components/form/use-form.js.map +1 -0
- package/lib/module/components/frame/index.js +124 -22
- package/lib/module/components/frame/index.js.map +1 -1
- package/lib/module/components/message/index.js +16 -1
- package/lib/module/components/message/index.js.map +1 -1
- package/lib/module/components/otp-input/index.js +303 -0
- package/lib/module/components/otp-input/index.js.map +1 -0
- package/lib/module/components/signature/index.js +500 -0
- package/lib/module/components/signature/index.js.map +1 -0
- package/lib/module/components/soundwave/index.js +813 -0
- package/lib/module/components/soundwave/index.js.map +1 -0
- package/lib/module/components/typography/index.js +196 -5
- package/lib/module/components/typography/index.js.map +1 -1
- package/lib/module/icons/index.js +287 -0
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +8 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts +15 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/checkbox/index.d.ts +8 -0
- package/lib/typescript/src/components/checkbox/index.d.ts.map +1 -1
- package/lib/typescript/src/components/direction/index.d.ts +64 -0
- package/lib/typescript/src/components/direction/index.d.ts.map +1 -0
- package/lib/typescript/src/components/field/index.d.ts +94 -0
- package/lib/typescript/src/components/field/index.d.ts.map +1 -0
- package/lib/typescript/src/components/flow/flow-paths.d.ts +89 -0
- package/lib/typescript/src/components/flow/flow-paths.d.ts.map +1 -0
- package/lib/typescript/src/components/flow/index.d.ts +310 -0
- package/lib/typescript/src/components/flow/index.d.ts.map +1 -0
- package/lib/typescript/src/components/form/index.d.ts +64 -0
- package/lib/typescript/src/components/form/index.d.ts.map +1 -0
- package/lib/typescript/src/components/form/use-field.d.ts +16 -0
- package/lib/typescript/src/components/form/use-field.d.ts.map +1 -0
- package/lib/typescript/src/components/form/use-form.d.ts +37 -0
- package/lib/typescript/src/components/form/use-form.d.ts.map +1 -0
- package/lib/typescript/src/components/frame/index.d.ts +39 -2
- package/lib/typescript/src/components/frame/index.d.ts.map +1 -1
- package/lib/typescript/src/components/message/index.d.ts.map +1 -1
- package/lib/typescript/src/components/otp-input/index.d.ts +141 -0
- package/lib/typescript/src/components/otp-input/index.d.ts.map +1 -0
- package/lib/typescript/src/components/signature/index.d.ts +254 -0
- package/lib/typescript/src/components/signature/index.d.ts.map +1 -0
- package/lib/typescript/src/components/soundwave/index.d.ts +91 -0
- package/lib/typescript/src/components/soundwave/index.d.ts.map +1 -0
- package/lib/typescript/src/components/typography/index.d.ts +154 -1
- package/lib/typescript/src/components/typography/index.d.ts.map +1 -1
- package/lib/typescript/src/icons/index.d.ts +23 -0
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +9 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +9 -1
- package/src/components/bottom-sheet/index.tsx +50 -12
- package/src/components/checkbox/index.tsx +40 -12
- package/src/components/direction/index.tsx +90 -0
- package/src/components/field/index.tsx +329 -0
- package/src/components/flow/flow-paths.ts +348 -0
- package/src/components/flow/index.tsx +1924 -0
- package/src/components/form/index.tsx +85 -0
- package/src/components/form/use-field.ts +65 -0
- package/src/components/form/use-form.ts +252 -0
- package/src/components/frame/index.tsx +162 -14
- package/src/components/message/index.tsx +17 -1
- package/src/components/otp-input/index.tsx +396 -0
- package/src/components/signature/index.tsx +681 -0
- package/src/components/soundwave/index.tsx +1029 -0
- package/src/components/typography/index.tsx +231 -10
- package/src/icons/index.tsx +195 -0
- package/src/index.ts +87 -0
|
@@ -23,8 +23,14 @@
|
|
|
23
23
|
* <Frame.Action>All agents under 25% token limit</Frame.Action>
|
|
24
24
|
* </Frame.Header>
|
|
25
25
|
* <Frame.Panel>
|
|
26
|
-
* <Frame.Row
|
|
27
|
-
*
|
|
26
|
+
* <Frame.Row>
|
|
27
|
+
* <Frame.Media><PackageIcon /></Frame.Media>
|
|
28
|
+
* <Frame.Content>
|
|
29
|
+
* <Frame.Title>opus-4.6</Frame.Title>
|
|
30
|
+
* <Frame.Description>Indexing the repository</Frame.Description>
|
|
31
|
+
* </Frame.Content>
|
|
32
|
+
* <Frame.Actions><Chip>Running</Chip></Frame.Actions>
|
|
33
|
+
* </Frame.Row>
|
|
28
34
|
* </Frame.Panel>
|
|
29
35
|
* </Frame>
|
|
30
36
|
* ```
|
|
@@ -32,8 +38,16 @@
|
|
|
32
38
|
* The panel draws the hairlines between its own rows. React Native has no
|
|
33
39
|
* `:first-child`, so the alternative is every caller writing
|
|
34
40
|
* `divided={index > 0}` on every row and getting it wrong once.
|
|
41
|
+
*
|
|
42
|
+
* A row is three slots, and they exist because of one React Native detail:
|
|
43
|
+
* Yoga defaults `flexShrink` to `0`, the opposite of the web. A child that is
|
|
44
|
+
* not told to shrink never does, so a fourth thing in a row pushes the others
|
|
45
|
+
* past the edge — where the frame's `overflow-hidden` silently cuts them off
|
|
46
|
+
* rather than wrapping or truncating. `Frame.Media` and `Frame.Actions` hold
|
|
47
|
+
* their size, `Frame.Content` takes what is left and is allowed to shrink to
|
|
48
|
+
* nothing, and the row fits at any width without the caller measuring anything.
|
|
35
49
|
*/
|
|
36
|
-
import { Children, cloneElement, forwardRef, isValidElement } from 'react';
|
|
50
|
+
import { Children, cloneElement, createContext, forwardRef, isValidElement, useContext } from 'react';
|
|
37
51
|
import { Pressable, View } from 'react-native';
|
|
38
52
|
import { tv } from 'tailwind-variants';
|
|
39
53
|
import { ChevronRightIcon } from "../../icons/index.js";
|
|
@@ -70,6 +84,13 @@ const frameVariants = tv({
|
|
|
70
84
|
variant: 'default'
|
|
71
85
|
}
|
|
72
86
|
});
|
|
87
|
+
/**
|
|
88
|
+
* True inside a `Frame.Content`. The header's caption and a row's title are the
|
|
89
|
+
* same part in two places and only the placement decides the weight: a header
|
|
90
|
+
* labels the tray the card sits in, so it stays quiet, while a row title is the
|
|
91
|
+
* row's subject and has to carry it.
|
|
92
|
+
*/
|
|
93
|
+
const FrameSlotContext = /*#__PURE__*/createContext(false);
|
|
73
94
|
const FrameRoot = /*#__PURE__*/forwardRef(({
|
|
74
95
|
className,
|
|
75
96
|
variant,
|
|
@@ -94,25 +115,43 @@ const FrameHeader = /*#__PURE__*/forwardRef(({
|
|
|
94
115
|
...props
|
|
95
116
|
}, ref) => /*#__PURE__*/_jsx(View, {
|
|
96
117
|
ref: ref,
|
|
97
|
-
className: cn(
|
|
118
|
+
className: cn(
|
|
119
|
+
// `min-w-0` on nothing here — the title itself takes the flexible side,
|
|
120
|
+
// so a long one truncates instead of shoving the action off the edge.
|
|
121
|
+
'flex-row items-center justify-between gap-3 px-4 pb-3 pt-2.5', className),
|
|
98
122
|
...props
|
|
99
123
|
}));
|
|
100
124
|
FrameHeader.displayName = 'Frame.Header';
|
|
101
125
|
|
|
102
126
|
/**
|
|
103
|
-
* Muted
|
|
104
|
-
* a
|
|
127
|
+
* Muted in a header, where it is a caption on the tray the card sits in. Inside
|
|
128
|
+
* a `Frame.Content` it is the row's subject instead, so it takes the foreground
|
|
129
|
+
* colour and medium weight, and truncates to one line rather than pushing the
|
|
130
|
+
* row's trailing slot out of view. Pass `numberOfLines` to override either way.
|
|
105
131
|
*/
|
|
106
132
|
const FrameTitle = /*#__PURE__*/forwardRef(({
|
|
107
133
|
className,
|
|
108
134
|
...props
|
|
109
|
-
}, ref) =>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
135
|
+
}, ref) => {
|
|
136
|
+
const inRow = useContext(FrameSlotContext);
|
|
137
|
+
if (inRow) {
|
|
138
|
+
return /*#__PURE__*/_jsx(Text, {
|
|
139
|
+
ref: ref,
|
|
140
|
+
size: "sm",
|
|
141
|
+
weight: "medium",
|
|
142
|
+
numberOfLines: 1,
|
|
143
|
+
className: className,
|
|
144
|
+
...props
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return /*#__PURE__*/_jsx(Text, {
|
|
148
|
+
ref: ref,
|
|
149
|
+
size: "sm",
|
|
150
|
+
muted: true,
|
|
151
|
+
className: cn('min-w-0 shrink', className),
|
|
152
|
+
...props
|
|
153
|
+
});
|
|
154
|
+
});
|
|
116
155
|
FrameTitle.displayName = 'Frame.Title';
|
|
117
156
|
/**
|
|
118
157
|
* Trailing slot on the header row — a column label, a count, a button, a badge.
|
|
@@ -124,7 +163,7 @@ const FrameAction = /*#__PURE__*/forwardRef(({
|
|
|
124
163
|
...props
|
|
125
164
|
}, ref) => /*#__PURE__*/_jsx(View, {
|
|
126
165
|
ref: ref,
|
|
127
|
-
className: cn('flex-row items-center gap-2', className),
|
|
166
|
+
className: cn('shrink-0 flex-row items-center gap-2', className),
|
|
128
167
|
...props,
|
|
129
168
|
children: typeof children === 'string' ? /*#__PURE__*/_jsx(Text, {
|
|
130
169
|
size: "sm",
|
|
@@ -134,18 +173,76 @@ const FrameAction = /*#__PURE__*/forwardRef(({
|
|
|
134
173
|
}));
|
|
135
174
|
FrameAction.displayName = 'Frame.Action';
|
|
136
175
|
|
|
137
|
-
/**
|
|
176
|
+
/**
|
|
177
|
+
* Secondary line under the title — in a column-wrapped header, or under a row's
|
|
178
|
+
* title inside `Frame.Content`, where it drops a size and wraps to two lines.
|
|
179
|
+
*/
|
|
138
180
|
const FrameDescription = /*#__PURE__*/forwardRef(({
|
|
139
181
|
className,
|
|
140
182
|
...props
|
|
141
|
-
}, ref) =>
|
|
183
|
+
}, ref) => {
|
|
184
|
+
const inRow = useContext(FrameSlotContext);
|
|
185
|
+
return /*#__PURE__*/_jsx(Text, {
|
|
186
|
+
ref: ref,
|
|
187
|
+
size: inRow ? 'xs' : 'sm',
|
|
188
|
+
muted: true,
|
|
189
|
+
numberOfLines: inRow ? 2 : undefined,
|
|
190
|
+
className: className,
|
|
191
|
+
...props
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
FrameDescription.displayName = 'Frame.Description';
|
|
195
|
+
/**
|
|
196
|
+
* Leading slot on a row — an icon, an avatar, a status dot. Holds its size, so
|
|
197
|
+
* whatever it holds is never squeezed by the text beside it.
|
|
198
|
+
*/
|
|
199
|
+
const FrameMedia = /*#__PURE__*/forwardRef(({
|
|
200
|
+
className,
|
|
201
|
+
...props
|
|
202
|
+
}, ref) => /*#__PURE__*/_jsx(View, {
|
|
142
203
|
ref: ref,
|
|
143
|
-
|
|
144
|
-
muted: true,
|
|
145
|
-
className: className,
|
|
204
|
+
className: cn('shrink-0 items-center justify-center', className),
|
|
146
205
|
...props
|
|
147
206
|
}));
|
|
148
|
-
|
|
207
|
+
FrameMedia.displayName = 'Frame.Media';
|
|
208
|
+
/**
|
|
209
|
+
* The flexible middle of a row — usually a `Frame.Title` over a
|
|
210
|
+
* `Frame.Description`. It takes whatever the media and actions leave and is
|
|
211
|
+
* allowed to shrink past its content, which is what keeps a long line from
|
|
212
|
+
* pushing the rest of the row off the edge.
|
|
213
|
+
*/
|
|
214
|
+
const FrameContent = /*#__PURE__*/forwardRef(({
|
|
215
|
+
className,
|
|
216
|
+
children,
|
|
217
|
+
...props
|
|
218
|
+
}, ref) =>
|
|
219
|
+
/*#__PURE__*/
|
|
220
|
+
// `min-w-0` is the whole trick: a flex child's minimum size is its content
|
|
221
|
+
// unless told otherwise, so `flex-1` alone still refuses to go narrower
|
|
222
|
+
// than the longest word in it.
|
|
223
|
+
_jsx(View, {
|
|
224
|
+
ref: ref,
|
|
225
|
+
className: cn('min-w-0 flex-1 gap-0.5', className),
|
|
226
|
+
...props,
|
|
227
|
+
children: /*#__PURE__*/_jsx(FrameSlotContext.Provider, {
|
|
228
|
+
value: true,
|
|
229
|
+
children: children
|
|
230
|
+
})
|
|
231
|
+
}));
|
|
232
|
+
FrameContent.displayName = 'Frame.Content';
|
|
233
|
+
/**
|
|
234
|
+
* Trailing slot on a row — a chip, a value, a switch, a small button. Holds its
|
|
235
|
+
* size, so it stays readable however long the content beside it runs.
|
|
236
|
+
*/
|
|
237
|
+
const FrameActions = /*#__PURE__*/forwardRef(({
|
|
238
|
+
className,
|
|
239
|
+
...props
|
|
240
|
+
}, ref) => /*#__PURE__*/_jsx(View, {
|
|
241
|
+
ref: ref,
|
|
242
|
+
className: cn('shrink-0 flex-row items-center gap-1.5', className),
|
|
243
|
+
...props
|
|
244
|
+
}));
|
|
245
|
+
FrameActions.displayName = 'Frame.Actions';
|
|
149
246
|
|
|
150
247
|
/**
|
|
151
248
|
* Marks the parts that take part in the panel's own divider bookkeeping —
|
|
@@ -196,11 +293,13 @@ const FrameRow = /*#__PURE__*/forwardRef(({
|
|
|
196
293
|
className,
|
|
197
294
|
divided,
|
|
198
295
|
chevron,
|
|
296
|
+
wrap,
|
|
297
|
+
align = 'center',
|
|
199
298
|
children,
|
|
200
299
|
onPress,
|
|
201
300
|
...props
|
|
202
301
|
}, ref) => {
|
|
203
|
-
const classes = cn('flex-row
|
|
302
|
+
const classes = cn('flex-row gap-3 px-4 py-3.5', align === 'start' ? 'items-start' : 'items-center', wrap && 'flex-wrap', divided && 'border-t border-border', onPress && 'active:bg-muted', className);
|
|
204
303
|
const body = /*#__PURE__*/_jsxs(_Fragment, {
|
|
205
304
|
children: [children, chevron ? /*#__PURE__*/_jsx(ChevronRightIcon, {
|
|
206
305
|
size: 16
|
|
@@ -261,6 +360,9 @@ export const Frame = Object.assign(FrameRoot, {
|
|
|
261
360
|
Description: FrameDescription,
|
|
262
361
|
Panel: FramePanel,
|
|
263
362
|
Section: FrameSection,
|
|
264
|
-
Row: FrameRow
|
|
363
|
+
Row: FrameRow,
|
|
364
|
+
Media: FrameMedia,
|
|
365
|
+
Content: FrameContent,
|
|
366
|
+
Actions: FrameActions
|
|
265
367
|
});
|
|
266
368
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Children","cloneElement","forwardRef","isValidElement","Pressable","View","tv","ChevronRightIcon","Text","cn","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","frameVariants","slots","root","panel","variants","variant","default","plain","defaultVariants","FrameRoot","className","props","ref","displayName","FrameHeader","FrameTitle","size","muted","FrameAction","children","FrameDescription","divideChildren","seen","map","child","DIVIDABLE","has","type","index","divided","
|
|
1
|
+
{"version":3,"names":["Children","cloneElement","createContext","forwardRef","isValidElement","useContext","Pressable","View","tv","ChevronRightIcon","Text","cn","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","frameVariants","slots","root","panel","variants","variant","default","plain","defaultVariants","FrameSlotContext","FrameRoot","className","props","ref","displayName","FrameHeader","FrameTitle","inRow","size","weight","numberOfLines","muted","FrameAction","children","FrameDescription","undefined","FrameMedia","FrameContent","Provider","value","FrameActions","divideChildren","seen","map","child","DIVIDABLE","has","type","index","divided","FramePanel","dividers","FrameRow","chevron","wrap","align","onPress","classes","body","accessibilityRole","FrameSection","title","Set","Frame","Object","assign","Header","Title","Action","Description","Panel","Section","Row","Media","Content","Actions"],"sourceRoot":"../../../../src","sources":["components/frame/index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
import { Children, cloneElement, createContext, forwardRef, isValidElement, useContext } from 'react';
|
|
26
26
|
import { View } from 'react-native';
|
|
27
27
|
import { tv } from 'tailwind-variants';
|
|
28
|
+
import { useCSSVariable } from 'uniwind';
|
|
29
|
+
import { IconColorProvider } from "../../icons/index.js";
|
|
28
30
|
import { AnimatedPressable } from "../../primitives/animated-pressable.js";
|
|
29
31
|
import { Text } from "../../primitives/text.js";
|
|
30
32
|
import { cn } from "../../utils/cn.js";
|
|
@@ -249,13 +251,26 @@ const MessageBubble = /*#__PURE__*/forwardRef(({
|
|
|
249
251
|
} = messageVariants({
|
|
250
252
|
align
|
|
251
253
|
});
|
|
254
|
+
|
|
255
|
+
/*
|
|
256
|
+
* A sent bubble is painted in the primary colour, and the theme's text
|
|
257
|
+
* colour is often that same colour — so anything inside it that resolves
|
|
258
|
+
* the foreground for itself draws black on black. Text has always been
|
|
259
|
+
* handled, through `Message.BubbleContent`; an icon or a waveform dropped
|
|
260
|
+
* into a bubble had no way to know. Publishing the bubble's own foreground
|
|
261
|
+
* here fixes all of them at once, the same way Button does for its label.
|
|
262
|
+
*/
|
|
263
|
+
const foreground = useCSSVariable(align === 'end' ? '--color-primary-foreground' : '--color-foreground');
|
|
252
264
|
return /*#__PURE__*/_jsx(View, {
|
|
253
265
|
ref: ref,
|
|
254
266
|
className: bubble({
|
|
255
267
|
className
|
|
256
268
|
}),
|
|
257
269
|
...props,
|
|
258
|
-
children:
|
|
270
|
+
children: /*#__PURE__*/_jsx(IconColorProvider, {
|
|
271
|
+
color: typeof foreground === 'string' ? foreground : undefined,
|
|
272
|
+
children: children
|
|
273
|
+
})
|
|
259
274
|
});
|
|
260
275
|
});
|
|
261
276
|
MessageBubble.displayName = 'Message.Bubble';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Children","cloneElement","createContext","forwardRef","isValidElement","useContext","View","tv","AnimatedPressable","Text","cn","jsx","_jsx","messageVariants","slots","root","avatar","content","header","bubble","bubbleContent","footer","group","variants","align","start","end","defaultVariants","MessageContext","stacked","useMessageContext","GroupContext","MessageRoot","className","onLongPress","children","props","ref","resolvedAlign","body","delayLongPress","Provider","value","displayName","MessageGroup","stackedChildren","map","child","index","undefined","MessageAvatar","MessageContent","MessageHeader","size","MessageBubble","MessageBubbleContent","MessageFooter","MessageActions","Message","Object","assign","Group","Avatar","Content","Header","Bubble","BubbleContent","Footer","Actions"],"sourceRoot":"../../../../src","sources":["components/message/index.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SACEA,QAAQ,EACRC,YAAY,EACZC,aAAa,EACbC,UAAU,EACVC,cAAc,EACdC,UAAU,QAEL,OAAO;AACd,SAASC,IAAI,QAAoD,cAAc;AAC/E,SAASC,EAAE,QAA2B,mBAAmB;AACzD,SAASC,iBAAiB,QAAQ,wCAAqC;AACvE,SAASC,IAAI,QAAwB,0BAAuB;AAC5D,SAASC,EAAE,QAAQ,mBAAgB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAEpC,MAAMC,eAAe,
|
|
1
|
+
{"version":3,"names":["Children","cloneElement","createContext","forwardRef","isValidElement","useContext","View","tv","useCSSVariable","IconColorProvider","AnimatedPressable","Text","cn","jsx","_jsx","messageVariants","slots","root","avatar","content","header","bubble","bubbleContent","footer","group","variants","align","start","end","defaultVariants","MessageContext","stacked","useMessageContext","GroupContext","MessageRoot","className","onLongPress","children","props","ref","resolvedAlign","body","delayLongPress","Provider","value","displayName","MessageGroup","stackedChildren","map","child","index","undefined","MessageAvatar","MessageContent","MessageHeader","size","MessageBubble","foreground","color","MessageBubbleContent","MessageFooter","MessageActions","Message","Object","assign","Group","Avatar","Content","Header","Bubble","BubbleContent","Footer","Actions"],"sourceRoot":"../../../../src","sources":["components/message/index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OtpInput — a one-time-code field drawn as a row of separate cells.
|
|
5
|
+
*
|
|
6
|
+
* The problem this solves is that a code is read and typed one character at a
|
|
7
|
+
* time, and a single text box hides that: you cannot see, at a glance, how
|
|
8
|
+
* many digits are left. So the value is spread across `length` cells, each its
|
|
9
|
+
* own box, and the caret sits in the cell you are about to fill.
|
|
10
|
+
*
|
|
11
|
+
* There is still exactly one text field underneath — a transparent input laid
|
|
12
|
+
* over the whole row — because the software keyboard, autofill and paste all
|
|
13
|
+
* belong to a real `TextInput`, and splitting the value across N inputs fights
|
|
14
|
+
* every one of them. The cells are drawn from the value; the input owns it.
|
|
15
|
+
* Tapping any cell focuses that one input, so the platform never sees the seam.
|
|
16
|
+
*
|
|
17
|
+
* The active cell's border crosses to the focus colour on the UI thread rather
|
|
18
|
+
* than snapping, matching the rest of the field family, and a caret blinks in
|
|
19
|
+
* the cell awaiting input. Each digit zooms in as it lands, so a fast type or a
|
|
20
|
+
* one-tap autofill reads as the code arriving rather than the box redrawing.
|
|
21
|
+
*
|
|
22
|
+
* ```tsx
|
|
23
|
+
* const [code, setCode] = useState('');
|
|
24
|
+
* <OtpInput value={code} onChangeText={setCode} onComplete={submit} />
|
|
25
|
+
* <OtpInput length={4} mask groupEvery={2} type="numeric" />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
29
|
+
import { Pressable, TextInput, View } from 'react-native';
|
|
30
|
+
import Animated, { cancelAnimation, interpolateColor, useAnimatedStyle, useSharedValue, withRepeat, withSequence, withTiming, ZoomIn } from 'react-native-reanimated';
|
|
31
|
+
import { tv } from 'tailwind-variants';
|
|
32
|
+
import { useCSSVariable } from 'uniwind';
|
|
33
|
+
import { Text } from "../../primitives/text.js";
|
|
34
|
+
|
|
35
|
+
/** Long enough to read as a transition, short enough not to lag a fast type. */
|
|
36
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
37
|
+
const FOCUS_DURATION = 150;
|
|
38
|
+
/** A caret that is on for the same time it is off reads as a resting cursor. */
|
|
39
|
+
const CARET_PERIOD = 560;
|
|
40
|
+
const otpVariants = tv({
|
|
41
|
+
slots: {
|
|
42
|
+
container: 'gap-1.5',
|
|
43
|
+
row: 'flex-row items-center',
|
|
44
|
+
cell: 'items-center justify-center rounded-lg border border-input bg-background',
|
|
45
|
+
char: 'text-foreground',
|
|
46
|
+
caret: 'w-0.5 rounded-full bg-foreground',
|
|
47
|
+
separator: 'h-0.5 rounded-full bg-border',
|
|
48
|
+
error: 'text-sm text-destructive'
|
|
49
|
+
},
|
|
50
|
+
variants: {
|
|
51
|
+
size: {
|
|
52
|
+
sm: {
|
|
53
|
+
cell: 'h-10 w-9',
|
|
54
|
+
char: 'text-base',
|
|
55
|
+
caret: 'h-5',
|
|
56
|
+
separator: 'w-2'
|
|
57
|
+
},
|
|
58
|
+
md: {
|
|
59
|
+
cell: 'h-12 w-11',
|
|
60
|
+
char: 'text-lg',
|
|
61
|
+
caret: 'h-6',
|
|
62
|
+
separator: 'w-2.5'
|
|
63
|
+
},
|
|
64
|
+
lg: {
|
|
65
|
+
cell: 'h-14 w-12',
|
|
66
|
+
char: 'text-xl',
|
|
67
|
+
caret: 'h-7',
|
|
68
|
+
separator: 'w-3'
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
disabled: {
|
|
72
|
+
true: {
|
|
73
|
+
row: 'opacity-[0.64]'
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
defaultVariants: {
|
|
78
|
+
size: 'md'
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
/**
|
|
82
|
+
* One box. It owns three animations, all on the UI thread: the border crossing
|
|
83
|
+
* to the focus (or error) colour when it becomes the active cell, the caret
|
|
84
|
+
* blinking while it waits, and the entrance of the character that lands in it.
|
|
85
|
+
*/
|
|
86
|
+
function OtpCell({
|
|
87
|
+
char,
|
|
88
|
+
active,
|
|
89
|
+
focused,
|
|
90
|
+
mask,
|
|
91
|
+
placeholder,
|
|
92
|
+
invalid,
|
|
93
|
+
className,
|
|
94
|
+
charClassName,
|
|
95
|
+
caretClassName
|
|
96
|
+
}) {
|
|
97
|
+
const restColor = useCSSVariable('--color-input');
|
|
98
|
+
const focusColor = useCSSVariable('--color-ring');
|
|
99
|
+
const errorColor = useCSSVariable('--color-destructive');
|
|
100
|
+
const placeholderColor = useCSSVariable('--color-muted-foreground');
|
|
101
|
+
const resting = typeof restColor === 'string' ? restColor : '#e5e5e5';
|
|
102
|
+
const activeColor = invalid ? typeof errorColor === 'string' ? errorColor : '#ef4444' : typeof focusColor === 'string' ? focusColor : '#a3a3a3';
|
|
103
|
+
// An invalid field carries its tint even when it is not the active cell —
|
|
104
|
+
// the error is a fact about the value, not about where the caret happens to be.
|
|
105
|
+
const idle = invalid ? activeColor : resting;
|
|
106
|
+
const lit = active && focused;
|
|
107
|
+
const border = useSharedValue(lit ? 1 : 0);
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
border.value = withTiming(lit ? 1 : 0, {
|
|
110
|
+
duration: FOCUS_DURATION
|
|
111
|
+
});
|
|
112
|
+
}, [lit, border]);
|
|
113
|
+
const borderStyle = useAnimatedStyle(() => ({
|
|
114
|
+
borderColor: interpolateColor(border.value, [0, 1], [idle, activeColor]),
|
|
115
|
+
// A ring only when lit — the resting cells keep their hairline.
|
|
116
|
+
borderWidth: 1 + border.value
|
|
117
|
+
}));
|
|
118
|
+
const caret = useSharedValue(0);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (lit && char.length === 0) {
|
|
121
|
+
caret.value = withRepeat(withSequence(withTiming(1, {
|
|
122
|
+
duration: 1
|
|
123
|
+
}), withTiming(1, {
|
|
124
|
+
duration: CARET_PERIOD
|
|
125
|
+
}), withTiming(0, {
|
|
126
|
+
duration: CARET_PERIOD
|
|
127
|
+
})), -1, false);
|
|
128
|
+
} else {
|
|
129
|
+
cancelAnimation(caret);
|
|
130
|
+
caret.value = 0;
|
|
131
|
+
}
|
|
132
|
+
return () => cancelAnimation(caret);
|
|
133
|
+
}, [lit, char.length, caret]);
|
|
134
|
+
const caretStyle = useAnimatedStyle(() => ({
|
|
135
|
+
opacity: caret.value
|
|
136
|
+
}));
|
|
137
|
+
return /*#__PURE__*/_jsx(Animated.View, {
|
|
138
|
+
style: borderStyle,
|
|
139
|
+
className: className,
|
|
140
|
+
children: char.length > 0 ? /*#__PURE__*/_jsx(Animated.Text, {
|
|
141
|
+
entering: ZoomIn.duration(140),
|
|
142
|
+
className: charClassName,
|
|
143
|
+
children: mask ? '•' : char
|
|
144
|
+
}, char) : lit ? /*#__PURE__*/_jsx(Animated.View, {
|
|
145
|
+
style: caretStyle,
|
|
146
|
+
className: caretClassName,
|
|
147
|
+
pointerEvents: "none"
|
|
148
|
+
}) : placeholder ? /*#__PURE__*/_jsx(Text, {
|
|
149
|
+
className: charClassName,
|
|
150
|
+
style: {
|
|
151
|
+
color: typeof placeholderColor === 'string' ? placeholderColor : '#a3a3a3'
|
|
152
|
+
},
|
|
153
|
+
children: placeholder
|
|
154
|
+
}) : null
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Clamp and filter a raw string down to what this field will hold. */
|
|
159
|
+
function sanitize(raw, length, type) {
|
|
160
|
+
const filtered = type === 'numeric' ? raw.replace(/[^0-9]/g, '') : raw;
|
|
161
|
+
return filtered.slice(0, length);
|
|
162
|
+
}
|
|
163
|
+
export const OtpInput = /*#__PURE__*/forwardRef(({
|
|
164
|
+
className,
|
|
165
|
+
cellClassName,
|
|
166
|
+
length = 6,
|
|
167
|
+
value: valueProp,
|
|
168
|
+
defaultValue = '',
|
|
169
|
+
onChangeText,
|
|
170
|
+
onComplete,
|
|
171
|
+
type = 'numeric',
|
|
172
|
+
mask = false,
|
|
173
|
+
placeholder,
|
|
174
|
+
groupEvery = 0,
|
|
175
|
+
size,
|
|
176
|
+
disabled,
|
|
177
|
+
isInvalid,
|
|
178
|
+
errorMessage,
|
|
179
|
+
accessibilityLabel,
|
|
180
|
+
onFocus,
|
|
181
|
+
onBlur,
|
|
182
|
+
style,
|
|
183
|
+
...props
|
|
184
|
+
}, ref) => {
|
|
185
|
+
const controlled = valueProp != null;
|
|
186
|
+
const [internal, setInternal] = useState(() => sanitize(defaultValue, length, type));
|
|
187
|
+
const value = sanitize(controlled ? valueProp : internal, length, type);
|
|
188
|
+
const invalid = isInvalid || !!errorMessage;
|
|
189
|
+
const [focused, setFocused] = useState(false);
|
|
190
|
+
const inputRef = useRef(null);
|
|
191
|
+
|
|
192
|
+
// A one-shot guard so onComplete fires on the transition to full, not on
|
|
193
|
+
// every keystroke that leaves the field full (e.g. a trailing focus event).
|
|
194
|
+
const completedRef = useRef(false);
|
|
195
|
+
const slots = otpVariants({
|
|
196
|
+
size,
|
|
197
|
+
disabled: !!disabled
|
|
198
|
+
});
|
|
199
|
+
const setRef = useCallback(node => {
|
|
200
|
+
inputRef.current = node;
|
|
201
|
+
if (typeof ref === 'function') ref(node);else if (ref) ref.current = node;
|
|
202
|
+
}, [ref]);
|
|
203
|
+
const handleChange = useCallback(raw => {
|
|
204
|
+
const next = sanitize(raw, length, type);
|
|
205
|
+
if (!controlled) setInternal(next);
|
|
206
|
+
onChangeText?.(next);
|
|
207
|
+
if (next.length === length) {
|
|
208
|
+
if (!completedRef.current) {
|
|
209
|
+
completedRef.current = true;
|
|
210
|
+
onComplete?.(next);
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
completedRef.current = false;
|
|
214
|
+
}
|
|
215
|
+
}, [controlled, length, type, onChangeText, onComplete]);
|
|
216
|
+
|
|
217
|
+
// Keep the guard honest when the value is driven from outside (a reset, a
|
|
218
|
+
// paste through the controlled prop) rather than through the keyboard.
|
|
219
|
+
useEffect(() => {
|
|
220
|
+
completedRef.current = value.length === length;
|
|
221
|
+
}, [value.length, length]);
|
|
222
|
+
const focus = useCallback(() => {
|
|
223
|
+
if (!disabled) inputRef.current?.focus();
|
|
224
|
+
}, [disabled]);
|
|
225
|
+
const activeIndex = Math.min(value.length, length - 1);
|
|
226
|
+
const cells = useMemo(() => Array.from({
|
|
227
|
+
length
|
|
228
|
+
}, (_, i) => i), [length]);
|
|
229
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
230
|
+
className: slots.container({
|
|
231
|
+
className
|
|
232
|
+
}),
|
|
233
|
+
children: [/*#__PURE__*/_jsxs(Pressable, {
|
|
234
|
+
onPress: focus,
|
|
235
|
+
disabled: disabled,
|
|
236
|
+
accessible: false,
|
|
237
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
238
|
+
className: slots.row(),
|
|
239
|
+
children: cells.map(i => /*#__PURE__*/_jsxs(View, {
|
|
240
|
+
className: "flex-row items-center",
|
|
241
|
+
children: [/*#__PURE__*/_jsx(OtpCell, {
|
|
242
|
+
char: value[i] ?? '',
|
|
243
|
+
active: i === activeIndex,
|
|
244
|
+
focused: focused,
|
|
245
|
+
mask: mask,
|
|
246
|
+
placeholder: placeholder,
|
|
247
|
+
invalid: invalid,
|
|
248
|
+
className: slots.cell({
|
|
249
|
+
className: `${i > 0 ? 'ml-2' : ''} ${cellClassName ?? ''}`
|
|
250
|
+
}),
|
|
251
|
+
charClassName: slots.char(),
|
|
252
|
+
caretClassName: slots.caret()
|
|
253
|
+
}), groupEvery > 0 && (i + 1) % groupEvery === 0 && i < length - 1 ? /*#__PURE__*/_jsx(View, {
|
|
254
|
+
className: `${slots.separator()} ml-2`
|
|
255
|
+
}) : null]
|
|
256
|
+
}, i))
|
|
257
|
+
}), /*#__PURE__*/_jsx(TextInput, {
|
|
258
|
+
ref: setRef,
|
|
259
|
+
value: value,
|
|
260
|
+
onChangeText: handleChange,
|
|
261
|
+
editable: !disabled,
|
|
262
|
+
keyboardType: type === 'numeric' ? 'number-pad' : 'default'
|
|
263
|
+
// The OS one-time-code affordances: iOS surfaces the SMS code above
|
|
264
|
+
// the keyboard, Android offers to autofill it.
|
|
265
|
+
,
|
|
266
|
+
textContentType: "oneTimeCode",
|
|
267
|
+
autoComplete: type === 'numeric' ? 'sms-otp' : 'one-time-code',
|
|
268
|
+
maxLength: length,
|
|
269
|
+
caretHidden: true,
|
|
270
|
+
accessibilityLabel: accessibilityLabel,
|
|
271
|
+
accessibilityState: {
|
|
272
|
+
disabled: !!disabled
|
|
273
|
+
},
|
|
274
|
+
"aria-invalid": invalid,
|
|
275
|
+
onFocus: e => {
|
|
276
|
+
setFocused(true);
|
|
277
|
+
onFocus?.(e);
|
|
278
|
+
},
|
|
279
|
+
onBlur: e => {
|
|
280
|
+
setFocused(false);
|
|
281
|
+
onBlur?.(e);
|
|
282
|
+
},
|
|
283
|
+
style: [{
|
|
284
|
+
position: 'absolute',
|
|
285
|
+
top: 0,
|
|
286
|
+
left: 0,
|
|
287
|
+
right: 0,
|
|
288
|
+
bottom: 0,
|
|
289
|
+
opacity: 0,
|
|
290
|
+
// Taps fall through to the Pressable, which focuses this input —
|
|
291
|
+
// so the caret lands wherever the row is touched.
|
|
292
|
+
pointerEvents: 'none'
|
|
293
|
+
}, style],
|
|
294
|
+
...props
|
|
295
|
+
})]
|
|
296
|
+
}), errorMessage ? /*#__PURE__*/_jsx(Text, {
|
|
297
|
+
className: slots.error(),
|
|
298
|
+
children: errorMessage
|
|
299
|
+
}) : null]
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
OtpInput.displayName = 'OtpInput';
|
|
303
|
+
//# sourceMappingURL=index.js.map
|