chore: Delete various UI components, form elements, and associated example/showcase pages from the UI package and web app.
This commit is contained in:
@@ -1,9 +1,3 @@
|
|||||||
import Showcase from './showcase/showcase';
|
|
||||||
|
|
||||||
export default function ExamplePage() {
|
export default function ExamplePage() {
|
||||||
return (
|
return <div></div>;
|
||||||
<div>
|
|
||||||
<Showcase />
|
|
||||||
</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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { DateServiceExample, StyleGuideOne, StyleGuideTree, StyleGuideTwo } from '@repo/ui';
|
|
||||||
import { lazy } from 'react';
|
import { lazy } from 'react';
|
||||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||||
|
|
||||||
@@ -7,10 +6,6 @@ const ExamplePage = lazy(() => import('./example/example.page'));
|
|||||||
export default function AppModule() {
|
export default function AppModule() {
|
||||||
return (
|
return (
|
||||||
<Routes>
|
<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={<ExamplePage />} />
|
||||||
<Route path="*" element={<Navigate to={'/404'} replace={true} />} />
|
<Route path="*" element={<Navigate to={'/404'} replace={true} />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|||||||
@@ -12,18 +12,8 @@
|
|||||||
"test:watch": "vitest --watch"
|
"test:watch": "vitest --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^6.1.0",
|
|
||||||
"@rc-component/checkbox": "^1.0.1",
|
|
||||||
"@rc-component/form": "^1.6.2",
|
|
||||||
"@rc-component/input": "^1.1.2",
|
|
||||||
"@rc-component/input-number": "^1.6.2",
|
|
||||||
"@rc-component/picker": "^1.9.0",
|
|
||||||
"@rc-component/switch": "^1.0.3",
|
|
||||||
"@rc-component/textarea": "^1.1.2",
|
|
||||||
"@repo/utils": "workspace:*",
|
"@repo/utils": "workspace:*",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"antd": "^6.2.3",
|
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"dayjs": "^1.11.19",
|
"dayjs": "^1.11.19",
|
||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
|
|
||||||
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Button({ children, ...other }: ButtonProps): ReactNode {
|
|
||||||
return (
|
|
||||||
<button type="button" {...other}>
|
|
||||||
{children}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Button.displayName = 'Button';
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
|
|
||||||
export const CounterExample: React.FC = () => {
|
|
||||||
const [count, setCount] = useState(0);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="py-4">
|
|
||||||
<div className="text-2xl font-semibold">tailwind on package UI</div>
|
|
||||||
<div className="bg-red-400 text-3xl font-bold underline">100</div>
|
|
||||||
<div className="mt-3 bg-brand-500 text-brand-800">sdsa</div>
|
|
||||||
<div className="text-5xl text-green-500">sada</div>
|
|
||||||
<button id="counter" type="button" onClick={() => setCount(count + 1)}>
|
|
||||||
{count}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
import { DateUtils } from '@repo/utils';
|
|
||||||
import React, { useState, useEffect, useMemo } from 'react';
|
|
||||||
|
|
||||||
export const DateServiceExample: React.FC = () => {
|
|
||||||
// --- 0. TIMEZONE CONFIGURATION (ROOT CONTROL) ---
|
|
||||||
const [currentZone, setCurrentZone] = useState<string>(DateUtils.getGlobalTimezone());
|
|
||||||
|
|
||||||
// Ambil list timezone dari helper static yang kita buat sebelumnya
|
|
||||||
const timezoneList = useMemo(() => DateUtils.getSupportedTimezones(), []);
|
|
||||||
|
|
||||||
// --- 1. STATE & DATA ---
|
|
||||||
|
|
||||||
// MOCK DATA dipindahkan ke sini & pakai useMemo
|
|
||||||
// Agar saat timezone ganti, tasks ini di-regenerate dengan waktu "Now" versi timezone baru.
|
|
||||||
const tasks = useMemo(() => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: 'Bayar Server (Lusa)',
|
|
||||||
dueDate: DateUtils.now().add(2, 'day').toISOString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: 'Laporan Bulanan (Lewat 5 Hari)',
|
|
||||||
dueDate: DateUtils.now().subtract(5, 'day').toISOString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
title: 'Meeting Tahunan (Bulan Depan)',
|
|
||||||
dueDate: DateUtils.now().add(1, 'month').toISOString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
title: 'Deadline Besok Pagi',
|
|
||||||
dueDate: DateUtils.now().add(1, 'day').startOf('day').toISOString(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}, [currentZone]); // Dependency: currentZone
|
|
||||||
|
|
||||||
const [currentTime, setCurrentTime] = useState<DateUtils>(DateUtils.now());
|
|
||||||
const [selectedDate, setSelectedDate] = useState<DateUtils>(DateUtils.now());
|
|
||||||
|
|
||||||
// State demo logic calendar
|
|
||||||
const [calendarTarget, setCalendarTarget] = useState(() => DateUtils.now().add(1, 'day').startOf('day'));
|
|
||||||
|
|
||||||
// Static date (Memo kosong) -> Akan tetap di Timezone saat pertama kali load (kecuali di-refresh)
|
|
||||||
// Ini bagus untuk demo bahwa object lama tidak berubah (immutable) kecuali dibuat ulang.
|
|
||||||
const staticDate = useMemo(() => new DateUtils(), []);
|
|
||||||
|
|
||||||
// Effect update jam tiap detik
|
|
||||||
useEffect(() => {
|
|
||||||
const timer = setInterval(() => {
|
|
||||||
setCurrentTime(DateUtils.now());
|
|
||||||
}, 1000);
|
|
||||||
return () => clearInterval(timer);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// --- HANDLER GANTI TIMEZONE ---
|
|
||||||
const handleZoneChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
||||||
const newZone = e.target.value;
|
|
||||||
setCurrentZone(newZone);
|
|
||||||
|
|
||||||
// 1. Set Global Config (Inti Perubahan)
|
|
||||||
DateUtils.setGlobalConfig(newZone);
|
|
||||||
|
|
||||||
// 2. Force Refresh State agar UI langsung berubah
|
|
||||||
// Kita buat instance baru agar mengambil config timezone terbaru
|
|
||||||
setCurrentTime(DateUtils.now());
|
|
||||||
|
|
||||||
// Kita recreate selectedDate dengan nilai raw yang sama, tapi context timezone baru
|
|
||||||
setSelectedDate((prev) => new DateUtils(prev.getRaw()));
|
|
||||||
|
|
||||||
// Recreate target demo calendar
|
|
||||||
setCalendarTarget(DateUtils.now().add(1, 'day').startOf('day'));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAddDay = (days: number) => {
|
|
||||||
setSelectedDate((prev) => prev.add(days, 'day'));
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="p-8 max-w-5xl mx-auto bg-gray-50 min-h-screen font-sans text-gray-800">
|
|
||||||
{/* HEADER & TIMEZONE CONTROLLER */}
|
|
||||||
<div className="flex flex-col md:flex-row justify-between items-start md:items-center mb-8 gap-4 border-b border-gray-200 pb-6">
|
|
||||||
<h1 className="text-3xl font-bold text-blue-900">DateUtils Feature Showcase</h1>
|
|
||||||
|
|
||||||
<div className="bg-white p-3 rounded-lg shadow-sm border border-blue-100 flex items-center gap-3">
|
|
||||||
<label htmlFor="tz-switcher" className="text-xs font-bold text-gray-500 uppercase tracking-wide">
|
|
||||||
App Timezone:
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
id="tz-switcher"
|
|
||||||
value={currentZone}
|
|
||||||
onChange={handleZoneChange}
|
|
||||||
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded focus:ring-blue-500 focus:border-blue-500 block p-1.5 outline-none font-mono"
|
|
||||||
>
|
|
||||||
{timezoneList.map((tz) => (
|
|
||||||
<option key={tz} value={tz}>
|
|
||||||
{tz}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
||||||
{/* --- CARD 1: REALTIME CLOCK --- */}
|
|
||||||
<div className="bg-white p-6 rounded-xl shadow-sm border border-gray-200 flex flex-col justify-between">
|
|
||||||
<div>
|
|
||||||
<h2 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-2">Realtime Clock</h2>
|
|
||||||
|
|
||||||
<div className="flex flex-col">
|
|
||||||
<div className="text-4xl font-mono font-bold text-gray-900">{currentTime.format('HH:mm:ss')}</div>
|
|
||||||
|
|
||||||
<div className="flex items-center gap-2 mt-2">
|
|
||||||
{/* UPDATE DI SINI: Gunakan .timezoneAbbr */}
|
|
||||||
<div className="text-sm font-bold text-blue-700 bg-blue-100 px-2 py-1 rounded border border-blue-200">
|
|
||||||
{/* Ini akan output "WIB", "WITA", atau "EST" */}
|
|
||||||
{currentTime.timezoneAbbr}
|
|
||||||
|
|
||||||
{/* Ini offset angka (+07:00) */}
|
|
||||||
<span className="opacity-60 text-xs ml-1">({currentTime.format('Z')})</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="text-sm font-bold text-blue-700 bg-blue-100 px-2 py-1 rounded border border-blue-200">
|
|
||||||
{currentTime.timezoneWithOffset}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="text-lg text-gray-500 mt-2">{currentTime.format('dddd, DD MMMM YYYY')}</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-4 text-xs bg-gray-100 p-2 rounded text-gray-500 font-mono break-all">
|
|
||||||
ISO (UTC): {currentTime.toISOString()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* --- CARD 2: EPOCH & TIMESTAMPS --- */}
|
|
||||||
<div className="bg-white p-6 rounded-xl shadow-sm border border-gray-200">
|
|
||||||
<h2 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">Epoch / Timestamp Data</h2>
|
|
||||||
|
|
||||||
<div className="space-y-4">
|
|
||||||
{/* STATIC SECTION */}
|
|
||||||
<div className="bg-blue-50 p-3 rounded-lg border border-blue-100">
|
|
||||||
<div className="text-xs font-bold text-blue-800 mb-1">STATIC (Load Once)</div>
|
|
||||||
<div className="text-xs text-blue-600 mb-2">Captured on mount (keeps original timezone).</div>
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<div className="text-[10px] uppercase text-gray-500">Epoch Millis</div>
|
|
||||||
<div className="font-mono font-bold text-gray-700">{staticDate.epochMillis}</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="text-[10px] uppercase text-gray-500">Epoch Seconds</div>
|
|
||||||
<div className="font-mono font-bold text-gray-700">{staticDate.epochSeconds}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* LIVE SECTION */}
|
|
||||||
<div className="bg-green-50 p-3 rounded-lg border border-green-100">
|
|
||||||
<div className="text-xs font-bold text-green-800 mb-1">LIVE (Reactive)</div>
|
|
||||||
<div className="text-xs text-green-600 mb-2">Updated every second (follows dropdown).</div>
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<div className="text-[10px] uppercase text-gray-500">Epoch Millis</div>
|
|
||||||
<div className="font-mono font-bold text-gray-700">{new DateUtils().epochMillis}</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div className="text-[10px] uppercase text-gray-500">Epoch Seconds</div>
|
|
||||||
<div className="font-mono font-bold text-gray-700">{new DateUtils().epochSeconds}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* --- CARD 3: CALENDAR LOGIC DEMO --- */}
|
|
||||||
<div className="bg-indigo-50 p-6 rounded-xl shadow-sm border border-indigo-200 md:col-span-2">
|
|
||||||
<h2 className="text-lg font-bold text-indigo-900 mb-4 flex items-center gap-2">
|
|
||||||
🗓️ Calendar Logic Demo (The "Zero Day" Issue)
|
|
||||||
</h2>
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
||||||
<div className="text-sm text-indigo-800 space-y-2">
|
|
||||||
<p>
|
|
||||||
Compare <strong>Current Time</strong> vs <strong>Tomorrow 00:00</strong>.
|
|
||||||
</p>
|
|
||||||
<div className="bg-white/50 p-2 rounded">
|
|
||||||
<div className="flex justify-between text-xs">
|
|
||||||
<span>Now ({currentZone}):</span>
|
|
||||||
<span className="font-mono font-bold">{currentTime.format('HH:mm')}</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-between text-xs mt-1">
|
|
||||||
<span>Target (Start of Day):</span>
|
|
||||||
<span className="font-mono font-bold">{calendarTarget.format('DD MMM HH:mm')}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="bg-white p-4 rounded-lg shadow-sm border-l-4 border-red-400">
|
|
||||||
<div className="text-xs text-gray-400 uppercase font-bold">Standard .diff('day')</div>
|
|
||||||
<div className="text-2xl font-bold text-red-600 mt-1">
|
|
||||||
{calendarTarget.diff(currentTime, 'day')}{' '}
|
|
||||||
<span className="text-sm font-normal text-gray-500">Days</span>
|
|
||||||
</div>
|
|
||||||
<p className="text-xs text-red-500 mt-1">Hasil 0 jika jarak < 24 jam.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="bg-white p-4 rounded-lg shadow-sm border-l-4 border-green-500">
|
|
||||||
<div className="text-xs text-gray-400 uppercase font-bold">New .diffCalendarDay()</div>
|
|
||||||
<div className="text-2xl font-bold text-green-600 mt-1">
|
|
||||||
{calendarTarget.diffCalendarDay(currentTime)}{' '}
|
|
||||||
<span className="text-sm font-normal text-gray-500">Days</span>
|
|
||||||
</div>
|
|
||||||
<p className="text-xs text-green-600 mt-1">Hasil 1. Benar secara kalender.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* --- CARD 4: MANIPULATION --- */}
|
|
||||||
<div className="bg-white p-6 rounded-xl shadow-sm border border-gray-200 md:col-span-2">
|
|
||||||
<h2 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">
|
|
||||||
Interactive Manipulation
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div className="flex flex-col md:flex-row items-center gap-4 bg-gray-50 p-4 rounded-lg mb-4">
|
|
||||||
<button
|
|
||||||
onClick={() => handleAddDay(-1)}
|
|
||||||
className="px-4 py-2 bg-white border border-gray-300 shadow-sm text-gray-700 rounded hover:bg-gray-100 transition font-medium"
|
|
||||||
>
|
|
||||||
- 1 Day
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div className="flex-1 text-center">
|
|
||||||
<span className="block text-3xl font-bold text-blue-900">{selectedDate.format('DD MMMM YYYY')}</span>
|
|
||||||
<span className="text-sm text-blue-600 font-medium">Selected Date State</span>
|
|
||||||
<span className="text-xs text-gray-400 block mt-1">Offset: {selectedDate.format('Z')}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={() => handleAddDay(1)}
|
|
||||||
className="px-4 py-2 bg-white border border-gray-300 shadow-sm text-gray-700 rounded hover:bg-gray-100 transition font-medium"
|
|
||||||
>
|
|
||||||
+ 1 Day
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4 text-center">
|
|
||||||
<div className="bg-gray-100 p-2 rounded">
|
|
||||||
<span className="text-xs text-gray-500 block">Precise Diff (Float)</span>
|
|
||||||
<span className="font-mono font-bold text-gray-700">
|
|
||||||
{selectedDate.diff(currentTime, 'day', true).toFixed(2)} days
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="bg-gray-100 p-2 rounded">
|
|
||||||
<span className="text-xs text-gray-500 block">Calendar Diff (Int)</span>
|
|
||||||
<span className="font-mono font-bold text-gray-700">
|
|
||||||
{selectedDate.diffCalendarDay(currentTime)} days
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* --- CARD 5: TASK LIST (DYNAMIC) --- */}
|
|
||||||
<div className="mt-8 bg-white p-6 rounded-xl shadow-sm border border-gray-200">
|
|
||||||
<h2 className="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-4">
|
|
||||||
Task List Implementation (Timezone Aware)
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<div className="overflow-x-auto">
|
|
||||||
<table className="w-full text-left border-collapse">
|
|
||||||
<thead>
|
|
||||||
<tr className="text-xs text-gray-500 border-b border-gray-100 bg-gray-50/50">
|
|
||||||
<th className="py-3 px-4 rounded-tl-lg">Task Name</th>
|
|
||||||
<th className="py-3 px-4">Due Date</th>
|
|
||||||
<th className="py-3 px-4">Status Badge</th>
|
|
||||||
<th className="py-3 px-4 rounded-tr-lg">Countdown</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{tasks.map((task) => {
|
|
||||||
const dueDate = new DateUtils(task.dueDate);
|
|
||||||
const now = DateUtils.now();
|
|
||||||
|
|
||||||
const isOverdue = now.isAfter(dueDate);
|
|
||||||
const daysDiff = dueDate.diffCalendarDay(now);
|
|
||||||
const isDueSoon = !isOverdue && daysDiff <= 3;
|
|
||||||
|
|
||||||
let statusBadge;
|
|
||||||
const rowClass = 'border-b border-gray-50 hover:bg-gray-50 transition-colors';
|
|
||||||
|
|
||||||
if (isOverdue) {
|
|
||||||
statusBadge = (
|
|
||||||
<span className="px-2 py-1 text-[10px] font-bold text-red-700 bg-red-100 rounded-full border border-red-200">
|
|
||||||
OVERDUE
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
} else if (isDueSoon) {
|
|
||||||
statusBadge = (
|
|
||||||
<span className="px-2 py-1 text-[10px] font-bold text-amber-700 bg-amber-100 rounded-full border border-amber-200">
|
|
||||||
DUE SOON
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
statusBadge = (
|
|
||||||
<span className="px-2 py-1 text-[10px] font-bold text-emerald-700 bg-emerald-100 rounded-full border border-emerald-200">
|
|
||||||
ACTIVE
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<tr key={task.id} className={rowClass}>
|
|
||||||
<td className="py-3 px-4 font-medium text-gray-700">{task.title}</td>
|
|
||||||
<td className="py-3 px-4 text-gray-500 font-mono text-sm">
|
|
||||||
{dueDate.format('DD MMM YYYY HH:mm')}
|
|
||||||
<span className="text-[10px] text-gray-400 ml-1">{dueDate.format('Z')}</span>
|
|
||||||
</td>
|
|
||||||
<td className="py-3 px-4">{statusBadge}</td>
|
|
||||||
<td className="py-3 px-4 text-sm text-gray-600 font-medium">
|
|
||||||
{isOverdue ? (
|
|
||||||
`${Math.abs(daysDiff)} days late`
|
|
||||||
) : daysDiff === 0 ? (
|
|
||||||
<span className="text-amber-600">Today!</span>
|
|
||||||
) : (
|
|
||||||
`${daysDiff} days left`
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
import { EncryptionUtils } from '@repo/utils';
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
|
|
||||||
export const EncryptionExample: React.FC = () => {
|
|
||||||
// --- 1. SETUP INSTANCE ---
|
|
||||||
// Kita gunakan Singleton agar hemat memory
|
|
||||||
const cryptoService = EncryptionUtils.getInstance();
|
|
||||||
|
|
||||||
// --- 2. STATE ---
|
|
||||||
const [plainText, setPlainText] = useState<string>('');
|
|
||||||
const [encryptedResult, setEncryptedResult] = useState<string>('');
|
|
||||||
const [decryptedResult, setDecryptedResult] = useState<string>('');
|
|
||||||
|
|
||||||
// State untuk demo LocalStorage
|
|
||||||
const [storageKey] = useState<string>('my_secure_token');
|
|
||||||
const [storageValue, setStorageValue] = useState<string>('');
|
|
||||||
const [savedStatus, setSavedStatus] = useState<string>('');
|
|
||||||
|
|
||||||
// --- 3. HANDLERS ---
|
|
||||||
|
|
||||||
const handleEncrypt = () => {
|
|
||||||
// Panggil method encrypt dari class
|
|
||||||
const result = cryptoService.encrypt(plainText);
|
|
||||||
setEncryptedResult(result);
|
|
||||||
|
|
||||||
// Reset decrypt result biar user harus klik decrypt lagi untuk validasi
|
|
||||||
setDecryptedResult('');
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDecrypt = () => {
|
|
||||||
// Panggil method decrypt dari class
|
|
||||||
const original = cryptoService.decrypt(encryptedResult);
|
|
||||||
setDecryptedResult(original);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- DEMO LOCALSTORAGE ---
|
|
||||||
const saveToStorage = () => {
|
|
||||||
try {
|
|
||||||
// Encrypt sebelum simpan
|
|
||||||
const secureData = cryptoService.encrypt(storageValue);
|
|
||||||
localStorage.setItem(storageKey, secureData);
|
|
||||||
setSavedStatus(`Saved securely! Cipher: ${secureData.substring(0, 15)}...`);
|
|
||||||
} catch (error) {
|
|
||||||
setSavedStatus('Error saving data');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const loadFromStorage = () => {
|
|
||||||
try {
|
|
||||||
const storedData = localStorage.getItem(storageKey);
|
|
||||||
if (!storedData) {
|
|
||||||
setSavedStatus('No data found in storage');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Decrypt setelah ambil
|
|
||||||
const originalData = cryptoService.decrypt(storedData);
|
|
||||||
setSavedStatus(`Loaded & Decrypted: "${originalData}"`);
|
|
||||||
} catch (error) {
|
|
||||||
setSavedStatus('Failed to decrypt storage data');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="p-8 max-w-4xl mx-auto bg-slate-50 min-h-screen font-sans text-slate-800">
|
|
||||||
<h1 className="text-3xl font-bold mb-8 text-slate-900">Encryption Service Demo</h1>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
||||||
{/* === SECTION 1: INTERACTIVE PLAYGROUND === */}
|
|
||||||
<div className="bg-white p-6 rounded-xl shadow-sm border border-slate-200">
|
|
||||||
<h2 className="text-lg font-bold text-indigo-600 mb-4 flex items-center gap-2">🔐 Live Playground</h2>
|
|
||||||
|
|
||||||
{/* INPUT */}
|
|
||||||
<div className="mb-4">
|
|
||||||
<label className="block text-xs font-bold text-slate-500 uppercase mb-1">Secret Message (Input)</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={plainText}
|
|
||||||
onChange={(e) => setPlainText(e.target.value)}
|
|
||||||
placeholder="Type sensitive data here..."
|
|
||||||
className="w-full p-2 border border-slate-300 rounded focus:ring-2 focus:ring-indigo-500 outline-none"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* ACTIONS */}
|
|
||||||
<div className="flex gap-2 mb-6">
|
|
||||||
<button
|
|
||||||
onClick={handleEncrypt}
|
|
||||||
className="bg-indigo-600 text-white px-4 py-2 rounded hover:bg-indigo-700 transition text-sm font-semibold"
|
|
||||||
>
|
|
||||||
Encrypt ⬇
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={handleDecrypt}
|
|
||||||
disabled={!encryptedResult}
|
|
||||||
className="bg-emerald-600 text-white px-4 py-2 rounded hover:bg-emerald-700 transition text-sm font-semibold disabled:opacity-50"
|
|
||||||
>
|
|
||||||
Decrypt ⬆
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* OUTPUT: ENCRYPTED */}
|
|
||||||
<div className="mb-4">
|
|
||||||
<label className="block text-xs font-bold text-slate-500 uppercase mb-1">
|
|
||||||
Encrypted Output (Ciphertext)
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
readOnly
|
|
||||||
value={encryptedResult}
|
|
||||||
className="w-full p-2 bg-slate-100 border border-slate-200 rounded text-xs font-mono text-slate-600 h-24 break-all"
|
|
||||||
placeholder="Result will appear here..."
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* OUTPUT: DECRYPTED */}
|
|
||||||
<div>
|
|
||||||
<label className="block text-xs font-bold text-slate-500 uppercase mb-1">Verified Decryption</label>
|
|
||||||
<div
|
|
||||||
className={`p-2 border rounded min-h-[40px] flex items-center ${
|
|
||||||
decryptedResult ? 'bg-green-50 border-green-200 text-green-800' : 'bg-slate-50 border-slate-200'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{decryptedResult || <span className="text-slate-400 italic text-sm">Waiting for decryption...</span>}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* === SECTION 2: SECURE LOCALSTORAGE === */}
|
|
||||||
<div className="bg-white p-6 rounded-xl shadow-sm border border-slate-200">
|
|
||||||
<h2 className="text-lg font-bold text-amber-600 mb-4 flex items-center gap-2">💾 Secure LocalStorage</h2>
|
|
||||||
<p className="text-sm text-slate-600 mb-4">
|
|
||||||
Simulasi menyimpan token auth. Data di browser storage akan terlihat acak, tapi aplikasi bisa membacanya
|
|
||||||
kembali.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div>
|
|
||||||
<label className="block text-xs font-bold text-slate-500 uppercase mb-1">Data to Save</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={storageValue}
|
|
||||||
onChange={(e) => setStorageValue(e.target.value)}
|
|
||||||
placeholder="e.g., Bearer eyJhbGci..."
|
|
||||||
className="w-full p-2 border border-slate-300 rounded focus:ring-2 focus:ring-amber-500 outline-none"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<button
|
|
||||||
onClick={saveToStorage}
|
|
||||||
className="bg-slate-800 text-white px-4 py-2 rounded hover:bg-slate-900 transition text-sm font-semibold flex-1"
|
|
||||||
>
|
|
||||||
Save Encrypted
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={loadFromStorage}
|
|
||||||
className="bg-white border border-slate-300 text-slate-700 px-4 py-2 rounded hover:bg-slate-50 transition text-sm font-semibold flex-1"
|
|
||||||
>
|
|
||||||
Load & Decrypt
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* STATUS MONITOR */}
|
|
||||||
<div className="mt-4 bg-amber-50 border border-amber-100 p-3 rounded">
|
|
||||||
<span className="text-xs font-bold text-amber-800 uppercase block mb-1">Log / Status</span>
|
|
||||||
<code className="text-xs text-amber-900 block break-all">{savedStatus || 'Ready...'}</code>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-4 pt-4 border-t border-slate-100">
|
|
||||||
<p className="text-xs text-slate-400">
|
|
||||||
<strong>Tips:</strong> Buka <em>Developer Tools > Application > LocalStorage</em>. Cari key{' '}
|
|
||||||
<code>my_secure_token</code>. Kamu akan melihat string acak (encrypted), bukan teks asli.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
interface HeaderExampleProps {
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const HeaderExample: React.FC<HeaderExampleProps> = ({ title }) => {
|
|
||||||
return (
|
|
||||||
<header id="header">
|
|
||||||
<h1>{title}</h1>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
// --- SHARED SUB-COMPONENTS ---
|
|
||||||
const Card = ({
|
|
||||||
title,
|
|
||||||
children,
|
|
||||||
className = '',
|
|
||||||
}: {
|
|
||||||
title?: string;
|
|
||||||
children: React.ReactNode;
|
|
||||||
className?: string;
|
|
||||||
}) => (
|
|
||||||
<div className={`bg-white border border-gray-200 rounded-lg shadow-sm ${className}`}>
|
|
||||||
{title && (
|
|
||||||
<div className="px-4 py-3 border-b border-gray-100 bg-gray-50/50">
|
|
||||||
<h3 className="text-lg font-semibold text-gray-800">{title}</h3>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="p-5">{children}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const Badge = ({
|
|
||||||
children,
|
|
||||||
variant = 'info',
|
|
||||||
}: {
|
|
||||||
children: React.ReactNode;
|
|
||||||
variant?: 'success' | 'error' | 'warning' | 'info';
|
|
||||||
}) => {
|
|
||||||
const styles = {
|
|
||||||
success: 'bg-green-50 text-green-600 border-green-100',
|
|
||||||
error: 'bg-red-50 text-red-600 border-red-100',
|
|
||||||
warning: 'bg-amber-50 text-amber-600 border-amber-100',
|
|
||||||
info: 'bg-brand-50 text-brand-600 border-brand-100',
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<span className={`px-2 py-0.5 rounded-sm text-xs font-bold border ${styles[variant]} uppercase tracking-wider`}>
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- MAIN PAGE COMPONENT ---
|
|
||||||
export function StyleGuideOne() {
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen bg-gray-50 text-gray-700 font-sans">
|
|
||||||
{/* 1. OBJECT HEADER (SAP Pattern) */}
|
|
||||||
<div className="bg-white border-b border-gray-200 px-8 py-6 sticky top-0 z-10 shadow-sm">
|
|
||||||
<div className="max-w-7xl mx-auto flex flex-col md:flex-row md:items-center justify-between gap-4">
|
|
||||||
<div>
|
|
||||||
<nav className="text-xs font-bold text-brand-600 uppercase tracking-widest mb-1">
|
|
||||||
Procurement / Purchase Orders
|
|
||||||
</nav>
|
|
||||||
<h1 className="text-xl font-bold text-gray-900 flex items-center gap-3">
|
|
||||||
PO #4500019283
|
|
||||||
<Badge variant="success">Released</Badge>
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<button className="px-4 py-1.5 border border-gray-300 rounded-md bg-white hover:bg-gray-50 font-medium transition-all shadow-sm">
|
|
||||||
Reject
|
|
||||||
</button>
|
|
||||||
<button className="px-4 py-1.5 bg-brand-500 text-white rounded-md hover:bg-brand-600 font-medium transition-all shadow-sm">
|
|
||||||
Approve Order
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="max-w-7xl mx-auto p-6 space-y-8">
|
|
||||||
{/* 2. ANALYTICS / KPI SECTION */}
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
||||||
{[
|
|
||||||
{ label: 'Total Value', val: '$12,450.00', color: 'text-gray-900' },
|
|
||||||
{ label: 'Items Count', val: '24 SKUs', color: 'text-gray-900' },
|
|
||||||
{ label: 'Days Overdue', val: '5 Days', color: 'text-red-500' },
|
|
||||||
{ label: 'Vendor Rating', val: '4.8 / 5.0', color: 'text-green-600' },
|
|
||||||
].map((kpi, i) => (
|
|
||||||
<div key={i} className="bg-white p-4 rounded-lg border border-gray-200 shadow-sm">
|
|
||||||
<p className="text-xs font-bold text-gray-500 uppercase tracking-wider">{kpi.label}</p>
|
|
||||||
<p className={`text-xl font-bold mt-1 ${kpi.color}`}>{kpi.val}</p>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
||||||
{/* LEFT: FORM & CONTROLS */}
|
|
||||||
<div className="lg:col-span-1 space-y-6">
|
|
||||||
<Card title="General Information">
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-medium text-gray-500">Vendor Name</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
readOnly
|
|
||||||
className="bg-gray-50 border border-gray-200 rounded-md px-3 py-1.5 text-gray-600 outline-none cursor-not-allowed"
|
|
||||||
defaultValue="Steel Global Corp"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-medium text-gray-500">Shipping Method</label>
|
|
||||||
<select className="border border-gray-300 rounded-md px-3 py-1.5 bg-white focus:ring-1 focus:ring-brand-500 outline-none">
|
|
||||||
<option>Sea Freight - Standard</option>
|
|
||||||
<option>Air Freight - Express</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-medium text-gray-500">Order Priority</label>
|
|
||||||
<div className="flex gap-4 mt-1">
|
|
||||||
<label className="flex items-center gap-2 cursor-pointer">
|
|
||||||
<input type="radio" name="prio" className="accent-brand-500" />{' '}
|
|
||||||
<span className="text-base">Normal</span>
|
|
||||||
</label>
|
|
||||||
<label className="flex items-center gap-2 cursor-pointer">
|
|
||||||
<input type="radio" name="prio" className="accent-brand-500" defaultChecked />{' '}
|
|
||||||
<span className="text-base">High</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card title="Order Status Logs">
|
|
||||||
<ul className="space-y-4">
|
|
||||||
{[
|
|
||||||
{ time: '10:00 AM', msg: 'Order Created', user: 'System' },
|
|
||||||
{ time: '11:30 AM', msg: 'Manager Approved', user: 'Budi Santoso' },
|
|
||||||
].map((log, i) => (
|
|
||||||
<li key={i} className="flex gap-3 border-l-2 border-brand-200 pl-4 relative">
|
|
||||||
<div className="absolute w-2.5 h-2.5 bg-brand-500 rounded-full -left-[6px] top-1"></div>
|
|
||||||
<div>
|
|
||||||
<p className="text-base font-medium text-gray-800">{log.msg}</p>
|
|
||||||
<p className="text-xs text-gray-500">
|
|
||||||
{log.time} • By {log.user}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* RIGHT: DATA TABLE (The Core of ERP) */}
|
|
||||||
<div className="lg:col-span-2">
|
|
||||||
<Card className="!p-0 overflow-hidden">
|
|
||||||
<div className="p-4 border-b border-gray-100 flex justify-between items-center">
|
|
||||||
<h3 className="text-lg font-semibold text-gray-800">Line Items</h3>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<button className="text-xs font-bold text-brand-600 hover:bg-brand-50 px-2 py-1 rounded">
|
|
||||||
EXPORT CSV
|
|
||||||
</button>
|
|
||||||
<button className="text-xs font-bold text-brand-600 hover:bg-brand-50 px-2 py-1 rounded">
|
|
||||||
PRINT PO
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="overflow-x-auto">
|
|
||||||
<table className="w-full border-collapse">
|
|
||||||
<thead>
|
|
||||||
<tr className="bg-gray-100/80">
|
|
||||||
<th className="px-4 py-2 text-xs font-bold text-gray-500 uppercase">Material</th>
|
|
||||||
<th className="px-4 py-2 text-xs font-bold text-gray-500 uppercase">Description</th>
|
|
||||||
<th className="px-4 py-2 text-xs font-bold text-gray-500 uppercase text-right">Qty</th>
|
|
||||||
<th className="px-4 py-2 text-xs font-bold text-gray-500 uppercase text-right">Price</th>
|
|
||||||
<th className="px-4 py-2 text-xs font-bold text-gray-500 uppercase text-right">Total</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody className="divide-y divide-gray-100 text-base">
|
|
||||||
{[1, 2, 3, 4, 5].map((item) => (
|
|
||||||
<tr key={item} className="hover:bg-brand-50/20 transition-all cursor-pointer group">
|
|
||||||
<td className="px-4 py-2 font-mono text-brand-600 group-hover:underline">M-1000{item}</td>
|
|
||||||
<td className="px-4 py-2 text-gray-800">
|
|
||||||
Industrial Steel Pipe 2.5" - Grade {item === 2 ? 'B' : 'A'}
|
|
||||||
</td>
|
|
||||||
<td className="px-4 py-2 text-right">100.00</td>
|
|
||||||
<td className="px-4 py-2 text-right">150.00</td>
|
|
||||||
<td className="px-4 py-2 text-right font-semibold text-gray-900">15,000.00</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
<tfoot className="bg-gray-50/80 font-bold border-t-2 border-gray-200">
|
|
||||||
<tr>
|
|
||||||
<td colSpan={4} className="px-4 py-3 text-right text-gray-500 uppercase text-xs tracking-widest">
|
|
||||||
Grand Total (Net)
|
|
||||||
</td>
|
|
||||||
<td className="px-4 py-3 text-right text-brand-600 text-lg">$ 75,000.00</td>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<div className="mt-4 bg-amber-50 border border-amber-100 rounded-lg p-4 flex gap-3">
|
|
||||||
<span className="text-xl">⚠️</span>
|
|
||||||
<div>
|
|
||||||
<p className="text-base font-bold text-amber-800">Budget Warning</p>
|
|
||||||
<p className="text-sm text-amber-700">
|
|
||||||
This purchase order exceeds the quarterly budget for Department "Steel Fabrication" by 12%.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,257 +0,0 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
// ==========================================================
|
|
||||||
// 1. ATOMIC COMPONENTS (Berdasar Config 13px & Burgundy)
|
|
||||||
// ==========================================================
|
|
||||||
|
|
||||||
const Card = ({ title, children, className = '', footer }: any) => (
|
|
||||||
<div className={`bg-white border border-gray-200 rounded-lg shadow-sm overflow-hidden ${className}`}>
|
|
||||||
{title && (
|
|
||||||
<div className="px-4 py-3 border-b border-gray-100 bg-gray-50/50 flex justify-between items-center">
|
|
||||||
<h3 className="text-lg font-semibold text-gray-800 tracking-tight">{title}</h3>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="p-5 text-base">{children}</div>
|
|
||||||
{footer && <div className="px-4 py-3 bg-gray-50 border-t border-gray-100">{footer}</div>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const Button = ({ children, variant = 'primary', className = '', ...props }: any) => {
|
|
||||||
const styles: any = {
|
|
||||||
primary: 'bg-brand-500 text-white hover:bg-brand-600 shadow-sm border border-brand-600',
|
|
||||||
secondary: 'bg-white border border-gray-300 text-gray-700 hover:bg-gray-50 shadow-xs',
|
|
||||||
ghost: 'text-gray-600 hover:bg-gray-100',
|
|
||||||
danger: 'bg-red-500 text-white hover:bg-red-600',
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
className={`px-3 py-1.5 rounded-md font-medium text-base transition-all active:scale-95 disabled:opacity-50 ${styles[variant]} ${className}`}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Badge = ({ children, variant = 'info' }: any) => {
|
|
||||||
const styles: any = {
|
|
||||||
success: 'bg-green-50 text-green-600 border-green-100',
|
|
||||||
error: 'bg-red-50 text-red-600 border-red-100',
|
|
||||||
warning: 'bg-amber-50 text-amber-600 border-amber-100',
|
|
||||||
info: 'bg-brand-50 text-brand-700 border-brand-100',
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<span className={`px-2 py-0.5 rounded-sm text-xs font-bold border ${styles[variant]} uppercase tracking-wider`}>
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ==========================================================
|
|
||||||
// 2. MAIN PAGE: ADVANCED STYLE GUIDE
|
|
||||||
// ==========================================================
|
|
||||||
|
|
||||||
export function StyleGuideTwo() {
|
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex min-h-screen bg-gray-50 font-sans text-gray-800">
|
|
||||||
{/* SIDE NAVIGATION */}
|
|
||||||
<aside className="w-64 bg-brand-950 text-white flex flex-col sticky top-0 h-screen shadow-xl shrink-0">
|
|
||||||
<div className="p-6 border-b border-brand-900 flex items-center gap-3">
|
|
||||||
<div className="w-8 h-8 bg-brand-500 rounded-lg flex items-center justify-center font-bold text-xl shadow-inner">
|
|
||||||
B
|
|
||||||
</div>
|
|
||||||
<span className="font-bold text-lg tracking-tight">BURGUNDY_ERP</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav className="flex-1 p-4 space-y-1">
|
|
||||||
<p className="text-brand-300 text-[10px] font-bold uppercase tracking-widest px-2 mb-2 opacity-60">
|
|
||||||
Finance Modules
|
|
||||||
</p>
|
|
||||||
<div className="flex items-center gap-3 px-3 py-2 rounded-md bg-brand-500 text-white shadow-lg cursor-pointer">
|
|
||||||
<span>📓</span> <span className="text-base font-medium">General Ledger</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-brand-900 text-brand-100 cursor-pointer transition-colors">
|
|
||||||
<span>📊</span> <span className="text-base font-medium">Cost Analysis</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-3 px-3 py-2 rounded-md hover:bg-brand-900 text-brand-100 cursor-pointer transition-colors">
|
|
||||||
<span>🏦</span> <span className="text-base font-medium">Bank Reconciliation</span>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
{/* MAIN CONTENT AREA */}
|
|
||||||
<main className="flex-1 flex flex-col min-w-0">
|
|
||||||
{/* TOP BAR */}
|
|
||||||
<header className="h-14 bg-white border-b border-gray-200 flex items-center justify-between px-8 shrink-0 shadow-sm">
|
|
||||||
<div className="text-sm text-gray-500 font-medium">
|
|
||||||
Master Data <span className="mx-2">/</span>{' '}
|
|
||||||
<span className="text-gray-900 font-bold">Chart of Accounts</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<div className="w-8 h-8 rounded-full bg-brand-100 border border-brand-200 flex items-center justify-center text-brand-700 font-bold text-xs">
|
|
||||||
JD
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{/* CONTENT */}
|
|
||||||
<div className="p-8 space-y-8 overflow-y-auto">
|
|
||||||
{/* HEADER SECTION */}
|
|
||||||
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
|
||||||
<div>
|
|
||||||
<h2 className="text-2xl font-bold text-gray-900">Account Overview: 110200</h2>
|
|
||||||
<p className="text-base text-gray-500 mt-1">
|
|
||||||
Domestic Trade Accounts Receivable •{' '}
|
|
||||||
<span className="text-brand-600 font-semibold italic">Local Currency (IDR)</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Button variant="secondary" onClick={() => window.print()}>
|
|
||||||
Print Statement
|
|
||||||
</Button>
|
|
||||||
<Button onClick={() => setIsModalOpen(true)}>Create Entry</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 xl:grid-cols-3 gap-8">
|
|
||||||
{/* LEFT: MAIN DATA TABLE */}
|
|
||||||
<div className="xl:col-span-2 space-y-6">
|
|
||||||
<Card title="Recent Transactions">
|
|
||||||
<div className="overflow-x-auto -mx-5 -my-5">
|
|
||||||
<table className="w-full text-left border-collapse">
|
|
||||||
<thead>
|
|
||||||
<tr className="bg-gray-50 border-b border-gray-100">
|
|
||||||
<th className="px-5 py-3 text-xs font-bold text-gray-500 uppercase">Document</th>
|
|
||||||
<th className="px-5 py-3 text-xs font-bold text-gray-500 uppercase">Partner</th>
|
|
||||||
<th className="px-5 py-3 text-xs font-bold text-gray-500 uppercase text-right">Debit</th>
|
|
||||||
<th className="px-5 py-3 text-xs font-bold text-gray-500 uppercase text-right">Credit</th>
|
|
||||||
<th className="px-5 py-3 text-xs font-bold text-gray-500 uppercase text-center">Status</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody className="divide-y divide-gray-50">
|
|
||||||
{[1, 2, 3, 4].map((i) => (
|
|
||||||
<tr key={i} className="hover:bg-brand-50/20 text-base transition-colors group">
|
|
||||||
<td className="px-5 py-3 font-mono text-brand-700 font-semibold">INV-2026-00{i}</td>
|
|
||||||
<td className="px-5 py-3">
|
|
||||||
<p className="font-medium text-gray-800">Global Tech Solutions</p>
|
|
||||||
<p className="text-xs text-gray-400">Vendor ID: V-9920</p>
|
|
||||||
</td>
|
|
||||||
<td className="px-5 py-3 text-right font-semibold">$ {i * 125}.00</td>
|
|
||||||
<td className="px-5 py-3 text-right text-gray-300">0.00</td>
|
|
||||||
<td className="px-5 py-3 text-center">
|
|
||||||
<Badge variant={i % 2 === 0 ? 'success' : 'warning'}>
|
|
||||||
{i % 2 === 0 ? 'Cleared' : 'Pending'}
|
|
||||||
</Badge>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
||||||
<Card title="Budget Utilization">
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="w-full bg-gray-100 rounded-full h-3">
|
|
||||||
<div className="bg-brand-500 h-3 rounded-full" style={{ width: '75%' }}></div>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-between text-sm">
|
|
||||||
<span className="text-gray-500 font-medium italic underline decoration-brand-200 underline-offset-4">
|
|
||||||
Spent: $75,000.00
|
|
||||||
</span>
|
|
||||||
<span className="text-gray-900 font-bold">Total: $100,000.00</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
<Card title="Quick Insight">
|
|
||||||
<p className="text-gray-600 leading-relaxed italic">
|
|
||||||
"Anomali terdeteksi pada baris INV-2026-003. Nilai transaksi melebihi rata-rata bulanan sebesar
|
|
||||||
40%."
|
|
||||||
</p>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* RIGHT: CONFIGURATION & ACTIONS */}
|
|
||||||
<div className="xl:col-span-1 space-y-6">
|
|
||||||
<Card title="Account Settings" footer={<Button className="w-full">Update Control</Button>}>
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-bold text-gray-500 uppercase tracking-tighter italic">
|
|
||||||
Reconciliation Type
|
|
||||||
</label>
|
|
||||||
<select className="w-full border border-gray-300 rounded-md px-3 py-1.5 bg-white focus:ring-1 focus:ring-brand-500 outline-none">
|
|
||||||
<option>Automatic Match</option>
|
|
||||||
<option>Manual Review</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-bold text-gray-500 uppercase tracking-tighter italic">
|
|
||||||
Tax Code
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
className="w-full border border-gray-300 rounded-md px-3 py-1.5 outline-none focus:border-brand-500 transition-colors"
|
|
||||||
placeholder="e.g. VAT_11"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-3 py-2 border-t border-gray-50">
|
|
||||||
<input type="checkbox" className="w-4 h-4 accent-brand-500" id="lock" />
|
|
||||||
<label htmlFor="lock" className="text-sm font-semibold text-gray-700">
|
|
||||||
Lock account for posting
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<div className="bg-brand-900 text-white p-5 rounded-lg shadow-lg relative overflow-hidden">
|
|
||||||
<div className="relative z-10">
|
|
||||||
<h4 className="text-lg font-bold mb-1 italic">Premium Support</h4>
|
|
||||||
<p className="text-sm text-brand-100 opacity-80">
|
|
||||||
Butuh bantuan rekonsiliasi? Hubungi konsultan finansial kami.
|
|
||||||
</p>
|
|
||||||
<button className="mt-4 text-xs font-bold bg-white text-brand-900 px-3 py-1.5 rounded uppercase tracking-widest shadow-lg">
|
|
||||||
Chat Konsultan
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="absolute -right-4 -bottom-4 text-6xl opacity-10 font-bold">ERP</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
{/* 3. SAMPLE MODAL (Overlay) */}
|
|
||||||
{isModalOpen && (
|
|
||||||
<div className="fixed inset-0 bg-brand-950/40 backdrop-blur-sm z-50 flex items-center justify-center p-4">
|
|
||||||
<div className="bg-white rounded-xl shadow-2xl w-full max-w-lg overflow-hidden border border-gray-200">
|
|
||||||
<div className="px-6 py-4 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
|
|
||||||
<h3 className="text-xl font-bold text-gray-900">New Journal Entry</h3>
|
|
||||||
<button onClick={() => setIsModalOpen(false)} className="text-gray-400 hover:text-gray-600 text-2xl">
|
|
||||||
×
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div className="p-6 space-y-4">
|
|
||||||
<p className="text-base text-gray-600">
|
|
||||||
Silakan masukkan detail entri jurnal baru untuk tahun fiskal 2026.
|
|
||||||
</p>
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div className="col-span-2 border border-brand-100 bg-brand-50/50 p-3 rounded-md italic text-xs text-brand-800">
|
|
||||||
Info: Pastikan periode pembukuan Januari sudah dibuka sebelum menekan "Post".
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="px-6 py-4 bg-gray-50 border-t border-gray-100 flex justify-end gap-2">
|
|
||||||
<Button variant="secondary" onClick={() => setIsModalOpen(false)}>
|
|
||||||
Discard
|
|
||||||
</Button>
|
|
||||||
<Button onClick={() => setIsModalOpen(false)}>Post Entry</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,232 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
// ==========================================================
|
|
||||||
// COMPACT UI COMPONENTS
|
|
||||||
// ==========================================================
|
|
||||||
|
|
||||||
const SectionTitle = ({ children }: { children: React.ReactNode }) => (
|
|
||||||
<h3 className="text-[11px] font-bold text-gray-500 uppercase tracking-widest mb-2 border-b border-gray-200 pb-1 italic">
|
|
||||||
{children}
|
|
||||||
</h3>
|
|
||||||
);
|
|
||||||
|
|
||||||
const CompactCard = ({ title, children, footer }: any) => (
|
|
||||||
<div className="bg-white border border-gray-200 rounded shadow-sm flex flex-col">
|
|
||||||
{title && (
|
|
||||||
<div className="px-3 py-1.5 border-b border-gray-100 bg-gray-50/50 flex justify-between items-center">
|
|
||||||
<span className="text-sm font-bold text-gray-700 tracking-tight">{title}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="p-3 flex-1">{children}</div>
|
|
||||||
{footer && <div className="px-3 py-2 bg-gray-50/80 border-t border-gray-100">{footer}</div>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const Badge = ({ children, variant = 'info' }: any) => {
|
|
||||||
const styles: any = {
|
|
||||||
success: 'bg-green-50 text-green-700 border-green-200',
|
|
||||||
error: 'bg-red-50 text-red-700 border-red-200',
|
|
||||||
warning: 'bg-amber-50 text-amber-700 border-amber-200',
|
|
||||||
info: 'bg-brand-50 text-brand-700 border-brand-200',
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
className={`px-1.5 py-0.5 rounded-sm text-[10px] font-bold border ${styles[variant]} uppercase tracking-tighter`}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ==========================================================
|
|
||||||
// MAIN STYLE SHOWCASE
|
|
||||||
// ==========================================================
|
|
||||||
|
|
||||||
export function StyleGuideTree() {
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen bg-gray-100 p-3 space-y-3 font-sans text-gray-800">
|
|
||||||
{/* GLOBAL ACTION BAR */}
|
|
||||||
<div className="bg-brand-900 text-white p-3 rounded flex justify-between items-center shadow-md">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<div className="bg-white p-1 rounded text-brand-900 font-bold text-xs uppercase">ERP-SYSTEM</div>
|
|
||||||
<h1 className="text-base font-bold tracking-tight">Financial Postings & Asset Management</h1>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<button className="bg-brand-700 hover:bg-brand-600 px-3 py-1 rounded text-base font-medium border border-brand-600 transition-all">
|
|
||||||
Simulate
|
|
||||||
</button>
|
|
||||||
<button className="bg-white text-brand-900 hover:bg-gray-100 px-3 py-1 rounded text-base font-bold shadow-sm transition-all">
|
|
||||||
Post Document
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="grid grid-cols-12 gap-3">
|
|
||||||
{/* ROW 1: ANALYTICS & STATS (Top Row) */}
|
|
||||||
{[
|
|
||||||
{ label: 'Total Debit', val: 'IDR 4.500.000.000', sub: '24 Entries Today', color: 'text-gray-900' },
|
|
||||||
{ label: 'Total Credit', val: 'IDR 4.500.000.000', sub: 'Balanced', color: 'text-green-600' },
|
|
||||||
{ label: 'Unposted Items', val: '12 Documents', sub: 'High Priority', color: 'text-amber-600' },
|
|
||||||
{ label: 'System Health', val: '99.9%', sub: 'No Latency', color: 'text-brand-600' },
|
|
||||||
].map((stat, i) => (
|
|
||||||
<div key={i} className="col-span-12 md:col-span-3 bg-white p-3 rounded border border-gray-200 shadow-sm">
|
|
||||||
<p className="text-[10px] font-bold text-gray-400 uppercase tracking-widest">{stat.label}</p>
|
|
||||||
<p className={`text-lg font-bold ${stat.color} tracking-tight`}>{stat.val}</p>
|
|
||||||
<p className="text-[11px] text-gray-400 font-medium italic">{stat.sub}</p>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{/* ROW 2: FORMS & CONTROLS (Left Panel) */}
|
|
||||||
<div className="col-span-12 lg:col-span-4 space-y-3">
|
|
||||||
<CompactCard title="Document Header">
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
|
||||||
<div className="col-span-1 flex flex-col">
|
|
||||||
<label className="text-xs font-bold text-gray-400 uppercase italic mb-1 tracking-tight">
|
|
||||||
Posting Date
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="date"
|
|
||||||
className="border border-gray-300 rounded px-2 py-1 text-base outline-none focus:border-brand-500 bg-gray-50"
|
|
||||||
defaultValue="2026-01-19"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-1 flex flex-col">
|
|
||||||
<label className="text-xs font-bold text-gray-400 uppercase italic mb-1 tracking-tight">Period</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
readOnly
|
|
||||||
className="border border-gray-200 rounded px-2 py-1 text-base bg-gray-100 text-gray-500"
|
|
||||||
defaultValue="01 / 2026"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-2 flex flex-col">
|
|
||||||
<label className="text-xs font-bold text-gray-400 uppercase italic mb-1 tracking-tight">
|
|
||||||
Document Type
|
|
||||||
</label>
|
|
||||||
<select className="border border-gray-300 rounded px-2 py-1 text-base outline-none bg-white">
|
|
||||||
<option>SA - GL Account Document</option>
|
|
||||||
<option>DZ - Customer Payment</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-2 flex flex-col">
|
|
||||||
<label className="text-xs font-bold text-gray-400 uppercase italic mb-1 tracking-tight">
|
|
||||||
Header Text
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
className="border border-gray-300 rounded px-2 py-1 text-base h-16 outline-none focus:border-brand-500"
|
|
||||||
placeholder="Monthly reconciliation..."
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CompactCard>
|
|
||||||
|
|
||||||
<CompactCard title="Operational Controls">
|
|
||||||
<div className="space-y-2">
|
|
||||||
<label className="flex items-center gap-3 p-2 border border-gray-100 rounded hover:bg-gray-50 cursor-pointer transition-colors">
|
|
||||||
<input type="checkbox" className="accent-brand-600 w-4 h-4" defaultChecked />
|
|
||||||
<span className="text-base font-medium">Automatic Tax Calculation</span>
|
|
||||||
</label>
|
|
||||||
<label className="flex items-center gap-3 p-2 border border-gray-100 rounded hover:bg-gray-50 cursor-pointer transition-colors">
|
|
||||||
<input type="checkbox" className="accent-brand-600 w-4 h-4" />
|
|
||||||
<span className="text-base font-medium">Post to All Ledgers</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</CompactCard>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* ROW 3: COMPLEX DATA TABLE (Center Panel) */}
|
|
||||||
<div className="col-span-12 lg:col-span-8 space-y-3">
|
|
||||||
<CompactCard className="!p-0 overflow-hidden">
|
|
||||||
<div className="bg-gray-50/50 px-4 py-2 border-b border-gray-200 flex justify-between items-center">
|
|
||||||
<SectionTitle>Line Item Entries (001 - 005)</SectionTitle>
|
|
||||||
<div className="flex gap-2 mb-2">
|
|
||||||
<button className="text-[10px] font-bold text-brand-700 bg-brand-50 px-2 py-0.5 rounded border border-brand-100">
|
|
||||||
ADD ROW
|
|
||||||
</button>
|
|
||||||
<button className="text-[10px] font-bold text-gray-500 bg-white px-2 py-0.5 rounded border border-gray-200">
|
|
||||||
CLEAR ALL
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="overflow-x-auto">
|
|
||||||
<table className="w-full border-collapse">
|
|
||||||
<thead>
|
|
||||||
<tr className="bg-gray-100 border-b border-gray-200">
|
|
||||||
<th className="px-3 py-1.5 text-[10px] font-bold text-gray-500 uppercase">Item</th>
|
|
||||||
<th className="px-3 py-1.5 text-[10px] font-bold text-gray-500 uppercase">GL Account</th>
|
|
||||||
<th className="px-3 py-1.5 text-[10px] font-bold text-gray-500 uppercase">Cost Center</th>
|
|
||||||
<th className="px-3 py-1.5 text-[10px] font-bold text-gray-500 uppercase text-right">
|
|
||||||
Amount (LC)
|
|
||||||
</th>
|
|
||||||
<th className="px-3 py-1.5 text-[10px] font-bold text-gray-500 uppercase text-center">Ind.</th>
|
|
||||||
<th className="px-3 py-1.5 text-[10px] font-bold text-gray-500 uppercase text-center">Status</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody className="divide-y divide-gray-100">
|
|
||||||
{[10, 20, 30, 40, 50].map((item, idx) => (
|
|
||||||
<tr key={item} className="hover:bg-brand-50/30 transition-colors group">
|
|
||||||
<td className="px-3 py-1.5 text-center font-mono text-gray-400">{item}</td>
|
|
||||||
<td className="px-3 py-1.5">
|
|
||||||
<div className="font-bold text-brand-700 text-base leading-none">11000{idx}</div>
|
|
||||||
<div className="text-[10px] text-gray-400 italic">Petty Cash - Main Office</div>
|
|
||||||
</td>
|
|
||||||
<td className="px-3 py-1.5">
|
|
||||||
<div className="font-medium text-gray-700">CC-HEAD-01</div>
|
|
||||||
</td>
|
|
||||||
<td className="px-3 py-1.5 text-right font-mono font-bold text-gray-900">
|
|
||||||
{(item * 1500000).toLocaleString('id-ID')}
|
|
||||||
</td>
|
|
||||||
<td className="px-3 py-1.5 text-center font-bold text-brand-600">{idx % 2 === 0 ? 'S' : 'H'}</td>
|
|
||||||
<td className="px-3 py-1.5 text-center">
|
|
||||||
<Badge variant={idx === 2 ? 'warning' : 'success'}>{idx === 2 ? 'Review' : 'Valid'}</Badge>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div className="bg-gray-50 p-3 flex justify-end gap-10 border-t border-gray-200">
|
|
||||||
<div className="text-right">
|
|
||||||
<p className="text-[10px] font-bold text-gray-400 uppercase">Total Debit</p>
|
|
||||||
<p className="text-lg font-bold text-gray-900 tracking-tight">IDR 450.000.000</p>
|
|
||||||
</div>
|
|
||||||
<div className="text-right">
|
|
||||||
<p className="text-[10px] font-bold text-gray-400 uppercase">Total Credit</p>
|
|
||||||
<p className="text-lg font-bold text-brand-600 tracking-tight">IDR 450.000.000</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CompactCard>
|
|
||||||
|
|
||||||
{/* MESSAGE LOGS / ACTIVITY */}
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
|
||||||
<CompactCard title="System Activity">
|
|
||||||
<div className="space-y-2">
|
|
||||||
{[
|
|
||||||
{ t: '09:41', u: 'System', m: 'Auto-balancing completed successfully.' },
|
|
||||||
{ t: '10:05', u: 'Admin', m: 'Modified Cost Center on Item 20.' },
|
|
||||||
].map((log, i) => (
|
|
||||||
<div key={i} className="text-base flex gap-2 border-b border-gray-50 pb-1">
|
|
||||||
<span className="font-mono text-brand-600 text-xs">{log.t}</span>
|
|
||||||
<span className="text-gray-600 leading-tight">
|
|
||||||
<strong>{log.u}:</strong> {log.m}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</CompactCard>
|
|
||||||
<CompactCard title="Quick Attachments">
|
|
||||||
<div className="flex flex-wrap gap-2">
|
|
||||||
<div className="border border-dashed border-gray-300 rounded p-2 text-center w-full hover:bg-gray-50 cursor-pointer">
|
|
||||||
<span className="text-xs font-bold text-gray-400">+ DROP FILES HERE</span>
|
|
||||||
</div>
|
|
||||||
<div className="bg-gray-100 px-2 py-1 rounded text-[11px] font-medium flex items-center gap-2">
|
|
||||||
📄 invoice_001.pdf <span className="text-red-500 font-bold cursor-pointer">×</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CompactCard>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import RcCheckbox from '@rc-component/checkbox';
|
|
||||||
import { CheckboxProps } from '../types';
|
|
||||||
import { forwardRef } from 'react';
|
|
||||||
import { InputRef } from '@rc-component/input/lib/interface';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checkbox component built on top of RcCheckbox.
|
|
||||||
*
|
|
||||||
* Renders a checkbox with an optional label (uses `label` prop or `children`).
|
|
||||||
* Default prop values: `status = 'default'`, `variant = 'outlined'`.
|
|
||||||
*
|
|
||||||
* The wrapper element will receive these classes:
|
|
||||||
* - 'rc-checkbox-wrapper'
|
|
||||||
* - `checkbox-status-{status}`
|
|
||||||
* - `checkbox-variant-{variant}`
|
|
||||||
* - 'rc-checkbox-wrapper-disabled' when `disabled` is true
|
|
||||||
* and any additional classes passed via `className`.
|
|
||||||
*
|
|
||||||
* All remaining props are forwarded to the underlying RcCheckbox, which is rendered with `prefixCls="rc-checkbox"`.
|
|
||||||
*
|
|
||||||
* Note: a `ref` parameter is accepted by the forwardRef call but is not currently attached to the rendered input element.
|
|
||||||
*
|
|
||||||
* @param props - Checkbox props
|
|
||||||
* @param ref - Forwarded ref (InputRef). Accepted but not applied to the DOM node in the current implementation.
|
|
||||||
* @returns JSX.Element
|
|
||||||
*/
|
|
||||||
export const Checkbox = forwardRef<InputRef, CheckboxProps>((props, ref) => {
|
|
||||||
const { label, status = 'default', className, children, ...rest } = props;
|
|
||||||
|
|
||||||
const displayLabel = label || children;
|
|
||||||
|
|
||||||
const wrapperClass = [
|
|
||||||
'rc-checkbox-wrapper',
|
|
||||||
`checkbox-status-${status}`,
|
|
||||||
rest.disabled ? 'rc-checkbox-wrapper-disabled' : '',
|
|
||||||
className,
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<label className={wrapperClass}>
|
|
||||||
<span className="rc-checkbox-container">
|
|
||||||
<RcCheckbox ref={ref} {...rest} prefixCls="rc-checkbox" />
|
|
||||||
</span>
|
|
||||||
{displayLabel && <span className="rc-checkbox-label-text">{displayLabel}</span>}
|
|
||||||
</label>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
Checkbox.displayName = 'Checkbox';
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import RcForm from '@rc-component/form';
|
|
||||||
import { FormProps } from '../types';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A form control component that wraps the underlying form library.
|
|
||||||
*
|
|
||||||
* @template Values - The type of values managed by the form. Defaults to `any`.
|
|
||||||
* @param props - The form configuration properties.
|
|
||||||
* @param props.children - The child elements to render within the form.
|
|
||||||
* @returns A rendered form component with the provided children.
|
|
||||||
*/
|
|
||||||
export default function FormControl<Values = any>({ children, ...props }: FormProps<Values>) {
|
|
||||||
return <RcForm {...props}>{children}</RcForm>;
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
import React, { ReactElement } from 'react';
|
|
||||||
import { Field } from '@rc-component/form';
|
|
||||||
import { FormItemProps } from '../types';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FormItem component that wraps form fields with validation, error/warning messaging, and styling.
|
|
||||||
*
|
|
||||||
* This component manages the rendering of a form field with associated label, validation rules,
|
|
||||||
* and status-based styling. It integrates with a Field control system to handle form state,
|
|
||||||
* errors, and warnings.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* ```tsx
|
|
||||||
* <FormItem
|
|
||||||
* name="username"
|
|
||||||
* label="Username"
|
|
||||||
* rules={[{ required: true, message: 'Username is required' }]}
|
|
||||||
* >
|
|
||||||
* <Input />
|
|
||||||
* </FormItem>
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @param {FormItemProps} props - The component props
|
|
||||||
* @param {string} props.name - The field name for form control binding
|
|
||||||
* @param {string} [props.label] - The label text to display above the input
|
|
||||||
* @param {ReactNode} props.children - The form control element (e.g., Input, Textarea)
|
|
||||||
* @param {Array<ValidationRule>} [props.rules] - Validation rules for the field
|
|
||||||
* @param {string} [props.valuePropName='value'] - The prop name used to bind the field value
|
|
||||||
* @param {any} [props.initialValue] - The initial value for the field
|
|
||||||
* @param {'error' | 'warning' | 'normal'} [props.status] - Override the status appearance
|
|
||||||
*
|
|
||||||
* @returns {ReactElement} A form item container with label, control, and validation messages
|
|
||||||
*/
|
|
||||||
export default function FormItem(props: FormItemProps) {
|
|
||||||
const { name, label, children, rules, valuePropName = 'value', initialValue, status: OverrideStatus } = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Field name={name} rules={rules} valuePropName={valuePropName} initialValue={initialValue}>
|
|
||||||
{(control, meta) => {
|
|
||||||
// Defensive check
|
|
||||||
const hasError = meta.errors && meta.errors.length > 0;
|
|
||||||
const hasWarning = meta.warnings && meta.warnings.length > 0;
|
|
||||||
|
|
||||||
// Determine status
|
|
||||||
const status = OverrideStatus ?? (hasError ? 'error' : hasWarning ? 'warning' : 'normal');
|
|
||||||
|
|
||||||
// Logic Clone Element
|
|
||||||
const isValid = React.isValidElement(children);
|
|
||||||
const childElement = isValid ? (children as ReactElement<{ status?: any }>) : null;
|
|
||||||
|
|
||||||
// Pass status to child (Input/Textarea) so their borders change color
|
|
||||||
const childNode = childElement ? React.cloneElement(childElement, { ...control, status }) : children;
|
|
||||||
|
|
||||||
// Logic Required Check
|
|
||||||
const isRequired = rules?.some((r: any) => r && typeof r === 'object' && r.required);
|
|
||||||
|
|
||||||
return (
|
|
||||||
// Wrapper Div with status class
|
|
||||||
<div className={`rc-form-item status-${status}`}>
|
|
||||||
{/* LABEL SECTION */}
|
|
||||||
{label && (
|
|
||||||
<label className="rc-form-item-label">
|
|
||||||
{label}
|
|
||||||
{isRequired && <span className="rc-form-item-required-mark">*</span>}
|
|
||||||
</label>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* INPUT CONTROL */}
|
|
||||||
<div className="rc-form-item-control relative">{childNode}</div>
|
|
||||||
|
|
||||||
{/* ERROR / WARNING MESSAGE */}
|
|
||||||
{(hasError || hasWarning) && (
|
|
||||||
<div className="rc-form-item-explain">{hasError ? meta.errors[0] : meta.warnings[0]}</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Field>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
// index.ts
|
|
||||||
import React from 'react';
|
|
||||||
import { useForm, List, FieldContext } from '@rc-component/form';
|
|
||||||
import { FormProps } from '../types';
|
|
||||||
|
|
||||||
import FormControl from './form-control.component';
|
|
||||||
import FormItem from './form-item.component';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal Form component using forwardRef to handle RcForm instance
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* React component that provides form context and forwards a ref to the underlying FormControl.
|
|
||||||
*
|
|
||||||
* @template Values - Shape of the form values (extends object). Defaults to any.
|
|
||||||
* @param props - FormProps for the form, augmented with an optional forwarded ref.
|
|
||||||
* @param props.ref - Optional forwarded ref passed to the underlying FormControl.
|
|
||||||
* @returns A React element that sets up form context and delegates rendering/behavior to FormControl.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* - Built using React.forwardRef and typed as a generic component so callers can infer form value types.
|
|
||||||
* - Use to wrap form fields and access form state/actions via context.
|
|
||||||
*/
|
|
||||||
const FormProvider = React.forwardRef(FormControl) as <Values extends object = any>(
|
|
||||||
props: FormProps<Values> & { ref?: React.ForwardedRef<any> },
|
|
||||||
) => React.ReactElement;
|
|
||||||
|
|
||||||
type CompoundedComponent = typeof FormProvider & {
|
|
||||||
Item: typeof FormItem;
|
|
||||||
useForm: typeof useForm;
|
|
||||||
List: typeof List;
|
|
||||||
Provider: typeof FieldContext.Provider;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Assign sub-components and utilities
|
|
||||||
const Form = FormProvider as CompoundedComponent;
|
|
||||||
Form.Item = FormItem;
|
|
||||||
Form.useForm = useForm;
|
|
||||||
Form.List = List;
|
|
||||||
Form.Provider = FieldContext.Provider;
|
|
||||||
|
|
||||||
export { Form };
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
export * from './types';
|
|
||||||
export * from './form-provider';
|
|
||||||
|
|
||||||
export * from './input/input.component';
|
|
||||||
export * from './input/input-password.component';
|
|
||||||
export * from './input/input-currency.component';
|
|
||||||
export * from './input/input-number.component';
|
|
||||||
|
|
||||||
export * from './textarea/textarea.component';
|
|
||||||
export * from './checkbox/checkbox.component';
|
|
||||||
export * from './switch/switch.component';
|
|
||||||
export * from "./picker";
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import { CurrencyUtils } from '@repo/utils';
|
|
||||||
import { InputCurrencyProps } from '../types';
|
|
||||||
import { InputNumber } from './input-number.component';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* InputCurrency
|
|
||||||
*
|
|
||||||
* A controlled InputNumber component with currency formatting.
|
|
||||||
* Delegates all formatting/parsing to CurrencyUtils.
|
|
||||||
*
|
|
||||||
* Features:
|
|
||||||
* - Display currency prefix (e.g., Rp, $)
|
|
||||||
* - Thousand separator formatting
|
|
||||||
* - Optional decimal rounding
|
|
||||||
* - Global prefix support via CurrencyUtils
|
|
||||||
*/
|
|
||||||
export const InputCurrency = (props: InputCurrencyProps) => {
|
|
||||||
const {
|
|
||||||
prefix, // Optional override for instance prefix
|
|
||||||
decimalSeparator, // Optional override for separator
|
|
||||||
decimalScale, // Optional rounding
|
|
||||||
...restProps
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
// Create a CurrencyUtils instance for this input
|
|
||||||
const currencyService = new CurrencyUtils({
|
|
||||||
prefix,
|
|
||||||
decimalSeparator,
|
|
||||||
decimalScale,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formatter: converts numeric value to formatted string for display
|
|
||||||
*/
|
|
||||||
const formatter = (value: number | string | undefined) => {
|
|
||||||
return currencyService.format(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parser: converts formatted string back to raw numeric string
|
|
||||||
* Note: never rounds or modifies the underlying value
|
|
||||||
*/
|
|
||||||
const parser = (displayValue: string | undefined) => {
|
|
||||||
return currencyService.parseToRaw(displayValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<InputNumber
|
|
||||||
{...restProps}
|
|
||||||
formatter={formatter}
|
|
||||||
parser={parser}
|
|
||||||
// Default min value to 0 for currency
|
|
||||||
min={props.min !== undefined ? props.min : 0}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* A controlled input component for numeric values with increment/decrement handlers.
|
|
||||||
*
|
|
||||||
* Wraps the rc-component InputNumber with custom styling support and status indicators.
|
|
||||||
* Features custom chevron-style up/down icons and support for multiple visual variants.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* ```tsx
|
|
||||||
* const ref = useRef<HTMLInputElement>(null);
|
|
||||||
* <InputNumber
|
|
||||||
* ref={ref}
|
|
||||||
* value={10}
|
|
||||||
* onChange={(val) => console.log(val)}
|
|
||||||
* status="success"
|
|
||||||
* />
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* @param {InputNumberProps} props - The input number component props
|
|
||||||
* @param {InputStatusType} [props.status] - The validation status ('default', 'success', 'error', etc.)
|
|
||||||
* @param {string} [props.className] - Additional CSS classes to apply
|
|
||||||
* @param {React.Ref<HTMLInputElement>} ref - Ref to the underlying input element
|
|
||||||
*
|
|
||||||
* @returns {React.ReactElement} The rendered input number component
|
|
||||||
*/
|
|
||||||
import { forwardRef } from 'react';
|
|
||||||
import RcInputNumber from '@rc-component/input-number';
|
|
||||||
import { InputNumberProps, InputStatusType, VALID_INPUT_STATUSES } from '../types';
|
|
||||||
|
|
||||||
// Handler Icons (Chevron Modern)
|
|
||||||
const UpIcon = () => (
|
|
||||||
<span className="input-number-action-up-inner flex items-center justify-center w-full h-full">
|
|
||||||
<svg viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" className="w-3 h-3">
|
|
||||||
<path d="M8.5 6.5L12 10 5 10z" />
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
|
|
||||||
const DownIcon = () => (
|
|
||||||
<span className="input-number-action-down-inner flex items-center justify-center w-full h-full">
|
|
||||||
<svg viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" className="w-3 h-3">
|
|
||||||
<path d="M8.5 9.5L5 6 12 6z" />
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
|
|
||||||
export const InputNumber = forwardRef<HTMLInputElement, InputNumberProps>((props, ref) => {
|
|
||||||
const { status, className, ...restProps } = props;
|
|
||||||
|
|
||||||
const currentStatus: InputStatusType = status && VALID_INPUT_STATUSES.includes(status) ? status : 'default';
|
|
||||||
|
|
||||||
const computedClassName = [className, `input-number-status-${currentStatus}`].filter(Boolean).join(' ');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RcInputNumber
|
|
||||||
ref={ref}
|
|
||||||
{...restProps}
|
|
||||||
className={computedClassName}
|
|
||||||
upHandler={<UpIcon />}
|
|
||||||
downHandler={<DownIcon />}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
InputNumber.displayName = 'InputNumber';
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
import { InputPasswordProps } from '../types';
|
|
||||||
import { Input } from './input.component';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Eye Icon for visibility toggle
|
|
||||||
* @returns JSX Element
|
|
||||||
*/
|
|
||||||
const EyeIcon = () => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
width="1em"
|
|
||||||
height="1em"
|
|
||||||
className="w-4 h-4"
|
|
||||||
>
|
|
||||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
|
||||||
<circle cx="12" cy="12" r="3" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Eye Off Icon for visibility toggle
|
|
||||||
* @returns JSX Element
|
|
||||||
*/
|
|
||||||
const EyeOffIcon = () => (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="2"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
width="1em"
|
|
||||||
height="1em"
|
|
||||||
className="w-4 h-4"
|
|
||||||
>
|
|
||||||
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
|
|
||||||
<line x1="1" y1="1" x2="23" y2="23" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* InputPassword Component
|
|
||||||
* @param props InputPasswordProps
|
|
||||||
* @returns JSX Element
|
|
||||||
*/
|
|
||||||
export const InputPassword = (props: InputPasswordProps) => {
|
|
||||||
// Set default props and state
|
|
||||||
const { suffix, disabled, visibilityToggle = true, ...restProps } = props;
|
|
||||||
const [visible, setVisible] = useState(false);
|
|
||||||
|
|
||||||
const toggleVisibility = () => {
|
|
||||||
if (disabled) return;
|
|
||||||
setVisible(!visible);
|
|
||||||
};
|
|
||||||
|
|
||||||
// If no suffix and no visibility toggle, render simple password input
|
|
||||||
if (!suffix && !visibilityToggle) {
|
|
||||||
return <Input {...restProps} disabled={disabled} type="password" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const combinedSuffix = (
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
{/* Suffix User */}
|
|
||||||
{suffix && <span className="text-gray-400 select-none">{suffix}</span>}
|
|
||||||
|
|
||||||
{/* Visibility Toggle Button */}
|
|
||||||
{visibilityToggle && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={toggleVisibility}
|
|
||||||
disabled={disabled}
|
|
||||||
className={`
|
|
||||||
flex items-center justify-center
|
|
||||||
focus:outline-none transition-colors
|
|
||||||
${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer text-gray-400 hover:text-gray-600'}
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{visible ? <EyeIcon /> : <EyeOffIcon />}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Input
|
|
||||||
{...restProps}
|
|
||||||
disabled={disabled}
|
|
||||||
// If toggle is disabled, force type to 'password', ignore visible state
|
|
||||||
type={visibilityToggle && visible ? 'text' : 'password'}
|
|
||||||
suffix={combinedSuffix}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { forwardRef } from 'react';
|
|
||||||
import RcInput, { InputRef } from '@rc-component/input';
|
|
||||||
import { InputProps, InputStatusType, VALID_INPUT_STATUSES } from '../types';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Input component that wraps the RC Input library with custom status.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @param {InputProps} props - The input component props
|
|
||||||
* @param {InputStatusType} [props.status] - The validation status of the input (validated against VALID_INPUT_STATUSES)
|
|
||||||
* @param {string} [props.className] - Additional CSS classes to apply to the input
|
|
||||||
* @param {boolean} [props.disabled] - Whether the input is disabled
|
|
||||||
* @param {InputRef} ref - Reference to the underlying RC Input element
|
|
||||||
* @returns {React.ReactElement} The rendered Input component with computed classes for status, and disabled state
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* - Invalid status values default to 'default'
|
|
||||||
* - The 'rc-input-disabled' class is automatically applied by RC Input library when disabled={true}
|
|
||||||
* - The 'input-disabled' helper class is manually added for custom wrapper styling when needed
|
|
||||||
*/
|
|
||||||
export const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
|
||||||
const { status, className, disabled, ...restProps } = props;
|
|
||||||
|
|
||||||
// Determine current status, defaulting to 'default' if invalid
|
|
||||||
const currentStatus: InputStatusType = status && VALID_INPUT_STATUSES.includes(status) ? status : 'default';
|
|
||||||
|
|
||||||
// Construct classname
|
|
||||||
// Note: class 'rc-input-disabled' is added automatically by RC Input when disabled
|
|
||||||
const computedClassName = [
|
|
||||||
className,
|
|
||||||
`input-status-${currentStatus}`,
|
|
||||||
// Add custom disabled class if disabled
|
|
||||||
disabled ? 'input-disabled' : '',
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
return <RcInput ref={ref} {...restProps} disabled={disabled} className={computedClassName} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
Input.displayName = 'Input';
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
import { forwardRef } from 'react';
|
|
||||||
import RcPicker, { PickerPanel as RcPickerPanel, RangePicker as RcRangePicker } from '@rc-component/picker';
|
|
||||||
import type { GenerateConfig } from '@rc-component/picker/lib/generate';
|
|
||||||
import enUS from '@rc-component/picker/lib/locale/en_US';
|
|
||||||
import {
|
|
||||||
PickerProps,
|
|
||||||
RangePickerProps,
|
|
||||||
PickerPanelProps,
|
|
||||||
InputStatusType,
|
|
||||||
VALID_INPUT_STATUSES,
|
|
||||||
SpecificPickerProps,
|
|
||||||
SpecificRangePickerProps,
|
|
||||||
} from '../types';
|
|
||||||
|
|
||||||
const COMPONENT_PREFIX = 'rc-picker';
|
|
||||||
|
|
||||||
interface PickerGenerateReturns<DateType extends object> {
|
|
||||||
Picker: React.ForwardRefExoticComponent<PickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
RangePicker: React.ForwardRefExoticComponent<RangePickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
Calendar: React.ForwardRefExoticComponent<PickerPanelProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
|
|
||||||
DatePicker: React.ForwardRefExoticComponent<SpecificPickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
WeekPicker: React.ForwardRefExoticComponent<SpecificPickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
MonthPicker: React.ForwardRefExoticComponent<SpecificPickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
QuarterPicker: React.ForwardRefExoticComponent<SpecificPickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
YearPicker: React.ForwardRefExoticComponent<SpecificPickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
TimePicker: React.ForwardRefExoticComponent<SpecificPickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
|
|
||||||
DateRangePicker: React.ForwardRefExoticComponent<SpecificRangePickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
WeekRangePicker: React.ForwardRefExoticComponent<SpecificRangePickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
MonthRangePicker: React.ForwardRefExoticComponent<SpecificRangePickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
QuarterRangePicker: React.ForwardRefExoticComponent<SpecificRangePickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
YearRangePicker: React.ForwardRefExoticComponent<SpecificRangePickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
TimeRangePicker: React.ForwardRefExoticComponent<SpecificRangePickerProps<DateType> & React.RefAttributes<any>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getStatusClassName = (prefixCls: string, className?: string, status?: InputStatusType, disabled?: boolean) => {
|
|
||||||
const currentStatus = status && VALID_INPUT_STATUSES.includes(status) ? status : '';
|
|
||||||
return [
|
|
||||||
className,
|
|
||||||
prefixCls,
|
|
||||||
currentStatus ? `picker-status-${currentStatus}` : '',
|
|
||||||
disabled ? `${prefixCls}-disabled` : '',
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ');
|
|
||||||
};
|
|
||||||
|
|
||||||
export function generateComponentPicker<DateType extends object>(
|
|
||||||
generateConfig: GenerateConfig<DateType>,
|
|
||||||
): PickerGenerateReturns<DateType> {
|
|
||||||
// 1. Generic Picker
|
|
||||||
const Picker = forwardRef<any, PickerProps<DateType>>((props, ref) => {
|
|
||||||
const { status, className, locale, prefixCls = COMPONENT_PREFIX, ...restProps } = props;
|
|
||||||
return (
|
|
||||||
<RcPicker<DateType>
|
|
||||||
ref={ref}
|
|
||||||
prefixCls={prefixCls}
|
|
||||||
generateConfig={generateConfig}
|
|
||||||
locale={locale || enUS}
|
|
||||||
className={getStatusClassName(prefixCls, className, status, props.disabled)}
|
|
||||||
prevIcon={<span className={`${prefixCls}-prev-icon`} />}
|
|
||||||
nextIcon={<span className={`${prefixCls}-next-icon`} />}
|
|
||||||
superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
|
|
||||||
superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
|
|
||||||
transitionName={`rc-slide-up`}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
Picker.displayName = 'Picker';
|
|
||||||
|
|
||||||
// 2. Generic Range Picker
|
|
||||||
const RangePicker = forwardRef<any, RangePickerProps<DateType>>((props, ref) => {
|
|
||||||
const { status, className, locale, prefixCls = COMPONENT_PREFIX, ...restProps } = props;
|
|
||||||
return (
|
|
||||||
<RcRangePicker<DateType>
|
|
||||||
ref={ref}
|
|
||||||
prefixCls={prefixCls}
|
|
||||||
generateConfig={generateConfig}
|
|
||||||
locale={locale || enUS}
|
|
||||||
className={getStatusClassName(prefixCls, className, status, props.disabled as boolean)}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
RangePicker.displayName = 'RangePicker';
|
|
||||||
|
|
||||||
// 3. Calendar
|
|
||||||
const Calendar = forwardRef<any, PickerPanelProps<DateType>>((props, ref) => {
|
|
||||||
const { locale, prefixCls = COMPONENT_PREFIX, ...restProps } = props;
|
|
||||||
return (
|
|
||||||
<RcPickerPanel<DateType>
|
|
||||||
ref={ref}
|
|
||||||
prefixCls={prefixCls}
|
|
||||||
generateConfig={generateConfig}
|
|
||||||
locale={locale || enUS}
|
|
||||||
{...restProps}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
Calendar.displayName = 'Calendar';
|
|
||||||
|
|
||||||
// ================== Specific Pickers ==================
|
|
||||||
const DatePicker = forwardRef<any, SpecificPickerProps<DateType>>((props, ref) => (
|
|
||||||
<Picker ref={ref} placeholder="Select date" {...props} picker="date" />
|
|
||||||
));
|
|
||||||
DatePicker.displayName = 'DatePicker';
|
|
||||||
|
|
||||||
const TimePicker = forwardRef<any, SpecificPickerProps<DateType>>((props, ref) => (
|
|
||||||
<Picker ref={ref} mode={undefined} placeholder="Select time" {...props} picker="time" />
|
|
||||||
));
|
|
||||||
TimePicker.displayName = 'TimePicker';
|
|
||||||
|
|
||||||
const WeekPicker = forwardRef<any, SpecificPickerProps<DateType>>((props, ref) => (
|
|
||||||
<Picker ref={ref} mode={undefined} placeholder="Select week" {...props} picker="week" />
|
|
||||||
));
|
|
||||||
WeekPicker.displayName = 'WeekPicker';
|
|
||||||
|
|
||||||
const MonthPicker = forwardRef<any, SpecificPickerProps<DateType>>((props, ref) => (
|
|
||||||
<Picker ref={ref} mode={undefined} placeholder="Select moth" {...props} picker="month" />
|
|
||||||
));
|
|
||||||
MonthPicker.displayName = 'MonthPicker';
|
|
||||||
|
|
||||||
const QuarterPicker = forwardRef<any, SpecificPickerProps<DateType>>((props, ref) => (
|
|
||||||
<Picker ref={ref} mode={undefined} placeholder="Select quarter" {...props} picker="quarter" />
|
|
||||||
));
|
|
||||||
QuarterPicker.displayName = 'QuarterPicker';
|
|
||||||
|
|
||||||
const YearPicker = forwardRef<any, SpecificPickerProps<DateType>>((props, ref) => (
|
|
||||||
<Picker ref={ref} mode={undefined} placeholder="Select year" {...props} picker="year" />
|
|
||||||
));
|
|
||||||
YearPicker.displayName = 'YearPicker';
|
|
||||||
|
|
||||||
// ================== Specific Range Pickers ==================
|
|
||||||
|
|
||||||
const DateRangePicker = forwardRef<any, SpecificRangePickerProps<DateType>>((props, ref) => (
|
|
||||||
<RangePicker ref={ref} placeholder={['Start date', 'End date']} {...props} picker="date" />
|
|
||||||
));
|
|
||||||
DateRangePicker.displayName = 'DateRangePicker';
|
|
||||||
|
|
||||||
const TimeRangePicker = forwardRef<any, SpecificRangePickerProps<DateType>>((props, ref) => (
|
|
||||||
<RangePicker ref={ref} mode={undefined} placeholder={['Start time', 'End time']} {...props} picker="time" />
|
|
||||||
));
|
|
||||||
TimeRangePicker.displayName = 'TimeRangePicker';
|
|
||||||
|
|
||||||
const WeekRangePicker = forwardRef<any, SpecificRangePickerProps<DateType>>((props, ref) => (
|
|
||||||
<RangePicker ref={ref} mode={undefined} placeholder={['Start week', 'End week']} {...props} picker="week" />
|
|
||||||
));
|
|
||||||
WeekRangePicker.displayName = 'WeekRangePicker';
|
|
||||||
|
|
||||||
const MonthRangePicker = forwardRef<any, SpecificRangePickerProps<DateType>>((props, ref) => (
|
|
||||||
<RangePicker ref={ref} mode={undefined} placeholder={['Start month', 'End month']} {...props} picker="month" />
|
|
||||||
));
|
|
||||||
MonthRangePicker.displayName = 'MonthRangePicker';
|
|
||||||
|
|
||||||
const QuarterRangePicker = forwardRef<any, SpecificRangePickerProps<DateType>>((props, ref) => (
|
|
||||||
<RangePicker
|
|
||||||
ref={ref}
|
|
||||||
mode={undefined}
|
|
||||||
placeholder={['Start quarter', 'End quarter']}
|
|
||||||
{...props}
|
|
||||||
picker="quarter"
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
QuarterRangePicker.displayName = 'QuarterRangePicker';
|
|
||||||
|
|
||||||
const YearRangePicker = forwardRef<any, SpecificRangePickerProps<DateType>>((props, ref) => (
|
|
||||||
<RangePicker ref={ref} mode={undefined} placeholder={['Start year', 'End year']} {...props} picker="year" />
|
|
||||||
));
|
|
||||||
YearRangePicker.displayName = 'YearRangePicker';
|
|
||||||
|
|
||||||
return {
|
|
||||||
Picker,
|
|
||||||
RangePicker,
|
|
||||||
Calendar,
|
|
||||||
DatePicker,
|
|
||||||
WeekPicker,
|
|
||||||
MonthPicker,
|
|
||||||
QuarterPicker,
|
|
||||||
YearPicker,
|
|
||||||
TimePicker,
|
|
||||||
DateRangePicker,
|
|
||||||
WeekRangePicker,
|
|
||||||
MonthRangePicker,
|
|
||||||
QuarterRangePicker,
|
|
||||||
YearRangePicker,
|
|
||||||
TimeRangePicker,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { Dayjs } from 'dayjs';
|
|
||||||
import dayjsGenerateConfig from '@rc-component/picker/es/generate/dayjs';
|
|
||||||
import { generateComponentPicker } from './generate-picker.component';
|
|
||||||
|
|
||||||
export const {
|
|
||||||
// Base
|
|
||||||
Picker,
|
|
||||||
RangePicker,
|
|
||||||
Calendar,
|
|
||||||
// Pickers
|
|
||||||
DatePicker,
|
|
||||||
WeekPicker,
|
|
||||||
MonthPicker,
|
|
||||||
QuarterPicker,
|
|
||||||
YearPicker,
|
|
||||||
TimePicker,
|
|
||||||
// Range Pickers
|
|
||||||
DateRangePicker,
|
|
||||||
WeekRangePicker,
|
|
||||||
MonthRangePicker,
|
|
||||||
QuarterRangePicker,
|
|
||||||
YearRangePicker,
|
|
||||||
TimeRangePicker,
|
|
||||||
} = generateComponentPicker<Dayjs>(dayjsGenerateConfig);
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* =========================================
|
|
||||||
BASE WRAPPER & LABEL
|
|
||||||
========================================= */
|
|
||||||
.rc-checkbox-wrapper {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: var(--form-label-font-size);
|
|
||||||
font-weight: var(--form-label-font-weight);
|
|
||||||
color: var(--form-label-color);
|
|
||||||
line-height: 1;
|
|
||||||
gap: 8px; /* Distance between checkbox and label */
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-checkbox-wrapper-disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
CORE CHECKBOX STRUCTURE
|
|
||||||
========================================= */
|
|
||||||
.rc-checkbox {
|
|
||||||
white-space: nowrap;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
line-height: 1;
|
|
||||||
vertical-align: middle;
|
|
||||||
top: -1px; /* Optically aligns the checkbox */
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-checkbox-input {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-checkbox-inner {
|
|
||||||
position: relative;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: inline-block;
|
|
||||||
width: var(--checkbox-size); /* Size of the checkbox */
|
|
||||||
height: var(--checkbox-size);
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: var(--checkbox-radius); /* Consistent with global shape */
|
|
||||||
border-color: var(--input-border);
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
/* Use standard 0.2s transition */
|
|
||||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check mark (The L-shape) */
|
|
||||||
.rc-checkbox-inner:after {
|
|
||||||
content: ' ';
|
|
||||||
position: absolute;
|
|
||||||
display: table;
|
|
||||||
border: 2px solid #fff;
|
|
||||||
border-top: 0;
|
|
||||||
border-left: 0;
|
|
||||||
transform: rotate(45deg) scale(0);
|
|
||||||
opacity: 0;
|
|
||||||
/* Position adjust for 16px box */
|
|
||||||
left: var(--checkbox-check-left);
|
|
||||||
top: var(--checkbox-check-top);
|
|
||||||
width: var(--checkbox-check-width);
|
|
||||||
height: var(--checkbox-check-height);
|
|
||||||
transition:
|
|
||||||
all 0.1s cubic-bezier(0.71, -0.46, 0.88, 0.6),
|
|
||||||
opacity 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
INTERACTION STATES
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* Hover */
|
|
||||||
.rc-checkbox:hover .rc-checkbox-inner,
|
|
||||||
.rc-checkbox-wrapper:hover .rc-checkbox-inner {
|
|
||||||
border-color: var(--input-border-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focus Ring */
|
|
||||||
.rc-checkbox-input:focus-visible + .rc-checkbox-inner {
|
|
||||||
border-color: var(--focus-border-color);
|
|
||||||
box-shadow: 0 0 0 3px var(--focus-ring-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checked State */
|
|
||||||
.rc-checkbox-checked .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-brand-500);
|
|
||||||
background-color: var(--color-brand-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-checkbox-checked .rc-checkbox-inner:after {
|
|
||||||
transform: rotate(45deg) scale(1);
|
|
||||||
opacity: 1;
|
|
||||||
transition: all 0.2s cubic-bezier(0.12, 0.4, 0.29, 1.46) 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
STATUS MATRIX (Error, Warning, Success, Info)
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* --- DEFAULT --- */
|
|
||||||
.checkbox-status-default .rc-checkbox-inner {
|
|
||||||
border-color: var(--input-border);
|
|
||||||
}
|
|
||||||
.checkbox-status-default:hover .rc-checkbox-inner {
|
|
||||||
border-color: var(--input-border-hover);
|
|
||||||
}
|
|
||||||
.checkbox-status-default .rc-checkbox-checked .rc-checkbox-inner {
|
|
||||||
background-color: var(--color-brand-500);
|
|
||||||
border-color: var(--color-brand-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-default .rc-checkbox-input:focus-visible + .rc-checkbox-inner {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-brand-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- ERROR --- */
|
|
||||||
.checkbox-status-error .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-error-300);
|
|
||||||
}
|
|
||||||
.checkbox-status-error:hover .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-error .rc-checkbox-checked .rc-checkbox-inner {
|
|
||||||
background-color: var(--color-error-500);
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-error .rc-checkbox-input:focus-visible + .rc-checkbox-inner {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-error-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- WARNING --- */
|
|
||||||
.checkbox-status-warning .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-warning-300);
|
|
||||||
}
|
|
||||||
.checkbox-status-warning:hover .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-warning .rc-checkbox-checked .rc-checkbox-inner {
|
|
||||||
background-color: var(--color-warning-500);
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-warning .rc-checkbox-input:focus-visible + .rc-checkbox-inner {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-warning-100);
|
|
||||||
}
|
|
||||||
/* --- SUCCESS --- */
|
|
||||||
.checkbox-status-success .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-success-300);
|
|
||||||
}
|
|
||||||
.checkbox-status-success:hover .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-success .rc-checkbox-checked .rc-checkbox-inner {
|
|
||||||
background-color: var(--color-success-500);
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-success .rc-checkbox-input:focus-visible + .rc-checkbox-inner {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-success-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- INFO --- */
|
|
||||||
.checkbox-status-info .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-info-300);
|
|
||||||
}
|
|
||||||
.checkbox-status-info:hover .rc-checkbox-inner {
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-info .rc-checkbox-checked .rc-checkbox-inner {
|
|
||||||
background-color: var(--color-info-500);
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
.checkbox-status-info .rc-checkbox-input:focus-visible + .rc-checkbox-inner {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-info-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
DISABLED STATE
|
|
||||||
========================================= */
|
|
||||||
.rc-checkbox-disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-checkbox-disabled .rc-checkbox-inner {
|
|
||||||
background-color: var(--disabled-bg) !important;
|
|
||||||
border-color: var(--disabled-border) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-checkbox-disabled.rc-checkbox-checked .rc-checkbox-inner:after {
|
|
||||||
border-color: var(--disabled-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-checkbox-disabled .rc-checkbox-input {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print Support */
|
|
||||||
@media print {
|
|
||||||
.rc-checkbox-checked .rc-checkbox-inner {
|
|
||||||
box-shadow: inset 0 0 0 16px var(--color-brand-500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* Container Form Item */
|
|
||||||
.rc-form-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: var(--form-item-margin-bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================
|
|
||||||
LABEL
|
|
||||||
========================= */
|
|
||||||
.rc-form-item-label {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: var(--form-label-font-size);
|
|
||||||
font-weight: var(--form-label-font-weight);
|
|
||||||
color: var(--form-label-color);
|
|
||||||
margin-bottom: var(--form-label-margin-bottom);
|
|
||||||
line-height: 1.4;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Required Asterisk (*) */
|
|
||||||
.rc-form-item-required-mark {
|
|
||||||
margin-left: 0.25rem;
|
|
||||||
color: var(--color-error-500);
|
|
||||||
font-family: SimSun, sans-serif; /* Standard font for asterisks agar vertical align */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================
|
|
||||||
MESSAGE (ERROR / WARNING)
|
|
||||||
========================= */
|
|
||||||
.rc-form-item-explain {
|
|
||||||
margin-top: var(--form-msg-margin-top);
|
|
||||||
font-size: var(--form-msg-font-size);
|
|
||||||
line-height: 1.4;
|
|
||||||
min-height: 1.4em; /* Reserve space even when empty to prevent layout shift */
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================
|
|
||||||
STATUS MODIFIERS
|
|
||||||
========================= */
|
|
||||||
|
|
||||||
/* --- ERROR STATE --- */
|
|
||||||
.rc-form-item.status-error .rc-form-item-label {
|
|
||||||
color: var(--color-error-600); /* Darker shade for label on error */
|
|
||||||
}
|
|
||||||
.rc-form-item.status-error .rc-form-item-explain {
|
|
||||||
color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- WARNING STATE --- */
|
|
||||||
.rc-form-item.status-warning .rc-form-item-label {
|
|
||||||
color: var(--color-warning-600);
|
|
||||||
}
|
|
||||||
.rc-form-item.status-warning .rc-form-item-explain {
|
|
||||||
color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
@import './form-item.style.css';
|
|
||||||
@import './input.style.css';
|
|
||||||
@import './input-number.style.css';
|
|
||||||
@import './textarea.style.css';
|
|
||||||
@import './checkbox.style.css';
|
|
||||||
@import './switch.style.css';
|
|
||||||
@import './picker.style.css';
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* =========================================
|
|
||||||
1. BASE SETUP (Layout & Reset)
|
|
||||||
========================================= */
|
|
||||||
.rc-input-number {
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
/* Global Variables */
|
|
||||||
height: var(--input-height);
|
|
||||||
font-size: var(--input-font-size);
|
|
||||||
border-radius: var(--input-radius);
|
|
||||||
line-height: 1.5;
|
|
||||||
color: var(--input-text);
|
|
||||||
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
border: 1px solid transparent;
|
|
||||||
|
|
||||||
/* Standard Transition */
|
|
||||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Input Element */
|
|
||||||
.rc-input-number-input {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 var(--input-padding-x);
|
|
||||||
background-color: transparent;
|
|
||||||
border: 0;
|
|
||||||
border-radius: var(--input-radius);
|
|
||||||
outline: 0;
|
|
||||||
color: inherit; /* Inherit from .rc-input-number */
|
|
||||||
transition: all 0.2s linear;
|
|
||||||
|
|
||||||
/* Prevent text under action buttons */
|
|
||||||
padding-right: var(--input-handler-width);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide Native Spinners (Browser Default) */
|
|
||||||
.rc-input-number-input::-webkit-inner-spin-button,
|
|
||||||
.rc-input-number-input::-webkit-outer-spin-button {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
margin: 0;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.rc-input-number-input {
|
|
||||||
-moz-appearance: textfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prefix Styling */
|
|
||||||
.rc-input-number-prefix {
|
|
||||||
margin-left: var(--input-padding-x);
|
|
||||||
margin-right: 0.5rem; /* ~8px */
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex: none;
|
|
||||||
color: var(--color-gray-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Suffix Styling */
|
|
||||||
.rc-input-number-suffix {
|
|
||||||
margin-right: var(--input-padding-x);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex: none;
|
|
||||||
color: var(--color-gray-500);
|
|
||||||
z-index: 10;
|
|
||||||
transition: margin-right 0.2s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Animation Trigger: On Hover/Focus, Suffix shifts left to accommodate action buttons */
|
|
||||||
.rc-input-number:hover .rc-input-number-suffix,
|
|
||||||
.rc-input-number-affix-wrapper:hover .rc-input-number-suffix,
|
|
||||||
.rc-input-number-focused .rc-input-number-suffix,
|
|
||||||
.rc-input-number-affix-wrapper-focused .rc-input-number-suffix,
|
|
||||||
.rc-input-number:focus-within .rc-input-number-suffix,
|
|
||||||
.rc-input-number-affix-wrapper:focus-within .rc-input-number-suffix {
|
|
||||||
margin-right: calc(var(--input-padding-x) + var(--input-handler-width));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
2. ACTIONS CONTAINER (Custom Spinners)
|
|
||||||
Target: .rc-input-number-actions
|
|
||||||
========================================= */
|
|
||||||
.rc-input-number-actions {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
|
|
||||||
width: var(--input-handler-width);
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
/* Using var input-bg for consistency (white) */
|
|
||||||
background: var(--input-bg);
|
|
||||||
|
|
||||||
/* Default Border (will be overridden by status) */
|
|
||||||
border-left: 1px solid var(--input-border);
|
|
||||||
border-radius: 0 var(--input-radius) var(--input-radius) 0;
|
|
||||||
|
|
||||||
opacity: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
transition: opacity 0.24s linear 0.1s;
|
|
||||||
z-index: 10;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show Actions on Interaction */
|
|
||||||
.rc-input-number:hover .rc-input-number-actions,
|
|
||||||
.rc-input-number:focus-within .rc-input-number-actions {
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Individual Buttons */
|
|
||||||
.rc-input-number-action {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
color: var(--color-gray-400);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.2s linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-input-number-action:active {
|
|
||||||
background-color: var(--color-gray-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-input-number-action:hover {
|
|
||||||
color: var(--color-brand-500);
|
|
||||||
height: 60%; /* Effect hover slightly reduces height */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Border between Up/Down Buttons */
|
|
||||||
.rc-input-number-action-up {
|
|
||||||
border-bottom: 1px solid var(--input-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
3. STATUS MATRIX
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* --- DEFAULT --- */
|
|
||||||
.input-number-status-default {
|
|
||||||
border-color: var(--input-border);
|
|
||||||
}
|
|
||||||
.input-number-status-default:hover:not(.rc-input-number-disabled) {
|
|
||||||
border-color: var(--input-border-hover);
|
|
||||||
}
|
|
||||||
.input-number-status-default:focus-within {
|
|
||||||
border-color: var(--focus-border-color);
|
|
||||||
box-shadow: 0 0 0 3px var(--focus-ring-color);
|
|
||||||
}
|
|
||||||
/* Action Borders Sync */
|
|
||||||
.input-number-status-default:focus-within .rc-input-number-actions {
|
|
||||||
border-left-color: var(--focus-border-color);
|
|
||||||
}
|
|
||||||
.input-number-status-default:focus-within .rc-input-number-action-up {
|
|
||||||
border-bottom-color: var(--focus-border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- ERROR --- */
|
|
||||||
.input-number-status-error {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
.input-number-status-error:hover:not(.rc-input-number-disabled) {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
}
|
|
||||||
.input-number-status-error:focus-within {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-error-100);
|
|
||||||
}
|
|
||||||
/* Action Borders Sync */
|
|
||||||
.input-number-status-error .rc-input-number-actions {
|
|
||||||
border-left-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
.input-number-status-error .rc-input-number-action-up {
|
|
||||||
border-bottom-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- WARNING --- */
|
|
||||||
.input-number-status-warning {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
.input-number-status-warning:hover:not(.rc-input-number-disabled) {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
}
|
|
||||||
.input-number-status-warning:focus-within {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-warning-100);
|
|
||||||
}
|
|
||||||
/* Action Borders Sync */
|
|
||||||
.input-number-status-warning .rc-input-number-actions {
|
|
||||||
border-left-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
.input-number-status-warning .rc-input-number-action-up {
|
|
||||||
border-bottom-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- SUCCESS --- */
|
|
||||||
.input-number-status-success {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
.input-number-status-success:hover:not(.rc-input-number-disabled) {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
}
|
|
||||||
.input-number-status-success:focus-within {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-success-100);
|
|
||||||
}
|
|
||||||
/* Action Borders Sync */
|
|
||||||
.input-number-status-success .rc-input-number-actions {
|
|
||||||
border-left-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
.input-number-status-success .rc-input-number-action-up {
|
|
||||||
border-bottom-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- INFO --- */
|
|
||||||
.input-number-status-info {
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
.input-number-status-info:hover:not(.rc-input-number-disabled) {
|
|
||||||
border-color: var(--color-info-600);
|
|
||||||
}
|
|
||||||
.input-number-status-info:focus-within {
|
|
||||||
border-color: var(--color-info-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-info-100);
|
|
||||||
}
|
|
||||||
/* Action Borders Sync */
|
|
||||||
.input-number-status-info .rc-input-number-actions {
|
|
||||||
border-left-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
.input-number-status-info .rc-input-number-action-up {
|
|
||||||
border-bottom-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
4. DISABLED STATE
|
|
||||||
========================================= */
|
|
||||||
.rc-input-number-disabled {
|
|
||||||
background-color: var(--disabled-bg) !important;
|
|
||||||
border-color: var(--disabled-border) !important;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.rc-input-number-disabled .rc-input-number-input {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
.rc-input-number-disabled .rc-input-number-actions {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,236 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* =========================================
|
|
||||||
BASE RESET & SHARED
|
|
||||||
========================================= */
|
|
||||||
.rc-input {
|
|
||||||
/* Use box-sizing border-box for predictable sizing */
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
/* Using variable dimensions */
|
|
||||||
height: var(--input-height);
|
|
||||||
padding: 0 var(--input-padding-x); /* Consistent with 0.92rem */
|
|
||||||
|
|
||||||
font-size: var(--input-font-size);
|
|
||||||
line-height: 1.5;
|
|
||||||
color: var(--input-text);
|
|
||||||
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: var(--input-radius);
|
|
||||||
|
|
||||||
/* Standard Transition */
|
|
||||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-input::placeholder {
|
|
||||||
color: var(--input-placeholder);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled State (Standalone Input) */
|
|
||||||
.rc-input:disabled {
|
|
||||||
background-color: var(--disabled-bg) !important;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
border-color: var(--disabled-border) !important;
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
CLEAR ICON
|
|
||||||
Button (x) to clear input content
|
|
||||||
========================================= */
|
|
||||||
.rc-input-clear-icon {
|
|
||||||
/* Reset Button Styles */
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
|
|
||||||
/* Layout & Sizing */
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: var(--text-sm); /* ~12px icon size */
|
|
||||||
line-height: 1;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
/* Colors & Transition */
|
|
||||||
color: var(--color-gray-400); /* Default gray color */
|
|
||||||
transition: color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
|
|
||||||
/* Visibility Control ( Smooth appearance/disappearance could use opacity + pointer-events )
|
|
||||||
/* visibility: hidden; */
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hover State: Darker Gray */
|
|
||||||
.rc-input-clear-icon:hover {
|
|
||||||
color: var(--color-gray-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Active/Click State */
|
|
||||||
.rc-input-clear-icon:active {
|
|
||||||
color: var(--color-gray-600);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hidden State */
|
|
||||||
.rc-input-clear-icon-hidden {
|
|
||||||
display: none;
|
|
||||||
/* Alternative approach to keep layout but invisible:
|
|
||||||
visibility: hidden;
|
|
||||||
pointer-events: none;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Placement Helper: Margin to separate from input text */
|
|
||||||
.rc-input-affix-wrapper .rc-input-clear-icon {
|
|
||||||
margin-left: 0.5rem; /* ~8px spacing from text */
|
|
||||||
z-index: 2; /* Above input text */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
AFFIX WRAPPER (PREFIX / SUFFIX) SETUP
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* Base Wrapper Style */
|
|
||||||
.rc-input-affix-wrapper {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
/* Using variable dimensions */
|
|
||||||
height: var(--input-height);
|
|
||||||
padding: 0 var(--input-padding-x);
|
|
||||||
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: var(--input-radius);
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset Input inside Affix Wrapper */
|
|
||||||
.rc-input-affix-wrapper .rc-input {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prefix & Suffix Positioning */
|
|
||||||
.rc-input-prefix {
|
|
||||||
margin-right: 0.5rem; /* ~8px, hardcoded */
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
.rc-input-suffix {
|
|
||||||
margin-left: 0.5rem; /* ~8px */
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled Wrapper */
|
|
||||||
.rc-input-affix-wrapper-disabled {
|
|
||||||
background-color: var(--disabled-bg) !important;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
border-color: var(--disabled-border) !important;
|
|
||||||
cursor: not-allowed;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.rc-input-affix-wrapper-disabled .rc-input {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
LOGIC MATRIX: [VARIANT] x [STATUS]
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* ------------------------------------------------
|
|
||||||
1. VARIANT: OUTLINED (Default)
|
|
||||||
------------------------------------------------ */
|
|
||||||
|
|
||||||
/* DEFAULT */
|
|
||||||
.input-status-default {
|
|
||||||
border-color: var(--input-border);
|
|
||||||
}
|
|
||||||
/* Hover */
|
|
||||||
.input-status-default:hover:not(.rc-input-affix-wrapper-disabled):not(:disabled) {
|
|
||||||
border-color: var(--input-border-hover);
|
|
||||||
}
|
|
||||||
/* Focus */
|
|
||||||
.input-status-default:focus,
|
|
||||||
.input-status-default.rc-input-affix-wrapper-focused {
|
|
||||||
border-color: var(--focus-border-color);
|
|
||||||
box-shadow: 0 0 0 3px var(--focus-ring-color);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ERROR */
|
|
||||||
.input-status-error {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.input-status-error:hover:not(.rc-input-affix-wrapper-disabled):not(:disabled) {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
}
|
|
||||||
.input-status-error:focus,
|
|
||||||
.input-status-error.rc-input-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-error-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WARNING */
|
|
||||||
.input-status-warning {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.input-status-warning:hover:not(.rc-input-affix-wrapper-disabled):not(:disabled) {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
}
|
|
||||||
.input-status-warning:focus,
|
|
||||||
.input-status-warning.rc-input-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-warning-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* SUCCESS */
|
|
||||||
.input-status-success {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.input-status-success:hover:not(.rc-input-affix-wrapper-disabled):not(:disabled) {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
}
|
|
||||||
.input-status-success:focus,
|
|
||||||
.input-status-success.rc-input-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-success-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* INFO */
|
|
||||||
.input-status-info {
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.input-status-info:hover:not(.rc-input-affix-wrapper-disabled):not(:disabled) {
|
|
||||||
border-color: var(--color-info-600);
|
|
||||||
}
|
|
||||||
.input-status-info:focus,
|
|
||||||
.input-status-info.rc-input-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-info-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-info-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,647 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* =========================================
|
|
||||||
PICKER BASE (INPUT WRAPPER)
|
|
||||||
========================================= */
|
|
||||||
.rc-picker {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
/* Using variable dimensions from globals.css */
|
|
||||||
height: var(--input-height);
|
|
||||||
padding: 0 var(--input-padding-x);
|
|
||||||
|
|
||||||
font-size: var(--input-font-size);
|
|
||||||
line-height: 1.5;
|
|
||||||
color: var(--input-text);
|
|
||||||
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-color: var(--input-border);
|
|
||||||
border-radius: var(--input-radius);
|
|
||||||
|
|
||||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Input inside Picker */
|
|
||||||
.rc-picker-input {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-input > input {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
min-width: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
border: 0;
|
|
||||||
outline: none;
|
|
||||||
color: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-input > input::placeholder {
|
|
||||||
color: var(--input-placeholder);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Suffix Icon (Calendar Icon) */
|
|
||||||
.rc-picker-suffix {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
color: var(--color-gray-400);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
pointer-events: none;
|
|
||||||
font-size: var(--text-lg);
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear Icon */
|
|
||||||
.rc-picker-clear {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
right: var(--input-padding-x);
|
|
||||||
transform: translateY(-50%);
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
transition:
|
|
||||||
opacity 0.2s,
|
|
||||||
color 0.2s;
|
|
||||||
background: var(--input-bg);
|
|
||||||
color: var(--color-gray-400);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 1;
|
|
||||||
width: 1.2em;
|
|
||||||
height: 1.2em;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker:hover:not(.rc-picker-disabled) .rc-picker-clear {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-clear:hover {
|
|
||||||
color: var(--color-gray-500);
|
|
||||||
background-color: var(--color-gray-100);
|
|
||||||
}
|
|
||||||
.rc-picker-clear-btn::after {
|
|
||||||
content: '×';
|
|
||||||
font-size: 1.2em;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
STATES (HOVER, FOCUS, DISABLED, ERROR)
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* Hover State */
|
|
||||||
.rc-picker:hover:not(.rc-picker-disabled) {
|
|
||||||
border-color: var(--input-border-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focused State */
|
|
||||||
.rc-picker-focused {
|
|
||||||
border-color: var(--focus-border-color);
|
|
||||||
box-shadow: 0 0 0 3px var(--focus-ring-color);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled State */
|
|
||||||
.rc-picker-disabled {
|
|
||||||
background-color: var(--disabled-bg);
|
|
||||||
color: var(--disabled-text);
|
|
||||||
border-color: var(--disabled-border);
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-disabled input {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Range Picker Specific */
|
|
||||||
.rc-picker-range.rc-picker-focused .rc-picker-active-bar {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-range-separator {
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
line-height: 1;
|
|
||||||
color: var(--color-gray-400);
|
|
||||||
display: inline-flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-active-bar {
|
|
||||||
bottom: -1px;
|
|
||||||
height: 2px;
|
|
||||||
margin-left: var(--input-padding-x); /* Align with input start */
|
|
||||||
background: var(--color-brand-500);
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 0.3s ease-out;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 2;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
PICKER DROPDOWN PANEL (THE MEAT)
|
|
||||||
========================================= */
|
|
||||||
.rc-picker-dropdown {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1050;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: var(--text-sm);
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-dropdown-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Arrow styling removed for modern clean look (AntD v5/v6 typically removes large arrows) */
|
|
||||||
.rc-picker-dropdown .rc-picker-range-arrow {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Panel Container */
|
|
||||||
.rc-picker-panel-container {
|
|
||||||
overflow: hidden;
|
|
||||||
vertical-align: top;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: var(--radius-lg);
|
|
||||||
/* Elevation 3/4 equivalent */
|
|
||||||
box-shadow:
|
|
||||||
0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
|
||||||
0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
|
||||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
transition: margin 0.3s;
|
|
||||||
border: 1px solid var(--color-gray-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-panel-layout {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-panel {
|
|
||||||
vertical-align: top;
|
|
||||||
background: transparent;
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Double Panel (Range Picker) */
|
|
||||||
.rc-picker-panel + .rc-picker-panel {
|
|
||||||
border-left: 1px solid var(--color-gray-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
HEADER SECTION
|
|
||||||
========================================= */
|
|
||||||
.rc-picker-header {
|
|
||||||
display: flex;
|
|
||||||
padding: 0 8px;
|
|
||||||
border-bottom: 1px solid var(--color-gray-100);
|
|
||||||
min-height: 40px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header > * {
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header-view {
|
|
||||||
flex: auto;
|
|
||||||
text-align: center;
|
|
||||||
font-weight: var(--font-weight-semibold);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header-view button {
|
|
||||||
color: var(--color-gray-800);
|
|
||||||
font-weight: inheriting;
|
|
||||||
padding: 0 4px;
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: var(--text-sm);
|
|
||||||
line-height: 40px;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header-view button:hover {
|
|
||||||
color: var(--color-brand-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navigation Buttons (< << >> >) */
|
|
||||||
.rc-picker-header-super-prev-btn,
|
|
||||||
.rc-picker-header-prev-btn,
|
|
||||||
.rc-picker-header-next-btn,
|
|
||||||
.rc-picker-header-super-next-btn {
|
|
||||||
min-width: 1.6em;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--color-gray-400);
|
|
||||||
cursor: pointer;
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
line-height: 40px;
|
|
||||||
padding: 0 5px;
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
transition: color 0.2s;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header-super-prev-btn:hover,
|
|
||||||
.rc-picker-header-prev-btn:hover,
|
|
||||||
.rc-picker-header-next-btn:hover,
|
|
||||||
.rc-picker-header-super-next-btn:hover {
|
|
||||||
color: var(--color-gray-900);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Arrow Symbols using pseudo elements if needed, or rely on RC Picker default text symbols but styled */
|
|
||||||
/* RC Picker default uses unicode arrows usually. */
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
BODY SECTION (CALENDAR GRID)
|
|
||||||
========================================= */
|
|
||||||
.rc-picker-body {
|
|
||||||
padding: 8px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-content {
|
|
||||||
width: 100%;
|
|
||||||
table-layout: fixed;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-content th,
|
|
||||||
.rc-picker-content td {
|
|
||||||
position: relative;
|
|
||||||
min-width: 24px;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-content th {
|
|
||||||
height: 32px;
|
|
||||||
color: var(--color-gray-500);
|
|
||||||
line-height: 32px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell {
|
|
||||||
padding: 4px 0;
|
|
||||||
color: var(--color-gray-400);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-in-view {
|
|
||||||
color: var(--color-gray-800);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
}
|
|
||||||
.rc-picker-cell-disabled .rc-picker-cell-inner {
|
|
||||||
background: var(--disabled-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inner Cell (The Circle/Square) */
|
|
||||||
.rc-picker-cell-inner {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
line-height: 24px;
|
|
||||||
border-radius: var(
|
|
||||||
--radius-md
|
|
||||||
); /* Ant Design v5 uses slightly rounded squares, not full circles usually, but we can do md radius */
|
|
||||||
transition:
|
|
||||||
background 0.2s,
|
|
||||||
border 0.2s,
|
|
||||||
color 0.2s;
|
|
||||||
text-align: center;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 4px; /* For longer text like months */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Month/Year Panel cells are wider */
|
|
||||||
.rc-picker-month-panel .rc-picker-cell-inner,
|
|
||||||
.rc-picker-year-panel .rc-picker-cell-inner,
|
|
||||||
.rc-picker-quarter-panel .rc-picker-cell-inner,
|
|
||||||
.rc-picker-decade-panel .rc-picker-cell-inner {
|
|
||||||
width: auto;
|
|
||||||
padding: 0 12px;
|
|
||||||
min-width: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hover State */
|
|
||||||
.rc-picker-cell:hover:not(.rc-picker-cell-selected):not(.rc-picker-cell-range-start):not(
|
|
||||||
.rc-picker-cell-range-end
|
|
||||||
):not(.rc-picker-cell-disabled)
|
|
||||||
.rc-picker-cell-inner {
|
|
||||||
background: var(--color-gray-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Selected Date */
|
|
||||||
.rc-picker-cell-selected .rc-picker-cell-inner,
|
|
||||||
.rc-picker-cell-range-start .rc-picker-cell-inner,
|
|
||||||
.rc-picker-cell-range-end .rc-picker-cell-inner {
|
|
||||||
color: #fff;
|
|
||||||
background: var(--color-brand-500);
|
|
||||||
box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-selected:hover .rc-picker-cell-inner {
|
|
||||||
background: var(--color-brand-600);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Today */
|
|
||||||
.rc-picker-cell-today .rc-picker-cell-inner::before {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
border: 1px solid var(--color-brand-500);
|
|
||||||
border-radius: var(--radius-md);
|
|
||||||
content: '';
|
|
||||||
transition: all 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-selected.rc-picker-cell-today .rc-picker-cell-inner::before {
|
|
||||||
border-color: #fff; /* White border inside selected today */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
RANGE SELECTION STYLING
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* The strip between start and end */
|
|
||||||
.rc-picker-cell-in-range > .rc-picker-cell-inner {
|
|
||||||
background: var(--color-brand-50);
|
|
||||||
border-radius: 0;
|
|
||||||
min-width: 100%; /* Fill the whole cell width */
|
|
||||||
color: var(--color-gray-800);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-in-range::before {
|
|
||||||
background: var(--color-brand-50);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Range Edge Adjustments */
|
|
||||||
.rc-picker-cell-range-start > .rc-picker-cell-inner {
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
border-top-left-radius: var(--radius-md);
|
|
||||||
border-bottom-left-radius: var(--radius-md);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-range-end > .rc-picker-cell-inner {
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
border-top-right-radius: var(--radius-md);
|
|
||||||
border-bottom-right-radius: var(--radius-md);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ghost/Pseudo elements for continuous range background */
|
|
||||||
/* RC Picker handles this logic via class combinations.
|
|
||||||
We need to ensure the background flows nicely. */
|
|
||||||
|
|
||||||
.rc-picker-cell-range-start.rc-picker-cell-range-end .rc-picker-cell-inner {
|
|
||||||
border-radius: var(--radius-md);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Range Hover (when selecting the second date) */
|
|
||||||
.rc-picker-cell-range-hover-start::after,
|
|
||||||
.rc-picker-cell-range-hover-end::after,
|
|
||||||
.rc-picker-cell-range-hover::after {
|
|
||||||
content: ''; /* Should show dotted line or lighter highlight */
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
border-top: 2px dashed var(--color-brand-300);
|
|
||||||
transform: translateY(-50%);
|
|
||||||
z-index: 0;
|
|
||||||
display: none; /* AntD v6 doesn't really emphasize this as much, can keep simple */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
TIME PANEL
|
|
||||||
========================================= */
|
|
||||||
.rc-picker-time-panel {
|
|
||||||
border-left: 1px solid var(--color-gray-100);
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel .rc-picker-content {
|
|
||||||
display: flex;
|
|
||||||
max-height: 224px;
|
|
||||||
height: 224px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column {
|
|
||||||
flex: 1 0 auto;
|
|
||||||
width: 60px; /* Wider for easier clicking */
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow-y: hidden;
|
|
||||||
text-align: left;
|
|
||||||
list-style: none;
|
|
||||||
transition: background 0.3s;
|
|
||||||
overflow-x: hidden;
|
|
||||||
border-left: 1px solid var(--color-gray-100); /* Separator between hrs/min/sec */
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column:first-child {
|
|
||||||
border-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column:hover {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column > li {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column > li .rc-picker-time-panel-cell-inner {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 28px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 0 0 12px;
|
|
||||||
color: var(--color-gray-800);
|
|
||||||
line-height: 28px;
|
|
||||||
text-align: left;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column > li:hover .rc-picker-time-panel-cell-inner {
|
|
||||||
background: var(--color-gray-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column > li.rc-picker-time-panel-cell-selected .rc-picker-time-panel-cell-inner {
|
|
||||||
background: var(--color-brand-50);
|
|
||||||
color: var(--color-brand-600);
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column > li.rc-picker-time-panel-cell-disabled .rc-picker-time-panel-cell-inner {
|
|
||||||
color: var(--disabled-text);
|
|
||||||
cursor: not-allowed;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Date + Time Layout */
|
|
||||||
.rc-picker-datetime-panel {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.rc-picker-datetime-panel .rc-picker-date-panel,
|
|
||||||
.rc-picker-datetime-panel .rc-picker-time-panel {
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
FOOTER
|
|
||||||
========================================= */
|
|
||||||
.rc-picker-footer {
|
|
||||||
width: auto;
|
|
||||||
min-width: 100%;
|
|
||||||
line-height: 38px;
|
|
||||||
text-align: center;
|
|
||||||
border-top: 1px solid var(--color-gray-100);
|
|
||||||
padding: 0 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-footer-extra {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ranges (Presets) */
|
|
||||||
.rc-picker-ranges {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ranges > li {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ranges .rc-picker-preset > .rc-picker-preset-tag {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 8px;
|
|
||||||
color: var(--color-brand-500);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ranges .rc-picker-preset > .rc-picker-preset-tag:hover {
|
|
||||||
color: var(--color-brand-600);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ranges .rc-picker-ok {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK Button */
|
|
||||||
.rc-picker-ok button {
|
|
||||||
background: var(--color-brand-500);
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
padding: 2px 12px;
|
|
||||||
height: 24px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: var(--text-sm);
|
|
||||||
transition: background 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ok button:hover {
|
|
||||||
background: var(--color-brand-600);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ok button:disabled {
|
|
||||||
background: var(--disabled-bg);
|
|
||||||
color: var(--disabled-text);
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-now-btn {
|
|
||||||
color: var(--color-brand-500);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
.rc-picker-now-btn:hover {
|
|
||||||
color: var(--color-brand-600);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
STATUS MODIFIERS (ERROR, WARNING, ETC)
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
.picker-status-error.rc-picker {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
.picker-status-error.rc-picker:hover:not(.rc-picker-disabled) {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
}
|
|
||||||
.picker-status-error.rc-picker.rc-picker-focused {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-error-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
.picker-status-warning.rc-picker {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
.picker-status-warning.rc-picker:hover:not(.rc-picker-disabled) {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
}
|
|
||||||
.picker-status-warning.rc-picker.rc-picker-focused {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-warning-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
.picker-status-success.rc-picker {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
.picker-status-success.rc-picker:hover:not(.rc-picker-disabled) {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
}
|
|
||||||
.picker-status-success.rc-picker.rc-picker-focused {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-success-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,746 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* ==========================================================================
|
|
||||||
Ant Design DatePicker - Pure CSS Implementation
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Variables & Tokens
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
:root {
|
|
||||||
/* Colors */
|
|
||||||
--ant-color-primary: #1677ff;
|
|
||||||
--ant-color-primary-hover: #4096ff;
|
|
||||||
--ant-color-primary-active: #0958d9;
|
|
||||||
--ant-color-primary-bg: #e6f4ff;
|
|
||||||
--ant-color-primary-border: #91caff;
|
|
||||||
|
|
||||||
--ant-color-bg-container: #ffffff;
|
|
||||||
--ant-color-bg-elevated: #ffffff;
|
|
||||||
--ant-color-bg-layout: #f5f5f5;
|
|
||||||
--ant-color-bg-mask: rgba(0, 0, 0, 0.45);
|
|
||||||
--ant-color-bg-spotlight: rgba(0, 0, 0, 0.85);
|
|
||||||
|
|
||||||
--ant-color-text: rgba(0, 0, 0, 0.88);
|
|
||||||
--ant-color-text-secondary: rgba(0, 0, 0, 0.65);
|
|
||||||
--ant-color-text-tertiary: rgba(0, 0, 0, 0.45);
|
|
||||||
--ant-color-text-quaternary: rgba(0, 0, 0, 0.25);
|
|
||||||
--ant-color-text-placeholder: rgba(0, 0, 0, 0.25);
|
|
||||||
--ant-color-text-disabled: rgba(0, 0, 0, 0.25);
|
|
||||||
--ant-color-text-heading: rgba(0, 0, 0, 0.88);
|
|
||||||
--ant-color-text-light-solid: #ffffff;
|
|
||||||
|
|
||||||
--ant-color-border: #d9d9d9;
|
|
||||||
--ant-color-split: rgba(5, 5, 5, 0.06);
|
|
||||||
--ant-color-error: #ff4d4f;
|
|
||||||
--ant-color-warning: #faad14;
|
|
||||||
|
|
||||||
/* Dimensions & Spacing */
|
|
||||||
--ant-control-height: 32px;
|
|
||||||
--ant-control-height-sm: 24px;
|
|
||||||
--ant-control-height-lg: 40px;
|
|
||||||
|
|
||||||
--ant-padding-xs: 8px;
|
|
||||||
--ant-padding-sm: 12px;
|
|
||||||
--ant-padding-md: 16px;
|
|
||||||
--ant-padding-xxs: 4px;
|
|
||||||
|
|
||||||
--ant-margin-xs: 8px;
|
|
||||||
--ant-margin-xxs: 4px;
|
|
||||||
|
|
||||||
--ant-border-radius: 6px;
|
|
||||||
--ant-border-radius-sm: 4px;
|
|
||||||
--ant-border-radius-lg: 8px;
|
|
||||||
|
|
||||||
--ant-line-width: 1px;
|
|
||||||
--ant-line-width-bold: 2px;
|
|
||||||
--ant-line-type: solid;
|
|
||||||
|
|
||||||
/* Font */
|
|
||||||
--ant-font-size: 14px;
|
|
||||||
--ant-font-size-sm: 12px;
|
|
||||||
--ant-font-size-lg: 16px;
|
|
||||||
--ant-line-height: 1.5714285714285714;
|
|
||||||
|
|
||||||
/* Animation */
|
|
||||||
--ant-motion-duration-mid: 0.2s;
|
|
||||||
--ant-motion-duration-slow: 0.3s;
|
|
||||||
|
|
||||||
/* Shadows */
|
|
||||||
--ant-box-shadow:
|
|
||||||
0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
--ant-box-shadow-secondary:
|
|
||||||
0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
/* Picker Specific Tokens */
|
|
||||||
--ant-picker-z-index-popup: 1050;
|
|
||||||
--ant-picker-cell-hover-bg: rgba(0, 0, 0, 0.04);
|
|
||||||
--ant-picker-cell-active-with-range-bg: var(--ant-color-primary-bg);
|
|
||||||
--ant-picker-basic-cell-hover-with-range-bg: #cce9ff; /* lighten(primary, 35) approx */
|
|
||||||
--ant-picker-date-hover-range-border-color: #7ec1ff; /* lighten(primary, 20) approx */
|
|
||||||
|
|
||||||
--ant-picker-panel-width: 280px; /* cellWidth * 7 + padding */
|
|
||||||
--ant-picker-year-month-cell-width: 60px;
|
|
||||||
--ant-picker-time-column-width: 56px;
|
|
||||||
--ant-picker-time-column-height: 224px;
|
|
||||||
--ant-picker-time-cell-height: 28px;
|
|
||||||
|
|
||||||
--ant-picker-cell-width: 36px;
|
|
||||||
--ant-picker-cell-height: 24px;
|
|
||||||
--ant-picker-text-height: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Base Styles (.rc-picker)
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
font-size: var(--ant-font-size);
|
|
||||||
line-height: var(--ant-line-height);
|
|
||||||
list-style: none;
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
background: var(--ant-color-bg-container);
|
|
||||||
border: var(--ant-line-width) var(--ant-line-type) var(--ant-color-border);
|
|
||||||
border-radius: var(--ant-border-radius);
|
|
||||||
transition:
|
|
||||||
border var(--ant-motion-duration-mid),
|
|
||||||
box-shadow var(--ant-motion-duration-mid);
|
|
||||||
padding: 4px 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Base States */
|
|
||||||
.rc-picker:hover,
|
|
||||||
.rc-picker-focused {
|
|
||||||
border-color: var(--ant-color-primary);
|
|
||||||
border-inline-end-width: var(--ant-line-width);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-focused {
|
|
||||||
box-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker.rc-picker-disabled {
|
|
||||||
background: var(--ant-color-bg-layout);
|
|
||||||
border-color: var(--ant-color-border);
|
|
||||||
color: var(--ant-color-text-disabled);
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker.rc-picker-disabled .rc-picker-suffix {
|
|
||||||
color: var(--ant-color-text-disabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clean Input Style */
|
|
||||||
.rc-picker-input {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-input > input {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
min-width: 1px; /* Firefox flex fix */
|
|
||||||
padding: 0;
|
|
||||||
color: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
outline: 0;
|
|
||||||
transition: all var(--ant-motion-duration-mid);
|
|
||||||
flex: auto;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-input > input::placeholder {
|
|
||||||
color: var(--ant-color-text-placeholder);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-input > input:disabled {
|
|
||||||
color: var(--ant-color-text-disabled);
|
|
||||||
background: transparent;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Suffix & Clear Icon */
|
|
||||||
.rc-picker-suffix {
|
|
||||||
display: flex;
|
|
||||||
flex: none;
|
|
||||||
align-self: center;
|
|
||||||
margin-inline-start: 4px;
|
|
||||||
color: var(--ant-color-text-quaternary);
|
|
||||||
line-height: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
transition:
|
|
||||||
opacity var(--ant-motion-duration-mid),
|
|
||||||
color var(--ant-motion-duration-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-clear {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
inset-inline-end: 0;
|
|
||||||
color: var(--ant-color-text-quaternary);
|
|
||||||
line-height: 1;
|
|
||||||
background: var(--ant-color-bg-container);
|
|
||||||
transform: translateY(-50%);
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
transition:
|
|
||||||
opacity var(--ant-motion-duration-mid),
|
|
||||||
color var(--ant-motion-duration-mid);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-clear:hover {
|
|
||||||
color: var(--ant-color-text-tertiary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker:hover .rc-picker-clear {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide suffix when clear is shown on hover (approximate behavior) */
|
|
||||||
.rc-picker:hover .rc-picker-clear + .rc-picker-suffix {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sizes */
|
|
||||||
.rc-picker-large {
|
|
||||||
padding: 6.5px 11px;
|
|
||||||
font-size: var(--ant-font-size-lg);
|
|
||||||
border-radius: var(--ant-border-radius-lg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-large .rc-picker-input > input {
|
|
||||||
font-size: var(--ant-font-size-lg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-small {
|
|
||||||
padding: 0px 7px;
|
|
||||||
border-radius: var(--ant-border-radius-sm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Range Picker Specifics
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-range {
|
|
||||||
position: relative;
|
|
||||||
display: inline-flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-range .rc-picker-clear {
|
|
||||||
inset-inline-end: 11px; /* padding inline */
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-range.rc-picker-small .rc-picker-clear {
|
|
||||||
inset-inline-end: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-range .rc-picker-active-bar {
|
|
||||||
bottom: -1px;
|
|
||||||
height: 2px;
|
|
||||||
margin-inline-start: 11px;
|
|
||||||
background: var(--ant-color-primary);
|
|
||||||
opacity: 0;
|
|
||||||
transition: all var(--ant-motion-duration-slow) ease-out;
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
width: 0; /* Dynamic width managed by JS usually, but styled here */
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-range.rc-picker-focused .rc-picker-active-bar {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-range-separator {
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
line-height: 1;
|
|
||||||
color: var(--ant-color-text-quaternary);
|
|
||||||
display: inline-flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Dropdown Panel
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-dropdown {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
font-size: var(--ant-font-size);
|
|
||||||
list-style: none;
|
|
||||||
position: absolute;
|
|
||||||
z-index: var(--ant-picker-z-index-popup);
|
|
||||||
top: -9999px;
|
|
||||||
left: -9999px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-dropdown-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-panel-container {
|
|
||||||
overflow: hidden;
|
|
||||||
vertical-align: top;
|
|
||||||
background: var(--ant-color-bg-elevated);
|
|
||||||
border-radius: var(--ant-border-radius-lg);
|
|
||||||
box-shadow: var(--ant-box-shadow-secondary);
|
|
||||||
transition: margin var(--ant-motion-duration-slow);
|
|
||||||
display: inline-block;
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Layout */
|
|
||||||
.rc-picker-panel-layout {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-panels {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-panel {
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: column;
|
|
||||||
text-align: center;
|
|
||||||
background: transparent;
|
|
||||||
outline: none;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Header */
|
|
||||||
.rc-picker-header {
|
|
||||||
display: flex;
|
|
||||||
padding: 0 8px;
|
|
||||||
color: var(--ant-color-text-heading);
|
|
||||||
border-bottom: var(--ant-line-width) var(--ant-line-type) var(--ant-color-split);
|
|
||||||
min-width: var(--ant-picker-panel-width);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header > * {
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header button {
|
|
||||||
padding: 0;
|
|
||||||
color: var(--ant-color-text-quaternary);
|
|
||||||
line-height: var(--ant-picker-text-height);
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color var(--ant-motion-duration-mid);
|
|
||||||
font-size: inherit;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-width: 1.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header button:hover {
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header-view {
|
|
||||||
flex: auto;
|
|
||||||
font-weight: 600; /* Strong */
|
|
||||||
line-height: var(--ant-picker-text-height);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header-view button {
|
|
||||||
color: inherit;
|
|
||||||
font-weight: inherit;
|
|
||||||
min-width: auto;
|
|
||||||
padding: 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-header-view button:hover {
|
|
||||||
color: var(--ant-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Header Icons (Arrows) */
|
|
||||||
.rc-picker-prev-icon,
|
|
||||||
.rc-picker-next-icon,
|
|
||||||
.rc-picker-super-prev-icon,
|
|
||||||
.rc-picker-super-next-icon {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 7px;
|
|
||||||
height: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-prev-icon::before,
|
|
||||||
.rc-picker-next-icon::before,
|
|
||||||
.rc-picker-super-prev-icon::before,
|
|
||||||
.rc-picker-super-next-icon::before {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 7px;
|
|
||||||
height: 7px;
|
|
||||||
border: 0 solid currentColor;
|
|
||||||
border-block-start-width: 1.5px;
|
|
||||||
border-inline-start-width: 1.5px;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-super-prev-icon::after,
|
|
||||||
.rc-picker-super-next-icon::after {
|
|
||||||
position: absolute;
|
|
||||||
top: 4px;
|
|
||||||
left: 4px;
|
|
||||||
display: inline-block;
|
|
||||||
width: 7px;
|
|
||||||
height: 7px;
|
|
||||||
border: 0 solid currentColor;
|
|
||||||
border-block-start-width: 1.5px;
|
|
||||||
border-inline-start-width: 1.5px;
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-prev-icon,
|
|
||||||
.rc-picker-super-prev-icon {
|
|
||||||
transform: rotate(-45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-next-icon,
|
|
||||||
.rc-picker-super-next-icon {
|
|
||||||
transform: rotate(135deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Body */
|
|
||||||
.rc-picker-body {
|
|
||||||
padding: 8px 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-content {
|
|
||||||
width: 100%;
|
|
||||||
table-layout: fixed;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-content th,
|
|
||||||
.rc-picker-content td {
|
|
||||||
position: relative;
|
|
||||||
min-width: var(--ant-picker-cell-width);
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-content th {
|
|
||||||
height: 30px;
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cells */
|
|
||||||
.rc-picker-cell {
|
|
||||||
padding: 3px 0;
|
|
||||||
color: var(--ant-color-text-disabled);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-in-view {
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell::before {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1;
|
|
||||||
height: var(--ant-picker-cell-height);
|
|
||||||
transform: translateY(-50%);
|
|
||||||
content: '';
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-inner {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
display: inline-block;
|
|
||||||
min-width: var(--ant-picker-cell-height);
|
|
||||||
height: var(--ant-picker-cell-height);
|
|
||||||
line-height: var(--ant-picker-cell-height);
|
|
||||||
border-radius: var(--ant-border-radius-sm);
|
|
||||||
transition: background-color var(--ant-motion-duration-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cell States */
|
|
||||||
.rc-picker-cell:hover:not(.rc-picker-cell-in-view):not(.rc-picker-cell-disabled) .rc-picker-cell-inner,
|
|
||||||
.rc-picker-cell:hover:not(.rc-picker-cell-selected):not(.rc-picker-cell-range-start):not(
|
|
||||||
.rc-picker-cell-range-end
|
|
||||||
):not(.rc-picker-cell-disabled)
|
|
||||||
.rc-picker-cell-inner {
|
|
||||||
background: var(--ant-picker-cell-hover-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Today */
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-today .rc-picker-cell-inner::before {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
border: 1px solid var(--ant-color-primary);
|
|
||||||
border-radius: var(--ant-border-radius-sm);
|
|
||||||
content: '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Selected / Range Start / Range End */
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-selected .rc-picker-cell-inner,
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-range-start .rc-picker-cell-inner,
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-range-end .rc-picker-cell-inner {
|
|
||||||
color: var(--ant-color-text-light-solid);
|
|
||||||
background: var(--ant-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In Range Background */
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-in-range::before,
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-range-start::before,
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-range-end::before {
|
|
||||||
background: var(--ant-picker-cell-active-with-range-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-range-start:not(.rc-picker-cell-range-end) .rc-picker-cell-inner {
|
|
||||||
border-start-end-radius: 0;
|
|
||||||
border-end-end-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-in-view.rc-picker-cell-range-end:not(.rc-picker-cell-range-start) .rc-picker-cell-inner {
|
|
||||||
border-start-start-radius: 0;
|
|
||||||
border-end-start-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled Cell */
|
|
||||||
.rc-picker-cell-disabled {
|
|
||||||
color: var(--ant-color-text-disabled);
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-disabled .rc-picker-cell-inner {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-cell-disabled::before {
|
|
||||||
background: var(--ant-color-bg-layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Special Panels (Year, Quarter, Month, Decade)
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-year-panel .rc-picker-body,
|
|
||||||
.rc-picker-quarter-panel .rc-picker-body,
|
|
||||||
.rc-picker-month-panel .rc-picker-body {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-year-panel .rc-picker-cell-inner,
|
|
||||||
.rc-picker-quarter-panel .rc-picker-cell-inner,
|
|
||||||
.rc-picker-month-panel .rc-picker-cell-inner {
|
|
||||||
width: var(--ant-picker-year-month-cell-width);
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-decade-panel .rc-picker-cell-inner {
|
|
||||||
padding: 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-decade-panel .rc-picker-cell::before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Time Panel
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-time-panel {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: auto;
|
|
||||||
min-width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel .rc-picker-content {
|
|
||||||
display: flex;
|
|
||||||
flex: auto;
|
|
||||||
height: 224px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column {
|
|
||||||
flex: 1 0 auto;
|
|
||||||
width: 56px;
|
|
||||||
margin: 4px 0;
|
|
||||||
padding: 0;
|
|
||||||
overflow-y: hidden;
|
|
||||||
text-align: start;
|
|
||||||
list-style: none;
|
|
||||||
transition: background-color var(--ant-motion-duration-mid);
|
|
||||||
overflow-x: hidden;
|
|
||||||
border-left: 1px solid var(--ant-color-split);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column:first-child {
|
|
||||||
border-left: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column:hover {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-column > li {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-cell .rc-picker-time-panel-cell-inner {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 28px;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 0 0 12px;
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
line-height: 28px;
|
|
||||||
border-radius: var(--ant-border-radius-sm);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color var(--ant-motion-duration-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-cell:hover .rc-picker-time-panel-cell-inner {
|
|
||||||
background: var(--ant-picker-cell-hover-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-time-panel-cell-selected .rc-picker-time-panel-cell-inner {
|
|
||||||
background: var(--ant-picker-cell-active-with-range-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Footer
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-footer {
|
|
||||||
width: min-content;
|
|
||||||
min-width: 100%;
|
|
||||||
line-height: 38px;
|
|
||||||
text-align: center;
|
|
||||||
border-top: 1px solid var(--ant-color-split);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-footer-extra {
|
|
||||||
padding: 0 12px;
|
|
||||||
line-height: 38px;
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ranges {
|
|
||||||
margin: 0;
|
|
||||||
padding: 4px 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
list-style: none;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-now-btn {
|
|
||||||
color: var(--ant-color-primary);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-ok {
|
|
||||||
margin-inline-start: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Variants
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-borderless {
|
|
||||||
background: transparent;
|
|
||||||
border-color: transparent;
|
|
||||||
box-shadow: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-filled {
|
|
||||||
background: var(--ant-color-bg-layout);
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-filled:hover,
|
|
||||||
.rc-picker-filled.rc-picker-focused {
|
|
||||||
background: var(--ant-color-bg-container);
|
|
||||||
border-color: var(--ant-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Status
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-status-error {
|
|
||||||
border-color: var(--ant-color-error) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-status-error.rc-picker-focused {
|
|
||||||
box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-status-warning {
|
|
||||||
border-color: var(--ant-color-warning) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-status-warning.rc-picker-focused {
|
|
||||||
box-shadow: 0 0 0 2px rgba(250, 173, 20, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
Multiple
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
.rc-picker-multiple .rc-picker-selector {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
padding: 1px 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-multiple .rc-picker-selection-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 24px;
|
|
||||||
margin-top: 2px;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
margin-inline-end: 4px;
|
|
||||||
padding-inline-start: 8px;
|
|
||||||
padding-inline-end: 4px;
|
|
||||||
background: var(--ant-color-bg-layout);
|
|
||||||
border-radius: var(--ant-border-radius-sm);
|
|
||||||
cursor: default;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-multiple .rc-picker-selection-item-remove {
|
|
||||||
color: var(--ant-color-text-quaternary);
|
|
||||||
font-size: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-flex;
|
|
||||||
margin-left: 4px;
|
|
||||||
transition: color var(--ant-motion-duration-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-picker-multiple .rc-picker-selection-item-remove:hover {
|
|
||||||
color: var(--ant-color-text-tertiary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,398 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* =========================================
|
|
||||||
BASE WRAPPER & LABEL
|
|
||||||
========================================= */
|
|
||||||
.rc-switch-wrapper {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: var(--form-label-font-size);
|
|
||||||
font-weight: var(--form-label-font-weight);
|
|
||||||
color: var(--form-label-color);
|
|
||||||
line-height: 1;
|
|
||||||
gap: 8px; /* Distance between switch and label */
|
|
||||||
transition: all 0.2s;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-switch-wrapper-disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-switch-label-text {
|
|
||||||
line-height: var(--switch-height); /* Align text vertically with switch */
|
|
||||||
font-size: var(--form-label-font-size);
|
|
||||||
font-weight: var(--form-label-font-weight);
|
|
||||||
color: var(--form-label-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Container for relative positioning of loading state */
|
|
||||||
.rc-switch-container {
|
|
||||||
position: relative;
|
|
||||||
line-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
CORE SWITCH STRUCTURE
|
|
||||||
========================================= */
|
|
||||||
.rc-switch {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: var(--switch-width);
|
|
||||||
height: var(--switch-height);
|
|
||||||
line-height: calc(var(--switch-height) - 2px);
|
|
||||||
padding: 0;
|
|
||||||
vertical-align: middle;
|
|
||||||
border-radius: 9999px; /* Pill shape */
|
|
||||||
border: 1px solid; /* Border color defined in variants */
|
|
||||||
background-color: transparent; /* Bg defined in variants */
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1);
|
|
||||||
overflow: visible; /* Changed to visible for focus rings or overflow effects if needed */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focus Ring (Consistent with Checkbox) */
|
|
||||||
.rc-switch:focus-visible,
|
|
||||||
.rc-switch:focus {
|
|
||||||
outline: none;
|
|
||||||
box-shadow: 0 0 0 3px var(--focus-ring-color);
|
|
||||||
border-color: var(--focus-border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
HANDLE (THE CIRCLE)
|
|
||||||
========================================= */
|
|
||||||
.rc-switch:after {
|
|
||||||
position: absolute;
|
|
||||||
content: ' ';
|
|
||||||
top: 1px; /* (Height - Handle) / 2 approx, adjusted for border */
|
|
||||||
left: var(--switch-padding);
|
|
||||||
width: var(--switch-handle-size);
|
|
||||||
height: var(--switch-handle-size);
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: #ffffff;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 35, 11, 0.2);
|
|
||||||
transform: scale(1);
|
|
||||||
transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hover Effect on Handle */
|
|
||||||
.rc-switch:hover:after {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-switch:active:after {
|
|
||||||
transform: scale(1); /* Reset on click */
|
|
||||||
width: calc(var(--switch-handle-size) + 4px); /* Stretch effect like iOS */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
CHECKED STATE
|
|
||||||
========================================= */
|
|
||||||
.rc-switch-checked:after {
|
|
||||||
left: var(--switch-checked-pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-switch-checked:active:after {
|
|
||||||
left: calc(var(--switch-checked-pos) - 4px); /* Adjust stretch position */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
INNER TEXT (ON/OFF LABELS)
|
|
||||||
========================================= */
|
|
||||||
.rc-switch-inner {
|
|
||||||
display: block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%; /* Make sure to take the full width of the container */
|
|
||||||
|
|
||||||
/* SETTING DEFAULT (STATE OFF / UNCHECKED) */
|
|
||||||
/* Handle on the Left -> Text must be on the Right */
|
|
||||||
/* Margin: Top | Right (Edge) | Bottom | Left (Handle) */
|
|
||||||
margin: 0 var(--switch-inner-indent-edge) 0 var(--switch-inner-indent-handle);
|
|
||||||
|
|
||||||
/* Typography */
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 600;
|
|
||||||
line-height: calc(var(--switch-height) - 2px);
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
/* Behavior */
|
|
||||||
pointer-events: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
/* Transition: Shift margin and change color */
|
|
||||||
transition:
|
|
||||||
margin 0.3s cubic-bezier(0.35, 0, 0.25, 1),
|
|
||||||
color 0.3s;
|
|
||||||
|
|
||||||
/* Default Color (OFF) */
|
|
||||||
color: var(--color-gray-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-switch-checked .rc-switch-inner {
|
|
||||||
/* Handle on the Right -> Text must be on the Left */
|
|
||||||
/* Margin: Top | Right (Handle) | Bottom | Left (Edge) */
|
|
||||||
margin: 0 var(--switch-inner-indent-handle) 0 var(--switch-inner-indent-edge);
|
|
||||||
|
|
||||||
/* Color ON */
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Text Color When ON -> Always White (because the background is colored) */
|
|
||||||
.rc-switch-checked .rc-switch-inner,
|
|
||||||
.rc-switch-checked .rc-switch-inner {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
LOADING STATE
|
|
||||||
========================================= */
|
|
||||||
.rc-switch-loading {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The SVG Icon inside the handle */
|
|
||||||
.rc-switch-loading-icon {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
color: var(--color-brand-500); /* Loading icon color */
|
|
||||||
animation: rcSwitchLoading 1s infinite linear;
|
|
||||||
/* Center inside the handle */
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Override handle style when loading */
|
|
||||||
.rc-switch-loading .rc-switch:after {
|
|
||||||
background-color: #fff; /* Ensure handle is white */
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rcSwitchLoading {
|
|
||||||
100% {
|
|
||||||
transform: translate(-50%, -50%) rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
STATUS COLORS (Applied to Checked State)
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* --- DEFAULT (Brand) --- */
|
|
||||||
|
|
||||||
.switch-status-default .rc-switch {
|
|
||||||
background-color: var(--color-gray-50);
|
|
||||||
border-color: var(--color-gray-200);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-default .rc-switch:hover {
|
|
||||||
border-color: var(--color-brand-500);
|
|
||||||
}
|
|
||||||
.switch-status-default .rc-switch-checked {
|
|
||||||
border-color: var(--color-brand-500);
|
|
||||||
background-color: var(--color-brand-500);
|
|
||||||
}
|
|
||||||
.switch-status-default .rc-switch:focus-visible,
|
|
||||||
.switch-status-default .rc-switch:focus {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-brand-100);
|
|
||||||
border-color: var(--color-brand-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- ERROR --- */
|
|
||||||
/* Hover Off state (Optional: Tint border red on hover even if off) */
|
|
||||||
.switch-status-error .rc-switch {
|
|
||||||
background-color: var(--color-gray-50);
|
|
||||||
border-color: var(--color-error-300);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-error .rc-switch:hover {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-error .rc-switch:after {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checked State */
|
|
||||||
.switch-status-error.switch-variant-outlined .rc-switch-checked {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
background-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
.switch-status-error.switch-variant-outlined .rc-switch-checked:after {
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 35, 11, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-error .rc-switch-checked {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
background-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focus */
|
|
||||||
.switch-status-error .rc-switch:focus-visible,
|
|
||||||
.switch-status-error .rc-switch:focus {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-error-100);
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
/* Loading Icon Color */
|
|
||||||
.switch-status-error .rc-switch-loading-icon {
|
|
||||||
color: var(--color-error-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- SUCCESS --- */
|
|
||||||
|
|
||||||
.switch-status-success .rc-switch {
|
|
||||||
background-color: var(--color-gray-50);
|
|
||||||
border-color: var(--color-success-300);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-success .rc-switch:hover {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-success .rc-switch:after {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checked State */
|
|
||||||
.switch-status-success.switch-variant-outlined .rc-switch-checked {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
background-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
.switch-status-success.switch-variant-outlined .rc-switch-checked:after {
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 35, 11, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-success .rc-switch-checked {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
background-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focus */
|
|
||||||
.switch-status-success .rc-switch:focus-visible,
|
|
||||||
.switch-status-success .rc-switch:focus {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-success-100);
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
/* Loading Icon Color */
|
|
||||||
.switch-status-success .rc-switch-loading-icon {
|
|
||||||
color: var(--color-success-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- WARNING --- */
|
|
||||||
.switch-status-warning .rc-switch {
|
|
||||||
background-color: var(--color-gray-50);
|
|
||||||
border-color: var(--color-warning-300);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-warning .rc-switch:hover {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-warning .rc-switch:after {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checked State */
|
|
||||||
.switch-status-warning.switch-variant-outlined .rc-switch-checked {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
background-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
.switch-status-warning.switch-variant-outlined .rc-switch-checked:after {
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 35, 11, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-warning .rc-switch-checked {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
background-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focus */
|
|
||||||
.switch-status-warning .rc-switch:focus-visible,
|
|
||||||
.switch-status-warning .rc-switch:focus {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-warning-100);
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
/* Loading Icon Color */
|
|
||||||
.switch-status-warning .rc-switch-loading-icon {
|
|
||||||
color: var(--color-warning-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- INFO --- */
|
|
||||||
.switch-status-info .rc-switch {
|
|
||||||
background-color: var(--color-gray-50);
|
|
||||||
border-color: var(--color-info-300);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-info .rc-switch:hover {
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-info .rc-switch:after {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Checked State */
|
|
||||||
.switch-status-info.switch-variant-outlined .rc-switch-checked {
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
background-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
.switch-status-info.switch-variant-outlined .rc-switch-checked:after {
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 2px 4px 0 rgba(0, 35, 11, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-status-info .rc-switch-checked {
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
background-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focus */
|
|
||||||
.switch-status-info .rc-switch:focus-visible,
|
|
||||||
.switch-status-info .rc-switch:focus {
|
|
||||||
box-shadow: 0 0 0 3px var(--color-info-100);
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
/* Loading Icon Color */
|
|
||||||
.switch-status-info .rc-switch-loading-icon {
|
|
||||||
color: var(--color-info-500);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
DISABLED STATE
|
|
||||||
========================================= */
|
|
||||||
.rc-switch-disabled,
|
|
||||||
.rc-switch-wrapper-disabled .rc-switch {
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 0.6;
|
|
||||||
background-color: var(--disabled-bg) !important;
|
|
||||||
border-color: var(--disabled-border) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-switch-disabled:after,
|
|
||||||
.rc-switch-wrapper-disabled .rc-switch:after {
|
|
||||||
cursor: not-allowed;
|
|
||||||
background-color: #f9fafb; /* Lighter white/gray for disabled knob */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If checked and disabled */
|
|
||||||
.rc-switch-disabled.rc-switch-checked {
|
|
||||||
background-color: var(--disabled-border) !important; /* Darker gray to show it is "on" but disabled */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable animations/hovers */
|
|
||||||
.rc-switch-disabled:hover:after {
|
|
||||||
transform: scale(1);
|
|
||||||
animation-name: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
@layer components {
|
|
||||||
/* =========================================
|
|
||||||
BASE STYLE: TEXTAREA (Standalone)
|
|
||||||
========================================= */
|
|
||||||
.rc-textarea {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
/* Global Variables */
|
|
||||||
min-height: var(--textarea-min-height);
|
|
||||||
padding: var(--textarea-padding-y) var(--textarea-padding-x);
|
|
||||||
|
|
||||||
font-size: var(--input-font-size);
|
|
||||||
line-height: 1.5;
|
|
||||||
color: var(--input-text);
|
|
||||||
|
|
||||||
/* Default Base (akan di-override jika ada wrapper) */
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: var(--input-radius);
|
|
||||||
|
|
||||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
outline: none;
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rc-textarea::placeholder {
|
|
||||||
color: var(--input-placeholder);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled State (Standalone) */
|
|
||||||
.rc-textarea:disabled {
|
|
||||||
background-color: var(--disabled-bg) !important;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
border-color: var(--disabled-border) !important;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
WRAPPER SETUP (allowClear / showCount)
|
|
||||||
Component akan memindahkan class Variant & Status ke div ini
|
|
||||||
========================================= */
|
|
||||||
.rc-textarea-affix-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
/* Wrapper harus punya base style border/bg agar status works */
|
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: var(--input-radius);
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RESET INNER TEXTAREA */
|
|
||||||
/* Saat dibungkus, textarea menjadi transparan, wrapper yang menangani warna */
|
|
||||||
.rc-textarea-affix-wrapper .rc-textarea {
|
|
||||||
background-color: transparent;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: none !important; /* Hapus shadow default inner */
|
|
||||||
/* Padding tetap di textarea agar text flow benar */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear Icon Position */
|
|
||||||
.rc-textarea-clear-icon {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
top: var(--textarea-padding-y);
|
|
||||||
right: var(--textarea-padding-x);
|
|
||||||
z-index: 5;
|
|
||||||
font-size: var(--text-sm);
|
|
||||||
line-height: 1;
|
|
||||||
color: var(--color-gray-400);
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
.rc-textarea-clear-icon:hover {
|
|
||||||
color: var(--color-gray-500);
|
|
||||||
}
|
|
||||||
.rc-textarea-clear-icon:active {
|
|
||||||
color: var(--color-gray-600);
|
|
||||||
}
|
|
||||||
.rc-textarea-clear-icon-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Padding adjustment jika ada clear icon */
|
|
||||||
.rc-textarea-has-clear {
|
|
||||||
padding-right: calc(var(--textarea-padding-x) + 1.25rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disabled Wrapper */
|
|
||||||
.rc-textarea-affix-wrapper-disabled {
|
|
||||||
background-color: var(--disabled-bg) !important;
|
|
||||||
border-color: var(--disabled-border) !important;
|
|
||||||
color: var(--disabled-text);
|
|
||||||
cursor: not-allowed;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.rc-textarea-affix-wrapper-disabled .rc-textarea {
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
|
||||||
LOGIC MATRIX: [VARIANT] x [STATUS]
|
|
||||||
Target: .rc-textarea (standalone) AND .rc-textarea-affix-wrapper (wrapped)
|
|
||||||
========================================= */
|
|
||||||
|
|
||||||
/* ------------------------------------------------
|
|
||||||
1. VARIANT: OUTLINED
|
|
||||||
------------------------------------------------ */
|
|
||||||
|
|
||||||
/* --- Default --- */
|
|
||||||
.textarea-status-default {
|
|
||||||
background-color: var(--input-bg);
|
|
||||||
border-color: var(--input-border);
|
|
||||||
}
|
|
||||||
/* Hover */
|
|
||||||
.textarea-status-default:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
|
|
||||||
border-color: var(--input-border-hover);
|
|
||||||
}
|
|
||||||
/* Focus (Standalone OR Wrapper Focused) */
|
|
||||||
.rc-textarea.textarea-status-default:focus,
|
|
||||||
.rc-textarea-affix-wrapper.textarea-status-default.rc-textarea-affix-wrapper-focused {
|
|
||||||
border-color: var(--focus-border-color);
|
|
||||||
box-shadow: 0 0 0 3px var(--focus-ring-color);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Error --- */
|
|
||||||
.textarea-status-error {
|
|
||||||
border-color: var(--color-error-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.textarea-status-error:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
}
|
|
||||||
.rc-textarea.textarea-status-error:focus,
|
|
||||||
.rc-textarea-affix-wrapper.textarea-status-error.rc-textarea-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-error-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-error-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Warning --- */
|
|
||||||
.textarea-status-warning {
|
|
||||||
border-color: var(--color-warning-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.textarea-status-warning:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
}
|
|
||||||
.rc-textarea.textarea-status-warning:focus,
|
|
||||||
.rc-textarea-affix-wrapper.textarea-status-warning.rc-textarea-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-warning-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-warning-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Success --- */
|
|
||||||
.textarea-status-success {
|
|
||||||
border-color: var(--color-success-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.textarea-status-success:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
}
|
|
||||||
.rc-textarea.textarea-status-success:focus,
|
|
||||||
.rc-textarea-affix-wrapper.textarea-status-success.rc-textarea-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-success-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-success-100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --- Info --- */
|
|
||||||
.textarea-status-info {
|
|
||||||
border-color: var(--color-info-500);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.textarea-status-info:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
|
|
||||||
border-color: var(--color-info-600);
|
|
||||||
}
|
|
||||||
.rc-textarea.textarea-status-info:focus,
|
|
||||||
.rc-textarea-affix-wrapper.textarea-status-info.rc-textarea-affix-wrapper-focused {
|
|
||||||
border-color: var(--color-info-600);
|
|
||||||
box-shadow: 0 0 0 3px var(--color-info-100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
import { forwardRef } from 'react';
|
|
||||||
import RcSwitch from '@rc-component/switch';
|
|
||||||
import { SwitchProps } from '../types';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* LoadingSpinner
|
|
||||||
*
|
|
||||||
* Renders a compact SVG loading indicator intended for use inside switch components.
|
|
||||||
*
|
|
||||||
* - Stateless React component that returns an SVG element.
|
|
||||||
* - Decorative: marked with `aria-hidden="true"` so it is ignored by assistive technologies.
|
|
||||||
* - Styled via the `rc-switch-loading-icon` CSS class; color is controlled by `currentColor`.
|
|
||||||
*
|
|
||||||
* @returns {JSX.Element} An SVG element representing a loading spinner.
|
|
||||||
*/
|
|
||||||
const LoadingSpinner = () => (
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 1024 1024"
|
|
||||||
focusable="false"
|
|
||||||
className="rc-switch-loading-icon"
|
|
||||||
data-icon="loading"
|
|
||||||
fill="currentColor"
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
<path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" />
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
|
|
||||||
export const Switch = forwardRef<HTMLButtonElement, SwitchProps>((props, ref) => {
|
|
||||||
const { label, status = 'default', className, children, style, loading, disabled, ...rest } = props;
|
|
||||||
|
|
||||||
const displayLabel = label || children;
|
|
||||||
|
|
||||||
const isEnabled = !disabled && !loading;
|
|
||||||
|
|
||||||
const wrapperClass = [
|
|
||||||
'rc-switch-wrapper',
|
|
||||||
`switch-status-${status}`,
|
|
||||||
!isEnabled ? 'rc-switch-wrapper-disabled' : '',
|
|
||||||
className,
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<label className={wrapperClass} style={style}>
|
|
||||||
<span className={`rc-switch-container ${loading ? 'rc-switch-loading' : ''}`}>
|
|
||||||
<RcSwitch
|
|
||||||
ref={ref}
|
|
||||||
prefixCls="rc-switch"
|
|
||||||
disabled={!isEnabled}
|
|
||||||
loadingIcon={loading ? <LoadingSpinner /> : null}
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{displayLabel && <span className="rc-switch-label-text">{displayLabel}</span>}
|
|
||||||
</label>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
Switch.displayName = 'Switch';
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import { forwardRef } from 'react';
|
|
||||||
import RcTextArea, { TextAreaRef } from '@rc-component/textarea';
|
|
||||||
import { InputStatusType, TextAreaProps, VALID_INPUT_STATUSES } from '../types';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forwarding React component that renders an RcTextArea with normalized status.
|
|
||||||
*
|
|
||||||
* The component computes a CSS class string from the optional `className`, a `textarea-status-<status>` class
|
|
||||||
* (falling back to 'default' when `status` is missing or not one of VALID_INPUT_STATUSES), and a
|
|
||||||
*
|
|
||||||
* The component forwards a ref to the underlying RcTextArea element.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* - `status` is validated against `VALID_INPUT_STATUSES`; if invalid or absent, `'default'` is used.
|
|
||||||
* - Computed className shape: [className?, `textarea-status-${status}`].filter(Boolean).join(' ')
|
|
||||||
*
|
|
||||||
* @param props.status - Optional input status (validated against VALID_INPUT_STATUSES).
|
|
||||||
* @param props.className - Optional additional class name(s) to apply.
|
|
||||||
* @param props.rest - All other props are forwarded to RcTextArea.
|
|
||||||
*
|
|
||||||
* @returns A React element: the wrapped RcTextArea with forwarded ref and computed classes.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* <TextArea status="error" placeholder="Enter text" />
|
|
||||||
*/
|
|
||||||
export const TextArea = forwardRef<TextAreaRef, TextAreaProps>((props, ref) => {
|
|
||||||
const { status, className, ...restProps } = props;
|
|
||||||
|
|
||||||
const currentStatus: InputStatusType = status && VALID_INPUT_STATUSES.includes(status) ? status : 'default';
|
|
||||||
|
|
||||||
const computedClassName = [className, `textarea-status-${currentStatus}`].filter(Boolean).join(' ');
|
|
||||||
|
|
||||||
return <RcTextArea ref={ref} className={computedClassName} {...restProps} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
TextArea.displayName = 'TextArea';
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
import type { FormProps as RcFormProps } from '@rc-component/form';
|
|
||||||
import type { Rule } from '@rc-component/form/lib/interface';
|
|
||||||
import { ReactNode, ReactElement, ComponentProps, CSSProperties } from 'react';
|
|
||||||
|
|
||||||
import { InputProps as RcInputProps } from '@rc-component/input';
|
|
||||||
import { TextAreaProps as RcTextAreaProps } from '@rc-component/textarea';
|
|
||||||
import { InputNumberProps as RcInputNumberProps } from '@rc-component/input-number';
|
|
||||||
|
|
||||||
import { CheckboxProps as RcCheckboxProps } from '@rc-component/checkbox';
|
|
||||||
import type { PickerProps as RcPickerProps, RangePickerProps as RcRangePickerProps, PickerPanelProps as RcPickerPanelProps } from '@rc-component/picker';
|
|
||||||
|
|
||||||
import RcSwitch from '@rc-component/switch';
|
|
||||||
type RcSwitchProps = ComponentProps<typeof RcSwitch>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define possible input statuses
|
|
||||||
*/
|
|
||||||
export type InputStatusType = 'default' | 'error' | 'warning' | 'success' | 'info';
|
|
||||||
export const VALID_INPUT_STATUSES: InputStatusType[] = ['default', 'error', 'warning', 'success', 'info'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define form props
|
|
||||||
*/
|
|
||||||
export interface FormProps<Values = any> extends Omit<RcFormProps<Values>, 'children'> {
|
|
||||||
children?: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define form item props
|
|
||||||
*/
|
|
||||||
export interface FormItemProps {
|
|
||||||
name?: string | (string | number)[];
|
|
||||||
label?: ReactNode;
|
|
||||||
children: ReactElement;
|
|
||||||
rules?: Rule[];
|
|
||||||
valuePropName?: string;
|
|
||||||
initialValue?: any;
|
|
||||||
status?: InputStatusType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define base component props
|
|
||||||
*/
|
|
||||||
interface BaseFormItemComponentProps {
|
|
||||||
status?: InputStatusType;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BaseFormInputComponentProps extends BaseFormItemComponentProps {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define specific component props
|
|
||||||
*/
|
|
||||||
export interface InputProps extends RcInputProps, BaseFormInputComponentProps {}
|
|
||||||
export interface InputPasswordProps extends InputProps {
|
|
||||||
visibilityToggle?: boolean; // Default: true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define InputNumber and InputCurrency props
|
|
||||||
*/
|
|
||||||
export interface InputNumberProps extends RcInputNumberProps, BaseFormInputComponentProps {}
|
|
||||||
export interface InputCurrencyProps extends InputNumberProps, BaseFormInputComponentProps {
|
|
||||||
prefix?: string; // Optional: Custom prefix, default 'Rp '
|
|
||||||
decimalSeparator?: ',' | '.';
|
|
||||||
decimalScale?: number; // optional
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define TextArea props
|
|
||||||
*/
|
|
||||||
export interface TextAreaProps extends RcTextAreaProps, BaseFormInputComponentProps {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define Checkbox props
|
|
||||||
*/
|
|
||||||
export interface CheckboxProps extends RcCheckboxProps, BaseFormInputComponentProps {
|
|
||||||
label?: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define Switch props
|
|
||||||
*/
|
|
||||||
export interface SwitchProps extends RcSwitchProps, BaseFormInputComponentProps {
|
|
||||||
label?: ReactNode;
|
|
||||||
loading?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define Picker props
|
|
||||||
* We omit generateConfig because it is injected by the generator.
|
|
||||||
* We make locale optional and default it in the implementation.
|
|
||||||
*/
|
|
||||||
export interface PickerProps<DateType extends object = any> extends Omit<RcPickerProps<DateType>, 'generateConfig' | 'locale'>, BaseFormInputComponentProps {
|
|
||||||
locale?: RcPickerProps<DateType>['locale'];
|
|
||||||
}
|
|
||||||
export interface RangePickerProps<DateType extends object = any> extends Omit<RcRangePickerProps<DateType>, 'generateConfig' | 'locale'>, BaseFormInputComponentProps {
|
|
||||||
locale?: RcRangePickerProps<DateType>['locale'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PickerPanelProps<DateType extends object = any> extends Omit<RcPickerPanelProps<DateType>, 'generateConfig' | 'locale'> {
|
|
||||||
locale?: RcPickerPanelProps<DateType>['locale'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SpecificPickerProps<DateType extends object> extends PickerProps<DateType> {};
|
|
||||||
export interface SpecificRangePickerProps<DateType extends object> extends RangePickerProps<DateType> {};
|
|
||||||
@@ -1,16 +1,4 @@
|
|||||||
export * from './examples/header-example';
|
|
||||||
export * from './examples/counter-example';
|
|
||||||
export * from './examples/date-example';
|
|
||||||
export * from './examples/encryption-example';
|
|
||||||
export * from './examples/style-guide-1';
|
|
||||||
export * from './examples/style-guide-2';
|
|
||||||
export * from './examples/style-guide-3';
|
|
||||||
|
|
||||||
export * from './system-pages/coming-soon';
|
export * from './system-pages/coming-soon';
|
||||||
export * from './system-pages/forbidden';
|
export * from './system-pages/forbidden';
|
||||||
export * from './system-pages/maintenance';
|
export * from './system-pages/maintenance';
|
||||||
export * from './system-pages/not-found';
|
export * from './system-pages/not-found';
|
||||||
|
|
||||||
export * from './button/button';
|
|
||||||
|
|
||||||
export * from './forms';
|
|
||||||
|
|||||||
@@ -1,5 +1,2 @@
|
|||||||
// UI Components
|
// UI Components
|
||||||
export * from './components';
|
export * from './components';
|
||||||
|
|
||||||
// UI utils
|
|
||||||
export * from './utils/cn';
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { ConfigProvider, App } from 'antd';
|
|
||||||
|
|
||||||
export const UIProvider = ({ children }: { children: React.ReactNode }) => {
|
|
||||||
return (
|
|
||||||
<ConfigProvider>
|
|
||||||
<App>{children}</App>
|
|
||||||
</ConfigProvider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { type ClassValue, clsx } from 'clsx';
|
|
||||||
import { twMerge } from 'tailwind-merge';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intelligently merges classnames.
|
|
||||||
* 1. clsx: handles conditional logic (true/false)
|
|
||||||
* 2. twMerge: removes conflicting Tailwind classes
|
|
||||||
*/
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
|
||||||
return twMerge(clsx(inputs));
|
|
||||||
}
|
|
||||||
Generated
+2
-825
@@ -161,42 +161,12 @@ importers:
|
|||||||
|
|
||||||
packages/ui:
|
packages/ui:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ant-design/icons':
|
|
||||||
specifier: ^6.1.0
|
|
||||||
version: 6.1.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/checkbox':
|
|
||||||
specifier: ^1.0.1
|
|
||||||
version: 1.0.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/form':
|
|
||||||
specifier: ^1.6.2
|
|
||||||
version: 1.6.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/input':
|
|
||||||
specifier: ^1.1.2
|
|
||||||
version: 1.1.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/input-number':
|
|
||||||
specifier: ^1.6.2
|
|
||||||
version: 1.6.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/picker':
|
|
||||||
specifier: ^1.9.0
|
|
||||||
version: 1.9.0(dayjs@1.11.19)(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/switch':
|
|
||||||
specifier: ^1.0.3
|
|
||||||
version: 1.0.3(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/textarea':
|
|
||||||
specifier: ^1.1.2
|
|
||||||
version: 1.1.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@repo/utils':
|
'@repo/utils':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../utils
|
version: link:../utils
|
||||||
'@tailwindcss/vite':
|
'@tailwindcss/vite':
|
||||||
specifier: ^4.1.18
|
specifier: ^4.1.18
|
||||||
version: 4.1.18(vite@5.4.17)
|
version: 4.1.18(vite@5.4.17)
|
||||||
antd:
|
|
||||||
specifier: ^6.2.3
|
|
||||||
version: 6.2.3(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx:
|
|
||||||
specifier: ^2.1.1
|
|
||||||
version: 2.1.1
|
|
||||||
dayjs:
|
dayjs:
|
||||||
specifier: ^1.11.19
|
specifier: ^1.11.19
|
||||||
version: 1.11.19
|
version: 1.11.19
|
||||||
@@ -274,80 +244,6 @@ importers:
|
|||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
/@ant-design/colors@8.0.1:
|
|
||||||
resolution: {integrity: sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==}
|
|
||||||
dependencies:
|
|
||||||
'@ant-design/fast-color': 3.0.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@ant-design/cssinjs-utils@2.0.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-Mq3Hm6fJuQeFNKSp3+yT4bjuhVbdrsyXE2RyfpJFL0xiYNZdaJ6oFaE3zFrzmHbmvTd2Wp3HCbRtkD4fU+v2ZA==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18'
|
|
||||||
react-dom: '>=18'
|
|
||||||
dependencies:
|
|
||||||
'@ant-design/cssinjs': 2.0.3(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@ant-design/cssinjs@2.0.3(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-HAo8SZ3a6G8v6jT0suCz1270na6EA3obeJWM4uzRijBhdwdoMAXWK2f4WWkwB28yUufsfk3CAhN1coGPQq4kNQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.0.0'
|
|
||||||
react-dom: '>=16.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
'@emotion/hash': 0.8.0
|
|
||||||
'@emotion/unitless': 0.7.5
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
csstype: 3.2.3
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
stylis: 4.3.6
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@ant-design/fast-color@3.0.1:
|
|
||||||
resolution: {integrity: sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@ant-design/icons-svg@4.4.2:
|
|
||||||
resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@ant-design/icons@6.1.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-KrWMu1fIg3w/1F2zfn+JlfNDU8dDqILfA5Tg85iqs1lf8ooyGlbkA+TkwfOKKgqpUmAiRY1PTFpuOU2DAIgSUg==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.0.0'
|
|
||||||
react-dom: '>=16.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@ant-design/colors': 8.0.1
|
|
||||||
'@ant-design/icons-svg': 4.4.2
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@ant-design/react-slick@2.0.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-HMS9sRoEmZey8LsE/Yo6+klhlzU12PisjrVcydW3So7RdklyEd2qehyU6a7Yp+OYN72mgsYs3NFCyP2lCPFVqg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
react-dom: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
clsx: 2.1.1
|
|
||||||
json2mq: 0.2.0
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
throttle-debounce: 5.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@babel/code-frame@7.27.1:
|
/@babel/code-frame@7.27.1:
|
||||||
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -496,6 +392,7 @@ packages:
|
|||||||
/@babel/runtime@7.28.4:
|
/@babel/runtime@7.28.4:
|
||||||
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
|
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@babel/template@7.27.2:
|
/@babel/template@7.27.2:
|
||||||
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
||||||
@@ -551,14 +448,6 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@emotion/hash@0.8.0:
|
|
||||||
resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@emotion/unitless@0.7.5:
|
|
||||||
resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@esbuild/aix-ppc64@0.21.5:
|
/@esbuild/aix-ppc64@0.21.5:
|
||||||
resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
|
resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -1244,615 +1133,6 @@ packages:
|
|||||||
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@rc-component/async-validator@5.1.0:
|
|
||||||
resolution: {integrity: sha512-n4HcR5siNUXRX23nDizbZBQPO0ZM/5oTtmKZ6/eqL0L2bo747cklFdZGRN2f+c9qWGICwDzrhW0H7tE9PptdcA==}
|
|
||||||
engines: {node: '>=14.x'}
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/cascader@1.11.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-VDiEsskThWi8l0/1Nquc9I4ytcMKQYAb9Jkm6wiX5O5fpcMRsm+b8OulBMbr/b4rFTl/2y2y4GdKqQ+2whD+XQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/select': 1.5.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/tree': 1.1.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/checkbox@1.0.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-08yTH8m+bSm8TOqbybbJ9KiAuIATti6bDs2mVeSfu4QfEnyeF6X0enHVvD1NEAyuBWEAo56QtLe++MYs2D9XiQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/collapse@1.2.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-ZRYSKSS39qsFx93p26bde7JUZJshsUBEQRlRXPuJYlAiNX0vyYlF5TsAm8JZN3LcF8XvKikdzPbgAtXSbkLUkw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/color-picker@3.0.3(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-V7gFF9O7o5XwIWafdbOtqI4BUUkEUkgdBwp6favy3xajMX/2dDqytFaiXlcwrpq6aRyPLp5dKLAG5RFKLXMeGA==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@ant-design/fast-color': 3.0.1
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/context@2.0.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-HyZbYm47s/YqtP6pKXNMjPEMaukyg7P0qVfgMLzr7YiFNMHbK2fKTAGzms9ykfGHSfyf75nBbgWw+hHkp+VImw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/dialog@1.8.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-CwDSjpjZ1FcgsdKFPuSoYfi9Vbt2bp+ak4Pzkwq4APQC8DopJKWetRu1V+HE9vI1CNAeqvT5WAvAxE6RiDhl7A==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/portal': 2.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/drawer@1.4.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-kNJQie/QjJO5wGeWrZQwSGeuo8staxXx1nYN+dpK2UY7i8teo5PQdZ6ukKSnnW9vmPXsLn3F5nKYRbf43e8+5g==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/portal': 2.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/dropdown@1.0.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-6PY2ecUSYhDPhkNHHb4wfeAya04WhpmUSKzdR60G+kMNVUCX2vjT/AgTS0Lz0I/K6xrPMJ3enQbwVpeN3sHCgg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.11.0'
|
|
||||||
react-dom: '>=16.11.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/form@1.6.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-OgIn2RAoaSBqaIgzJf/X6iflIa9LpTozci1lagLBdURDFhGA370v0+T0tXxOi8YShMjTha531sFhwtnrv+EJaQ==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/async-validator': 5.1.0
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/image@1.6.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-tSfn2ZE/oP082g4QIOxeehkmgnXB7R+5AFj/lIFr4k7pEuxHBdyGIq9axoCY9qea8NN0DY6p4IB/F07tLqaT5A==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/portal': 2.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/input-number@1.6.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-Gjcq7meZlCOiWN1t1xCC+7/s85humHVokTBI7PJgTfoyw5OWF74y3e6P8PHX104g9+b54jsodFIzyaj6p8LI9w==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/mini-decimal': 1.1.0
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/input@1.1.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-Q61IMR47piUBudgixJ30CciKIy9b1H95qe7GgEKOmSJVJXvFRWJllJfQry9tif+MX2cWFXWJf/RXz4kaCeq/Fg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.0.0'
|
|
||||||
react-dom: '>=16.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/mentions@1.6.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-KIkQNP6habNuTsLhUv0UGEOwG67tlmE7KNIJoQZZNggEZl5lQJTytFDb69sl5CK3TDdISCTjKP3nGEBKgT61CQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/input': 1.1.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/menu': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/textarea': 1.1.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/menu@1.2.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-VWwDuhvYHSnTGj4n6bV3ISrLACcPAzdPOq3d0BzkeiM5cve8BEYfvkEhNoM0PLzv51jpcejeyrLXeMVIJ+QJlg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/overflow': 1.0.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/mini-decimal@1.1.0:
|
|
||||||
resolution: {integrity: sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/motion@1.1.6(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-aEQobs/YA0kqRvHIPjQvOytdtdRVyhf/uXAal4chBjxDu6odHckExJzjn2D+Ju1aKK6hx3pAs6BXdV9+86xkgQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/motion@1.2.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-Vx+OL3I1l3HWflc1miXgjeFR9OnStKD8FOMLJCdby3I6HAOi8jo7of7iqF4hqvxQhoP31RTlNk+C+v5QjytAVg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/mutate-observer@2.0.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-AyarjoLU5YlxuValRi+w8JRH2Z84TBbFO2RoGWz9d8bSu0FqT8DtugH3xC3BV7mUwlmROFauyWuXFuq4IFbH+w==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/notification@1.2.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-OX3J+zVU7rvoJCikjrfW7qOUp7zlDeFBK2eA3SFbGSkDqo63Sl4Ss8A04kFP+fxHSxMDIS9jYVEZtU1FNCFuBA==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/overflow@1.0.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-GSlBeoE0XTBi5cf3zl8Qh7Uqhn7v8RrlJ8ajeVpEkNe94HWy5l5BQ0Mwn2TVUq9gdgbfEMUmTX7tJFAg7mz0Rw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/pagination@1.2.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-YcpUFE8dMLfSo6OARJlK6DbHHvrxz7pMGPGmC/caZSJJz6HRKHC1RPP001PRHCvG9Z/veD039uOQmazVuLJzlw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/picker@1.9.0(dayjs@1.11.19)(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-OLisdk8AWVCG9goBU1dWzuH5QlBQk8jktmQ6p0/IyBFwdKGwyIZOSjnBYo8hooHiTdl0lU+wGf/OfMtVBw02KQ==}
|
|
||||||
engines: {node: '>=12.x'}
|
|
||||||
peerDependencies:
|
|
||||||
date-fns: '>= 2.x'
|
|
||||||
dayjs: '>= 1.x'
|
|
||||||
luxon: '>= 3.x'
|
|
||||||
moment: '>= 2.x'
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
date-fns:
|
|
||||||
optional: true
|
|
||||||
dayjs:
|
|
||||||
optional: true
|
|
||||||
luxon:
|
|
||||||
optional: true
|
|
||||||
moment:
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/overflow': 1.0.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
dayjs: 1.11.19
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/portal@2.2.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-oc6FlA+uXCMiwArHsJyHcIkX4q6uKyndrPol2eWX8YPkAnztHOPsFIRtmWG4BMlGE5h7YIRE3NiaJ5VS8Lb1QQ==}
|
|
||||||
engines: {node: '>=12.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/progress@1.0.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-WZUnH9eGxH1+xodZKqdrHke59uyGZSWgj5HBM5Kwk5BrTMuAORO7VJ2IP5Qbm9aH3n9x3IcesqHHR0NWPBC7fQ==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/qrcode@1.1.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-LfLGNymzKdUPjXUbRP+xOhIWY4jQ+YMj5MmWAcgcAq1Ij8XP7tRmAXqyuv96XvLUBE/5cA8hLFl9eO1JQMujrA==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/rate@1.0.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-bkXxeBqDpl5IOC7yL7GcSYjQx9G8H+6kLYQnNZWeBYq2OYIv1MONd6mqKTjnnJYpV0cQIU2z3atdW0j1kttpTw==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/resize-observer@1.1.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-NfXXMmiR+SmUuKE1NwJESzEUYUFWIDUn2uXpxCTOLwiRUUakd62DRNFjRJArgzyFW8S5rsL4aX5XlyIXyC/vRA==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/segmented@1.3.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-5J/bJ01mbDnoA6P/FW8SxUvKn+OgUSTZJPzCNnTBntG50tzoP7DydGhqxp7ggZXZls7me3mc2EQDXakU3iTVFg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.0.0'
|
|
||||||
react-dom: '>=16.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/select@1.5.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-7wqD5D4I2+fc5XoB4nzDDK656QPlDnFAUaxLljkU1wwSpi4+MZxndv9vgg7NQfveuuf0/ilUdOjuPg7NPl7Mmg==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '*'
|
|
||||||
react-dom: '*'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/overflow': 1.0.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/virtual-list': 1.0.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/slider@1.0.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-uDhEPU1z3WDfCJhaL9jfd2ha/Eqpdfxsn0Zb0Xcq1NGQAman0TWaR37OWp2vVXEOdV2y0njSILTMpTfPV1454g==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/steps@1.2.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-/yVIZ00gDYYPHSY0JP+M+s3ZvuXLu2f9rEjQqiUDs7EcYsUYrpJ/1bLj9aI9R7MBR3fu/NGh6RM9u2qGfqp+Nw==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/switch@1.0.3(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-Jgi+EbOBquje/XNdofr7xbJQZPYJP+BlPfR0h+WN4zFkdtB2EWqEfvkXJWeipflwjWip0/17rNbxEAqs8hVHfw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/table@1.9.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-FVI5ZS/GdB3BcgexfCYKi3iHhZS3Fr59EtsxORszYGrfpH1eWr33eDNSYkVfLI6tfJ7vftJDd9D5apfFWqkdJg==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/context': 2.0.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/virtual-list': 1.0.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/tabs@1.7.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-J48cs2iBi7Ho3nptBxxIqizEliUC+ExE23faspUQKGQ550vaBlv3aGF8Epv/UB1vFWeoJDTW/dNzgIU0Qj5i/w==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/dropdown': 1.0.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/menu': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/textarea@1.1.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-9rMUEODWZDMovfScIEHXWlVZuPljZ2pd1LKNjslJVitn4SldEzq5vO1CL3yy3Dnib6zZal2r2DPtjy84VVpF6A==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/input': 1.1.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/tooltip@1.4.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-8Rx5DCctIlLI4raR0I0xHjVTf1aF48+gKCNeAAo5bmF5VoR5YED+A/XEqzXv9KKqrJDRcd3Wndpxh2hyzrTtSg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/tour@2.3.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-K04K9r32kUC+auBSQfr+Fss4SpSIS9JGe56oq/ALAX0p+i2ylYOI1MgR83yBY7v96eO6ZFXcM/igCQmubps0Ow==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/portal': 2.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/tree-select@1.6.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-UvEGmZT+gcVvRwImAZg3/sXw9nUdn4FmCs1rSIMWjEXEIAo0dTGmIyWuLCvs+1rGe9AZ7CHMPiQUEbdadwV0fw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '*'
|
|
||||||
react-dom: '*'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/select': 1.5.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/tree': 1.1.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/tree@1.1.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-HZs3aOlvFgQdgrmURRc/f4IujiNBf4DdEeXUlkS0lPoLlx9RoqsZcF0caXIAMVb+NaWqKtGQDnrH8hqLCN5zlA==}
|
|
||||||
engines: {node: '>=10.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '*'
|
|
||||||
react-dom: '*'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/virtual-list': 1.0.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/trigger@3.9.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-X8btpwfrT27AgrZVOz4swclhEHTZcqaHeQMXXBgveagOiakTa36uObXbdwerXffgV8G9dH1fAAE0DHtVQs8EHg==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/motion': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/portal': 2.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/upload@1.1.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-LIBV90mAnUE6VK5N4QvForoxZc4XqEYZimcp7fk+lkE4XwHHyJWxpIXQQwMU8hJM+YwBbsoZkGksL1sISWHQxw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/util@1.7.0(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-tIvIGj4Vl6fsZFvWSkYw9sAfiCKUXMyhVz6kpKyZbwyZyRPqv2vxYZROdaO1VB4gqTNvUZFXh6i3APUiterw5g==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
is-mobile: 5.0.0
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
react-is: 18.3.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/util@1.8.1(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-Ku6BzF0Ov5L9U3ewFJZDQ//iWCR2nIkLBBiYSrhxIVl3PqeUqiYP2W8gNI8qoKAFQKZdYcS0+B6+SQTDtv/erw==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
is-mobile: 5.0.0
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
react-is: 18.3.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rc-component/virtual-list@1.0.2(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-uvTol/mH74FYsn5loDGJxo+7kjkO4i+y4j87Re1pxJBs0FaeuMuLRzQRGaXwnMcV1CxpZLi2Z56Rerj2M00fjQ==}
|
|
||||||
engines: {node: '>=8.x'}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=16.9.0'
|
|
||||||
react-dom: '>=16.9.0'
|
|
||||||
dependencies:
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@rolldown/pluginutils@1.0.0-beta.53:
|
/@rolldown/pluginutils@1.0.0-beta.53:
|
||||||
resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==}
|
resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -3574,68 +2854,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
|
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
/antd@6.2.3(react-dom@19.2.3)(react@19.2.3):
|
|
||||||
resolution: {integrity: sha512-q92r7/hcQAR2iv6CCysdz7c2Pdl/3nhslc3azF9e6AEl4knO6v+nlaeor1oF2jBanZ/tiw2m3NprOVUgPDvyhg==}
|
|
||||||
peerDependencies:
|
|
||||||
react: '>=18.0.0'
|
|
||||||
react-dom: '>=18.0.0'
|
|
||||||
dependencies:
|
|
||||||
'@ant-design/colors': 8.0.1
|
|
||||||
'@ant-design/cssinjs': 2.0.3(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@ant-design/cssinjs-utils': 2.0.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@ant-design/fast-color': 3.0.1
|
|
||||||
'@ant-design/icons': 6.1.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@ant-design/react-slick': 2.0.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@babel/runtime': 7.28.4
|
|
||||||
'@rc-component/cascader': 1.11.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/checkbox': 1.0.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/collapse': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/color-picker': 3.0.3(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/dialog': 1.8.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/drawer': 1.4.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/dropdown': 1.0.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/form': 1.6.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/image': 1.6.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/input': 1.1.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/input-number': 1.6.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/mentions': 1.6.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/menu': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/motion': 1.1.6(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/mutate-observer': 2.0.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/notification': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/pagination': 1.2.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/picker': 1.9.0(dayjs@1.11.19)(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/progress': 1.0.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/qrcode': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/rate': 1.0.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/resize-observer': 1.1.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/segmented': 1.3.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/select': 1.5.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/slider': 1.0.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/steps': 1.2.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/switch': 1.0.3(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/table': 1.9.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/tabs': 1.7.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/textarea': 1.1.2(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/tooltip': 1.4.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/tour': 2.3.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/tree': 1.1.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/tree-select': 1.6.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/trigger': 3.9.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/upload': 1.1.0(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
'@rc-component/util': 1.8.1(react-dom@19.2.3)(react@19.2.3)
|
|
||||||
clsx: 2.1.1
|
|
||||||
dayjs: 1.11.19
|
|
||||||
react: 19.2.3
|
|
||||||
react-dom: 19.2.3(react@19.2.3)
|
|
||||||
scroll-into-view-if-needed: 3.1.0
|
|
||||||
throttle-debounce: 5.0.2
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- date-fns
|
|
||||||
- luxon
|
|
||||||
- moment
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/arch@2.2.0:
|
/arch@2.2.0:
|
||||||
resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==}
|
resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -3979,11 +3197,6 @@ packages:
|
|||||||
is-wsl: 2.2.0
|
is-wsl: 2.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/clsx@2.1.1:
|
|
||||||
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
|
|
||||||
engines: {node: '>=6'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color-convert@2.0.1:
|
/color-convert@2.0.1:
|
||||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||||
engines: {node: '>=7.0.0'}
|
engines: {node: '>=7.0.0'}
|
||||||
@@ -4015,10 +3228,6 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/compute-scroll-into-view@3.1.1:
|
|
||||||
resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/concat-map@0.0.1:
|
/concat-map@0.0.1:
|
||||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||||
|
|
||||||
@@ -4059,6 +3268,7 @@ packages:
|
|||||||
|
|
||||||
/csstype@3.2.3:
|
/csstype@3.2.3:
|
||||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/damerau-levenshtein@1.0.8:
|
/damerau-levenshtein@1.0.8:
|
||||||
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
||||||
@@ -5505,10 +4715,6 @@ packages:
|
|||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/is-mobile@5.0.0:
|
|
||||||
resolution: {integrity: sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-negative-zero@2.0.3:
|
/is-negative-zero@2.0.3:
|
||||||
resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
|
resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -5702,12 +4908,6 @@ packages:
|
|||||||
/json-stable-stringify-without-jsonify@1.0.1:
|
/json-stable-stringify-without-jsonify@1.0.1:
|
||||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||||
|
|
||||||
/json2mq@0.2.0:
|
|
||||||
resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==}
|
|
||||||
dependencies:
|
|
||||||
string-convert: 0.2.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/json5@1.0.2:
|
/json5@1.0.2:
|
||||||
resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
|
resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -6880,10 +6080,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/react-is@18.3.1:
|
|
||||||
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/react-refresh@0.18.0:
|
/react-refresh@0.18.0:
|
||||||
resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
|
resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -7213,12 +6409,6 @@ packages:
|
|||||||
/scheduler@0.27.0:
|
/scheduler@0.27.0:
|
||||||
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
|
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
|
||||||
|
|
||||||
/scroll-into-view-if-needed@3.1.0:
|
|
||||||
resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==}
|
|
||||||
dependencies:
|
|
||||||
compute-scroll-into-view: 3.1.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/semver@5.7.2:
|
/semver@5.7.2:
|
||||||
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
|
resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@@ -7452,10 +6642,6 @@ packages:
|
|||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/string-convert@0.2.1:
|
|
||||||
resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/string-width@4.2.3:
|
/string-width@4.2.3:
|
||||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -7603,10 +6789,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
/stylis@4.3.6:
|
|
||||||
resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/supports-color@7.2.0:
|
/supports-color@7.2.0:
|
||||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -7659,11 +6841,6 @@ packages:
|
|||||||
/text-table@0.2.0:
|
/text-table@0.2.0:
|
||||||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
||||||
|
|
||||||
/throttle-debounce@5.0.2:
|
|
||||||
resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==}
|
|
||||||
engines: {node: '>=12.22'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/tiny-invariant@1.3.3:
|
/tiny-invariant@1.3.3:
|
||||||
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
|
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|||||||
Reference in New Issue
Block a user