UNPKG

react-modern-password-generator

Version:

Modern password generator React component

186 lines 6.55 kB
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;