Skip to content

Commit

Permalink
feat(input): add placeholder
Browse files Browse the repository at this point in the history
  • Loading branch information
guilhermerodz committed Nov 1, 2024
1 parent 7203ec4 commit 208ba3a
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
12 changes: 8 additions & 4 deletions apps/website/src/components/ui/input-otp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const InputOTP = React.forwardRef<
<OTPInput
ref={ref}
containerClassName={cn(
'flex items-center gap-2 has-[:disabled]:opacity-50',
'group flex items-center gap-2 has-[:disabled]:opacity-50',
containerClassName,
)}
className={cn('disabled:cursor-not-allowed', className)}
Expand Down Expand Up @@ -47,7 +47,9 @@ const InputOTPSlot = React.forwardRef<
)}
{...props}
>
{slotProps.char}
<div className="group-has-[input[data-input-otp-empty]]:opacity-20">
{slotProps.char ?? slotProps.placeholderChar}
</div>
{slotProps.hasFakeCaret && (
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
<div className="animate-caret-blink h-4 w-px bg-foreground duration-1000" />
Expand All @@ -61,7 +63,7 @@ InputOTPSlot.displayName = 'InputOTPSlot'
const InputOTPRenderSlot = React.forwardRef<
React.ElementRef<'div'>,
SlotProps & React.ComponentPropsWithoutRef<'div'>
>(({ char, hasFakeCaret, isActive, className, ...props }, ref) => {
>(({ char, placeholderChar, hasFakeCaret, isActive, className, ...props }, ref) => {
return (
<div
ref={ref}
Expand All @@ -72,7 +74,9 @@ const InputOTPRenderSlot = React.forwardRef<
)}
{...props}
>
{char}
<div className="group-has-[input[data-input-otp-empty]]:opacity-20">
{char ?? placeholderChar}
</div>
{hasFakeCaret && (
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
<div className="animate-caret-blink h-4 w-px bg-foreground duration-1000" />
Expand Down
5 changes: 5 additions & 0 deletions packages/input-otp/src/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const OTPInput = React.forwardRef<HTMLInputElement, OTPInputProps>(
maxLength,
textAlign = 'left',
pattern = REGEXP_ONLY_DIGITS,
placeholder,
inputMode = 'numeric',
onComplete,
pushPasswordManagerStrategy = 'increase-width',
Expand Down Expand Up @@ -408,10 +409,12 @@ export const OTPInput = React.forwardRef<HTMLInputElement, OTPInputProps>(
autoComplete={props.autoComplete || 'one-time-code'}
{...props}
data-input-otp
data-input-otp-empty={value.length === 0 || undefined}
data-input-otp-mss={mirrorSelectionStart}
data-input-otp-mse={mirrorSelectionEnd}
inputMode={inputMode}
pattern={regexp?.source}
aria-placeholder={placeholder}
style={inputStyle}
maxLength={maxLength}
value={value}
Expand Down Expand Up @@ -466,9 +469,11 @@ export const OTPInput = React.forwardRef<HTMLInputElement, OTPInputProps>(
(slotIdx >= mirrorSelectionStart && slotIdx < mirrorSelectionEnd))

const char = value[slotIdx] !== undefined ? value[slotIdx] : null
const placeholderChar = value[0] !== undefined ? null : placeholder?.[slotIdx] ?? null

return {
char,
placeholderChar,
isActive,
hasFakeCaret: isActive && char === null,
}
Expand Down
1 change: 1 addition & 0 deletions packages/input-otp/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface SlotProps {
isActive: boolean
char: string | null
placeholderChar: string | null
hasFakeCaret: boolean
}
export interface RenderProps {
Expand Down

0 comments on commit 208ba3a

Please sign in to comment.