first commit

This commit is contained in:
2026-07-16 20:48:43 -03:00
commit 5696cee264
1111 changed files with 322270 additions and 0 deletions
@@ -0,0 +1,131 @@
"use client";
import classNames from "classnames";
import { forwardRef } from "react";
import style from "./textbox.module.css";
export type TextboxWidth = "80%" | "100%" | "50%" | "custom";
export type TextboxVariant = "solid" | "transparent" | "search";
export type TextboxIcon = "none" | "search";
export type TextboxType = "text" | "password" | "email" | "number" | "comments";
interface TextboxProps {
name?: string;
type: TextboxType;
value: string;
placeholder?: string;
width?: TextboxWidth;
variant?: TextboxVariant;
icon?: TextboxIcon;
onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
onClick?: (e: React.MouseEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
style?: React.CSSProperties;
limitSize?: number | undefined;
}
const Textbox = forwardRef<HTMLInputElement | HTMLTextAreaElement, TextboxProps>((props, ref) => {
const {
width = "80%",
variant = "solid",
icon = "none",
placeholder,
type = "text",
limitSize = undefined,
} = props;
/* eslint-disable @typescript-eslint/no-explicit-any */
const getWidth = (base: any) => {
if (width === "100%") {
return classNames(base, style.textboxWidth100);
} else if (width === "80%") {
return classNames(base, style.textboxWidth80);
} else if (width === "50%") {
return classNames(base, style.textboxWidth50);
}
return classNames(base);
};
const getClassNames = () => {
const classList: classNames.ArgumentArray = [];
classList.push(style.textbox);
if (variant === "transparent") {
classList.push(style.textboxTransparent);
} else if (variant === "solid") {
classList.push(style.textboxSolid);
} else if (variant === "search") {
classList.push(style.textboxSearch);
}
if (width === "100%") {
classList.push(style.textboxWidth100);
} else if (width === "80%") {
classList.push(style.textboxWidth80);
} else if (width === "50%") {
classList.push(style.textboxWidth50);
}
if (icon === "search") {
classList.push(style.textboxIconSearch);
} else if (icon === "none") {
if (variant === "transparent") {
classList.push(style.textboxIconNoneTransparent);
} else {
classList.push(style.textboxIconNoneSolid);
}
}
return classNames(classList);
};
const calcRemaining = () => {
if (limitSize) {
return limitSize - props.value.length;
}
return 0;
};
return (
<>
{variant !== "search" && placeholder && (
<div className={getWidth(style.textboxLabelContainer)}>
<div className={style.textboxLabel}>{placeholder}</div>
{limitSize && <span> [{calcRemaining()}]</span>}
</div>
)}
{type === "comments" ? (
<textarea
className={getClassNames()}
id={props.name}
onChange={props.onChange}
onKeyUp={props.onKeyUp}
onClick={props.onClick}
value={props.value}
style={props.style}
ref={ref as React.Ref<HTMLTextAreaElement>}
{...(limitSize && { maxLength: limitSize })}
/>
) : (
<input
className={getClassNames()}
placeholder={variant === "search" ? placeholder : ""}
type={type}
id={props.name}
value={props.value}
onChange={props.onChange}
onKeyUp={props.onKeyUp}
onClick={props.onClick}
style={props.style}
ref={ref as React.Ref<HTMLInputElement>}
{...(limitSize && { maxLength: limitSize })}
/>
)}
</>
);
});
Textbox.displayName = "Textbox";
export default Textbox;
@@ -0,0 +1,80 @@
.textboxLabelContainer {
text-align: center;
display: inline-block;
display: flex;
flex-direction: row;
align-items: center;
}
.textboxLabelContainer span {
color: var(--gray-light);
padding-top: 10px;
}
.textboxLabel {
color: var(--black);
font-size: 16px;
font-weight: 700;
padding-top: 10px;
padding-left: 5px;
line-height: 40px;
margin-right: 8px;
text-align: left;
}
.textbox {
border-radius: 10px;
padding: 10px;
height: 42px;
font-size: 14px;
font-weight: 600;
color: var(--black);
}
.textboxTransparent {
border: inset 1.5px #2b0b5f;
color: var(--white-darkest);
background-color: transparent;
background: none;
}
.textboxSolid {
border: solid 1px var(--gray-dark);
background: var(--white-dark);
background: linear-gradient(180deg, var(--white-dark) 0%, var(--white) 100%);
}
.textboxSearch {
border: solid 1px var(--wine-dark);
background: var(--wine);
color: white;
}
.textboxIconNoneTransparent {
background-image: none;
}
.textboxIconNoneSolid {
background: var(--white-dark);
background: linear-gradient(180deg, var(--white-dark) 0%, var(--white) 100%);
}
.textboxIconSearch {
background-image: url("/icon-search.svg");
background-repeat: no-repeat;
background-position: 6px center;
background-size: 28px 28px;
padding-left: 42px;
}
.textboxWidth50 {
width: 50%;
}
.textboxWidth80 {
width: 80%;
}
.textboxWidth100 {
width: 100%;
}