feat: Refactor example page and showcase components
- Updated ExamplePage to use a single Showcase component instead of separate InputShowCase and FormShowcase components. - Added CheckboxShowcase, FormShowcase, and InputShowCase components to the showcase directory. - Implemented Checkbox component with various states and styles. - Enhanced InputShowCase to demonstrate different input types and states. - Integrated new styles for checkbox variants and states. - Updated package dependencies to include @rc-component/checkbox.
This commit is contained in:
@@ -1,11 +1,9 @@
|
|||||||
import FormShowcase from './form-showcase/form-showcase';
|
import Showcase from './showcase/showcase';
|
||||||
import InputShowCase from './input-showcase';
|
|
||||||
|
|
||||||
export default function ExamplePage() {
|
export default function ExamplePage() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<InputShowCase />
|
<Showcase />
|
||||||
<FormShowcase />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
import { Checkbox, InputStatusType } from '@repo/ui';
|
||||||
|
|
||||||
|
interface CheckboxShowcaseProps {
|
||||||
|
status?: InputStatusType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CheckboxShowcase({ status: overrideStatus }: CheckboxShowcaseProps) {
|
||||||
|
/**
|
||||||
|
* Helper untuk menentukan status.
|
||||||
|
* Jika overrideStatus diberikan (dari props pemanggil), maka gunakan itu.
|
||||||
|
* Jika tidak, gunakan status lokal yang didefinisikan di matrix.
|
||||||
|
*/
|
||||||
|
const resolveStatus = (localStatus: InputStatusType): InputStatusType => {
|
||||||
|
return overrideStatus && overrideStatus !== 'default' ? overrideStatus : localStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-12">
|
||||||
|
{/* 1. VARIANT COMPARISON */}
|
||||||
|
<section>
|
||||||
|
<div className="mb-4">
|
||||||
|
<h2 className="text-lg font-bold text-gray-800">Checkbox Variants</h2>
|
||||||
|
<p className="text-sm text-gray-500">Dua tipe visual utama: Outlined (default) dan Filled.</p>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div className="p-4 border border-gray-100 rounded-xl bg-gray-50/50">
|
||||||
|
<span className="block mb-3 text-xs font-bold text-gray-400 uppercase">Outlined (Default)</span>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<Checkbox status={overrideStatus} label="Standard" defaultChecked />
|
||||||
|
<Checkbox status={overrideStatus} label="Unchecked" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="p-4 border border-gray-100 rounded-xl bg-gray-50/50">
|
||||||
|
<span className="block mb-3 text-xs font-bold text-gray-400 uppercase">Filled</span>
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<Checkbox variant="filled" status={overrideStatus} label="Standard" defaultChecked />
|
||||||
|
<Checkbox variant="filled" status={overrideStatus} label="Unchecked" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 2. STATUS MATRIX (OVERRIDABLE) */}
|
||||||
|
<section>
|
||||||
|
<div className="mb-4">
|
||||||
|
<h2 className="text-lg font-bold text-gray-800">Status Matrix</h2>
|
||||||
|
<p className="text-sm text-gray-500">
|
||||||
|
Warna akan berubah otomatis berdasarkan status (Error, Warning, Success, Info).
|
||||||
|
{overrideStatus && (
|
||||||
|
<span className="text-brand-600 font-medium"> [Overridden by Prop: {overrideStatus}]</span>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 gap-6">
|
||||||
|
{/* Outlined Status */}
|
||||||
|
<div className="flex flex-wrap gap-6 p-6 border border-gray-200 rounded-xl">
|
||||||
|
<Checkbox status={resolveStatus('default')} label={resolveStatus('default')} defaultChecked />
|
||||||
|
<Checkbox status={resolveStatus('error')} label={resolveStatus('error')} defaultChecked />
|
||||||
|
<Checkbox status={resolveStatus('warning')} label={resolveStatus('warning')} defaultChecked />
|
||||||
|
<Checkbox status={resolveStatus('success')} label={resolveStatus('success')} defaultChecked />
|
||||||
|
<Checkbox status={resolveStatus('info')} label={resolveStatus('info')} defaultChecked />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Filled Status */}
|
||||||
|
<div className="flex flex-wrap gap-6 p-6 bg-gray-50 border border-gray-200 rounded-xl">
|
||||||
|
<Checkbox
|
||||||
|
variant="filled"
|
||||||
|
status={resolveStatus('default')}
|
||||||
|
label={`${resolveStatus('default')} Filled`}
|
||||||
|
defaultChecked
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
variant="filled"
|
||||||
|
status={resolveStatus('error')}
|
||||||
|
label={`${resolveStatus('error')} Filled`}
|
||||||
|
defaultChecked
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
variant="filled"
|
||||||
|
status={resolveStatus('warning')}
|
||||||
|
label={`${resolveStatus('warning')} Filled`}
|
||||||
|
defaultChecked
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
variant="filled"
|
||||||
|
status={resolveStatus('success')}
|
||||||
|
label={`${resolveStatus('success')} Filled`}
|
||||||
|
defaultChecked
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
variant="filled"
|
||||||
|
status={resolveStatus('info')}
|
||||||
|
label={`${resolveStatus('info')} Filled`}
|
||||||
|
defaultChecked
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* 3. CONTENT & LAYOUT FEATURES */}
|
||||||
|
<section>
|
||||||
|
<div className="mb-4">
|
||||||
|
<h2 className="text-lg font-bold text-gray-800">Rich Content & States</h2>
|
||||||
|
<p className="text-sm text-gray-500">
|
||||||
|
Mendukung konten kompleks di dalam label dan berbagai state interaksi.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
{/* Column A: Complex Labels */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<span className="text-xs font-bold text-gray-400 uppercase">Label Variations</span>
|
||||||
|
<Checkbox status={overrideStatus}>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<span className="font-medium text-gray-900 leading-tight">Terms of Service</span>
|
||||||
|
<span className="text-xs text-gray-500 mt-1">I have read and agree to the privacy policy.</span>
|
||||||
|
</div>
|
||||||
|
</Checkbox>
|
||||||
|
<Checkbox status={overrideStatus} label={<strong>Bold Label Text</strong>} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Column B: Interactive States */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<span className="text-xs font-bold text-gray-400 uppercase">Disabled States</span>
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<Checkbox disabled label="Disabled Unchecked" />
|
||||||
|
<Checkbox disabled defaultChecked label="Disabled Checked" />
|
||||||
|
<Checkbox disabled variant="filled" label="Disabled Filled" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Column C: Edge Cases */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<span className="text-xs font-bold text-gray-400 uppercase">Layout Config</span>
|
||||||
|
<div className="flex items-center gap-6">
|
||||||
|
<Checkbox status={overrideStatus} />
|
||||||
|
<span className="text-xs text-gray-400 italic font-mono bg-gray-100 px-2 py-1 rounded">
|
||||||
|
No Label Prop
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Checkbox status={overrideStatus}>
|
||||||
|
<span className="flex items-center gap-2 text-brand-600 font-semibold">
|
||||||
|
<span className="w-2 h-2 rounded-full bg-brand-500 animate-pulse" />
|
||||||
|
Live Children Label
|
||||||
|
</span>
|
||||||
|
</Checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
import { Form, Input, InputPassword } from '@repo/ui';
|
import { Form, Input, InputPassword } from '@repo/ui';
|
||||||
import React from 'react';
|
|
||||||
// --- 2. Main Showcase Component ---
|
// --- 2. Main Showcase Component ---
|
||||||
export default function FormShowcase() {
|
export default function FormShowcase() {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
+2
-2
@@ -8,9 +8,9 @@ const Label = ({ children }: { children: React.ReactNode }) => (
|
|||||||
// Helper untuk prefix/suffix visual
|
// Helper untuk prefix/suffix visual
|
||||||
const Fix = ({ children }: { children: React.ReactNode }) => <span className="text-gray-400 text-sm">{children}</span>;
|
const Fix = ({ children }: { children: React.ReactNode }) => <span className="text-gray-400 text-sm">{children}</span>;
|
||||||
|
|
||||||
export default function GroupComponent({ status }: { status?: InputStatusType }) {
|
export default function InputShowCase({ status }: { status?: InputStatusType }) {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-12 p-8 rounded-2xl">
|
<div className="p-8 rounded-2xl">
|
||||||
{/* --- SECTION 1: OUTLINED VARIANT (DEFAULT) --- */}
|
{/* --- SECTION 1: OUTLINED VARIANT (DEFAULT) --- */}
|
||||||
<section className="space-y-6">
|
<section className="space-y-6">
|
||||||
<h2 className="text-lg font-bold text-gray-800 border-b pb-2">Outlined Variant (Standard)</h2>
|
<h2 className="text-lg font-bold text-gray-800 border-b pb-2">Outlined Variant (Standard)</h2>
|
||||||
+9
-5
@@ -1,13 +1,14 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import GroupComponent from './group-component';
|
|
||||||
import { InputStatusType } from '@repo/ui';
|
import { InputStatusType } from '@repo/ui';
|
||||||
|
import CheckboxShowcase from './components/checkbox.showcase';
|
||||||
|
import InputShowCase from './components/input.showcase';
|
||||||
|
|
||||||
export default function InputShowCase() {
|
export default function Showcase() {
|
||||||
// State untuk menyimpan status yang dipilih
|
// State untuk menyimpan status yang dipilih
|
||||||
const [selectedStatus, setSelectedStatus] = useState<InputStatusType>('normal');
|
const [selectedStatus, setSelectedStatus] = useState<InputStatusType>('default');
|
||||||
|
|
||||||
const statuses: { label: string; value: InputStatusType; color: string }[] = [
|
const statuses: { label: string; value: InputStatusType; color: string }[] = [
|
||||||
{ label: 'Normal', value: 'normal', color: 'bg-gray-500' },
|
{ label: 'Default', value: 'default', color: 'bg-gray-500' },
|
||||||
{ label: 'Error', value: 'error', color: 'bg-red-500' },
|
{ label: 'Error', value: 'error', color: 'bg-red-500' },
|
||||||
{ label: 'Warning', value: 'warning', color: 'bg-amber-500' },
|
{ label: 'Warning', value: 'warning', color: 'bg-amber-500' },
|
||||||
{ label: 'Success', value: 'success', color: 'bg-emerald-500' },
|
{ label: 'Success', value: 'success', color: 'bg-emerald-500' },
|
||||||
@@ -63,7 +64,10 @@ export default function InputShowCase() {
|
|||||||
Active Status: <span className="text-blue-600">{selectedStatus}</span>
|
Active Status: <span className="text-blue-600">{selectedStatus}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<GroupComponent status={selectedStatus} />
|
<div className="space-y-12 ">
|
||||||
|
<CheckboxShowcase status={selectedStatus} />
|
||||||
|
<InputShowCase status={selectedStatus} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
"test:watch": "vitest --watch"
|
"test:watch": "vitest --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@rc-component/checkbox": "^1.0.1",
|
||||||
"@rc-component/form": "^1.6.2",
|
"@rc-component/form": "^1.6.2",
|
||||||
"@rc-component/input": "^1.1.2",
|
"@rc-component/input": "^1.1.2",
|
||||||
"@rc-component/input-number": "^1.6.2",
|
"@rc-component/input-number": "^1.6.2",
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import RcCheckbox from '@rc-component/checkbox';
|
||||||
|
import { CheckboxProps } from '../types';
|
||||||
|
import { forwardRef } from 'react';
|
||||||
|
import { InputRef } from '@rc-component/input/lib/interface';
|
||||||
|
|
||||||
|
export const Checkbox = forwardRef<InputRef, CheckboxProps>((props, ref) => {
|
||||||
|
const { label, status = 'default', variant = 'outlined', className, children, ...rest } = props;
|
||||||
|
|
||||||
|
const displayLabel = label || children;
|
||||||
|
|
||||||
|
const wrapperClass = [
|
||||||
|
'rc-checkbox-wrapper',
|
||||||
|
`checkbox-status-${status}`,
|
||||||
|
`checkbox-variant-${variant}`,
|
||||||
|
rest.disabled ? 'rc-checkbox-wrapper-disabled' : '',
|
||||||
|
className,
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<label className={wrapperClass}>
|
||||||
|
<span className="rc-checkbox-container">
|
||||||
|
<RcCheckbox {...rest} prefixCls="rc-checkbox" />
|
||||||
|
{/* HAPUS BARIS DI BAWAH INI */}
|
||||||
|
{/* <span className="rc-checkbox-inner" /> */}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{displayLabel && <span className="rc-checkbox-label-text">{displayLabel}</span>}
|
||||||
|
</label>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Checkbox.displayName = 'Checkbox';
|
||||||
@@ -7,3 +7,4 @@ export * from './input/input-currency.component';
|
|||||||
export * from './input/input-number.component';
|
export * from './input/input-number.component';
|
||||||
|
|
||||||
export * from './textarea/textarea.component';
|
export * from './textarea/textarea.component';
|
||||||
|
export * from './checkbox/checkbox.component';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { forwardRef } from 'react';
|
import { forwardRef } from 'react';
|
||||||
import RcInput, { InputRef, InputProps as RcInputProps } from '@rc-component/input';
|
import RcInput, { InputRef } from '@rc-component/input';
|
||||||
import { InputProps, InputStatusType, VALID_INPUT_STATUSES } from '../types';
|
import { InputProps, InputStatusType, VALID_INPUT_STATUSES } from '../types';
|
||||||
|
|
||||||
export const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
export const Input = forwardRef<InputRef, InputProps>((props, ref) => {
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
@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; /* Jarak antara kotak dan teks */
|
||||||
|
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; /* Optikal alignment */
|
||||||
|
}
|
||||||
|
|
||||||
|
.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: 16px; /* Sedikit diperbesar dari 14px agar proporsional dengan font 13px */
|
||||||
|
height: 16px;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-radius: var(--radius-sm); /* Konsisten dengan shape global */
|
||||||
|
border-color: var(--input-border);
|
||||||
|
background-color: var(--input-bg);
|
||||||
|
/* Menggunakan durasi transisi standar kita 0.2s */
|
||||||
|
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checkmark (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 untuk 16px box */
|
||||||
|
left: 4.5px;
|
||||||
|
top: 1.5px;
|
||||||
|
width: 5px;
|
||||||
|
height: 9px;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================================
|
||||||
|
VARIANT: FILLED
|
||||||
|
========================================= */
|
||||||
|
|
||||||
|
/* --- Default Filled --- */
|
||||||
|
.checkbox-variant-filled .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-gray-50);
|
||||||
|
border-color: var(--input-border); /* Sedikit border agar tetap terlihat di bg putih */
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled:hover .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-gray-100);
|
||||||
|
border-color: var(--input-border-hover);
|
||||||
|
}
|
||||||
|
/* Saat checked, filled beralih ke warna solid brand */
|
||||||
|
.checkbox-variant-filled.checkbox-status-default .rc-checkbox-checked .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-brand-500);
|
||||||
|
border-color: var(--color-brand-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Error Filled --- */
|
||||||
|
.checkbox-variant-filled.checkbox-status-error .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-error-50);
|
||||||
|
border-color: var(--color-error-300);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-error:hover .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-error-100);
|
||||||
|
border-color: var(--color-error-500);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-error .rc-checkbox-checked .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-error-500);
|
||||||
|
border-color: var(--color-error-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Warning Filled --- */
|
||||||
|
.checkbox-variant-filled.checkbox-status-warning .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-warning-50);
|
||||||
|
border-color: var(--color-warning-300);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-warning:hover .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-warning-100);
|
||||||
|
border-color: var(--color-warning-500);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-warning .rc-checkbox-checked .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-warning-500);
|
||||||
|
border-color: var(--color-warning-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Success Filled --- */
|
||||||
|
.checkbox-variant-filled.checkbox-status-success .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-success-50);
|
||||||
|
border-color: var(--color-success-300);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-success:hover .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-success-100);
|
||||||
|
border-color: var(--color-success-500);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-success .rc-checkbox-checked .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-success-500);
|
||||||
|
border-color: var(--color-success-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Info Filled --- */
|
||||||
|
.checkbox-variant-filled.checkbox-status-info .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-info-50);
|
||||||
|
border-color: var(--color-info-300);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-info:hover .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-info-100);
|
||||||
|
border-color: var(--color-info-500);
|
||||||
|
}
|
||||||
|
.checkbox-variant-filled.checkbox-status-info .rc-checkbox-checked .rc-checkbox-inner {
|
||||||
|
background-color: var(--color-info-500);
|
||||||
|
border-color: var(--color-info-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Logic Focus untuk Filled (tetap konsisten dengan ring status) */
|
||||||
|
.checkbox-variant-filled .rc-checkbox-input:focus-visible + .rc-checkbox-inner {
|
||||||
|
/* Box shadow akan mengikuti warna status masing-masing dari block STATUS MATRIX di atas */
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================================
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,3 +2,4 @@
|
|||||||
@import './input.style.css';
|
@import './input.style.css';
|
||||||
@import './input-number.style.css';
|
@import './input-number.style.css';
|
||||||
@import './textarea.style.css';
|
@import './textarea.style.css';
|
||||||
|
@import './checkbox.style.css';
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { InputProps as RcInputProps } from '@rc-component/input';
|
|||||||
import { TextAreaProps as RcTextAreaProps } from '@rc-component/textarea';
|
import { TextAreaProps as RcTextAreaProps } from '@rc-component/textarea';
|
||||||
import { InputNumberProps as RcInputNumberProps } from '@rc-component/input-number';
|
import { InputNumberProps as RcInputNumberProps } from '@rc-component/input-number';
|
||||||
|
|
||||||
|
import { CheckboxProps as RcCheckboxProps } from '@rc-component/checkbox';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define possible input statuses
|
* Define possible input statuses
|
||||||
*/
|
*/
|
||||||
@@ -35,7 +37,7 @@ export interface FormItemProps {
|
|||||||
/**
|
/**
|
||||||
* Define base component props
|
* Define base component props
|
||||||
*/
|
*/
|
||||||
interface BaseComponentProps {
|
interface BaseFormItemComponentProps {
|
||||||
status?: InputStatusType;
|
status?: InputStatusType;
|
||||||
variant?: 'outlined' | 'filled';
|
variant?: 'outlined' | 'filled';
|
||||||
}
|
}
|
||||||
@@ -43,7 +45,7 @@ interface BaseComponentProps {
|
|||||||
/**
|
/**
|
||||||
* Define specific component props
|
* Define specific component props
|
||||||
*/
|
*/
|
||||||
export interface InputProps extends RcInputProps, BaseComponentProps {}
|
export interface InputProps extends RcInputProps, BaseFormItemComponentProps {}
|
||||||
export interface InputPasswordProps extends InputProps {
|
export interface InputPasswordProps extends InputProps {
|
||||||
visibilityToggle?: boolean; // Default: true
|
visibilityToggle?: boolean; // Default: true
|
||||||
}
|
}
|
||||||
@@ -51,8 +53,8 @@ export interface InputPasswordProps extends InputProps {
|
|||||||
/**
|
/**
|
||||||
* Define InputNumber and InputCurrency props
|
* Define InputNumber and InputCurrency props
|
||||||
*/
|
*/
|
||||||
export interface InputNumberProps extends RcInputNumberProps, BaseComponentProps {}
|
export interface InputNumberProps extends RcInputNumberProps, BaseFormItemComponentProps {}
|
||||||
export interface InputCurrencyProps extends InputNumberProps, BaseComponentProps {
|
export interface InputCurrencyProps extends InputNumberProps, BaseFormItemComponentProps {
|
||||||
prefix?: string; // Optional: Custom prefix, default 'Rp '
|
prefix?: string; // Optional: Custom prefix, default 'Rp '
|
||||||
decimalSeparator?: ',' | '.';
|
decimalSeparator?: ',' | '.';
|
||||||
decimalScale?: number; // optional
|
decimalScale?: number; // optional
|
||||||
@@ -61,4 +63,11 @@ export interface InputCurrencyProps extends InputNumberProps, BaseComponentProps
|
|||||||
/**
|
/**
|
||||||
* Define TextArea props
|
* Define TextArea props
|
||||||
*/
|
*/
|
||||||
export interface TextAreaProps extends RcTextAreaProps, BaseComponentProps {}
|
export interface TextAreaProps extends RcTextAreaProps, BaseFormItemComponentProps {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define Checkbox props
|
||||||
|
*/
|
||||||
|
export interface CheckboxProps extends RcCheckboxProps, BaseFormItemComponentProps {
|
||||||
|
label?: ReactNode;
|
||||||
|
}
|
||||||
|
|||||||
@@ -62,26 +62,57 @@
|
|||||||
--color-gray-800: #1f2937;
|
--color-gray-800: #1f2937;
|
||||||
--color-gray-900: #111827;
|
--color-gray-900: #111827;
|
||||||
|
|
||||||
/* Semantics */
|
/* -------------------------------
|
||||||
|
COLORS: SEMANTICS (COMPLETED)
|
||||||
|
------------------------------- */
|
||||||
|
|
||||||
|
/* Error (Red) */
|
||||||
--color-error-50: #fef2f2;
|
--color-error-50: #fef2f2;
|
||||||
--color-error-100: #fee2e2;
|
--color-error-100: #fee2e2;
|
||||||
|
--color-error-200: #fecaca;
|
||||||
|
--color-error-300: #fca5a5;
|
||||||
|
--color-error-400: #f87171;
|
||||||
--color-error-500: #ef4444;
|
--color-error-500: #ef4444;
|
||||||
--color-error-600: #dc2626;
|
--color-error-600: #dc2626;
|
||||||
|
--color-error-700: #b91c1c;
|
||||||
|
--color-error-800: #991b1b;
|
||||||
|
--color-error-900: #7f1d1d;
|
||||||
|
|
||||||
|
/* Warning (Amber/Orange) */
|
||||||
--color-warning-50: #fffbeb;
|
--color-warning-50: #fffbeb;
|
||||||
--color-warning-100: #fef3c7;
|
--color-warning-100: #fef3c7;
|
||||||
|
--color-warning-200: #fde68a;
|
||||||
|
--color-warning-300: #fcd34d;
|
||||||
|
--color-warning-400: #fbbf24;
|
||||||
--color-warning-500: #f59e0b;
|
--color-warning-500: #f59e0b;
|
||||||
--color-warning-600: #d97706;
|
--color-warning-600: #d97706;
|
||||||
|
--color-warning-700: #b45309;
|
||||||
|
--color-warning-800: #92400e;
|
||||||
|
--color-warning-900: #78350f;
|
||||||
|
|
||||||
|
/* Success (Green) */
|
||||||
--color-success-50: #f0fdf4;
|
--color-success-50: #f0fdf4;
|
||||||
--color-success-100: #dcfce7;
|
--color-success-100: #dcfce7;
|
||||||
|
--color-success-200: #bbf7d0;
|
||||||
|
--color-success-300: #86efac;
|
||||||
|
--color-success-400: #4ade80;
|
||||||
--color-success-500: #22c55e;
|
--color-success-500: #22c55e;
|
||||||
--color-success-600: #16a34a;
|
--color-success-600: #16a34a;
|
||||||
|
--color-success-700: #15803d;
|
||||||
|
--color-success-800: #166534;
|
||||||
|
--color-success-900: #14532d;
|
||||||
|
|
||||||
|
/* Info (Blue/Sky) */
|
||||||
--color-info-50: #f0f9ff;
|
--color-info-50: #f0f9ff;
|
||||||
--color-info-100: #e0f2fe;
|
--color-info-100: #e0f2fe;
|
||||||
|
--color-info-200: #bae6fd;
|
||||||
|
--color-info-300: #7dd3fc;
|
||||||
|
--color-info-400: #38bdf8;
|
||||||
--color-info-500: #0ea5e9;
|
--color-info-500: #0ea5e9;
|
||||||
--color-info-600: #0284c7;
|
--color-info-600: #0284c7;
|
||||||
|
--color-info-700: #0369a1;
|
||||||
|
--color-info-800: #075985;
|
||||||
|
--color-info-900: #0c4a6e;
|
||||||
|
|
||||||
/* -------------------------------
|
/* -------------------------------
|
||||||
FORM ITEM SPECIFICS
|
FORM ITEM SPECIFICS
|
||||||
|
|||||||
Generated
+15
@@ -158,6 +158,9 @@ importers:
|
|||||||
|
|
||||||
packages/ui:
|
packages/ui:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@rc-component/checkbox':
|
||||||
|
specifier: ^1.0.1
|
||||||
|
version: 1.0.1(react-dom@19.2.3)(react@19.2.3)
|
||||||
'@rc-component/form':
|
'@rc-component/form':
|
||||||
specifier: ^1.6.2
|
specifier: ^1.6.2
|
||||||
version: 1.6.2(react-dom@19.2.3)(react@19.2.3)
|
version: 1.6.2(react-dom@19.2.3)(react@19.2.3)
|
||||||
@@ -1145,6 +1148,18 @@ packages:
|
|||||||
'@babel/runtime': 7.28.4
|
'@babel/runtime': 7.28.4
|
||||||
dev: false
|
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/form@1.6.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):
|
||||||
resolution: {integrity: sha512-OgIn2RAoaSBqaIgzJf/X6iflIa9LpTozci1lagLBdURDFhGA370v0+T0tXxOi8YShMjTha531sFhwtnrv+EJaQ==}
|
resolution: {integrity: sha512-OgIn2RAoaSBqaIgzJf/X6iflIa9LpTozci1lagLBdURDFhGA370v0+T0tXxOi8YShMjTha531sFhwtnrv+EJaQ==}
|
||||||
engines: {node: '>=8.x'}
|
engines: {node: '>=8.x'}
|
||||||
|
|||||||
Reference in New Issue
Block a user