@@ -358,6 +358,7 @@ export const generatePattern = (mode, options) => {
358358 *
359359 * @param {UseMaskOptions } options The hook options
360360 * @param {boolean } [options.autoClear=false] Clear value on blur when mask is incomplete
361+ * @param {string } [options.initialValue=""] Initial raw value
361362 * @param {string | Array<string | RegExp> } options.mask Mask pattern string or array of literals and RegExp tokens
362363 * @param {(value: string) => Partial<Pick<UseMaskOptions, 'mask' | 'showMask' | 'slot' | 'tokens'>> } [options.modify] Called before masking and can return dynamic mask option overrides
363364 * @param {UseMaskShow } [options.showMask="focus"] Defines when placeholder slots are displayed
@@ -375,18 +376,32 @@ export const generatePattern = (mode, options) => {
375376export const useMask = ( options ) => {
376377 const optionsRef = useRef ( options ) ;
377378 optionsRef . current = options ;
379+ const initialRawValue = options . initialValue ?? '' ;
380+ const initialResolvedOptions = getResolvedOptions ( options , initialRawValue ) ;
381+ const initialMaskedValue = applyMaskToRaw (
382+ initialRawValue ,
383+ initialResolvedOptions . slots ,
384+ initialResolvedOptions . transform
385+ ) ;
386+ const initialDisplayValue = buildDisplayValue (
387+ initialMaskedValue ,
388+ initialResolvedOptions . slots ,
389+ initialResolvedOptions . slot ,
390+ shouldShowMask ( initialResolvedOptions . showMask , false , initialMaskedValue )
391+ ) ;
392+ const initialFilled = checkComplete ( initialMaskedValue , initialResolvedOptions . slots ) ;
378393 const inputRef = useRef ( null ) ;
379394 const valueRef = useRef ( {
380- displayValue : '' ,
381- filled : false ,
382- maskedValue : '' ,
383- rawValue : '' ,
384- value : ''
395+ displayValue : initialDisplayValue ,
396+ filled : initialFilled ,
397+ maskedValue : initialMaskedValue ,
398+ rawValue : initialRawValue ,
399+ value : initialDisplayValue
385400 } ) ;
386- const processedRef = useRef ( '' ) ;
387- const displayValueRef = useRef ( '' ) ;
388- const rawValueRef = useRef ( '' ) ;
389- const wasCompleteRef = useRef ( false ) ;
401+ const processedRef = useRef ( initialMaskedValue ) ;
402+ const displayValueRef = useRef ( initialDisplayValue ) ;
403+ const rawValueRef = useRef ( initialRawValue ) ;
404+ const wasCompleteRef = useRef ( initialFilled ) ;
390405 const isFocusedRef = useRef ( false ) ;
391406 const watchingRef = useRef ( false ) ;
392407 const undoStackRef = useRef ( [ ] ) ;
@@ -506,11 +521,20 @@ export const useMask = (options) => {
506521 const nextMaskedValue = applyMaskToRaw ( state . rawValue , slots , transform ) ;
507522 updateValue ( nextMaskedValue , state . selectionStart ) ;
508523 } ;
509- const set = ( value ) => {
524+ const setValue = ( value ) => {
510525 const { slots, transform } = getResolvedOptions ( optionsRef . current , value ) ;
511526 const nextMaskedValue = applyMaskToRaw ( value , slots , transform ) ;
512527 updateValue ( nextMaskedValue ) ;
513528 } ;
529+ const getValue = ( type = 'raw' ) => {
530+ if ( type === 'display' ) {
531+ return valueRef . current . displayValue ;
532+ }
533+ if ( type === 'masked' ) {
534+ return valueRef . current . maskedValue ;
535+ }
536+ return valueRef . current . rawValue ;
537+ } ;
514538 const clampCursorToProcessed = ( element ) => {
515539 const start = element . selectionStart ?? 0 ;
516540 const end = element . selectionEnd ?? 0 ;
@@ -534,14 +558,13 @@ export const useMask = (options) => {
534558 if ( ! node || node . value ) {
535559 return ;
536560 }
537- const { showMask, slots, slot } = getResolvedOptions ( optionsRef . current , '' ) ;
538- if ( ! shouldShowMask ( showMask , false , '' ) ) {
539- return ;
540- }
541- const displayValue = buildDisplayValue ( '' , slots , slot , true ) ;
542- node . value = displayValue ;
543- displayValueRef . current = displayValue ;
544- updateRefs ( { displayValue } ) ;
561+ node . value = displayValueRef . current ;
562+ updateRefs ( {
563+ displayValue : displayValueRef . current ,
564+ filled : wasCompleteRef . current ,
565+ maskedValue : processedRef . current ,
566+ rawValue : rawValueRef . current
567+ } ) ;
545568 } ,
546569 onChange : ( event ) => {
547570 const element = event . currentTarget ;
@@ -816,42 +839,41 @@ export const useMask = (options) => {
816839 const reset = ( ) => {
817840 const input = inputRef . current ;
818841 const hookOptions = optionsRef . current ;
819- processedRef . current = '' ;
820- displayValueRef . current = '' ;
821- rawValueRef . current = '' ;
842+ const nextRawValue = hookOptions . initialValue ?? '' ;
843+ const { showMask, slots, slot, transform } = getResolvedOptions ( hookOptions , nextRawValue ) ;
844+ const nextMaskedValue = applyMaskToRaw ( nextRawValue , slots , transform ) ;
845+ const nextDisplayValue = buildDisplayValue (
846+ nextMaskedValue ,
847+ slots ,
848+ slot ,
849+ shouldShowMask ( showMask , false , nextMaskedValue )
850+ ) ;
851+ const complete = checkComplete ( nextMaskedValue , slots ) ;
852+ processedRef . current = nextMaskedValue ;
853+ displayValueRef . current = nextDisplayValue ;
854+ rawValueRef . current = nextRawValue ;
822855 undoStackRef . current = [ ] ;
823856 redoStackRef . current = [ ] ;
824857 updateRefs ( {
825- displayValue : '' ,
826- filled : false ,
827- maskedValue : '' ,
828- rawValue : ''
858+ displayValue : nextDisplayValue ,
859+ filled : complete ,
860+ maskedValue : nextMaskedValue ,
861+ rawValue : nextRawValue
829862 } ) ;
830- wasCompleteRef . current = false ;
831- let nextDisplayValue = '' ;
863+ wasCompleteRef . current = complete ;
832864 if ( input ) {
833- const { showMask, slots, slot } = getResolvedOptions ( hookOptions , '' ) ;
834- if ( shouldShowMask ( showMask , false , '' ) ) {
835- nextDisplayValue = buildDisplayValue ( '' , slots , slot , true ) ;
836- displayValueRef . current = nextDisplayValue ;
837- updateRefs ( { displayValue : nextDisplayValue } ) ;
838- }
839865 input . value = nextDisplayValue ;
840866 }
841- hookOptions . onChangeRaw ?. ( '' , nextDisplayValue ) ;
867+ hookOptions . onChangeRaw ?. ( nextRawValue , nextDisplayValue ) ;
842868 } ;
843869 const watch = ( ) => {
844870 watchingRef . current = true ;
845871 return valueRef . current ;
846872 } ;
847873 return {
874+ getValue,
848875 register,
849- displayValue : valueRef . current . displayValue ,
850- value : valueRef . current . value ,
851- maskedValue : valueRef . current . maskedValue ,
852- rawValue : valueRef . current . rawValue ,
853- filled : valueRef . current . filled ,
854- set,
876+ setValue,
855877 reset,
856878 watch
857879 } ;
0 commit comments