Skip to content

Commit

Permalink
Merge pull request #70 from NeuroNexul/main
Browse files Browse the repository at this point in the history
fix(ui): resolve issue with PasswordInput component reveal icon
  • Loading branch information
ruru-m07 authored Sep 17, 2024
2 parents a5aae2c + 3b43c8a commit 4b6070a
Show file tree
Hide file tree
Showing 3 changed files with 6,817 additions and 5,541 deletions.
2 changes: 1 addition & 1 deletion apps/www/public/registry/components/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": [
{
"name": "input.tsx",
"content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { EyeClosedIcon, EyeOpenIcon } from \"@radix-ui/react-icons\";\n\nexport interface InputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"children\" | \"prefix\" | \"suffix\"\n > {\n \n className?: string;\n \n iclassName?: string;\n \n prefix?: React.ReactNode | string;\n \n suffix?: React.ReactNode | string;\n \n prefixStyling?: boolean;\n \n label?: string;\n \n suffixStyling?: boolean;\n \n error?: string;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n className,\n iclassName,\n prefix,\n suffix,\n prefixStyling = true,\n suffixStyling = true,\n label,\n type,\n error,\n ...props\n },\n ref,\n ) => {\n \n const prefixRef = React.useRef<HTMLDivElement>(null);\n const suffixRef = React.useRef<HTMLDivElement>(null);\n \n const [prefixWidth, setPrefixWidth] = React.useState(0);\n const [suffixWidth, setSuffixWidth] = React.useState(0);\n \n React.useEffect(() => {\n if (prefixRef.current) {\n setPrefixWidth(prefixRef.current.offsetWidth);\n }\n if (suffixRef.current) {\n setSuffixWidth(suffixRef.current.offsetWidth);\n }\n }, [prefix, suffix]);\n\n return (\n <div className={cn(\"relative\", className)}>\n {label && (\n <label\n className={`text-sm ${error ? \"text-[#ff6166]\" : \"text-muted-foreground\"} `}\n htmlFor={props.id}\n >\n {label}\n </label>\n )}\n {prefix && (\n <div\n ref={prefixRef}\n className={cn(\n \"absolute top-0 left-0 h-full flex items-center justify-center pl-2 text-muted-foreground\",\n `${prefixStyling ? \"rounded-l-md\" : \"\"}`,\n )}\n >\n {prefix}\n {prefixStyling && <div className=\"h-[94%] w-px ml-2 bg-border \" />}\n </div>\n )}\n <input\n type={type}\n className={cn(\n \"flex w-full h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-shadow file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:border-primary/75 focus-visible:ring-primary/35 disabled:cursor-not-allowed disabled:opacity-50\",\n iclassName,\n `${error ? \"outline-none ring-2 ring-[#ffe6e6] border-[#ff6166] dark:ring-[#561a1e] focus-visible:dark:ring-primary/35 dark:hover:ring-[#832126] hover:ring-[#f8b9b9]\" : \"\"}`,\n )}\n style={{\n paddingLeft: prefix ? `${prefixWidth + 12}px` : \"0.75rem\",\n paddingRight: suffix ? `${suffixWidth + 12}px` : \"0.75rem\",\n }}\n ref={ref}\n {...props}\n />\n {suffix && (\n <div\n ref={suffixRef}\n className={cn(\n \"absolute top-0 right-0 h-full flex items-center justify-center pr-2 text-muted-foreground\",\n `${suffixStyling ? \"rounded-r-md\" : \"\"}`,\n )}\n >\n {suffixStyling && (\n <div className=\"h-[94%] w-[1px] mr-2 bg-border \" />\n )}\n {suffix}\n </div>\n )}\n {error && (\n <div\n className=\"flex items-center text-sm text-[#ff6166] mt-1\"\n role=\"alert\"\n >\n <svg\n data-testid=\"geist-icon\"\n height=\"16\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n style={{ color: \"currentcolor\" }}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.30761 1.5L1.5 5.30761L1.5 10.6924L5.30761 14.5H10.6924L14.5 10.6924V5.30761L10.6924 1.5H5.30761ZM5.10051 0C4.83529 0 4.58094 0.105357 4.3934 0.292893L0.292893 4.3934C0.105357 4.58094 0 4.83529 0 5.10051V10.8995C0 11.1647 0.105357 11.4191 0.292894 11.6066L4.3934 15.7071C4.58094 15.8946 4.83529 16 5.10051 16H10.8995C11.1647 16 11.4191 15.8946 11.6066 15.7071L15.7071 11.6066C15.8946 11.4191 16 11.1647 16 10.8995V5.10051C16 4.83529 15.8946 4.58093 15.7071 4.3934L11.6066 0.292893C11.4191 0.105357 11.1647 0 10.8995 0H5.10051ZM8.75 3.75V4.5V8L8.75 8.75H7.25V8V4.5V3.75H8.75ZM8 12C8.55229 12 9 11.5523 9 11C9 10.4477 8.55229 10 8 10C7.44772 10 7 10.4477 7 11C7 11.5523 7.44772 12 8 12Z\"\n fill=\"currentColor\"\n ></path>\n </svg>\n <label className=\"ml-1\" htmlFor=\"error\">\n {error}\n </label>\n </div>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n\nexport interface SearchInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"children\"> {\n \n enablePrefixStyling?: boolean;\n}\n\nconst SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(\n ({ enablePrefixStyling = false, ...props }, ref) => {\n return (\n <Input\n type=\"search\"\n prefix={\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 6.5C10 8.433 8.433 10 6.5 10C4.567 10 3 8.433 3 6.5C3 4.567 4.567 3 6.5 3C8.433 3 10 4.567 10 6.5ZM9.30884 10.0159C8.53901 10.6318 7.56251 11 6.5 11C4.01472 11 2 8.98528 2 6.5C2 4.01472 4.01472 2 6.5 2C8.98528 2 11 4.01472 11 6.5C11 7.56251 10.6318 8.53901 10.0159 9.30884L12.8536 12.1464C13.0488 12.3417 13.0488 12.6583 12.8536 12.8536C12.6583 13.0488 12.3417 13.0488 12.1464 12.8536L9.30884 10.0159Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n ></path>\n </svg>\n }\n prefixStyling={enablePrefixStyling}\n className={cn(\"rounded-full\", props.className)}\n ref={ref}\n {...props}\n />\n );\n },\n);\n\nSearchInput.displayName = \"SearchInput\";\n\nconst PasswordInput = React.forwardRef<\n HTMLInputElement,\n Omit<InputProps, \"label\" | \"error\">\n>(({ className, ...props }, ref) => {\n const [showPassword, setShowPassword] = React.useState(false);\n\n return (\n <div className=\"relative\">\n <Input\n type={showPassword ? \"text\" : \"password\"}\n className={cn(\"hide-password-toggle\", className)}\n ref={ref}\n {...props}\n />\n <button\n type=\"button\"\n className={\n \"absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent\"\n }\n onClick={() => setShowPassword((prev) => !prev)}\n disabled={props.disabled}\n >\n {showPassword ? (\n <EyeOpenIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <EyeClosedIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n <span className=\"sr-only\">\n {showPassword ? \"Hide password\" : \"Show password\"}\n </span>\n </button>\n\n {}\n <style>{`\n\t\t\t\t\t.hide-password-toggle::-ms-reveal,\n\t\t\t\t\t.hide-password-toggle::-ms-clear {\n\t\t\t\t\t\tvisibility: hidden;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t`}</style>\n </div>\n );\n});\nPasswordInput.displayName = \"PasswordInput\";\n\nexport { Input, SearchInput, PasswordInput };\n"
"content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { EyeClosedIcon, EyeOpenIcon } from \"@radix-ui/react-icons\";\n\nexport interface InputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"children\" | \"prefix\" | \"suffix\"\n > {\n \n className?: string;\n \n iclassName?: string;\n \n prefix?: React.ReactNode | string;\n \n suffix?: React.ReactNode | string;\n \n prefixStyling?: boolean;\n \n label?: string;\n \n suffixStyling?: boolean;\n \n error?: string;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n className,\n iclassName,\n prefix,\n suffix,\n prefixStyling = true,\n suffixStyling = true,\n label,\n type,\n error,\n ...props\n },\n ref,\n ) => {\n \n const prefixRef = React.useRef<HTMLDivElement>(null);\n const suffixRef = React.useRef<HTMLDivElement>(null);\n \n const [prefixWidth, setPrefixWidth] = React.useState(0);\n const [suffixWidth, setSuffixWidth] = React.useState(0);\n \n React.useEffect(() => {\n if (prefixRef.current) {\n setPrefixWidth(prefixRef.current.offsetWidth);\n }\n if (suffixRef.current) {\n setSuffixWidth(suffixRef.current.offsetWidth);\n }\n }, [prefix, suffix]);\n\n return (\n <div className={cn(\"relative\", className)}>\n {label && (\n <label\n className={`text-sm ${error ? \"text-[#ff6166]\" : \"text-muted-foreground\"} `}\n htmlFor={props.id}\n >\n {label}\n </label>\n )}\n {prefix && (\n <div\n ref={prefixRef}\n className={cn(\n \"absolute top-0 left-0 h-full flex items-center justify-center pl-2 text-muted-foreground\",\n `${prefixStyling ? \"rounded-l-md\" : \"\"}`,\n )}\n >\n {prefix}\n {prefixStyling && <div className=\"h-[94%] w-px ml-2 bg-border \" />}\n </div>\n )}\n <input\n type={type}\n className={cn(\n \"flex w-full h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-shadow file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:border-primary/75 focus-visible:ring-primary/35 disabled:cursor-not-allowed disabled:opacity-50\",\n iclassName,\n `${error ? \"outline-none ring-2 ring-[#ffe6e6] border-[#ff6166] dark:ring-[#561a1e] focus-visible:dark:ring-primary/35 dark:hover:ring-[#832126] hover:ring-[#f8b9b9]\" : \"\"}`,\n )}\n style={{\n paddingLeft: prefix ? `${prefixWidth + 12}px` : \"0.75rem\",\n paddingRight: suffix ? `${suffixWidth + 12}px` : \"0.75rem\",\n }}\n ref={ref}\n {...props}\n />\n {suffix && (\n <div\n ref={suffixRef}\n className={cn(\n \"absolute top-0 right-0 h-full flex items-center justify-center pr-2 text-muted-foreground\",\n `${suffixStyling ? \"rounded-r-md\" : \"\"}`,\n )}\n >\n {suffixStyling && (\n <div className=\"h-[94%] w-[1px] mr-2 bg-border \" />\n )}\n {suffix}\n </div>\n )}\n {error && (\n <div\n className=\"flex items-center text-sm text-[#ff6166] mt-1\"\n role=\"alert\"\n >\n <svg\n data-testid=\"geist-icon\"\n height=\"16\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n style={{ color: \"currentcolor\" }}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.30761 1.5L1.5 5.30761L1.5 10.6924L5.30761 14.5H10.6924L14.5 10.6924V5.30761L10.6924 1.5H5.30761ZM5.10051 0C4.83529 0 4.58094 0.105357 4.3934 0.292893L0.292893 4.3934C0.105357 4.58094 0 4.83529 0 5.10051V10.8995C0 11.1647 0.105357 11.4191 0.292894 11.6066L4.3934 15.7071C4.58094 15.8946 4.83529 16 5.10051 16H10.8995C11.1647 16 11.4191 15.8946 11.6066 15.7071L15.7071 11.6066C15.8946 11.4191 16 11.1647 16 10.8995V5.10051C16 4.83529 15.8946 4.58093 15.7071 4.3934L11.6066 0.292893C11.4191 0.105357 11.1647 0 10.8995 0H5.10051ZM8.75 3.75V4.5V8L8.75 8.75H7.25V8V4.5V3.75H8.75ZM8 12C8.55229 12 9 11.5523 9 11C9 10.4477 8.55229 10 8 10C7.44772 10 7 10.4477 7 11C7 11.5523 7.44772 12 8 12Z\"\n fill=\"currentColor\"\n ></path>\n </svg>\n <label className=\"ml-1\" htmlFor=\"error\">\n {error}\n </label>\n </div>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n\nexport interface SearchInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"children\"> {\n \n enablePrefixStyling?: boolean;\n}\n\nconst SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(\n ({ enablePrefixStyling = false, ...props }, ref) => {\n return (\n <Input\n type=\"search\"\n prefix={\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 6.5C10 8.433 8.433 10 6.5 10C4.567 10 3 8.433 3 6.5C3 4.567 4.567 3 6.5 3C8.433 3 10 4.567 10 6.5ZM9.30884 10.0159C8.53901 10.6318 7.56251 11 6.5 11C4.01472 11 2 8.98528 2 6.5C2 4.01472 4.01472 2 6.5 2C8.98528 2 11 4.01472 11 6.5C11 7.56251 10.6318 8.53901 10.0159 9.30884L12.8536 12.1464C13.0488 12.3417 13.0488 12.6583 12.8536 12.8536C12.6583 13.0488 12.3417 13.0488 12.1464 12.8536L9.30884 10.0159Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n ></path>\n </svg>\n }\n prefixStyling={enablePrefixStyling}\n className={cn(\"rounded-full\", props.className)}\n ref={ref}\n {...props}\n />\n );\n },\n);\n\nSearchInput.displayName = \"SearchInput\";\n\nconst PasswordInput = React.forwardRef<\n HTMLInputElement,\n Omit<InputProps, \"label\" | \"error\">\n>(({ className, ...props }, ref) => {\n const [showPassword, setShowPassword] = React.useState(false);\n\n return (\n <div className=\"relative\">\n <Input\n type={showPassword ? \"text\" : \"password\"}\n iclassName=\"hide-password-toggle\"\n className={className}\n ref={ref}\n {...props}\n />\n <button\n type=\"button\"\n className={\n \"absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent\"\n }\n onClick={() => setShowPassword((prev) => !prev)}\n disabled={props.disabled}\n >\n {showPassword ? (\n <EyeOpenIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <EyeClosedIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n <span className=\"sr-only\">\n {showPassword ? \"Hide password\" : \"Show password\"}\n </span>\n </button>\n\n {}\n <style>{`\n\t\t\t\t\t.hide-password-toggle::-ms-reveal,\n\t\t\t\t\t.hide-password-toggle::-ms-clear {\n\t\t\t\t\t\tvisibility: hidden;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t`}</style>\n </div>\n );\n});\nPasswordInput.displayName = \"PasswordInput\";\n\nexport { Input, SearchInput, PasswordInput };\n"
}
],
"type": "components:ui"
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/components/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ const PasswordInput = React.forwardRef<
<div className="relative">
<Input
type={showPassword ? "text" : "password"}
className={cn("hide-password-toggle", className)}
iclassName="hide-password-toggle"
className={className}
ref={ref}
{...props}
/>
Expand Down
Loading

0 comments on commit 4b6070a

Please sign in to comment.