chore: Delete various UI components, form elements, and associated example/showcase pages from the UI package and web app.

This commit is contained in:
Firman Ramdhani
2026-02-05 10:08:12 +07:00
parent 660a9ace20
commit 24e0d2ca61
45 changed files with 3 additions and 6612 deletions
@@ -1,9 +1,3 @@
import Showcase from './showcase/showcase';
export default function ExamplePage() {
return (
<div>
<Showcase />
</div>
);
return <div></div>;
}
@@ -1,117 +0,0 @@
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 status={overrideStatus} label="Standard" defaultChecked />
<Checkbox 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>
</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 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,208 +0,0 @@
import React from 'react';
import dayjs from 'dayjs';
import {
TimePicker,
DatePicker,
WeekPicker,
MonthPicker,
QuarterPicker,
YearPicker,
TimeRangePicker,
DateRangePicker,
WeekRangePicker,
MonthRangePicker,
QuarterRangePicker,
YearRangePicker,
InputStatusType,
Calendar,
} from '@repo/ui'; // Sesuaikan path
import { DateUtils } from '@repo/utils';
// --- UI Helper Components ---
const Section = ({
title,
description,
children,
}: {
title: string;
description?: string;
children: React.ReactNode;
}) => (
<section className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden mb-8">
<div className="bg-gray-50 px-6 py-4 border-b border-gray-200">
<h2 className="text-lg font-bold text-gray-800">{title}</h2>
{description && <p className="text-sm text-gray-500 mt-1">{description}</p>}
</div>
<div className="p-6 grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">{children}</div>
</section>
);
const Card = ({ label, code, children }: { label: string; code?: string; children: React.ReactNode }) => (
<div className="flex flex-col space-y-2">
<div className="flex justify-between items-baseline">
<label className="text-sm font-semibold text-gray-700">{label}</label>
{code && <span className="text-xs font-mono text-gray-400 bg-gray-100 px-1.5 py-0.5 rounded">{code}</span>}
</div>
<div className="w-full">{children}</div>
</div>
);
export default function PickerShowcase({ status }: { status: InputStatusType }) {
return (
<div className="min-h-screen bg-gray-50 py-10 px-4 sm:px-6 lg:px-8 font-sans">
<div className="max-w-7xl mx-auto">
{/* Header */}
<div className="mb-10 text-center">
<h1 className="text-3xl font-extrabold text-gray-900 tracking-tight">Component Picker Showcase</h1>
<p className="mt-2 text-lg text-gray-600">
Fully typed, Tailwind-styled, and robust date manipulation components.
</p>
</div>
{/* 1. Single Pickers */}
<Section title="Single Pickers" description="Komponen untuk memilih satu nilai waktu spesifik.">
<Card label="Time Picker" code="<TimePicker />">
<TimePicker placeholder="Select time..." className="w-full" />
</Card>
<Card label="Date Picker" code="<DatePicker />">
<DatePicker placeholder="Select date..." className="w-full" />
</Card>
<Card label="Week Picker" code="<WeekPicker />">
<WeekPicker placeholder="Select week..." className="w-full" />
</Card>
<Card label="Month Picker" code="<MonthPicker />">
<MonthPicker placeholder="Select month..." className="w-full" />
</Card>
<Card label="Quarter Picker" code="<QuarterPicker />">
<QuarterPicker placeholder="Select quarter..." className="w-full" />
</Card>
<Card label="Year Picker" code="<YearPicker />">
<YearPicker placeholder="Select year..." className="w-full" />
</Card>
</Section>
{/* 2. Range Pickers */}
<Section title="Range Pickers" description="Komponen untuk memilih rentang waktu (Start - End).">
<Card label="Time Range" code="<TimeRangePicker />">
<TimeRangePicker className="w-full" />
</Card>
<Card label="Date Range" code="<DateRangePicker />">
<DateRangePicker className="w-full" />
</Card>
<Card label="Week Range" code="<WeekRangePicker />">
<WeekRangePicker className="w-full" />
</Card>
<Card label="Month Range" code="<MonthRangePicker />">
<MonthRangePicker className="w-full" />
</Card>
<Card label="Quarter Range" code="<QuarterRangePicker />">
<QuarterRangePicker className="w-full" />
</Card>
<Card label="Year Range" code="<YearRangePicker />">
<YearRangePicker className="w-full" />
</Card>
</Section>
{/* 3. Validation States */}
<Section title="Validation & States" description="Visualisasi state error, warning, dan disabled.">
<Card label="Error State" code={`status="${status}"`}>
<DatePicker status={status} placeholder="Field is required" />
<span className="text-xs text-red-500 mt-1 block">This field is required.</span>
</Card>
<Card label="Warning State" code={`status="${status}"`}>
<DatePicker status={status} placeholder="Check compatibility" defaultValue={dayjs()} />
<span className="text-xs text-yellow-600 mt-1 block">Warning: Date is in the past.</span>
</Card>
<Card label="Success State" code={`status="${status}"`}>
<DatePicker status={status} defaultValue={dayjs()} />
</Card>
<Card label="Disabled State" code="disabled">
<div className="space-y-3">
<DatePicker disabled placeholder="Cannot select" />
<DateRangePicker disabled />
</div>
</Card>
</Section>
{/* 4. Advanced & Customization */}
<Section title="Advanced Features" description="Fitur lanjutan seperti format, waktu, dan presets.">
<Card label="Date & Time" code="showTime">
<DatePicker showTime format="YYYY-MM-DD HH:mm" placeholder="Select date & time" />
</Card>
<Card label="Custom Format" code='format="DD/MM/YYYY"'>
<DatePicker format="DD/MM/YYYY" placeholder="31/12/2025" />
</Card>
<Card label="Range with Presets" code="presets={[...]}">
<DateRangePicker
presets={[
{ label: 'Today', value: [dayjs(), dayjs()] },
{ label: 'Next 7 Days', value: [dayjs(), dayjs().add(7, 'd')] },
{ label: 'This Month', value: [dayjs().startOf('month'), dayjs().endOf('month')] },
]}
/>
</Card>
<Card label="Read Only Input" code="inputReadOnly">
<DatePicker inputReadOnly placeholder="Click to open (No typing)" />
</Card>
</Section>
{/* 5. STATIC CALENDAR (Picker Panel) */}
<Section
title="Static Calendar (Embedded)"
description="Kalender statis yang langsung ditampilkan di halaman (bukan popup)."
>
{/* Basic Calendar */}
<div className="col-span-1 md:col-span-1">
<Card label="Standard Calendar" code="<Calendar />">
<div className="border border-gray-200 rounded-lg shadow-sm bg-white inline-block overflow-hidden">
<Calendar />
</div>
</Card>
</div>
{/* Calendar with State & Time */}
<div className="col-span-1 md:col-span-2">
<Card label="Calendar with Date & Time" code="<Calendar showTime />">
<div className="flex flex-col sm:flex-row gap-6 items-start">
{/* Visual Calendar */}
<div className="border border-gray-200 rounded-lg shadow-sm bg-white inline-block overflow-hidden">
<Calendar
showTime
onChange={(date) => {
console.log('Selected:', new DateUtils(date as any).format('YYYY-MM-DD HH:mm:ss'));
}}
/>
</div>
{/* Info Text */}
<div className="p-4 bg-blue-50 text-blue-800 rounded-lg text-sm max-w-xs">
<p className="font-semibold mb-2">Info:</p>
<p>
Komponen <code>Calendar</code> ini adalah <i>Panel</i> dasar. Sangat berguna untuk sidebar,
dashboard widget, atau form yang membutuhkan pemilihan tanggal yang selalu terlihat.
</p>
</div>
</div>
</Card>
</div>
</Section>
</div>
</div>
);
}
@@ -1,74 +0,0 @@
import { Form, Input, InputPassword } from '@repo/ui';
// --- 2. Main Showcase Component ---
export default function FormShowcase() {
const [form] = Form.useForm();
const handleFinish = (values: any) => {
console.log('Success - Form Values:', values);
alert(JSON.stringify(values, null, 2));
};
const handleFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
};
return (
<div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-lg shadow-md border border-gray-200">
<h2 className="text-xl font-bold mb-6 text-gray-800">Test Migrasi @rc-component/form</h2>
<Form
form={form}
onFinish={handleFinish}
onFinishFailed={handleFinishFailed}
initialValues={{ role: 'user', agree: false }}
>
{/* Case 1: Text Input Biasa + Validasi Required */}
<Form.Item name="username" label="Username" rules={[{ required: true, message: 'Username wajib diisi!' }]}>
<Input placeholder="Masukkan username" />
</Form.Item>
{/* Case 2: Email + Validasi Format */}
<Form.Item
name="email"
label="Email"
rules={[
{ required: true, message: 'Email wajib diisi!' },
{ type: 'email', message: 'Format email tidak valid!' },
]}
>
<Input type="email" placeholder="contoh@email.com" />
</Form.Item>
{/* Case 3: Password + Validasi Panjang */}
<Form.Item
name="password"
label="Password"
rules={[
{ required: true, message: 'Password wajib diisi!' },
{ min: 6, message: 'Password minimal 6 karakter!' },
]}
>
<InputPassword placeholder="Masukkan password" />
</Form.Item>
{/* Tombol Aksi */}
<div className="flex gap-3 mt-6">
<button
type="submit"
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 font-medium transition"
>
Submit
</button>
<button
type="button"
onClick={() => form.resetFields()}
className="px-4 py-2 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 font-medium transition"
>
Reset
</button>
</div>
</Form>
</div>
);
}
@@ -1,129 +0,0 @@
import { Input, InputPassword, InputNumber, InputCurrency, InputStatusType, TextArea } from '@repo/ui';
// Helper untuk label kolom
const Label = ({ children }: { children: React.ReactNode }) => (
<div className="text-xs font-bold text-gray-400 uppercase mb-3 tracking-wider">{children}</div>
);
// Helper untuk prefix/suffix visual
const Fix = ({ children }: { children: React.ReactNode }) => <span className="text-gray-400 text-sm">{children}</span>;
export default function InputShowCase({ status }: { status?: InputStatusType }) {
return (
<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>
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
<div className="space-y-3">
<Label>Basic</Label>
<Input status={status} placeholder="Input text..." />
<InputPassword status={status} placeholder="Password..." />
<InputNumber status={status} className="w-full" placeholder="Number..." />
<InputCurrency status={status} className="w-full" placeholder="Currency..." />
<TextArea status={status} placeholder="TextArea..." rows={2} />
</div>
<div className="space-y-3">
<Label>With Prefix</Label>
<Input status={status} prefix={<Fix>@</Fix>} placeholder="username" />
<InputPassword status={status} prefix={<Fix>🔒</Fix>} placeholder="password" />
<InputNumber status={status} prefix={<Fix>#</Fix>} className="w-full" placeholder="id" />
<InputCurrency status={status} prefix="Rp " className="w-full" placeholder="price" />
</div>
<div className="space-y-3">
<Label>With Suffix</Label>
<Input status={status} suffix={<Fix>.com</Fix>} placeholder="website" />
<InputPassword status={status} suffix={<Fix>Required</Fix>} placeholder="password" />
<InputNumber status={status} suffix={<Fix>kg</Fix>} className="w-full" placeholder="weight" />
<InputCurrency status={status} suffix={<Fix>nett</Fix>} className="w-full" placeholder="total" />
</div>
<div className="space-y-3">
<Label>Both & Special</Label>
<Input status={status} prefix={<Fix>https://</Fix>} suffix={<Fix>.io</Fix>} placeholder="domain" />
{/* Password Tanpa Toggle */}
<InputPassword
status={status}
visibilityToggle={false}
prefix={<Fix>🔑</Fix>}
suffix={<Fix>?</Fix>}
placeholder="Hidden Password"
/>
<InputNumber
status={status}
prefix={<Fix>+</Fix>}
suffix={<Fix>%</Fix>}
className="w-full"
placeholder="tax"
/>
<InputCurrency
status={status}
prefix="USD "
suffix={<Fix>cents</Fix>}
className="w-full"
placeholder="amount"
/>
</div>
</div>
</section>
{/* --- SECTION 2: Component States & Validation --- */}
<section className="space-y-6 mt-6">
<h2 className="text-lg font-bold text-gray-800 border-b pb-2">Component States & Validation</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{/* COLUMN 1: DISABLED (Semua Component) */}
<div className="space-y-3">
<Label>Disabled State</Label>
<div className="p-4 bg-gray-50 rounded-lg space-y-3 border border-dashed border-gray-200">
<Input disabled placeholder="Disabled Input" prefix={<Fix>🚫</Fix>} />
<InputPassword disabled placeholder="Disabled Password" />
<InputNumber disabled className="w-full" placeholder="0" />
<InputCurrency disabled className="w-full" placeholder="Rp 0" />
<TextArea disabled placeholder="Disabled TextArea" rows={2} />
</div>
</div>
{/* COLUMN 2: READ ONLY (Semua Component) */}
<div className="space-y-3">
<Label>Read Only State</Label>
<div className="p-4 bg-gray-50 rounded-lg space-y-3 border border-dashed border-gray-200">
<Input readOnly value="Read only text" prefix={<Fix>📖</Fix>} />
<InputPassword readOnly value="secretpassword" />
<InputNumber readOnly className="w-full" value={12345} />
<InputCurrency readOnly className="w-full" value={50000} />
<TextArea readOnly value="This content is read only and cannot be edited." rows={2} />
</div>
</div>
{/* COLUMN 3: ERROR OUTLINED */}
<div className="space-y-3">
<Label>Error (Outlined)</Label>
<div className="space-y-3">
<Input status="error" placeholder="Invalid input" />
<InputPassword status="error" placeholder="Wrong password" />
<InputNumber status="error" className="w-full" placeholder="Out of range" />
<InputCurrency status="error" className="w-full" placeholder="Invalid amount" />
<TextArea status="error" placeholder="Error in message" rows={2} />
</div>
</div>
{/* COLUMN 4: ERROR FILLED */}
<div className="space-y-3">
<Label>Error (Filled)</Label>
<div className="space-y-3">
<Input status="error" placeholder="Invalid input" />
<InputPassword status="error" placeholder="Wrong password" />
<InputNumber status="error" className="w-full" placeholder="Out of range" />
<InputCurrency status="error" className="w-full" placeholder="Invalid amount" />
<TextArea status="error" placeholder="Error in message" rows={2} />
</div>
</div>
</div>
</section>
</div>
);
}
@@ -1,219 +0,0 @@
import React, { useState } from 'react';
import { Switch } from '@repo/ui';
export const SwitchShowcase = () => {
// State untuk Controlled Switch Demo
const [checked, setChecked] = useState(false);
const [loading, setLoading] = useState(false);
return (
<div className="min-h-screen bg-gray-50 p-8 font-sans text-gray-800">
<div className="max-w-4xl mx-auto space-y-10">
{/* Header */}
<div className="border-b border-gray-200 pb-5">
<h1 className="text-3xl font-bold text-gray-900">Switch Component</h1>
<p className="mt-2 text-gray-600">Showcase fitur, variant, status, dan state interaksi.</p>
</div>
{/* 1. VARIANTS */}
<section>
<h2 className="text-xl font-semibold mb-4 text-gray-700">1. Variants</h2>
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
{/* Variant: Outlined (Default) */}
<div className="space-y-2">
<h3 className="text-sm font-medium text-gray-500 uppercase tracking-wider">Outlined (Default)</h3>
<p className="text-xs text-gray-400 mb-2">Background transparan saat off.</p>
<div className="flex flex-col gap-3">
<Switch label="Outlined Off" />
<Switch defaultChecked label="Outlined On" />
</div>
</div>
{/* Variant: Filled */}
<div className="space-y-2">
<h3 className="text-sm font-medium text-gray-500 uppercase tracking-wider">Filled</h3>
<p className="text-xs text-gray-400 mb-2">Background abu-abu solid saat off.</p>
<div className="flex flex-col gap-3">
<Switch label="Filled Off" />
<Switch defaultChecked label="Filled On" />
</div>
</div>
</div>
</div>
</section>
{/* 2. STATUS COLORS */}
<section>
<h2 className="text-xl font-semibold mb-4 text-gray-700">2. Status Colors</h2>
<p className="text-sm text-gray-500 mb-4">
Warna diterapkan pada state <strong>Checked</strong> dan <strong>Focus Ring</strong>.
</p>
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-6">
<div className="flex flex-col items-center gap-2">
<Switch status="default" defaultChecked />
<span className="text-xs font-medium text-gray-500">Default (Brand)</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="success" defaultChecked />
<span className="text-xs font-medium text-green-600">Success</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="warning" defaultChecked />
<span className="text-xs font-medium text-amber-600">Warning</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="error" defaultChecked />
<span className="text-xs font-medium text-red-600">Error</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="info" defaultChecked />
<span className="text-xs font-medium text-sky-600">Info</span>
</div>
</div>
</div>
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-6">
<div className="flex flex-col items-center gap-2">
<Switch status="default" defaultChecked />
<span className="text-xs font-medium text-gray-500">Default (Brand)</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="success" defaultChecked />
<span className="text-xs font-medium text-green-600">Success</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="warning" defaultChecked />
<span className="text-xs font-medium text-amber-600">Warning</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="error" defaultChecked />
<span className="text-xs font-medium text-red-600">Error</span>
</div>
<div className="flex flex-col items-center gap-2">
<Switch status="info" defaultChecked />
<span className="text-xs font-medium text-sky-600">Info</span>
</div>
</div>
</div>
</section>
{/* 3. STATES (Loading & Disabled) */}
<section>
<h2 className="text-xl font-semibold mb-4 text-gray-700">3. States</h2>
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200 space-y-8">
{/* Disabled State */}
<div>
<h3 className="text-sm font-medium text-gray-500 mb-3">Disabled</h3>
<div className="flex gap-6 items-center">
<Switch disabled label="Disabled Off" />
<Switch disabled defaultChecked label="Disabled On" />
</div>
</div>
<hr className="border-gray-100" />
{/* Loading State */}
<div>
<h3 className="text-sm font-medium text-gray-500 mb-3">Loading</h3>
<div className="flex gap-6 items-center flex-wrap">
<Switch loading label="Loading Off" />
<Switch loading defaultChecked label="Loading On" />
{/* Loading with Status Color */}
<Switch loading status="error" defaultChecked label="Loading Error" />
</div>
</div>
</div>
</section>
{/* 4. CUSTOM SIZES */}
<section>
<h2 className="text-xl font-semibold mb-4 text-gray-700">4. Custom Sizes</h2>
<p className="text-sm text-gray-500 mb-4">Menggunakan CSS Variables inline untuk override ukuran default.</p>
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200 flex items-end gap-8">
{/* Small Override */}
<div className="flex flex-col items-center gap-2">
<Switch
defaultChecked
style={
{
'--switch-width': '32px',
'--switch-height': '16px',
'--switch-handle-size': '12px',
} as React.CSSProperties
}
/>
<span className="text-xs text-gray-400">Tiny</span>
</div>
{/* Normal */}
<div className="flex flex-col items-center gap-2">
<Switch defaultChecked />
<span className="text-xs text-gray-400">Default</span>
</div>
{/* Large Override */}
<div className="flex flex-col items-center gap-2">
<Switch
defaultChecked
style={
{
'--switch-width': '60px',
'--switch-height': '30px',
'--switch-handle-size': '26px',
} as React.CSSProperties
}
/>
<span className="text-xs text-gray-400">Large</span>
</div>
</div>
</section>
{/* 5. INTERACTIVE PLAYGROUND */}
<section>
<h2 className="text-xl font-semibold mb-4 text-gray-700">5. Interactive Playground</h2>
<div className="bg-white p-6 rounded-lg shadow-sm border border-gray-200">
<div className="flex items-center justify-between mb-6 bg-gray-50 p-4 rounded-md">
<div className="text-sm">
<p>
<strong>Value:</strong> {checked ? 'true' : 'false'}
</p>
<p>
<strong>Loading:</strong> {loading ? 'true' : 'false'}
</p>
</div>
<button
onClick={() => setLoading(!loading)}
className="px-3 py-1 text-xs bg-white border border-gray-300 rounded shadow-sm hover:bg-gray-50"
>
Toggle Loading
</button>
</div>
<div className="flex gap-8 justify-center p-8 border-2 border-dashed border-gray-100 rounded-lg">
<Switch
checked={checked}
onChange={(v) => setChecked(v)}
loading={loading}
label="Control Me"
status="success"
/>
</div>
</div>
</section>
</div>
</div>
);
};
@@ -1,80 +0,0 @@
import { useState } from 'react';
import { InputStatusType } from '@repo/ui';
import CheckboxShowcase from './components/checkbox.showcase';
import InputShowCase from './components/input.showcase';
import { SwitchShowcase } from './components/switch.showcase';
import PickerShowcase from './components/date-picker.showcase';
export default function Showcase() {
// State untuk menyimpan status yang dipilih
const [selectedStatus, setSelectedStatus] = useState<InputStatusType>('default');
const statuses: { label: string; value: InputStatusType; color: string }[] = [
{ 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' },
{ label: 'Info', value: 'info', color: 'bg-blue-500' },
];
return (
<div className="min-h-screen bg-gray-50/50">
<main className="mx-auto p-8 space-y-8">
{/* HEADER & SELECTOR */}
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 bg-white p-6 rounded-2xl border border-gray-200 shadow-sm">
<div className="space-y-1">
<div className="flex items-center gap-2">
<h2 className="text-xl font-bold text-gray-800">Input Components</h2>
<span className="px-2 py-0.5 text-[10px] bg-blue-100 text-blue-600 rounded-full uppercase tracking-wider font-bold">
Interactive Lab
</span>
</div>
<p className="text-sm text-gray-500">
Pilih status untuk melihat perubahan validasi pada semua tipe input.
</p>
</div>
{/* TAB SELECTOR */}
<div className="flex bg-gray-100 p-1 rounded-xl w-fit border border-gray-200">
{statuses.map((item) => (
<button
key={item.value}
onClick={() => setSelectedStatus(item.value)}
className={`
px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
${
selectedStatus === item.value
? 'bg-white text-gray-900 shadow-sm'
: 'text-gray-500 hover:text-gray-700 hover:bg-gray-50'
}
`}
>
<div className="flex items-center gap-2">
<span className={`w-2 h-2 rounded-full ${item.color}`} />
{item.label}
</div>
</button>
))}
</div>
</div>
{/* RENDER COMPONENT */}
<section className="animate-in fade-in slide-in-from-bottom-2 duration-500">
<div className="relative">
{/* Label Indikator Status Aktif */}
<div className="absolute -top-3 left-8 px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-widest bg-white border border-gray-200 shadow-sm z-10">
Active Status: <span className="text-blue-600">{selectedStatus}</span>
</div>
<div className="space-y-12 p-8 ">
{/* <SwitchShowcase /> */}
{/* <CheckboxShowcase status={selectedStatus} /> */}
{/* <InputShowCase status={selectedStatus} /> */}
<PickerShowcase status={selectedStatus} />
</div>
</div>
</section>
</main>
</div>
);
}
-5
View File
@@ -1,4 +1,3 @@
import { DateServiceExample, StyleGuideOne, StyleGuideTree, StyleGuideTwo } from '@repo/ui';
import { lazy } from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
@@ -7,10 +6,6 @@ const ExamplePage = lazy(() => import('./example/example.page'));
export default function AppModule() {
return (
<Routes>
<Route path="/example/*" element={<DateServiceExample />} />
<Route path="/guide-1/*" element={<StyleGuideOne />} />
<Route path="/guide-2/*" element={<StyleGuideTwo />} />
<Route path="/guide-3/*" element={<StyleGuideTree />} />
<Route path="/" element={<ExamplePage />} />
<Route path="*" element={<Navigate to={'/404'} replace={true} />} />
</Routes>