5. Conditional ClassName
Selain conditional rendering
kita juga sering mengimplementasikan conditional className
berdasarkan props yand dikirim oleh Parent Component
.
1. Membuat Conditional ClassName
Pada contoh ini , kita akan membuat kondisi jika isError bernilai true, maka border pada TextInput akan berwarna merah
interface InputProps {
isError?: boolean;
messageError?: string;
}
const InputText: React.FC<
InputProps & React.InputHTMLAttributes<HTMLInputElement>
> = ({ messageError = "wajib di isi", isError = false, ...props }) => {
return (
<section>
<input
className={`w-full h-8 border ${
isError ? "border-red-500 border-2" : "border-gray-700"
} rounded px-2`}
{...props}
/>
{isError ? (
<p className="text-red-500 font-bold">{messageError}</p>
) : (
<></>
)}
</section>
);
};
export default InputText;
pada property className
kita gunakan {}
dan membukan dengan backtik ``
. Kemudian pada kode ${ isError ? "border-red-500 border-2" : "border-gray-700"}
kita membuat kondisi jika isError bernilai true, maka border pada TextInput
akan berwarna merah`
2. Jalankan pada Browser
3. Library clsx
Kita sudah berhasil membuat conditional className menggunakan ternary operator
. Namun cara seperti ini akan merepotkan jika banya conditional className dan secara penulisan akan tidak rapi.
Untuk membuat conditional className kita akan menggunakan library clsx
agar kodingan kita lebih rapi dan mudah untuk di maintenance.
dokumentasi : https://www.npmjs.com/package/clsx
Kemudian kita edit koding pada komponen InputText
import clsx from "clsx";
interface InputProps {
isError?: boolean;
messageError?: string;
}
const InputText: React.FC<
InputProps & React.InputHTMLAttributes<HTMLInputElement>
> = ({ messageError = "wajib di isi", isError = false, ...props }) => {
return (
<section>
<input
className={clsx(`w-full h-8 border rounded px-2`, {
"border-red-500 border-2": isError,
"border-gray-700": !isError,
})}
{...props}
/>
{isError ? (
<p className="text-red-500 font-bold">{messageError}</p>
) : (
<></>
)}
</section>
);
};
export default InputText;
Lihat kembali pada browser
Hasilnya tetap sama seperti sebelumnya
4. Contoh Penggunaan clsx
Implementasikan pada komponen Note
import { ReactNode } from "react";
import clsx from "clsx";
type status = "warning" | "error" | "success";
interface SectionProps {
title: string;
children: ReactNode;
status: status;
}
const Note: React.FC<SectionProps> = ({
title,
status,
children,
...props
}) => {
return (
<section
className={clsx(`mt-5 rounded-lg border-2 shadow-md px-2`, {
"border-red-500": status === "error",
"border-yellow-500": status === "warning",
"border-green-500": status === "success",
})}
>
<div
className={clsx(`py-2 border-b-2`, {
"border-red-500": status === "error",
"border-yellow-500": status === "warning",
"border-green-500": status === "success",
})}
>
<h5
className={clsx("font-bold", {
"text-red-500": status === "error",
"text-yellow-500": status === "warning",
"text-green-500": status === "success",
})}
>
{" "}
{title}
</h5>
</div>
<div {...props} className="py-3 ">
{children}
</div>
</section>
);
};
export default Note;
**Panggil kembali komponen Note di app/page.tsx
"use client"; // gunakan use client karena ada onChange pda komponen
import Button from "./component/Button";
import InputText from "./component/InputText";
import Latihan from "./component/latihan";
import Note from "./component/Note";
const Home = () => {
return (
<main className="space-y-5">
<h1>Hello World</h1>
<InputText
placeholder="username"
type="text"
isError
messageError="Username not empty"
/>
<InputText placeholder="******" type="passoword" isError />
<InputText
value={12}
onChange={() => {
console.log("ok");
}}
/>
<Note title="Belajar ReactJS" status="warning">
<p>Saya belajar React</p>
</Note>
<Note title="Belajar TypeScript" status="error">
<div className="bg-blue-500">
<p className="text-white">Saya sedang belajar TypeScript</p>
</div>
</Note>
<Note title="Belajar NestJS" status="success">
<div className="bg-green-500">
<p className="text-white">
Saya sedang belajar NestJS untuk menjadi backend developer
</p>
</div>
</Note>
</main>
);
};
export default Home;
Jalankan pada Browser