react-modern-password-generator
Version:
Modern password generator React component
186 lines • 6.55 kB
JavaScript
import React, { useState, useEffect } from 'react';
import { Copy, RefreshCw, ShieldCheck } from 'lucide-react';
const PasswordGenerator = ({
theme = 'light',
defaultLength = 12
}) => {
const [password, setPassword] = useState('');
const [length, setLength] = useState(defaultLength);
const [options, setOptions] = useState({
lowercase: true,
uppercase: true,
numbers: true,
symbols: true
});
const [strength, setStrength] = useState(0);
const generatePassword = () => {
const lowercase = 'abcdefghijklmnopqrstuvwxyz';
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numbers = '0123456789';
const symbols = '!@#$%^&*()_+-=[]{}|;:,.<>?';
let chars = '';
if (options.lowercase) chars += lowercase;
if (options.uppercase) chars += uppercase;
if (options.numbers) chars += numbers;
if (options.symbols) chars += symbols;
if (!chars) {
setPassword('');
return;
}
let newPassword = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * chars.length);
newPassword += chars[randomIndex];
}
setPassword(newPassword);
};
const calculateStrength = () => {
let score = 0;
if (password.length >= 12) score += 1;
if (password.match(/[a-z]/)) score += 1;
if (password.match(/[A-Z]/)) score += 1;
if (password.match(/[0-9]/)) score += 1;
if (password.match(/[^a-zA-Z0-9]/)) score += 1;
setStrength(score);
};
useEffect(() => {
generatePassword();
}, [length, options]);
useEffect(() => {
if (password) {
calculateStrength();
}
}, [password]);
const copyToClipboard = () => {
navigator.clipboard.writeText(password);
};
const getStrengthColor = () => {
switch (strength) {
case 0:
case 1:
return 'bg-red-500';
case 2:
case 3:
return 'bg-yellow-500';
case 4:
case 5:
return 'bg-green-500';
default:
return 'bg-gray-200';
}
};
const getStrengthText = () => {
switch (strength) {
case 0:
case 1:
return 'Weak';
case 2:
case 3:
return 'Medium';
case 4:
case 5:
return 'Strong';
default:
return 'N/A';
}
};
return /*#__PURE__*/React.createElement("div", {
className: "min-h-screen bg-gray-100 flex items-center justify-center p-4"
}, /*#__PURE__*/React.createElement("div", {
className: "bg-white rounded-lg shadow-xl p-6 w-full max-w-md space-y-6"
}, /*#__PURE__*/React.createElement("div", {
className: "flex items-center justify-between"
}, /*#__PURE__*/React.createElement("h1", {
className: "text-2xl font-bold text-gray-800"
}, "Password Generator"), /*#__PURE__*/React.createElement(ShieldCheck, {
className: "w-6 h-6 text-blue-500"
})), /*#__PURE__*/React.createElement("div", {
className: "relative"
}, /*#__PURE__*/React.createElement("input", {
type: "text",
value: password,
readOnly: true,
className: "w-full p-3 pr-24 text-gray-700 bg-gray-50 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
}), /*#__PURE__*/React.createElement("div", {
className: "absolute right-2 top-1/2 -translate-y-1/2 flex gap-2"
}, /*#__PURE__*/React.createElement("button", {
onClick: generatePassword,
className: "p-2 text-gray-500 hover:text-blue-500 transition-colors"
}, /*#__PURE__*/React.createElement(RefreshCw, {
className: "w-5 h-5"
})), /*#__PURE__*/React.createElement("button", {
onClick: copyToClipboard,
className: "p-2 text-gray-500 hover:text-blue-500 transition-colors"
}, /*#__PURE__*/React.createElement(Copy, {
className: "w-5 h-5"
})))), /*#__PURE__*/React.createElement("div", {
className: "space-y-2"
}, /*#__PURE__*/React.createElement("div", {
className: "flex justify-between items-center"
}, /*#__PURE__*/React.createElement("label", {
className: "text-gray-700"
}, "Password Length: ", length), /*#__PURE__*/React.createElement("span", {
className: `px-3 py-1 rounded-full text-sm text-white ${getStrengthColor()}`
}, getStrengthText())), /*#__PURE__*/React.createElement("input", {
type: "range",
min: "6",
max: "32",
value: length,
onChange: e => setLength(parseInt(e.target.value)),
className: "w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"
})), /*#__PURE__*/React.createElement("div", {
className: "grid grid-cols-2 gap-4"
}, /*#__PURE__*/React.createElement("label", {
className: "flex items-center space-x-2"
}, /*#__PURE__*/React.createElement("input", {
type: "checkbox",
checked: options.lowercase,
onChange: e => setOptions({
...options,
lowercase: e.target.checked
}),
className: "w-4 h-4 text-blue-500 rounded focus:ring-blue-500"
}), /*#__PURE__*/React.createElement("span", {
className: "text-gray-700"
}, "Lowercase")), /*#__PURE__*/React.createElement("label", {
className: "flex items-center space-x-2"
}, /*#__PURE__*/React.createElement("input", {
type: "checkbox",
checked: options.uppercase,
onChange: e => setOptions({
...options,
uppercase: e.target.checked
}),
className: "w-4 h-4 text-blue-500 rounded focus:ring-blue-500"
}), /*#__PURE__*/React.createElement("span", {
className: "text-gray-700"
}, "Uppercase")), /*#__PURE__*/React.createElement("label", {
className: "flex items-center space-x-2"
}, /*#__PURE__*/React.createElement("input", {
type: "checkbox",
checked: options.numbers,
onChange: e => setOptions({
...options,
numbers: e.target.checked
}),
className: "w-4 h-4 text-blue-500 rounded focus:ring-blue-500"
}), /*#__PURE__*/React.createElement("span", {
className: "text-gray-700"
}, "Numbers")), /*#__PURE__*/React.createElement("label", {
className: "flex items-center space-x-2"
}, /*#__PURE__*/React.createElement("input", {
type: "checkbox",
checked: options.symbols,
onChange: e => setOptions({
...options,
symbols: e.target.checked
}),
className: "w-4 h-4 text-blue-500 rounded focus:ring-blue-500"
}), /*#__PURE__*/React.createElement("span", {
className: "text-gray-700"
}, "Symbols"))), /*#__PURE__*/React.createElement("button", {
onClick: generatePassword,
className: "w-full py-3 px-4 bg-blue-500 hover:bg-blue-600 text-white font-medium rounded-lg transition-colors"
}, "Generate Password")));
};
export default PasswordGenerator;