96 lines
3.1 KiB
TypeScript
96 lines
3.1 KiB
TypeScript
import { createRef, HTMLAttributes, InputHTMLAttributes, useState } from "react"
|
|
import { overrideTailwindClasses } from '../general'
|
|
import { SVGEye } from "./Icons"
|
|
|
|
interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
|
|
invalid?: boolean
|
|
}
|
|
|
|
export function InputText({ invalid, ...props }: InputProps) {
|
|
var inputRef = createRef<HTMLInputElement>()
|
|
return (
|
|
<input type="text" ref={inputRef} {...props}
|
|
className={overrideTailwindClasses(`
|
|
rounded-full
|
|
px-3 py-1 mx-2
|
|
w-64
|
|
bg-gray-800 focus:bg-gray-700
|
|
text-gray-400 focus:text-gray-200
|
|
shadow-glow
|
|
outline-none shadow-transparent
|
|
${invalid ? "outline-red-600 shadow-red-600" : ""}
|
|
focus:outline-blue-500 focus:shadow-blue-500
|
|
transition-all
|
|
`)} />
|
|
)
|
|
}
|
|
|
|
export function InputPassword({ invalid, ...props }: InputProps) {
|
|
var inputRef = createRef<HTMLInputElement>()
|
|
var [focused, setFocused] = useState(false)
|
|
var [showPassword, setShowPassword] = useState(false)
|
|
|
|
var toggleShowPassword = () => {
|
|
setShowPassword(!showPassword)
|
|
inputRef.current?.focus()
|
|
}
|
|
|
|
return (
|
|
<span
|
|
onFocus={() => setFocused(true)}
|
|
onBlur={() => setFocused(false)}
|
|
className={overrideTailwindClasses(`
|
|
flex
|
|
flex-row
|
|
rounded-full
|
|
px-3 py-1 mx-2
|
|
w-64
|
|
bg-gray-800
|
|
shadow-glow
|
|
outline-none shadow-transparent
|
|
${invalid ? "outline-red-600 shadow-red-600" : ""}
|
|
${focused ? "outline-blue-500 shadow-blue-500 bg-gray-700" : ""}
|
|
transition-all
|
|
`)}>
|
|
<input type={showPassword ? "text" : "password"}
|
|
ref={inputRef}
|
|
{...props}
|
|
className={`
|
|
w-1 flex-grow
|
|
bg-transparent
|
|
text-gray-400 focus:text-gray-200
|
|
outline-none
|
|
`} />
|
|
<span className={overrideTailwindClasses(`
|
|
h-full
|
|
pl-2
|
|
border-l border-gray-600
|
|
${focused ? "opacity-100" : "opacity-0"}
|
|
transition-all
|
|
${showPassword ? "fill-blue-500" : "fill-gray-400"}
|
|
`)} onClick={() => toggleShowPassword()}>
|
|
<SVGEye />
|
|
</span>
|
|
</span>
|
|
)
|
|
}
|
|
|
|
interface ButtonProps extends HTMLAttributes<HTMLButtonElement> { }
|
|
|
|
export function Button({ children, ...props }: ButtonProps) {
|
|
return (
|
|
<button className={`
|
|
rounded-full outline-none
|
|
bg-gray-800 focus:bg-gray-700
|
|
hover:bg-gray-700 active:bg-gray-800
|
|
fill-gray-400 focus:fill-gray-200
|
|
px-3 py-2
|
|
shadow-glow shadow-transparent
|
|
focus:outline-blue-500 focus:shadow-blue-500
|
|
transition-all
|
|
`}
|
|
{...props}>
|
|
{children}
|
|
</button>
|
|
)
|
|
} |