From 644fbe5b00ca00960e7af75656a5109c63f72ba4 Mon Sep 17 00:00:00 2001 From: Maharshi Alpesh Date: Fri, 20 Dec 2024 00:00:52 +0530 Subject: [PATCH 1/3] fix: virtual keyboard on mobile should be based on the allowed keys --- .changeset/cyan-donkeys-swim.md | 5 +++++ packages/components/input-otp/src/use-input-otp.ts | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 .changeset/cyan-donkeys-swim.md diff --git a/.changeset/cyan-donkeys-swim.md b/.changeset/cyan-donkeys-swim.md new file mode 100644 index 0000000000..07558fd0b0 --- /dev/null +++ b/.changeset/cyan-donkeys-swim.md @@ -0,0 +1,5 @@ +--- +"@nextui-org/input-otp": patch +--- + +Fix virtual keyboard to display the keys based on allowedKeys(#4408) diff --git a/packages/components/input-otp/src/use-input-otp.ts b/packages/components/input-otp/src/use-input-otp.ts index 0206c4565d..a6a2a66342 100644 --- a/packages/components/input-otp/src/use-input-otp.ts +++ b/packages/components/input-otp/src/use-input-otp.ts @@ -223,6 +223,12 @@ export function useInputOtp(originalProps: UseInputOtpProps) { [baseDomRef, slots, baseStyles, isDisabled, isInvalid, isRequired, isReadOnly, value, length], ); + const isNumeric = (pattern: string) => { + const numericPattern = /(^|\W)[0-9](\W|$)/; + + return numericPattern.test(pattern) && !/[^\d\^$\[\]\(\)\*\+\-\.\|]/.test(pattern); + }; + const getInputOtpProps = useCallback( (props: Partial = {}) => { const otpProps: Omit & { @@ -246,6 +252,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) { pushPasswordManagerStrategy, pasteTransformer, noScriptCSSFallback, + inputMode: isNumeric(allowedKeys) ? "numeric" : "text", containerClassName: slots.wrapper?.({class: clsx(classNames?.wrapper, containerClassName)}), ...props, }; From 6ae4db7e6d9629dae395df185793378c52bb3517 Mon Sep 17 00:00:00 2001 From: Maharshi Alpesh Date: Sat, 21 Dec 2024 16:27:30 +0530 Subject: [PATCH 2/3] chore: applying junior's suggestions --- packages/components/input-otp/src/use-input-otp.ts | 10 ++-------- packages/utilities/shared-utils/src/index.ts | 1 + packages/utilities/shared-utils/src/regex.ts | 5 +++++ 3 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 packages/utilities/shared-utils/src/regex.ts diff --git a/packages/components/input-otp/src/use-input-otp.ts b/packages/components/input-otp/src/use-input-otp.ts index a6a2a66342..07322256f0 100644 --- a/packages/components/input-otp/src/use-input-otp.ts +++ b/packages/components/input-otp/src/use-input-otp.ts @@ -13,7 +13,7 @@ import { } from "@nextui-org/system"; import {inputOtp} from "@nextui-org/theme"; import {filterDOMProps, ReactRef, useDOMRef} from "@nextui-org/react-utils"; -import {clsx, dataAttr, objectToDeps} from "@nextui-org/shared-utils"; +import {clsx, dataAttr, objectToDeps, isPatternNumeric} from "@nextui-org/shared-utils"; import {useCallback, useMemo} from "react"; import {chain, mergeProps, useFormReset} from "@react-aria/utils"; import {AriaTextFieldProps} from "@react-types/textfield"; @@ -223,12 +223,6 @@ export function useInputOtp(originalProps: UseInputOtpProps) { [baseDomRef, slots, baseStyles, isDisabled, isInvalid, isRequired, isReadOnly, value, length], ); - const isNumeric = (pattern: string) => { - const numericPattern = /(^|\W)[0-9](\W|$)/; - - return numericPattern.test(pattern) && !/[^\d\^$\[\]\(\)\*\+\-\.\|]/.test(pattern); - }; - const getInputOtpProps = useCallback( (props: Partial = {}) => { const otpProps: Omit & { @@ -252,7 +246,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) { pushPasswordManagerStrategy, pasteTransformer, noScriptCSSFallback, - inputMode: isNumeric(allowedKeys) ? "numeric" : "text", + inputMode: isPatternNumeric(allowedKeys) ? "numeric" : "text", containerClassName: slots.wrapper?.({class: clsx(classNames?.wrapper, containerClassName)}), ...props, }; diff --git a/packages/utilities/shared-utils/src/index.ts b/packages/utilities/shared-utils/src/index.ts index b4b452ebef..eec14e1c31 100644 --- a/packages/utilities/shared-utils/src/index.ts +++ b/packages/utilities/shared-utils/src/index.ts @@ -8,3 +8,4 @@ export * from "./numbers"; export * from "./console"; export * from "./types"; export * from "./dates"; +export * from "./regex"; diff --git a/packages/utilities/shared-utils/src/regex.ts b/packages/utilities/shared-utils/src/regex.ts new file mode 100644 index 0000000000..ea614296f1 --- /dev/null +++ b/packages/utilities/shared-utils/src/regex.ts @@ -0,0 +1,5 @@ +export const isPatternNumeric = (pattern: string) => { + const numericPattern = /(^|\W)[0-9](\W|$)/; + + return numericPattern.test(pattern) && !/[^\d\^$\[\]\(\)\*\+\-\.\|]/.test(pattern); +}; From 3862259ccdb49b194ac8c5b66f55b014503eff30 Mon Sep 17 00:00:00 2001 From: Junior Garcia Date: Sun, 22 Dec 2024 11:26:41 -0300 Subject: [PATCH 3/3] chore: add inputmode prop, update changeset --- .changeset/cyan-donkeys-swim.md | 1 + packages/components/input-otp/src/use-input-otp.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.changeset/cyan-donkeys-swim.md b/.changeset/cyan-donkeys-swim.md index 07558fd0b0..fbd47f425a 100644 --- a/.changeset/cyan-donkeys-swim.md +++ b/.changeset/cyan-donkeys-swim.md @@ -1,5 +1,6 @@ --- "@nextui-org/input-otp": patch +"@nextui-org/shared-utils": patch --- Fix virtual keyboard to display the keys based on allowedKeys(#4408) diff --git a/packages/components/input-otp/src/use-input-otp.ts b/packages/components/input-otp/src/use-input-otp.ts index 07322256f0..f5c2d8d5c4 100644 --- a/packages/components/input-otp/src/use-input-otp.ts +++ b/packages/components/input-otp/src/use-input-otp.ts @@ -120,6 +120,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) { containerClassName, noScriptCSSFallback, onChange, + inputMode, ...otherProps } = props; @@ -237,16 +238,16 @@ export function useInputOtp(originalProps: UseInputOtpProps) { minLength: minLength ?? length, textAlign, ref: inputRef, - name: name, - value: value, + name, + value, autoFocus, onChange: setValue, onBlur: chain(focusProps.onBlur, props?.onBlur), - onComplete: onComplete, + onComplete, pushPasswordManagerStrategy, pasteTransformer, noScriptCSSFallback, - inputMode: isPatternNumeric(allowedKeys) ? "numeric" : "text", + inputMode: inputMode ?? (isPatternNumeric(allowedKeys) ? "numeric" : "text"), containerClassName: slots.wrapper?.({class: clsx(classNames?.wrapper, containerClassName)}), ...props, }; @@ -254,6 +255,7 @@ export function useInputOtp(originalProps: UseInputOtpProps) { return otpProps; }, [ + inputMode, isRequired, isDisabled, isReadOnly,