Refactor and Unification of Inputs/Textarea Components using ShadCn Styling (#669)

**BRANCH CREATED FROM MODALREFACTOR***

This pull request introduces a significant enhancement to the existing
codebase by refactoring the inputs and textarea components. Currently,
each input and textarea element uses different styling components,
leading to inconsistencies and difficulties in maintaining a unified
design language across the application. To address this issue, we
propose a refactor that unifies all inputs and textareas under a single
ShadCn component.
This commit is contained in:
Cristhian Zanforlin Lousa 2023-07-25 10:50:34 -03:00 • committed by GitHub
commit 3aa4270fe7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 70 additions and 89 deletions

View file

@ -1,5 +1,6 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
import { Input } from "../ui/input";
export default function FloatComponent({ export default function FloatComponent({
value, value,
@ -19,8 +20,8 @@ export default function FloatComponent({
}, [disabled, onChange]); }, [disabled, onChange]);
return ( return (
<div className={"w-full " + (disabled ? "float-component-pointer" : "")}> <div className="w-full">
<input <Input
type="number" type="number"
step={step} step={step}
min={min} min={min}
@ -34,12 +35,8 @@ export default function FloatComponent({
}} }}
max={max} max={max}
value={value ?? ""} value={value ?? ""}
className={ disabled={disabled}
"nopan nodrag noundo nocopy " + className={editNode ? "input-edit-node" : ""}
(editNode
? "input-edit-node"
: "input-primary" + (disabled ? " input-disable " : ""))
}
placeholder={ placeholder={
editNode ? "Number 0 to 1" : "Type a number from zero to one" editNode ? "Number 0 to 1" : "Type a number from zero to one"
} }

View file

@ -1,6 +1,7 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { InputComponentType } from "../../types/components"; import { InputComponentType } from "../../types/components";
import { classNames } from "../../utils/utils"; import { classNames } from "../../utils/utils";
import { Input } from "../ui/input";
export default function InputComponent({ export default function InputComponent({
value, value,
@ -19,16 +20,15 @@ export default function InputComponent({
}, [disabled, onChange]); }, [disabled, onChange]);
return ( return (
<div className={disabled ? "input-component-div" : "relative"}> <div className="relative w-full">
<input <Input
value={value} value={value}
disabled={disabled}
className={classNames( className={classNames(
disabled ? " input-disable " : "",
password && !pwdVisible && value !== "" ? " text-clip password " : "", password && !pwdVisible && value !== "" ? " text-clip password " : "",
editNode ? " input-edit-node " : " input-primary ", editNode ? " input-edit-node " : "",
password && editNode ? "pr-8" : "", password && editNode ? "pr-8" : "",
password && !editNode ? "pr-10" : "", password && !editNode ? "pr-10" : ""
"nopan nodrag noundo nocopy"
)} )}
placeholder={password && editNode ? "Key" : "Type something..."} placeholder={password && editNode ? "Key" : "Type something..."}
onChange={(e) => { onChange={(e) => {

View file

@ -1,6 +1,8 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { InputListComponentType } from "../../types/components"; import { InputListComponentType } from "../../types/components";
import { Input } from "../ui/input";
import { classNames } from "../../utils/utils";
import _ from "lodash"; import _ from "lodash";
import IconComponent from "../genericIconComponent"; import IconComponent from "../genericIconComponent";
@ -17,24 +19,21 @@ export default function InputListComponent({
}, [disabled]); }, [disabled]);
return ( return (
<div <div
className={ className={
(disabled ? "pointer-events-none cursor-not-allowed" : "") + classNames(
"flex flex-col gap-3" value.length > 1 && editNode ? "my-1" : "",
} "flex flex-col gap-3"
> )
}>
{value.map((i, idx) => { {value.map((i, idx) => {
return ( return (
<div key={idx} className="flex w-full gap-3"> <div key={idx} className="flex w-full gap-3">
<input <Input
disabled={disabled}
type="text" type="text"
value={i} value={i}
className={ className={editNode ? "input-edit-node" : ""}
"nopan nodrag noundo nocopy " +
(editNode
? "input-edit-node "
: "input-primary " + (disabled ? "input-disable" : ""))
}
placeholder="Type something..." placeholder="Type something..."
onChange={(e) => { onChange={(e) => {
let newInputList = _.cloneDeep(value); let newInputList = _.cloneDeep(value);

View file

@ -1,5 +1,6 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { FloatComponentType } from "../../types/components"; import { FloatComponentType } from "../../types/components";
import { Input } from "../ui/input";
export default function IntComponent({ export default function IntComponent({
value, value,
@ -17,13 +18,8 @@ export default function IntComponent({
}, [disabled, onChange]); }, [disabled, onChange]);
return ( return (
<div <div className="w-full">
className={ <Input
"w-full " +
(disabled ? "pointer-events-none w-full cursor-not-allowed" : "")
}
>
<input
onKeyDown={(event) => { onKeyDown={(event) => {
if ( if (
event.key !== "Backspace" && event.key !== "Backspace" &&
@ -51,12 +47,8 @@ export default function IntComponent({
} }
}} }}
value={value ?? ""} value={value ?? ""}
className={ className={editNode ? "input-edit-node" : ""}
"nopan nodrag noundo nocopy " + disabled={disabled}
(editNode
? " input-edit-node "
: " input-primary " + (disabled ? " input-disable" : ""))
}
placeholder={editNode ? "Integer number" : "Type an integer number"} placeholder={editNode ? "Integer number" : "Type an integer number"}
onChange={(e) => { onChange={(e) => {
onChange(e.target.value); onChange(e.target.value);

View file

@ -3,6 +3,7 @@ import { TypeModal } from "../../constants/enums";
import GenericModal from "../../modals/genericModal"; import GenericModal from "../../modals/genericModal";
import { TextAreaComponentType } from "../../types/components"; import { TextAreaComponentType } from "../../types/components";
import IconComponent from "../genericIconComponent"; import IconComponent from "../genericIconComponent";
import { Input } from "../ui/input";
export default function TextAreaComponent({ export default function TextAreaComponent({
value, value,
@ -18,42 +19,36 @@ export default function TextAreaComponent({
}, [disabled]); }, [disabled]);
return ( return (
<div className={disabled ? "pointer-events-none w-full " : " w-full"}> <div className="flex w-full items-center">
<div className="flex w-full items-center"> <Input
<input value={value}
disabled={disabled}
className={editNode ? "input-edit-node" : ""}
placeholder={"Type something..."}
onChange={(e) => {
onChange(e.target.value);
}}
/>
<div>
<GenericModal
type={TypeModal.TEXT}
buttonText="Finishing Editing"
modalTitle="Edit Text"
value={value} value={value}
className={ setValue={(t: string) => {
(editNode onChange(t);
? " input-edit-node "
: " input-primary " + (disabled ? " input-disable" : "")) +
" nopan nodrag noundo nocopy w-full"
}
placeholder={"Type something..."}
onChange={(e) => {
onChange(e.target.value);
}} }}
/> >
<div> {!editNode && (
<GenericModal <IconComponent
type={TypeModal.TEXT} name="ExternalLink"
buttonText="Finishing Editing" className={
modalTitle="Edit Text" "icons-parameters-comp" +
value={value} (disabled ? " text-ring" : " hover:text-accent-foreground")
setValue={(t: string) => { }
onChange(t); />
}} )}
> </GenericModal>
{!editNode && (
<IconComponent
name="ExternalLink"
className={
"icons-parameters-comp" +
(disabled ? " text-ring" : " hover:text-accent-foreground")
}
/>
)}
</GenericModal>
</div>
</div> </div>
</div> </div>
); );

View file

@ -9,10 +9,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
return ( return (
<input <input
type={type} type={type}
className={cn( className={cn("nopan nodrag noundo nocopy input-primary", className)}
"nopan nodrag noundo nocopy flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background 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:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref} ref={ref}
{...props} {...props}
/> />

View file

@ -8,10 +8,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => { ({ className, ...props }, ref) => {
return ( return (
<textarea <textarea
className={cn( className={cn("nopan nodrag noundo nocopy textarea-primary", className)}
"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref} ref={ref}
{...props} {...props}
/> />

View file

@ -243,13 +243,15 @@ The cursor: default; property value restores the browser's default cursor style
.button-div-style { .button-div-style {
@apply gap-2 flex @apply gap-2 flex
} }
.input-primary:focus{ .input-primary{
@apply focus:placeholder-transparent focus:ring-ring focus:border-ring @apply disabled:cursor-not-allowed disabled:opacity-50 focus:placeholder-transparent focus:ring-ring focus:border-ring bg-background block text-left border-border form-input px-3 placeholder:text-muted-foreground rounded-md shadow-sm sm:text-sm w-full truncate
} }
.input-primary {
@apply bg-background block text-left border-border form-input px-3 placeholder:text-muted-foreground rounded-md shadow-sm sm:text-sm truncate w-full; /* The same as input-primary but no-truncate */
.textarea-primary{
@apply disabled:cursor-not-allowed disabled:opacity-50 focus:placeholder-transparent focus:ring-ring focus:border-ring bg-background block text-left border-border form-input px-3 placeholder:text-muted-foreground rounded-md shadow-sm sm:text-sm w-full
} }
.input-edit-node{ .input-edit-node{
@apply input-primary border-border pt-0.5 pb-0.5 text-left w-full @apply input-primary border-border pt-0.5 pb-0.5 text-left w-full
} }

View file

@ -1,5 +1,6 @@
import { useEffect } from "react"; import { useEffect } from "react";
import IconComponent from "../../../components/genericIconComponent"; import IconComponent from "../../../components/genericIconComponent";
import { Textarea } from "../../../components/ui/textarea";
import { classNames } from "../../../utils/utils"; import { classNames } from "../../../utils/utils";
export default function ChatInput({ export default function ChatInput({
@ -25,7 +26,7 @@ export default function ChatInput({
return ( return (
<div className="relative"> <div className="relative">
<textarea <Textarea
onKeyDown={(event) => { onKeyDown={(event) => {
if (event.key === "Enter" && !lockChat && !event.shiftKey) { if (event.key === "Enter" && !lockChat && !event.shiftKey) {
sendMessage(); sendMessage();

View file

@ -1,6 +1,7 @@
import { useContext, useState } from "react"; import { useContext, useState } from "react";
import ShadTooltip from "../../../../components/ShadTooltipComponent"; import ShadTooltip from "../../../../components/ShadTooltipComponent";
import IconComponent from "../../../../components/genericIconComponent"; import IconComponent from "../../../../components/genericIconComponent";
import { Input } from "../../../../components/ui/input";
import { Separator } from "../../../../components/ui/separator"; import { Separator } from "../../../../components/ui/separator";
import { alertContext } from "../../../../contexts/alertContext"; import { alertContext } from "../../../../contexts/alertContext";
import { TabsContext } from "../../../../contexts/tabsContext"; import { TabsContext } from "../../../../contexts/tabsContext";
@ -109,7 +110,7 @@ export default function ExtraSidebar() {
</div> </div>
<Separator /> <Separator />
<div className="side-bar-search-div-placement"> <div className="side-bar-search-div-placement">
<input <Input
type="text" type="text"
name="search" name="search"
id="search" id="search"