33import { type ReactNode , useCallback , useMemo , useState } from 'react'
44import { Check , ChevronRight , Clipboard , Info } from 'lucide-react'
55import { useShallow } from 'zustand/react/shallow'
6- import { Checkbox , Input , Label , toast , Tooltip , Wizard } from '@/components/emcn'
6+ import {
7+ Checkbox ,
8+ Input ,
9+ Label ,
10+ SecretInput ,
11+ toast ,
12+ Tooltip ,
13+ Wizard ,
14+ } from '@/components/emcn'
715import { cn } from '@/lib/core/utils/cn'
816import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
917import { useWebhookManagement } from '@/hooks/use-webhook-management'
@@ -343,7 +351,7 @@ function StepSecret({ blockId, value, onChange, disabled }: StepSecretProps) {
343351 </ SubStep >
344352 < SubStep n = { 3 } > Paste it into the field below.</ SubStep >
345353 </ SubStepList >
346- < SecretInput
354+ < SecretField
347355 id = { `${ blockId } -wizard-signing-secret` }
348356 label = 'Signing Secret'
349357 value = { value }
@@ -375,7 +383,7 @@ function StepToken({ blockId, value, onChange, disabled }: StepTokenProps) {
375383 </ SubStep >
376384 < SubStep n = { 3 } > Paste it into the field below.</ SubStep >
377385 </ SubStepList >
378- < SecretInput
386+ < SecretField
379387 id = { `${ blockId } -wizard-bot-token` }
380388 label = 'Bot Token'
381389 value = { value }
@@ -387,7 +395,7 @@ function StepToken({ blockId, value, onChange, disabled }: StepTokenProps) {
387395 )
388396}
389397
390- interface SecretInputProps {
398+ interface SecretFieldProps {
391399 id : string
392400 label : string
393401 value : string
@@ -397,40 +405,23 @@ interface SecretInputProps {
397405}
398406
399407/**
400- * Password-style input that masks its value with bullets only while the
401- * field is unfocused. Typing, pasting, and selection all see the real text
402- * so users can verify what they just pasted before clicking Next.
403- *
404- * @remarks
405- * Change events that fire while the field is blurred carry the bullet
406- * string as their value (autofill, form resets, synthetic React events),
407- * which would silently overwrite the stored secret with `•` characters.
408- * We gate the `onChange` callback on `isFocused` so only real edits — made
409- * while the user is interacting and the displayed value is the real text —
410- * propagate to the store.
408+ * Label + SecretInput pair used by the signing-secret and bot-token wizard
409+ * steps. The masked-on-blur behavior lives in the emcn `SecretInput`
410+ * primitive; this wrapper just pins the label/input composition the wizard
411+ * reuses twice.
411412 */
412- function SecretInput ( { id, label, value, onChange, disabled, placeholder } : SecretInputProps ) {
413- const [ isFocused , setIsFocused ] = useState < boolean > ( false )
414- const displayValue = isFocused ? value : '•' . repeat ( value . length )
415-
413+ function SecretField ( { id, label, value, onChange, disabled, placeholder } : SecretFieldProps ) {
416414 return (
417415 < div className = 'space-y-1.5' >
418416 < Label htmlFor = { id } className = 'font-medium text-[var(--text-secondary)] text-xs' >
419417 { label }
420418 </ Label >
421- < Input
419+ < SecretInput
422420 id = { id }
423- type = 'text'
424- value = { displayValue }
425- onChange = { ( e ) => {
426- if ( ! isFocused ) return
427- onChange ( e . target . value )
428- } }
429- onFocus = { ( ) => setIsFocused ( true ) }
430- onBlur = { ( ) => setIsFocused ( false ) }
421+ value = { value }
422+ onChange = { onChange }
431423 disabled = { disabled }
432424 placeholder = { placeholder }
433- autoComplete = 'off'
434425 className = 'h-9 text-sm'
435426 />
436427 </ div >
0 commit comments