From ae6ef49eb83b838576a9d44b211080d6c3131afd Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Tue, 30 Jan 2024 15:27:19 +0800 Subject: [PATCH 01/33] chore: added Password Input field --- .../PasswordInput/PasswordInput.scss | 47 +++++++++++++++++++ lib/components/PasswordInput/index.tsx | 16 +++++++ 2 files changed, 63 insertions(+) create mode 100644 lib/components/PasswordInput/PasswordInput.scss create mode 100644 lib/components/PasswordInput/index.tsx diff --git a/lib/components/PasswordInput/PasswordInput.scss b/lib/components/PasswordInput/PasswordInput.scss new file mode 100644 index 00000000..227ff2f8 --- /dev/null +++ b/lib/components/PasswordInput/PasswordInput.scss @@ -0,0 +1,47 @@ +$NEUTRAL: #e6e9e9; +$SUCCESS: #4bb4b3; +$ERROR: #ec3f3f; + +.deriv-password { + width: fit-content; + position: relative; + + &-meter { + z-index: -1; + bottom: 1px; + border-radius: 0px 0px 4px 4px; + position: absolute; + width: 100%; + height: 4px; + background-color: $NEUTRAL; + } +} + +.deriv-password-meter--bar { + height: 100%; + border-radius: 0px 0px 4px 4px; + + &__weak { + background-color: $ERROR; + width: 25%; + border-radius: 0px 0px 0px 4px; + } + + &__moderate { + background-color: $ERROR; + width: 50%; + border-radius: 0px 0px 0px 4px; + } + + &__strong { + background-color: $SUCCESS; + width: 50%; + border-radius: 0px 0px 0px 4px; + } + + &__complete { + background-color: $SUCCESS; + width: 100%; + border-radius: 0px 0px 4px 4px; + } +} diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx new file mode 100644 index 00000000..994d2733 --- /dev/null +++ b/lib/components/PasswordInput/index.tsx @@ -0,0 +1,16 @@ +import React, { ComponentProps } from "react"; +import { Input } from "../Input"; +import "./PasswordInput.scss"; + +interface PasswordInputProps extends ComponentProps {} + +export const PasswordInput = ({ ...props }: PasswordInputProps) => { + return ( +
+ +
+
+
+
+ ); +}; From af8378bb8e49cf98bc07bf5991f020fbf2ab089e Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Tue, 30 Jan 2024 15:28:08 +0800 Subject: [PATCH 02/33] chore: import PasswordInput inside of main.ts --- lib/main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main.ts b/lib/main.ts index d5707a4a..4285c69a 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -5,5 +5,5 @@ export { Loader } from "./components/Loader"; export { Tab, Tabs } from "./components/Tabs"; export { Text } from "./components/Text"; export { Tooltip } from "./components/Tooltip"; -export {ToggleSwitch} from "./components/ToggleSwitch" - +export { ToggleSwitch } from "./components/ToggleSwitch"; +export { PasswordInput } from "./components/PasswordInput"; From 13b9d337e9922acc5ea4ca70a76cdb35be7df5de Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Tue, 30 Jan 2024 16:28:02 +0800 Subject: [PATCH 03/33] chore: added password meter colors, width and colors --- lib/components/PasswordInput/index.tsx | 35 +++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index 994d2733..8d131a00 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -1,15 +1,42 @@ import React, { ComponentProps } from "react"; +import clsx from "clsx"; import { Input } from "../Input"; import "./PasswordInput.scss"; -interface PasswordInputProps extends ComponentProps {} +interface PasswordInputProps extends ComponentProps { + score: 0 | 1 | 2 | 3 | 4; +} + +export const PasswordInput = ({ score = 0, ...props }: PasswordInputProps) => { + const PasswordStrengthClass: Record = { + 0: "", + 1: "deriv-password-meter--bar__weak", + 2: "deriv-password-meter--bar__moderate", + 3: "deriv-password-meter--bar__strong", + 4: "deriv-password-meter--bar__complete", + }; + + const PasswordVariant: Record< + PasswordInputProps["score"], + PasswordInputProps["variant"] + > = { + 0: "general", + 1: "error", + 2: "error", + 3: "success", + 4: "success", + }; -export const PasswordInput = ({ ...props }: PasswordInputProps) => { return (
- +
-
+
); From 8f433839daa08431e531e9f2a3c45b30a682aa45 Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Tue, 30 Jan 2024 17:28:16 +0800 Subject: [PATCH 04/33] fix: added helperMessage based on score --- .../PasswordInput/PasswordConstants.ts | 59 ++++++++++++++++++ .../PasswordInput/PasswordInput.scss | 2 +- lib/components/PasswordInput/PasswordUtils.ts | 50 ++++++++++++++++ lib/components/PasswordInput/index.tsx | 60 +++++++++++++++---- package.json | 4 +- 5 files changed, 161 insertions(+), 14 deletions(-) create mode 100644 lib/components/PasswordInput/PasswordConstants.ts create mode 100644 lib/components/PasswordInput/PasswordUtils.ts diff --git a/lib/components/PasswordInput/PasswordConstants.ts b/lib/components/PasswordInput/PasswordConstants.ts new file mode 100644 index 00000000..465a1377 --- /dev/null +++ b/lib/components/PasswordInput/PasswordConstants.ts @@ -0,0 +1,59 @@ +export type passwordKeys = + | "common" + | "commonNames" + | "dates" + | "extendedRepeat" + | "keyPattern" + | "namesByThemselves" + | "pwned" + | "recentYears" + | "sequences" + | "similarToCommon" + | "simpleRepeat" + | "straightRow" + | "topHundred" + | "topTen" + | "userInputs" + | "wordByItself"; + +export const passwordRegex = { + hasLowerCase: /[a-z]/, + hasNumber: /\d/, + hasSymbol: /\W/, + hasUpperCase: /[A-Z]/, + isLengthValid: /^.{8,25}$/, + isPasswordValid: /^(?=.*[a-z])(?=.*\d)(?=.*[A-Z])[!-~]{8,25}$/, +}; + +export const passwordValues = { + longPassword: 12, + maxLength: 25, + minLength: 8, +}; + +export const passwordErrorMessage = { + invalidLength: "You should enter 8-25 characters.", + missingCharacter: + "Password should have lower and uppercase English letters with numbers.", + PasswordError: "That password is incorrect. Please try again.", +}; + +export const warningMessages: Record = { + common: "This is a very common password.", + commonNames: "Common names and surnames are easy to guess.", + dates: "Dates are easy to guess.", + extendedRepeat: + 'Repeated character patterns like "abcabcabc" are easy to guess.', + keyPattern: "Short keyboard patterns are easy to guess.", + namesByThemselves: "Single names or surnames are easy to guess.", + pwned: "Your password was exposed by a data breach on the Internet.", + recentYears: "Recent years are easy to guess.", + sequences: 'Common character sequences like "abc" are easy to guess.', + similarToCommon: "This is similar to a commonly used password.", + simpleRepeat: 'Repeated characters like "aaa" are easy to guess.', + straightRow: "Straight rows of keys on your keyboard are easy to guess.", + topHundred: "This is a frequently used password.", + topTen: "This is a heavily used password.", + userInputs: "There should not be any personal or page related data.", + wordByItself: "Single words are easy to guess.", +}; diff --git a/lib/components/PasswordInput/PasswordInput.scss b/lib/components/PasswordInput/PasswordInput.scss index 227ff2f8..0a279761 100644 --- a/lib/components/PasswordInput/PasswordInput.scss +++ b/lib/components/PasswordInput/PasswordInput.scss @@ -35,7 +35,7 @@ $ERROR: #ec3f3f; &__strong { background-color: $SUCCESS; - width: 50%; + width: 75%; border-radius: 0px 0px 0px 4px; } diff --git a/lib/components/PasswordInput/PasswordUtils.ts b/lib/components/PasswordInput/PasswordUtils.ts new file mode 100644 index 00000000..f88b0481 --- /dev/null +++ b/lib/components/PasswordInput/PasswordUtils.ts @@ -0,0 +1,50 @@ +import { passwordRegex, passwordValues } from "./PasswordConstants"; + +export const validPassword = (value: string) => + passwordRegex.isPasswordValid.test(value); + +export const isPasswordValid = (password: string) => { + return ( + passwordRegex.isPasswordValid.test(password) && + passwordRegex.isLengthValid.test(password) + ); +}; + +export const isPasswordModerate = (password: string) => { + const hasMoreThanOneSymbol = (password.match(/\W/g) ?? []).length > 1; + return ( + isPasswordValid(password) && + hasMoreThanOneSymbol && + password.length >= passwordValues.minLength && + password.length < passwordValues.longPassword && + passwordRegex.isLengthValid + ); +}; + +export const isPasswordStrong = (password: string) => { + const hasMoreThanOneSymbol = (password.match(/\W/g) ?? []).length > 1; + return ( + isPasswordValid(password) && + hasMoreThanOneSymbol && + password.length >= passwordValues.longPassword && + passwordRegex.isLengthValid + ); +}; + +export const calculateScore = (password: string) => { + if (password.length === 0) return 0; + if (!isPasswordValid(password)) return 1; + if ( + !isPasswordStrong(password) && + isPasswordValid(password) && + !isPasswordModerate(password) + ) + return 2; + if ( + !isPasswordStrong(password) && + isPasswordValid(password) && + isPasswordModerate(password) + ) + return 3; + if (isPasswordStrong(password)) return 4; +}; diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index 8d131a00..3f0abc96 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -1,14 +1,45 @@ -import React, { ComponentProps } from "react"; +import React, { ComponentProps, useMemo } from "react"; import clsx from "clsx"; +import { zxcvbn, zxcvbnOptions } from "@zxcvbn-ts/core"; +import { dictionary } from "@zxcvbn-ts/language-common"; import { Input } from "../Input"; import "./PasswordInput.scss"; +import { calculateScore, isPasswordValid } from "./PasswordUtils"; +import { + passwordErrorMessage, + passwordKeys, + passwordRegex, + warningMessages, +} from "./PasswordConstants"; -interface PasswordInputProps extends ComponentProps { - score: 0 | 1 | 2 | 3 | 4; -} +type TScore = 0 | 1 | 2 | 3 | 4; +interface PasswordInputProps extends ComponentProps {} -export const PasswordInput = ({ score = 0, ...props }: PasswordInputProps) => { - const PasswordStrengthClass: Record = { +export const validatePassword = (password: string) => { + const score = calculateScore(password); + let errorMessage = ""; + + const options = { dictionary: { ...dictionary } }; + zxcvbnOptions.setOptions(options); + + const { feedback } = zxcvbn(password); + if (!passwordRegex.isLengthValid.test(password)) { + errorMessage = passwordErrorMessage.invalidLength; + } else if (!isPasswordValid(password)) { + errorMessage = passwordErrorMessage.missingCharacter; + } else { + errorMessage = warningMessages[feedback.warning as passwordKeys] ?? ""; + } + return { errorMessage, score }; +}; + +export const PasswordInput = ({ ...props }: PasswordInputProps) => { + const { errorMessage, score } = useMemo( + () => validatePassword(props.value as string), + [props.value] + ); + + const PasswordStrengthClass: Record = { 0: "", 1: "deriv-password-meter--bar__weak", 2: "deriv-password-meter--bar__moderate", @@ -16,10 +47,7 @@ export const PasswordInput = ({ score = 0, ...props }: PasswordInputProps) => { 4: "deriv-password-meter--bar__complete", }; - const PasswordVariant: Record< - PasswordInputProps["score"], - PasswordInputProps["variant"] - > = { + const PasswordVariant: Record = { 0: "general", 1: "error", 2: "error", @@ -27,14 +55,22 @@ export const PasswordInput = ({ score = 0, ...props }: PasswordInputProps) => { 4: "success", }; + console.log(score); + return (
- +
diff --git a/package.json b/package.json index 27938ddb..a4b86cc9 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "import": "./dist/main.js", "types": "./dist/main.d.ts" } - }, + }, "sideEffects": [ "**/*.css" ], @@ -46,6 +46,8 @@ "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", "@vitejs/plugin-react": "^4.2.1", + "@zxcvbn-ts/core": "^3.0.4", + "@zxcvbn-ts/language-common": "^3.0.4", "clsx": "^2.1.0", "eslint": "^8.55.0", "eslint-plugin-react-hooks": "^4.6.0", From 97da93d93047c6de1e01ce33fd47474bac1470f2 Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Tue, 30 Jan 2024 18:06:35 +0800 Subject: [PATCH 05/33] fix: added warning variant inside for helperMessage --- lib/components/Input/HelperMessage.tsx | 1 + lib/components/Input/Input.scss | 5 +++++ lib/components/Input/index.tsx | 4 +++- lib/components/PasswordInput/PasswordInput.scss | 1 + lib/components/PasswordInput/index.tsx | 2 +- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/components/Input/HelperMessage.tsx b/lib/components/Input/HelperMessage.tsx index 7f03ecc0..9efec8f1 100644 --- a/lib/components/Input/HelperMessage.tsx +++ b/lib/components/Input/HelperMessage.tsx @@ -13,6 +13,7 @@ export interface HelperMessageProps { const MessageVariant: Record = { general: "deriv-helper-message__general", success: "deriv-helper-message__success", + warning: "deriv-helper-message__warning", error: "deriv-helper-message__error", }; diff --git a/lib/components/Input/Input.scss b/lib/components/Input/Input.scss index ce714132..3a09ab0f 100644 --- a/lib/components/Input/Input.scss +++ b/lib/components/Input/Input.scss @@ -2,6 +2,7 @@ $disabled_color: #d6d6d6; $inactive_color: #999999; $active_color: #85acb0; $success_color: #4bb4b3; +$warning_color: #ffad3a; $error_field: #ec3f3f; $inactive_color: #999999; $border: 1px solid; @@ -83,6 +84,7 @@ $border: 1px solid; position: absolute; left: 16px; margin-top: 2px; + line-height: 1; } &--right-content { @@ -122,6 +124,9 @@ $border: 1px solid; &__success { color: $success_color; } + &__warning { + color: $warning_color; + } &__error { color: $error_field; } diff --git a/lib/components/Input/index.tsx b/lib/components/Input/index.tsx index 7bb9736d..8d934169 100644 --- a/lib/components/Input/index.tsx +++ b/lib/components/Input/index.tsx @@ -3,7 +3,7 @@ import clsx from "clsx"; import HelperMessage from "./HelperMessage"; import "./Input.scss"; -export type InputVariants = "general" | "success" | "error"; +export type InputVariants = "general" | "success" | "error" | "warning"; interface InputProps extends Omit, "style" | "placeholder"> { label?: string; @@ -16,12 +16,14 @@ interface InputProps const InputVariant: Record = { general: "deriv-input--field__general", success: "deriv-input--field__success", + warning: "deriv-input--field__general", error: "deriv-input--field__error", }; const LabelVariant: Record = { general: "deriv-input--label__general", success: "deriv-input--label__success", + warning: "deriv-input--label__general", error: "deriv-input--label__error", }; diff --git a/lib/components/PasswordInput/PasswordInput.scss b/lib/components/PasswordInput/PasswordInput.scss index 0a279761..9df3f7ec 100644 --- a/lib/components/PasswordInput/PasswordInput.scss +++ b/lib/components/PasswordInput/PasswordInput.scss @@ -20,6 +20,7 @@ $ERROR: #ec3f3f; .deriv-password-meter--bar { height: 100%; border-radius: 0px 0px 4px 4px; + transition: "width 0.25s ease-in-out"; &__weak { background-color: $ERROR; diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index 3f0abc96..aa44a83b 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -50,7 +50,7 @@ export const PasswordInput = ({ ...props }: PasswordInputProps) => { const PasswordVariant: Record = { 0: "general", 1: "error", - 2: "error", + 2: "warning", 3: "success", 4: "success", }; From d6c382d3b85b0bb32bec747a505bdecbcd3a897d Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Tue, 30 Jan 2024 21:13:55 +0800 Subject: [PATCH 06/33] chore: refactor PasswordMeter as a child component --- .../PasswordInput/PasswordConstants.ts | 2 + .../PasswordInput/PasswordMeter.tsx | 26 +++++++++++ lib/components/PasswordInput/index.tsx | 43 ++++++------------- 3 files changed, 41 insertions(+), 30 deletions(-) create mode 100644 lib/components/PasswordInput/PasswordMeter.tsx diff --git a/lib/components/PasswordInput/PasswordConstants.ts b/lib/components/PasswordInput/PasswordConstants.ts index 465a1377..d585f367 100644 --- a/lib/components/PasswordInput/PasswordConstants.ts +++ b/lib/components/PasswordInput/PasswordConstants.ts @@ -1,3 +1,5 @@ +export type TScore = 0 | 1 | 2 | 3 | 4; + export type passwordKeys = | "common" | "commonNames" diff --git a/lib/components/PasswordInput/PasswordMeter.tsx b/lib/components/PasswordInput/PasswordMeter.tsx new file mode 100644 index 00000000..df332aab --- /dev/null +++ b/lib/components/PasswordInput/PasswordMeter.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import clsx from "clsx"; +import { TScore } from "./PasswordConstants"; + +type PasswordMeterProps = { + score: TScore; +}; + +const PasswordStrengthClass: Record = { + 0: "", + 1: "deriv-password-meter--bar__weak", + 2: "deriv-password-meter--bar__moderate", + 3: "deriv-password-meter--bar__strong", + 4: "deriv-password-meter--bar__complete", +}; + +export const PasswordMeter = ({ score }: PasswordMeterProps) => ( +
+
+
+); diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index aa44a83b..37c37637 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -1,19 +1,17 @@ import React, { ComponentProps, useMemo } from "react"; -import clsx from "clsx"; import { zxcvbn, zxcvbnOptions } from "@zxcvbn-ts/core"; import { dictionary } from "@zxcvbn-ts/language-common"; import { Input } from "../Input"; import "./PasswordInput.scss"; import { calculateScore, isPasswordValid } from "./PasswordUtils"; import { + TScore, passwordErrorMessage, passwordKeys, passwordRegex, warningMessages, } from "./PasswordConstants"; - -type TScore = 0 | 1 | 2 | 3 | 4; -interface PasswordInputProps extends ComponentProps {} +import { PasswordMeter } from "./PasswordMeter"; export const validatePassword = (password: string) => { const score = calculateScore(password); @@ -33,30 +31,22 @@ export const validatePassword = (password: string) => { return { errorMessage, score }; }; +const PasswordVariant: Record = { + 0: "general", + 1: "error", + 2: "warning", + 3: "success", + 4: "success", +}; + +interface PasswordInputProps extends ComponentProps {} + export const PasswordInput = ({ ...props }: PasswordInputProps) => { const { errorMessage, score } = useMemo( () => validatePassword(props.value as string), [props.value] ); - const PasswordStrengthClass: Record = { - 0: "", - 1: "deriv-password-meter--bar__weak", - 2: "deriv-password-meter--bar__moderate", - 3: "deriv-password-meter--bar__strong", - 4: "deriv-password-meter--bar__complete", - }; - - const PasswordVariant: Record = { - 0: "general", - 1: "error", - 2: "warning", - 3: "success", - 4: "success", - }; - - console.log(score); - return (
{ {...props} variant={PasswordVariant[score as TScore]} /> -
-
-
+
); }; From 83060c37d8a7895ed60428169d22ac051bdcf4a4 Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Tue, 30 Jan 2024 21:40:13 +0800 Subject: [PATCH 07/33] added hidePasswordMeter --- lib/components/PasswordInput/index.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index 37c37637..1ed89b9f 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -39,9 +39,14 @@ const PasswordVariant: Record = { 4: "success", }; -interface PasswordInputProps extends ComponentProps {} +interface PasswordInputProps extends ComponentProps { + hidePasswordMeter?: boolean; +} -export const PasswordInput = ({ ...props }: PasswordInputProps) => { +export const PasswordInput = ({ + hidePasswordMeter, + ...props +}: PasswordInputProps) => { const { errorMessage, score } = useMemo( () => validatePassword(props.value as string), [props.value] @@ -56,7 +61,7 @@ export const PasswordInput = ({ ...props }: PasswordInputProps) => { {...props} variant={PasswordVariant[score as TScore]} /> - + {!hidePasswordMeter && }
); }; From 7ea72ace1a11162ff18d7381e8b3ff2ca36a7615 Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Wed, 31 Jan 2024 10:13:17 +0800 Subject: [PATCH 08/33] add package-lock --- package-lock.json | 243 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) diff --git a/package-lock.json b/package-lock.json index d9031dfe..a6b2930c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,8 @@ "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", "@vitejs/plugin-react": "^4.2.1", + "@zxcvbn-ts/core": "^3.0.4", + "@zxcvbn-ts/language-common": "^3.0.4", "clsx": "^2.1.0", "eslint": "^8.55.0", "eslint-plugin-react-hooks": "^4.6.0", @@ -7112,6 +7114,21 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/@zxcvbn-ts/core": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz", + "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==", + "dev": true, + "dependencies": { + "fastest-levenshtein": "1.0.16" + } + }, + "node_modules/@zxcvbn-ts/language-common": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz", + "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==", + "dev": true + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -10033,6 +10050,15 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, "node_modules/fastq": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", @@ -13029,6 +13055,7 @@ }, "node_modules/npm/node_modules/@colors/colors": { "version": "1.5.0", + "dev": true, "inBundle": true, "license": "MIT", "optional": true, @@ -13038,6 +13065,7 @@ }, "node_modules/npm/node_modules/@isaacs/cliui": { "version": "8.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13054,6 +13082,7 @@ }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.0.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13065,11 +13094,13 @@ }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13086,6 +13117,7 @@ }, "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13100,11 +13132,13 @@ }, "node_modules/npm/node_modules/@isaacs/string-locale-compare": { "version": "1.1.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { "version": "2.2.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13120,6 +13154,7 @@ }, "node_modules/npm/node_modules/@npmcli/arborist": { "version": "7.3.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13166,6 +13201,7 @@ }, "node_modules/npm/node_modules/@npmcli/config": { "version": "8.1.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13184,6 +13220,7 @@ }, "node_modules/npm/node_modules/@npmcli/disparity-colors": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13195,6 +13232,7 @@ }, "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13209,6 +13247,7 @@ }, "node_modules/npm/node_modules/@npmcli/fs": { "version": "3.1.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13220,6 +13259,7 @@ }, "node_modules/npm/node_modules/@npmcli/git": { "version": "5.0.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13238,6 +13278,7 @@ }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { "version": "2.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13253,6 +13294,7 @@ }, "node_modules/npm/node_modules/@npmcli/map-workspaces": { "version": "3.0.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13267,6 +13309,7 @@ }, "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13281,6 +13324,7 @@ }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -13289,6 +13333,7 @@ }, "node_modules/npm/node_modules/@npmcli/node-gyp": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -13297,6 +13342,7 @@ }, "node_modules/npm/node_modules/@npmcli/package-json": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13314,6 +13360,7 @@ }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { "version": "7.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13325,6 +13372,7 @@ }, "node_modules/npm/node_modules/@npmcli/query": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13336,6 +13384,7 @@ }, "node_modules/npm/node_modules/@npmcli/run-script": { "version": "7.0.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13351,6 +13400,7 @@ }, "node_modules/npm/node_modules/@pkgjs/parseargs": { "version": "0.11.0", + "dev": true, "inBundle": true, "license": "MIT", "optional": true, @@ -13360,6 +13410,7 @@ }, "node_modules/npm/node_modules/@sigstore/bundle": { "version": "2.1.1", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -13371,6 +13422,7 @@ }, "node_modules/npm/node_modules/@sigstore/core": { "version": "0.2.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { @@ -13379,6 +13431,7 @@ }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { "version": "0.2.1", + "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { @@ -13387,6 +13440,7 @@ }, "node_modules/npm/node_modules/@sigstore/sign": { "version": "2.2.1", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -13401,6 +13455,7 @@ }, "node_modules/npm/node_modules/@sigstore/tuf": { "version": "2.3.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -13413,6 +13468,7 @@ }, "node_modules/npm/node_modules/@sigstore/verify": { "version": "0.1.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -13426,6 +13482,7 @@ }, "node_modules/npm/node_modules/@tufjs/canonical-json": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13434,6 +13491,7 @@ }, "node_modules/npm/node_modules/@tufjs/models": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13446,6 +13504,7 @@ }, "node_modules/npm/node_modules/abbrev": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -13454,6 +13513,7 @@ }, "node_modules/npm/node_modules/agent-base": { "version": "7.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13465,6 +13525,7 @@ }, "node_modules/npm/node_modules/aggregate-error": { "version": "3.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13477,6 +13538,7 @@ }, "node_modules/npm/node_modules/ansi-regex": { "version": "5.0.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13485,6 +13547,7 @@ }, "node_modules/npm/node_modules/ansi-styles": { "version": "6.2.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13496,16 +13559,19 @@ }, "node_modules/npm/node_modules/aproba": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/archy": { "version": "1.0.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/are-we-there-yet": { "version": "4.0.2", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -13514,11 +13580,13 @@ }, "node_modules/npm/node_modules/balanced-match": { "version": "1.0.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/bin-links": { "version": "4.0.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13533,6 +13601,7 @@ }, "node_modules/npm/node_modules/binary-extensions": { "version": "2.2.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13541,6 +13610,7 @@ }, "node_modules/npm/node_modules/brace-expansion": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13549,6 +13619,7 @@ }, "node_modules/npm/node_modules/builtins": { "version": "5.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13557,6 +13628,7 @@ }, "node_modules/npm/node_modules/cacache": { "version": "18.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13579,6 +13651,7 @@ }, "node_modules/npm/node_modules/chalk": { "version": "5.3.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13590,6 +13663,7 @@ }, "node_modules/npm/node_modules/chownr": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -13598,6 +13672,7 @@ }, "node_modules/npm/node_modules/ci-info": { "version": "4.0.0", + "dev": true, "funding": [ { "type": "github", @@ -13612,6 +13687,7 @@ }, "node_modules/npm/node_modules/cidr-regex": { "version": "4.0.3", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -13623,6 +13699,7 @@ }, "node_modules/npm/node_modules/clean-stack": { "version": "2.2.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13631,6 +13708,7 @@ }, "node_modules/npm/node_modules/cli-columns": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13643,6 +13721,7 @@ }, "node_modules/npm/node_modules/cli-table3": { "version": "0.6.3", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13657,6 +13736,7 @@ }, "node_modules/npm/node_modules/clone": { "version": "1.0.4", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13665,6 +13745,7 @@ }, "node_modules/npm/node_modules/cmd-shim": { "version": "6.0.2", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -13673,6 +13754,7 @@ }, "node_modules/npm/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13684,11 +13766,13 @@ }, "node_modules/npm/node_modules/color-name": { "version": "1.1.4", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/color-support": { "version": "1.1.3", + "dev": true, "inBundle": true, "license": "ISC", "bin": { @@ -13697,6 +13781,7 @@ }, "node_modules/npm/node_modules/columnify": { "version": "1.6.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13709,16 +13794,19 @@ }, "node_modules/npm/node_modules/common-ancestor-path": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/console-control-strings": { "version": "1.1.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/cross-spawn": { "version": "7.0.3", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13732,6 +13820,7 @@ }, "node_modules/npm/node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13746,6 +13835,7 @@ }, "node_modules/npm/node_modules/cssesc": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "MIT", "bin": { @@ -13757,6 +13847,7 @@ }, "node_modules/npm/node_modules/debug": { "version": "4.3.4", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13773,11 +13864,13 @@ }, "node_modules/npm/node_modules/debug/node_modules/ms": { "version": "2.1.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/defaults": { "version": "1.0.4", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13789,6 +13882,7 @@ }, "node_modules/npm/node_modules/diff": { "version": "5.1.0", + "dev": true, "inBundle": true, "license": "BSD-3-Clause", "engines": { @@ -13797,16 +13891,19 @@ }, "node_modules/npm/node_modules/eastasianwidth": { "version": "0.2.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/emoji-regex": { "version": "8.0.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/encoding": { "version": "0.1.13", + "dev": true, "inBundle": true, "license": "MIT", "optional": true, @@ -13816,6 +13913,7 @@ }, "node_modules/npm/node_modules/env-paths": { "version": "2.2.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13824,16 +13922,19 @@ }, "node_modules/npm/node_modules/err-code": { "version": "2.0.3", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/exponential-backoff": { "version": "3.1.1", + "dev": true, "inBundle": true, "license": "Apache-2.0" }, "node_modules/npm/node_modules/fastest-levenshtein": { "version": "1.0.16", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -13842,6 +13943,7 @@ }, "node_modules/npm/node_modules/foreground-child": { "version": "3.1.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13857,6 +13959,7 @@ }, "node_modules/npm/node_modules/fs-minipass": { "version": "3.0.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13868,6 +13971,7 @@ }, "node_modules/npm/node_modules/function-bind": { "version": "1.1.2", + "dev": true, "inBundle": true, "license": "MIT", "funding": { @@ -13876,6 +13980,7 @@ }, "node_modules/npm/node_modules/gauge": { "version": "5.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13894,6 +13999,7 @@ }, "node_modules/npm/node_modules/glob": { "version": "10.3.10", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13915,16 +14021,19 @@ }, "node_modules/npm/node_modules/graceful-fs": { "version": "4.2.11", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/has-unicode": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/hasown": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13936,6 +14045,7 @@ }, "node_modules/npm/node_modules/hosted-git-info": { "version": "7.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13947,11 +14057,13 @@ }, "node_modules/npm/node_modules/http-cache-semantics": { "version": "4.1.1", + "dev": true, "inBundle": true, "license": "BSD-2-Clause" }, "node_modules/npm/node_modules/http-proxy-agent": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13964,6 +14076,7 @@ }, "node_modules/npm/node_modules/https-proxy-agent": { "version": "7.0.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -13976,6 +14089,7 @@ }, "node_modules/npm/node_modules/iconv-lite": { "version": "0.6.3", + "dev": true, "inBundle": true, "license": "MIT", "optional": true, @@ -13988,6 +14102,7 @@ }, "node_modules/npm/node_modules/ignore-walk": { "version": "6.0.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -13999,6 +14114,7 @@ }, "node_modules/npm/node_modules/imurmurhash": { "version": "0.1.4", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14007,6 +14123,7 @@ }, "node_modules/npm/node_modules/indent-string": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14015,6 +14132,7 @@ }, "node_modules/npm/node_modules/ini": { "version": "4.1.1", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14023,6 +14141,7 @@ }, "node_modules/npm/node_modules/init-package-json": { "version": "6.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14040,11 +14159,13 @@ }, "node_modules/npm/node_modules/ip": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/ip-regex": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14056,6 +14177,7 @@ }, "node_modules/npm/node_modules/is-cidr": { "version": "5.0.3", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -14067,6 +14189,7 @@ }, "node_modules/npm/node_modules/is-core-module": { "version": "2.13.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14078,6 +14201,7 @@ }, "node_modules/npm/node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14086,16 +14210,19 @@ }, "node_modules/npm/node_modules/is-lambda": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/isexe": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { "version": "2.3.6", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -14113,6 +14240,7 @@ }, "node_modules/npm/node_modules/json-parse-even-better-errors": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14121,6 +14249,7 @@ }, "node_modules/npm/node_modules/json-stringify-nice": { "version": "1.1.4", + "dev": true, "inBundle": true, "license": "ISC", "funding": { @@ -14129,6 +14258,7 @@ }, "node_modules/npm/node_modules/jsonparse": { "version": "1.3.1", + "dev": true, "engines": [ "node >= 0.2.0" ], @@ -14137,16 +14267,19 @@ }, "node_modules/npm/node_modules/just-diff": { "version": "6.0.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/just-diff-apply": { "version": "5.5.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { "version": "8.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14159,6 +14292,7 @@ }, "node_modules/npm/node_modules/libnpmdiff": { "version": "6.0.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14178,6 +14312,7 @@ }, "node_modules/npm/node_modules/libnpmexec": { "version": "7.0.7", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14199,6 +14334,7 @@ }, "node_modules/npm/node_modules/libnpmfund": { "version": "5.0.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14210,6 +14346,7 @@ }, "node_modules/npm/node_modules/libnpmhook": { "version": "10.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14222,6 +14359,7 @@ }, "node_modules/npm/node_modules/libnpmorg": { "version": "6.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14234,6 +14372,7 @@ }, "node_modules/npm/node_modules/libnpmpack": { "version": "6.0.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14248,6 +14387,7 @@ }, "node_modules/npm/node_modules/libnpmpublish": { "version": "9.0.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14266,6 +14406,7 @@ }, "node_modules/npm/node_modules/libnpmsearch": { "version": "7.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14277,6 +14418,7 @@ }, "node_modules/npm/node_modules/libnpmteam": { "version": "6.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14289,6 +14431,7 @@ }, "node_modules/npm/node_modules/libnpmversion": { "version": "5.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14304,6 +14447,7 @@ }, "node_modules/npm/node_modules/lru-cache": { "version": "10.1.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14312,6 +14456,7 @@ }, "node_modules/npm/node_modules/make-fetch-happen": { "version": "13.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14333,6 +14478,7 @@ }, "node_modules/npm/node_modules/minimatch": { "version": "9.0.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14347,6 +14493,7 @@ }, "node_modules/npm/node_modules/minipass": { "version": "7.0.4", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14355,6 +14502,7 @@ }, "node_modules/npm/node_modules/minipass-collect": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14366,6 +14514,7 @@ }, "node_modules/npm/node_modules/minipass-fetch": { "version": "3.0.4", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14382,6 +14531,7 @@ }, "node_modules/npm/node_modules/minipass-flush": { "version": "1.0.5", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14393,6 +14543,7 @@ }, "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14404,6 +14555,7 @@ }, "node_modules/npm/node_modules/minipass-json-stream": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14413,6 +14565,7 @@ }, "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14424,6 +14577,7 @@ }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14435,6 +14589,7 @@ }, "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14446,6 +14601,7 @@ }, "node_modules/npm/node_modules/minipass-sized": { "version": "1.0.3", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14457,6 +14613,7 @@ }, "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14468,6 +14625,7 @@ }, "node_modules/npm/node_modules/minizlib": { "version": "2.1.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14480,6 +14638,7 @@ }, "node_modules/npm/node_modules/minizlib/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14491,6 +14650,7 @@ }, "node_modules/npm/node_modules/mkdirp": { "version": "1.0.4", + "dev": true, "inBundle": true, "license": "MIT", "bin": { @@ -14502,11 +14662,13 @@ }, "node_modules/npm/node_modules/ms": { "version": "2.1.3", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { "version": "1.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14515,6 +14677,7 @@ }, "node_modules/npm/node_modules/negotiator": { "version": "0.6.3", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14523,6 +14686,7 @@ }, "node_modules/npm/node_modules/node-gyp": { "version": "10.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14546,6 +14710,7 @@ }, "node_modules/npm/node_modules/nopt": { "version": "7.2.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14560,6 +14725,7 @@ }, "node_modules/npm/node_modules/normalize-package-data": { "version": "6.0.0", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -14574,6 +14740,7 @@ }, "node_modules/npm/node_modules/npm-audit-report": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14582,6 +14749,7 @@ }, "node_modules/npm/node_modules/npm-bundled": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14593,6 +14761,7 @@ }, "node_modules/npm/node_modules/npm-install-checks": { "version": "6.3.0", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { @@ -14604,6 +14773,7 @@ }, "node_modules/npm/node_modules/npm-normalize-package-bin": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14612,6 +14782,7 @@ }, "node_modules/npm/node_modules/npm-package-arg": { "version": "11.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14626,6 +14797,7 @@ }, "node_modules/npm/node_modules/npm-packlist": { "version": "8.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14637,6 +14809,7 @@ }, "node_modules/npm/node_modules/npm-pick-manifest": { "version": "9.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14651,6 +14824,7 @@ }, "node_modules/npm/node_modules/npm-profile": { "version": "9.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14663,6 +14837,7 @@ }, "node_modules/npm/node_modules/npm-registry-fetch": { "version": "16.1.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14680,6 +14855,7 @@ }, "node_modules/npm/node_modules/npm-user-validate": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "BSD-2-Clause", "engines": { @@ -14688,6 +14864,7 @@ }, "node_modules/npm/node_modules/npmlog": { "version": "7.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14702,6 +14879,7 @@ }, "node_modules/npm/node_modules/p-map": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14716,6 +14894,7 @@ }, "node_modules/npm/node_modules/pacote": { "version": "17.0.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14747,6 +14926,7 @@ }, "node_modules/npm/node_modules/parse-conflict-json": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14760,6 +14940,7 @@ }, "node_modules/npm/node_modules/path-key": { "version": "3.1.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14768,6 +14949,7 @@ }, "node_modules/npm/node_modules/path-scurry": { "version": "1.10.1", + "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -14783,6 +14965,7 @@ }, "node_modules/npm/node_modules/postcss-selector-parser": { "version": "6.0.15", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14795,6 +14978,7 @@ }, "node_modules/npm/node_modules/proc-log": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14803,6 +14987,7 @@ }, "node_modules/npm/node_modules/promise-all-reject-late": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "ISC", "funding": { @@ -14811,6 +14996,7 @@ }, "node_modules/npm/node_modules/promise-call-limit": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "ISC", "funding": { @@ -14819,11 +15005,13 @@ }, "node_modules/npm/node_modules/promise-inflight": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/promise-retry": { "version": "2.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14836,6 +15024,7 @@ }, "node_modules/npm/node_modules/promzard": { "version": "1.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14847,6 +15036,7 @@ }, "node_modules/npm/node_modules/qrcode-terminal": { "version": "0.12.0", + "dev": true, "inBundle": true, "bin": { "qrcode-terminal": "bin/qrcode-terminal.js" @@ -14854,6 +15044,7 @@ }, "node_modules/npm/node_modules/read": { "version": "2.1.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14865,6 +15056,7 @@ }, "node_modules/npm/node_modules/read-cmd-shim": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14873,6 +15065,7 @@ }, "node_modules/npm/node_modules/read-package-json": { "version": "7.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14887,6 +15080,7 @@ }, "node_modules/npm/node_modules/read-package-json-fast": { "version": "3.0.2", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14899,6 +15093,7 @@ }, "node_modules/npm/node_modules/retry": { "version": "0.12.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14907,12 +15102,14 @@ }, "node_modules/npm/node_modules/safer-buffer": { "version": "2.1.2", + "dev": true, "inBundle": true, "license": "MIT", "optional": true }, "node_modules/npm/node_modules/semver": { "version": "7.5.4", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14927,6 +15124,7 @@ }, "node_modules/npm/node_modules/semver/node_modules/lru-cache": { "version": "6.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -14938,11 +15136,13 @@ }, "node_modules/npm/node_modules/set-blocking": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/shebang-command": { "version": "2.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -14954,6 +15154,7 @@ }, "node_modules/npm/node_modules/shebang-regex": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14962,6 +15163,7 @@ }, "node_modules/npm/node_modules/signal-exit": { "version": "4.1.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -14973,6 +15175,7 @@ }, "node_modules/npm/node_modules/sigstore": { "version": "2.2.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -14989,6 +15192,7 @@ }, "node_modules/npm/node_modules/smart-buffer": { "version": "4.2.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -14998,6 +15202,7 @@ }, "node_modules/npm/node_modules/socks": { "version": "2.7.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15011,6 +15216,7 @@ }, "node_modules/npm/node_modules/socks-proxy-agent": { "version": "8.0.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15024,6 +15230,7 @@ }, "node_modules/npm/node_modules/spdx-correct": { "version": "3.2.0", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -15033,11 +15240,13 @@ }, "node_modules/npm/node_modules/spdx-exceptions": { "version": "2.3.0", + "dev": true, "inBundle": true, "license": "CC-BY-3.0" }, "node_modules/npm/node_modules/spdx-expression-parse": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15047,11 +15256,13 @@ }, "node_modules/npm/node_modules/spdx-license-ids": { "version": "3.0.16", + "dev": true, "inBundle": true, "license": "CC0-1.0" }, "node_modules/npm/node_modules/ssri": { "version": "10.0.5", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15063,6 +15274,7 @@ }, "node_modules/npm/node_modules/string-width": { "version": "4.2.3", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15077,6 +15289,7 @@ "node_modules/npm/node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15090,6 +15303,7 @@ }, "node_modules/npm/node_modules/strip-ansi": { "version": "6.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15102,6 +15316,7 @@ "node_modules/npm/node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15113,6 +15328,7 @@ }, "node_modules/npm/node_modules/supports-color": { "version": "9.4.0", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -15124,6 +15340,7 @@ }, "node_modules/npm/node_modules/tar": { "version": "6.2.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15140,6 +15357,7 @@ }, "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { "version": "2.1.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15151,6 +15369,7 @@ }, "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { "version": "3.3.6", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15162,6 +15381,7 @@ }, "node_modules/npm/node_modules/tar/node_modules/minipass": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -15170,16 +15390,19 @@ }, "node_modules/npm/node_modules/text-table": { "version": "0.2.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/tiny-relative-date": { "version": "1.3.0", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -15188,6 +15411,7 @@ }, "node_modules/npm/node_modules/tuf-js": { "version": "2.2.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15201,6 +15425,7 @@ }, "node_modules/npm/node_modules/unique-filename": { "version": "3.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15212,6 +15437,7 @@ }, "node_modules/npm/node_modules/unique-slug": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15223,11 +15449,13 @@ }, "node_modules/npm/node_modules/util-deprecate": { "version": "1.0.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/validate-npm-package-license": { "version": "3.0.4", + "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { @@ -15237,6 +15465,7 @@ }, "node_modules/npm/node_modules/validate-npm-package-name": { "version": "5.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15248,11 +15477,13 @@ }, "node_modules/npm/node_modules/walk-up-path": { "version": "3.0.1", + "dev": true, "inBundle": true, "license": "ISC" }, "node_modules/npm/node_modules/wcwidth": { "version": "1.0.1", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15261,6 +15492,7 @@ }, "node_modules/npm/node_modules/which": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15275,6 +15507,7 @@ }, "node_modules/npm/node_modules/which/node_modules/isexe": { "version": "3.1.1", + "dev": true, "inBundle": true, "license": "ISC", "engines": { @@ -15283,6 +15516,7 @@ }, "node_modules/npm/node_modules/wide-align": { "version": "1.1.5", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15291,6 +15525,7 @@ }, "node_modules/npm/node_modules/wrap-ansi": { "version": "8.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15308,6 +15543,7 @@ "node_modules/npm/node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15324,6 +15560,7 @@ }, "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15338,6 +15575,7 @@ }, "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -15349,11 +15587,13 @@ }, "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "9.2.2", + "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { "version": "5.1.2", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15370,6 +15610,7 @@ }, "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", + "dev": true, "inBundle": true, "license": "MIT", "dependencies": { @@ -15384,6 +15625,7 @@ }, "node_modules/npm/node_modules/write-file-atomic": { "version": "5.0.1", + "dev": true, "inBundle": true, "license": "ISC", "dependencies": { @@ -15396,6 +15638,7 @@ }, "node_modules/npm/node_modules/yallist": { "version": "4.0.0", + "dev": true, "inBundle": true, "license": "ISC" }, From 12458ced635b2400640ea2c5f92146cfa7f20ce4 Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Wed, 31 Jan 2024 11:50:51 +0800 Subject: [PATCH 09/33] fix: added variants according to production --- .../PasswordInput/PasswordInput.scss | 12 +++++++ .../PasswordInput/PasswordMeter.tsx | 2 +- lib/components/PasswordInput/index.tsx | 36 ++++++++++++++++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/lib/components/PasswordInput/PasswordInput.scss b/lib/components/PasswordInput/PasswordInput.scss index 9df3f7ec..2abf4593 100644 --- a/lib/components/PasswordInput/PasswordInput.scss +++ b/lib/components/PasswordInput/PasswordInput.scss @@ -22,6 +22,18 @@ $ERROR: #ec3f3f; border-radius: 0px 0px 4px 4px; transition: "width 0.25s ease-in-out"; + &__initial { + background-color: $NEUTRAL; + width: 0%; + border-radius: 0px 0px 0px 4px; + } + + &__error { + background-color: $ERROR; + width: 0%; + border-radius: 0px 0px 0px 4px; + } + &__weak { background-color: $ERROR; width: 25%; diff --git a/lib/components/PasswordInput/PasswordMeter.tsx b/lib/components/PasswordInput/PasswordMeter.tsx index df332aab..8c286fb1 100644 --- a/lib/components/PasswordInput/PasswordMeter.tsx +++ b/lib/components/PasswordInput/PasswordMeter.tsx @@ -7,7 +7,7 @@ type PasswordMeterProps = { }; const PasswordStrengthClass: Record = { - 0: "", + 0: "deriv-password-meter--bar__error", 1: "deriv-password-meter--bar__weak", 2: "deriv-password-meter--bar__moderate", 3: "deriv-password-meter--bar__strong", diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index 1ed89b9f..bd0cb555 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -1,8 +1,13 @@ -import React, { ComponentProps, useMemo } from "react"; +import React, { + ChangeEvent, + ComponentProps, + useCallback, + useMemo, + useState, +} from "react"; import { zxcvbn, zxcvbnOptions } from "@zxcvbn-ts/core"; import { dictionary } from "@zxcvbn-ts/language-common"; import { Input } from "../Input"; -import "./PasswordInput.scss"; import { calculateScore, isPasswordValid } from "./PasswordUtils"; import { TScore, @@ -12,6 +17,7 @@ import { warningMessages, } from "./PasswordConstants"; import { PasswordMeter } from "./PasswordMeter"; +import "./PasswordInput.scss"; export const validatePassword = (password: string) => { const score = calculateScore(password); @@ -32,7 +38,7 @@ export const validatePassword = (password: string) => { }; const PasswordVariant: Record = { - 0: "general", + 0: "error", 1: "error", 2: "warning", 3: "success", @@ -47,19 +53,39 @@ export const PasswordInput = ({ hidePasswordMeter, ...props }: PasswordInputProps) => { + const [isTouched, setIsTouched] = useState(false); + const { errorMessage, score } = useMemo( () => validatePassword(props.value as string), [props.value] ); + const handleChange = useCallback( + (e: ChangeEvent) => { + props.onChange?.(e); + if (!isTouched) { + setIsTouched(true); + } + }, + [isTouched, props.onChange] + ); + + const handleBlur = useCallback(() => { + if (!isTouched) { + setIsTouched(true); + } + }, [isTouched]); + return (
{!hidePasswordMeter && }
From ce0cfcfae39111967cf1a234c2ef6fc2223a274b Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Wed, 31 Jan 2024 13:37:18 +0800 Subject: [PATCH 10/33] change props to rest to match the rest of the components --- lib/components/PasswordInput/index.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index bd0cb555..b5225c40 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -51,23 +51,23 @@ interface PasswordInputProps extends ComponentProps { export const PasswordInput = ({ hidePasswordMeter, - ...props + ...rest }: PasswordInputProps) => { const [isTouched, setIsTouched] = useState(false); const { errorMessage, score } = useMemo( - () => validatePassword(props.value as string), - [props.value] + () => validatePassword(rest.value as string), + [rest.value] ); const handleChange = useCallback( (e: ChangeEvent) => { - props.onChange?.(e); + rest.onChange?.(e); if (!isTouched) { setIsTouched(true); } }, - [isTouched, props.onChange] + [isTouched, rest.onChange] ); const handleBlur = useCallback(() => { @@ -80,12 +80,12 @@ export const PasswordInput = ({
{!hidePasswordMeter && }
From afb6eca6f9c4cb3edf8c4d1e8596e793076ea0ca Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Wed, 31 Jan 2024 15:09:07 +0800 Subject: [PATCH 11/33] added show password and hide password icon --- .../PasswordInput/PasswordInput.scss | 10 +++++ lib/components/PasswordInput/index.tsx | 39 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib/components/PasswordInput/PasswordInput.scss b/lib/components/PasswordInput/PasswordInput.scss index 2abf4593..6d33b224 100644 --- a/lib/components/PasswordInput/PasswordInput.scss +++ b/lib/components/PasswordInput/PasswordInput.scss @@ -15,6 +15,16 @@ $ERROR: #ec3f3f; height: 4px; background-color: $NEUTRAL; } + &-icon { + cursor: pointer; + background-color: inherit; + display: flex; + align-items: center; + justify-content: center; + svg { + color: $NEUTRAL; + } + } } .deriv-password-meter--bar { diff --git a/lib/components/PasswordInput/index.tsx b/lib/components/PasswordInput/index.tsx index b5225c40..0c156c1d 100644 --- a/lib/components/PasswordInput/index.tsx +++ b/lib/components/PasswordInput/index.tsx @@ -54,6 +54,7 @@ export const PasswordInput = ({ ...rest }: PasswordInputProps) => { const [isTouched, setIsTouched] = useState(false); + const [showPassword, setShowPassword] = useState(false); const { errorMessage, score } = useMemo( () => validatePassword(rest.value as string), @@ -79,12 +80,48 @@ export const PasswordInput = ({ return (
setShowPassword(!showPassword)} + > + {showPassword ? ( + + + + + + + + + ) : ( + + + + + + + + + )} + + } {...rest} /> {!hidePasswordMeter && } From 6fdaad794b1717b83c8f9fe47f985e17faf60b5e Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Wed, 31 Jan 2024 17:56:21 +0800 Subject: [PATCH 12/33] fix: change css for input --- lib/components/Input/HelperMessage.tsx | 7 ++- lib/components/Input/Input.scss | 83 +++++++++++++------------- lib/components/Input/index.tsx | 40 +++++++++---- 3 files changed, 72 insertions(+), 58 deletions(-) diff --git a/lib/components/Input/HelperMessage.tsx b/lib/components/Input/HelperMessage.tsx index 9efec8f1..b38753e3 100644 --- a/lib/components/Input/HelperMessage.tsx +++ b/lib/components/Input/HelperMessage.tsx @@ -9,8 +9,8 @@ export interface HelperMessageProps { variant?: InputVariants; disabled?: boolean; } - -const MessageVariant: Record = { +type TMessageVariant = Exclude; +const MessageVariant: Record = { general: "deriv-helper-message__general", success: "deriv-helper-message__success", warning: "deriv-helper-message__warning", @@ -26,7 +26,8 @@ const HelperMessage = ({

{message} diff --git a/lib/components/Input/Input.scss b/lib/components/Input/Input.scss index 3a09ab0f..6adc8380 100644 --- a/lib/components/Input/Input.scss +++ b/lib/components/Input/Input.scss @@ -8,22 +8,39 @@ $inactive_color: #999999; $border: 1px solid; .deriv-input { - display: inline-block; + display: inline-flex; position: relative; + border-radius: 4px; + width: 328px; + box-sizing: border-box; + text-align: left; + padding: 10px 16px; + border: $border; + + &__general { + border-color: $inactive_color; + &:focus-within { + border-color: $active_color; + } + } + &__error { + border-color: $error_field; + } + &__success { + border-color: $success_color; + } + + &__active { + border-color: $active_color; + } + + &__disabled { + border-color: $disabled_color; + } &--field { width: 100%; - padding: 10px 16px; outline: none; - border-radius: 4px; - width: 328px; - box-sizing: border-box; - outline: none; - text-align: left; - &:disabled { - border: $border $disabled_color; - color: $inactive_color; - } &::placeholder { visibility: hidden; } @@ -37,24 +54,6 @@ $border: 1px solid; height: fit-content; } } - &__general { - border: $border $inactive_color; - &:focus { - border: $border $active_color; - } - } - &__error { - border: $border $error_field; - &:focus { - border: $border $error_field; - } - } - &__success { - border: $border $success_color; - &:focus { - border: $border $success_color; - } - } } &--label { @@ -78,38 +77,36 @@ $border: 1px solid; &__success { color: $success_color; } + &__active { + color: $active_color; + } + + &__disabled { + color: $disabled_color; + } } &--helper-message { + top: 100%; position: absolute; left: 16px; - margin-top: 2px; line-height: 1; } &--right-content { - position: absolute; - right: 16px; - bottom: 25%; + margin-left: 16px; } } -.deriv-input--field__general:disabled + .deriv-input--label, -.deriv-input--field__error:disabled + .deriv-input--label, -.deriv-input--field__success:disabled + .deriv-input--label { - color: $inactive_color; - cursor: not-allowed; -} - -.deriv-input--field:focus + .deriv-input--label { +.deriv-input__general .deriv-input--field:focus + .deriv-input--label { color: $active_color; } -.deriv-input--field__error:focus + .deriv-input--label { +.deriv-input__error .deriv-input--field:focus + .deriv-input--label { color: $error_field; } -.deriv-input--field__success:focus + .deriv-input--label { +.deriv-input__success .deriv-input--field:focus + .deriv-input--label { color: $success_color; } diff --git a/lib/components/Input/index.tsx b/lib/components/Input/index.tsx index f2bca784..e46c33a7 100644 --- a/lib/components/Input/index.tsx +++ b/lib/components/Input/index.tsx @@ -3,7 +3,12 @@ import clsx from "clsx"; import HelperMessage from "./HelperMessage"; import "./Input.scss"; -export type InputVariants = "general" | "success" | "error" | "warning"; +export type InputVariants = + | "general" + | "success" + | "error" + | "warning" + | "disabled"; interface InputProps extends Omit, "style" | "placeholder"> { label?: string; @@ -15,10 +20,11 @@ interface InputProps } const InputVariant: Record = { - general: "deriv-input--field__general", - success: "deriv-input--field__success", - warning: "deriv-input--field__general", - error: "deriv-input--field__error", + general: "deriv-input__general", + success: "deriv-input__success", + warning: "deriv-input__general", + error: "deriv-input__error", + disabled: "deriv-input__disabled", }; const LabelVariant: Record = { @@ -26,6 +32,7 @@ const LabelVariant: Record = { success: "deriv-input--label__success", warning: "deriv-input--label__general", error: "deriv-input--label__error", + disabled: "deriv-input--label__disabled", }; export const Input = ({ @@ -41,24 +48,33 @@ export const Input = ({ ...rest }: InputProps) => { return ( -

+
{leftPlaceholder && (
{leftPlaceholder}
)}