@@ -3,12 +3,13 @@ import React from 'react';
33
44import { Animated } from '~/primitives/animated' ;
55import * as Field from '~/primitives/field' ;
6+ import { cx } from '~/utils/dva' ;
67
78export function OTPField ( {
89 label,
910 resend,
1011 ...props
11- } : React . ComponentProps < typeof Common . Input > & {
12+ } : React . ComponentProps < 'span' > & {
1213 /**
1314 * **Note:** this prop is required as the `label` differs depending on the context (e.g. email code vs. link code)
1415 */
@@ -36,34 +37,59 @@ export function OTPField({
3637 className = 'flex justify-center gap-2'
3738 passwordManagerOffset = { 24 }
3839 render = { ( { value, status } ) => (
39- < Field . Input
40- variant = 'otp-digit'
41- intent = { state }
42- state = {
43- (
44- {
45- cursor : 'focus-visible' ,
46- selected : 'focus-visible' ,
47- hovered : 'hover' ,
48- none : 'native' ,
49- } as const
50- ) [ status ]
51- }
40+ < span
41+ className = { cx (
42+ 'py-[--field-input-py]' ,
43+ 'ps-[--field-input-px]' ,
44+ // If an `InputGroup` exists, use the `pe` value, or fallback to the
45+ // standard input `px` value
46+ 'pe-[var(--field-input-group-pe,var(--field-input-px))]' ,
47+ 'text-gray-12 relative flex min-w-0 items-center rounded-md bg-white text-base outline-none ring ring-offset-1' ,
48+ 'shadow-[0px_1px_1px_0px_theme(colors.gray.a3)]' ,
49+ 'disabled:cursor-not-allowed disabled:opacity-50' ,
50+ 'supports-ios:text-[length:1rem] supports-ios:min-h-[1.875rem]' ,
51+ 'aspect-square size-10 justify-center text-[calc(var(--cl-font-size)*1.4)] font-semibold' ,
52+ {
53+ none : 'ring-offset-[--cl-field-input-border] focus-visible:ring focus-visible:ring-[--cl-field-input-ring,theme(ringColor.light)] focus-visible:ring-offset-[--cl-field-input-border-active] hover:enabled:ring-offset-[--cl-field-input-border-active] [&:not(:focus-visible)]:ring-transparent' ,
54+ hovered : 'ring-transparent ring-offset-[--cl-field-input-border-active]' ,
55+ cursor :
56+ 'ring-[--cl-field-input-ring,theme(ringColor.light)] ring-offset-[--cl-field-input-border-active]' ,
57+ selected :
58+ 'ring-[--cl-field-input-ring,theme(ringColor.light)] ring-offset-[--cl-field-input-border-active]' ,
59+ } [ status ] ,
60+ {
61+ idle : [
62+ '[--cl-field-input-border:theme(colors.gray.a4)]' ,
63+ '[--cl-field-input-border-active:theme(colors.gray.a7)]' ,
64+ ] ,
65+ info : [
66+ '[--cl-field-input-border:theme(colors.gray.a7)]' ,
67+ '[--cl-field-input-border-active:theme(colors.gray.a7)]' ,
68+ ] ,
69+ error : [
70+ '[--cl-field-input-border:theme(colors.danger.DEFAULT)]' ,
71+ '[--cl-field-input-border-active:theme(colors.danger.DEFAULT)]' ,
72+ '[--cl-field-input-ring:theme(colors.danger.DEFAULT/0.2)]' ,
73+ ] ,
74+ success : [
75+ '[--cl-field-input-border:theme(colors.success.DEFAULT)]' ,
76+ '[--cl-field-input-border-active:theme(colors.success.DEFAULT)]' ,
77+ '[--cl-field-input-ring:theme(colors.success.DEFAULT/0.25)]' , // (optically adjusted ring to 25 opacity)
78+ ] ,
79+ warning : [
80+ '[--cl-field-input-border:theme(colors.warning.DEFAULT)]' ,
81+ '[--cl-field-input-border-active:theme(colors.warning.DEFAULT)]' ,
82+ '[--cl-field-input-ring:theme(colors.warning.DEFAULT/0.2)]' ,
83+ ] ,
84+ } [ state ] ,
85+ ) }
5286 { ...props }
53- asChild
5487 >
55- < span >
56- { status === 'cursor' && (
57- < span
58- data-otp-field-cursor = ''
59- // Note:
60- // Opportunity to extract lineHeight to theme
61- className = 'motion-safe:animate-blink h-[calc(theme(fontSize.base)*1.38462)] w-[2px] self-center rounded-full bg-current'
62- />
63- ) }
64- { value }
65- </ span >
66- </ Field . Input >
88+ { status === 'cursor' && (
89+ < span className = 'motion-safe:animate-blink h-[calc(theme(fontSize.base)*1.38462)] w-[2px] self-center rounded-full bg-current' />
90+ ) }
91+ { value }
92+ </ span >
6793 ) }
6894 />
6995 ) }
0 commit comments