Browse Source

Merge pull request #3 from Skidragon/view-plain-text-password-field

Toggle Plain Text on Password Fields
pull/5/head
Phillip 3 months ago committed by GitHub
parent
commit
0e2816f57e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1693
      package-lock.json
  2. 11
      package.json
  3. 16
      src/App.tsx
  4. 28
      src/components/PasswordField/PasswordField.spec.tsx
  5. 61
      src/components/PasswordField/PasswordField.tsx
  6. 1
      src/components/index.ts
  7. 1
      src/test/setup.ts
  8. 6
      vite.config.ts

1693
package-lock.json generated

File diff suppressed because it is too large Load Diff

11
package.json

@ -7,12 +7,16 @@
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
"preview": "vite preview",
"test": "vitest",
"coverage": "vitest run --coverage"
},
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.15.14",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/user-event": "^14.5.2",
"@types/chrome": "^0.0.263",
"asmcrypto.js": "2.3.2",
"bcryptjs": "2.4.3",
@ -25,6 +29,8 @@
"react-dropzone": "^14.2.3"
},
"devDependencies": {
"@testing-library/dom": "^10.3.0",
"@testing-library/react": "^16.0.0",
"@types/react": "^18.2.64",
"@types/react-copy-to-clipboard": "^5.0.7",
"@types/react-dom": "^18.2.21",
@ -35,6 +41,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"typescript": "^5.2.2",
"vite": "^5.1.6"
"vite": "^5.1.6",
"vitest": "^1.6.0"
}
}

16
src/App.tsx

@ -41,6 +41,7 @@ import {
} from "./App-styles";
import { Spacer } from "./common/Spacer";
import { Loader } from "./components/Loader";
import { PasswordField } from "./components";
type extStates =
| "not-authenticated"
@ -741,8 +742,7 @@ function App() {
Confirm Wallet Password
</CustomLabel>
<Spacer height="5px" />
<CustomInput
type="password"
<PasswordField
id="standard-adornment-password"
value={paymentPassword}
onChange={(e) => setPaymentPassword(e.target.value)}
@ -808,8 +808,7 @@ function App() {
Confirm Wallet Password
</CustomLabel>
<Spacer height="5px" />
<CustomInput
type="password"
<PasswordField
id="standard-adornment-password"
value={paymentPassword}
onChange={(e) => setPaymentPassword(e.target.value)}
@ -1000,8 +999,7 @@ function App() {
Confirm Wallet Password
</CustomLabel>
<Spacer height="5px" />
<CustomInput
type="password"
<PasswordField
id="standard-adornment-password"
value={walletToBeDownloadedPassword}
onChange={(e) =>
@ -1073,8 +1071,7 @@ function App() {
Wallet Password
</CustomLabel>
<Spacer height="5px" />
<CustomInput
type="password"
<PasswordField
id="standard-adornment-password"
value={walletToBeDownloadedPassword}
onChange={(e) =>
@ -1086,8 +1083,7 @@ function App() {
Confirm Wallet Password
</CustomLabel>
<Spacer height="5px" />
<CustomInput
type="password"
<PasswordField
id="standard-adornment-password"
value={walletToBeDownloadedPasswordConfirm}
onChange={(e) =>

28
src/components/PasswordField/PasswordField.spec.tsx

@ -0,0 +1,28 @@
import {
describe,
expect,
test
} from 'vitest';
import { render } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {
PasswordField
} from './PasswordField'
describe('PasswordField', () => {
test('it renders', () => {
const { queryByTestId } = render(<PasswordField data-testid="test-id" value="test-value" />)
expect(queryByTestId('test-id')).toBeTruthy()
})
test('User can toggle between plain text view and password view', async () => {
const { getByTestId } = render(<PasswordField data-testid="test-id" value="test-value" />)
const user = userEvent.setup();
expect(getByTestId("password-text-indicator").textContent).toBe('👁🗨');
await user.click(getByTestId('toggle-view-password-btn'));
expect(getByTestId("plain-text-indicator").textContent).toBe('👁');
await user.click(getByTestId('toggle-view-password-btn'));
expect(getByTestId("password-text-indicator").textContent).toBe('👁🗨');
})
})

61
src/components/PasswordField/PasswordField.tsx

@ -0,0 +1,61 @@
import { Button, InputAdornment, TextField, TextFieldProps, styled } from "@mui/material";
import { useState } from 'react'
export const CustomInput = styled(TextField)({
width: "183px", // Adjust the width as needed
borderRadius: "5px",
// backgroundColor: "rgba(30, 30, 32, 1)",
outline: "none",
input: {
fontSize: 10,
fontFamily: "Inter",
fontWeight: 400,
color: "white",
"&::placeholder": {
fontSize: 16,
color: "rgba(255, 255, 255, 0.2)",
},
outline: "none",
padding: "10px",
},
"& .MuiOutlinedInput-root": {
"& fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)',
},
"&:hover fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)',
},
"&.Mui-focused fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)',
},
},
"& .MuiInput-underline:before": {
borderBottom: "none",
},
"& .MuiInput-underline:hover:not(.Mui-disabled):before": {
borderBottom: "none",
},
"& .MuiInput-underline:after": {
borderBottom: "none",
},
});
export const PasswordField: React.FunctionComponent<TextFieldProps> = ({ ...props }) => {
const [canViewPassword, setCanViewPassword] = useState(false);
return (
<CustomInput
type={canViewPassword ? 'text' : 'password'}
InputProps={{
endAdornment: (
<InputAdornment position="end" data-testid="toggle-view-password-btn" onClick={() => {
setCanViewPassword((prevState) => !prevState)
}}>
{canViewPassword ? <Button data-testid="plain-text-indicator" sx={{ minWidth: 0, p: 0 }}>👁</Button> : <Button data-testid="password-text-indicator" sx={{ minWidth: 0, p: 0 }}>👁🗨</Button>}
</InputAdornment>
)
}}
{...props}
/>
)
}

1
src/components/index.ts

@ -0,0 +1 @@
export * from './PasswordField/PasswordField';

1
src/test/setup.ts

@ -0,0 +1 @@
import '@testing-library/jest-dom'

6
vite.config.ts

@ -1,9 +1,15 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// Import path module for resolving file paths
import { resolve } from 'path';
export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./src/test/setup.ts']
},
plugins: [react()],
build: {
rollupOptions: {

Loading…
Cancel
Save