feat: Refactor example page and showcase components

- Updated ExamplePage to use a single Showcase component instead of separate InputShowCase and FormShowcase components.
- Added CheckboxShowcase, FormShowcase, and InputShowCase components to the showcase directory.
- Implemented Checkbox component with various states and styles.
- Enhanced InputShowCase to demonstrate different input types and states.
- Integrated new styles for checkbox variants and states.
- Updated package dependencies to include @rc-component/checkbox.
This commit is contained in:
Firman Ramdhani
2026-01-28 11:53:03 +07:00
parent c021df8012
commit b52e458a9d
14 changed files with 557 additions and 19 deletions
@@ -1,11 +1,9 @@
import FormShowcase from './form-showcase/form-showcase';
import InputShowCase from './input-showcase';
import Showcase from './showcase/showcase';
export default function ExamplePage() {
return (
<div>
<InputShowCase />
<FormShowcase />
<Showcase />
</div>
);
}
@@ -0,0 +1,151 @@
import { Checkbox, InputStatusType } from '@repo/ui';
interface CheckboxShowcaseProps {
status?: InputStatusType;
}
export default function CheckboxShowcase({ status: overrideStatus }: CheckboxShowcaseProps) {
/**
* Helper untuk menentukan status.
* Jika overrideStatus diberikan (dari props pemanggil), maka gunakan itu.
* Jika tidak, gunakan status lokal yang didefinisikan di matrix.
*/
const resolveStatus = (localStatus: InputStatusType): InputStatusType => {
return overrideStatus && overrideStatus !== 'default' ? overrideStatus : localStatus;
};
return (
<div className="flex flex-col gap-12">
{/* 1. VARIANT COMPARISON */}
<section>
<div className="mb-4">
<h2 className="text-lg font-bold text-gray-800">Checkbox Variants</h2>
<p className="text-sm text-gray-500">Dua tipe visual utama: Outlined (default) dan Filled.</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="p-4 border border-gray-100 rounded-xl bg-gray-50/50">
<span className="block mb-3 text-xs font-bold text-gray-400 uppercase">Outlined (Default)</span>
<div className="flex gap-4">
<Checkbox status={overrideStatus} label="Standard" defaultChecked />
<Checkbox status={overrideStatus} label="Unchecked" />
</div>
</div>
<div className="p-4 border border-gray-100 rounded-xl bg-gray-50/50">
<span className="block mb-3 text-xs font-bold text-gray-400 uppercase">Filled</span>
<div className="flex gap-4">
<Checkbox variant="filled" status={overrideStatus} label="Standard" defaultChecked />
<Checkbox variant="filled" status={overrideStatus} label="Unchecked" />
</div>
</div>
</div>
</section>
{/* 2. STATUS MATRIX (OVERRIDABLE) */}
<section>
<div className="mb-4">
<h2 className="text-lg font-bold text-gray-800">Status Matrix</h2>
<p className="text-sm text-gray-500">
Warna akan berubah otomatis berdasarkan status (Error, Warning, Success, Info).
{overrideStatus && (
<span className="text-brand-600 font-medium"> [Overridden by Prop: {overrideStatus}]</span>
)}
</p>
</div>
<div className="grid grid-cols-1 gap-6">
{/* Outlined Status */}
<div className="flex flex-wrap gap-6 p-6 border border-gray-200 rounded-xl">
<Checkbox status={resolveStatus('default')} label={resolveStatus('default')} defaultChecked />
<Checkbox status={resolveStatus('error')} label={resolveStatus('error')} defaultChecked />
<Checkbox status={resolveStatus('warning')} label={resolveStatus('warning')} defaultChecked />
<Checkbox status={resolveStatus('success')} label={resolveStatus('success')} defaultChecked />
<Checkbox status={resolveStatus('info')} label={resolveStatus('info')} defaultChecked />
</div>
{/* Filled Status */}
<div className="flex flex-wrap gap-6 p-6 bg-gray-50 border border-gray-200 rounded-xl">
<Checkbox
variant="filled"
status={resolveStatus('default')}
label={`${resolveStatus('default')} Filled`}
defaultChecked
/>
<Checkbox
variant="filled"
status={resolveStatus('error')}
label={`${resolveStatus('error')} Filled`}
defaultChecked
/>
<Checkbox
variant="filled"
status={resolveStatus('warning')}
label={`${resolveStatus('warning')} Filled`}
defaultChecked
/>
<Checkbox
variant="filled"
status={resolveStatus('success')}
label={`${resolveStatus('success')} Filled`}
defaultChecked
/>
<Checkbox
variant="filled"
status={resolveStatus('info')}
label={`${resolveStatus('info')} Filled`}
defaultChecked
/>
</div>
</div>
</section>
{/* 3. CONTENT & LAYOUT FEATURES */}
<section>
<div className="mb-4">
<h2 className="text-lg font-bold text-gray-800">Rich Content & States</h2>
<p className="text-sm text-gray-500">
Mendukung konten kompleks di dalam label dan berbagai state interaksi.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{/* Column A: Complex Labels */}
<div className="space-y-4">
<span className="text-xs font-bold text-gray-400 uppercase">Label Variations</span>
<Checkbox status={overrideStatus}>
<div className="flex flex-col">
<span className="font-medium text-gray-900 leading-tight">Terms of Service</span>
<span className="text-xs text-gray-500 mt-1">I have read and agree to the privacy policy.</span>
</div>
</Checkbox>
<Checkbox status={overrideStatus} label={<strong>Bold Label Text</strong>} />
</div>
{/* Column B: Interactive States */}
<div className="space-y-4">
<span className="text-xs font-bold text-gray-400 uppercase">Disabled States</span>
<div className="flex flex-col gap-3">
<Checkbox disabled label="Disabled Unchecked" />
<Checkbox disabled defaultChecked label="Disabled Checked" />
<Checkbox disabled variant="filled" label="Disabled Filled" />
</div>
</div>
{/* Column C: Edge Cases */}
<div className="space-y-4">
<span className="text-xs font-bold text-gray-400 uppercase">Layout Config</span>
<div className="flex items-center gap-6">
<Checkbox status={overrideStatus} />
<span className="text-xs text-gray-400 italic font-mono bg-gray-100 px-2 py-1 rounded">
No Label Prop
</span>
</div>
<Checkbox status={overrideStatus}>
<span className="flex items-center gap-2 text-brand-600 font-semibold">
<span className="w-2 h-2 rounded-full bg-brand-500 animate-pulse" />
Live Children Label
</span>
</Checkbox>
</div>
</div>
</section>
</div>
);
}
@@ -1,5 +1,4 @@
import { Form, Input, InputPassword } from '@repo/ui';
import React from 'react';
// --- 2. Main Showcase Component ---
export default function FormShowcase() {
const [form] = Form.useForm();
@@ -8,9 +8,9 @@ const Label = ({ children }: { children: React.ReactNode }) => (
// Helper untuk prefix/suffix visual
const Fix = ({ children }: { children: React.ReactNode }) => <span className="text-gray-400 text-sm">{children}</span>;
export default function GroupComponent({ status }: { status?: InputStatusType }) {
export default function InputShowCase({ status }: { status?: InputStatusType }) {
return (
<div className="space-y-12 p-8 rounded-2xl">
<div className="p-8 rounded-2xl">
{/* --- SECTION 1: OUTLINED VARIANT (DEFAULT) --- */}
<section className="space-y-6">
<h2 className="text-lg font-bold text-gray-800 border-b pb-2">Outlined Variant (Standard)</h2>
@@ -1,13 +1,14 @@
import { useState } from 'react';
import GroupComponent from './group-component';
import { InputStatusType } from '@repo/ui';
import CheckboxShowcase from './components/checkbox.showcase';
import InputShowCase from './components/input.showcase';
export default function InputShowCase() {
export default function Showcase() {
// State untuk menyimpan status yang dipilih
const [selectedStatus, setSelectedStatus] = useState<InputStatusType>('normal');
const [selectedStatus, setSelectedStatus] = useState<InputStatusType>('default');
const statuses: { label: string; value: InputStatusType; color: string }[] = [
{ label: 'Normal', value: 'normal', color: 'bg-gray-500' },
{ label: 'Default', value: 'default', color: 'bg-gray-500' },
{ label: 'Error', value: 'error', color: 'bg-red-500' },
{ label: 'Warning', value: 'warning', color: 'bg-amber-500' },
{ label: 'Success', value: 'success', color: 'bg-emerald-500' },
@@ -63,7 +64,10 @@ export default function InputShowCase() {
Active Status: <span className="text-blue-600">{selectedStatus}</span>
</div>
<GroupComponent status={selectedStatus} />
<div className="space-y-12 ">
<CheckboxShowcase status={selectedStatus} />
<InputShowCase status={selectedStatus} />
</div>
</div>
</section>
</main>