Skip to content

Commit

Permalink
feat: Show/hide value in text input password (#615)
Browse files Browse the repository at this point in the history
  • Loading branch information
gitstart committed Oct 1, 2023
1 parent d12d51f commit e6559d4
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 17 deletions.
1 change: 0 additions & 1 deletion src/assets/ArrowDownHeadIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const ArrowDownHeadIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/ArrowDownIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const ArrowDownIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/ArrowDownRightIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const ArrowDownRightIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/ArrowUpHeadIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const ArrowUpHeadIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/ArrowUpIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const ArrowUpIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/ArrowUpRightIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const ArrowUpRightIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/CalendarIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const CalendarIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/DoubleArrowLeftHeadIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const DoubleArrowLeftHeadIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/DoubleArrowRightHeadIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const DoubleArrowRightHeadIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/ExclamationFilledIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const ExclamationFilledIcon = ({ ...props }) => (
Expand Down
21 changes: 21 additions & 0 deletions src/assets/EyeIcon.tsx
@@ -0,0 +1,21 @@
import React from "react";

const EyeIcon = ({ ...props }) => (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
/>
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
);

export default EyeIcon;
20 changes: 20 additions & 0 deletions src/assets/EyeOffIcon.tsx
@@ -0,0 +1,20 @@
import React from "react";

const EyeOffIcon = ({ ...props }) => (
<svg
{...props}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
/>
</svg>
);

export default EyeOffIcon;
1 change: 0 additions & 1 deletion src/assets/LoadingSpinner.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const LoadingSpinner = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/MinusIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const MinusIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/PlusIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const PlusIcon = ({ ...props }) => (
Expand Down
1 change: 0 additions & 1 deletion src/assets/SearchIcon.tsx
@@ -1,4 +1,3 @@
/* eslint-disable max-len */
import React from "react";

const SearchIcon = ({ ...props }) => (
Expand Down
2 changes: 2 additions & 0 deletions src/assets/index.ts
Expand Up @@ -16,3 +16,5 @@ export { default as SearchIcon } from "./SearchIcon";
export { default as XCircleIcon } from "./XCircleIcon";
export { default as PlusIcon } from "./PlusIcon";
export { default as MinusIcon } from "./MinusIcon";
export { default as EyeIcon } from "./EyeIcon";
export { default as EyeOffIcon } from "./EyeOffIcon";
43 changes: 40 additions & 3 deletions src/components/input-elements/BaseInput.tsx
@@ -1,7 +1,7 @@
"use client";
import React, { ReactNode, useRef, useState } from "react";
import React, { ReactNode, useCallback, useRef, useState } from "react";
import { border, mergeRefs, sizing, spacing, tremorTwMerge } from "lib";
import { ExclamationFilledIcon } from "assets";
import { ExclamationFilledIcon, EyeIcon, EyeOffIcon } from "assets";
import { getSelectButtonColors, hasValue } from "components/input-elements/selectUtils";

export interface BaseInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
Expand Down Expand Up @@ -32,6 +32,12 @@ const BaseInput = React.forwardRef<HTMLInputElement, BaseInputProps>((props, ref
...other
} = props;
const [isFocused, setIsFocused] = useState(false);
const [isPasswordVisible, setIsPasswordVisible] = useState(false);

const toggleIsPasswordVisible = useCallback(
() => setIsPasswordVisible(!isPasswordVisible),
[isPasswordVisible, setIsPasswordVisible],
);

const Icon = icon;

Expand Down Expand Up @@ -104,7 +110,7 @@ const BaseInput = React.forwardRef<HTMLInputElement, BaseInputProps>((props, ref
ref={mergeRefs([inputRef, ref])}
defaultValue={defaultValue}
value={value}
type={type}
type={isPasswordVisible ? "text" : type}
className={tremorTwMerge(
makeInputClassName("input"),
// common
Expand All @@ -126,6 +132,37 @@ const BaseInput = React.forwardRef<HTMLInputElement, BaseInputProps>((props, ref
data-testid="base-input"
{...other}
/>
{type === "password" && !disabled ? (
<button
className={tremorTwMerge(makeInputClassName("toggleButton"), "mr-2")}
type="button"
onClick={() => toggleIsPasswordVisible()}
>
{isPasswordVisible ? (
<EyeOffIcon
className={tremorTwMerge(
// common
"flex-none h-5 w-5 transition",
// light
"text-tremor-content-subtle hover:text-tremor-content",
// dark
"dark:text-dark-tremor-content-subtle hover:dark:text-dark-tremor-content",
)}
/>
) : (
<EyeIcon
className={tremorTwMerge(
// common
"flex-none h-5 w-5 transition",
// light
"text-tremor-content-subtle hover:text-tremor-content",
// dark
"dark:text-dark-tremor-content-subtle hover:dark:text-dark-tremor-content",
)}
/>
)}
</button>
) : null}
{error ? (
<ExclamationFilledIcon
className={tremorTwMerge(
Expand Down

0 comments on commit e6559d4

Please sign in to comment.