From 24e0d2ca6136d3e03c2ac86af0edceb1a1fc4c2b Mon Sep 17 00:00:00 2001 From: Firman Ramdhani <33869609+firmanramdhani@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:08:12 +0700 Subject: [PATCH] chore: Delete various UI components, form elements, and associated example/showcase pages from the UI package and web app. --- .../src/apps/modules/example/example.page.tsx | 8 +- .../showcase/components/checkbox.showcase.tsx | 117 --- .../components/date-picker.showcase.tsx | 208 ----- .../showcase/components/form.showcase.tsx | 74 -- .../showcase/components/input.showcase.tsx | 129 --- .../showcase/components/switch.showcase.tsx | 219 ----- .../modules/example/showcase/showcase.tsx | 80 -- apps/web/src/apps/modules/index.tsx | 5 - packages/ui/package.json | 10 - packages/ui/src/components/button/button.tsx | 15 - .../components/examples/counter-example.tsx | 17 - .../src/components/examples/date-example.tsx | 337 ------- .../examples/encryption-example.tsx | 179 ---- .../components/examples/header-example.tsx | 13 - .../src/components/examples/style-guide-1.tsx | 208 ----- .../src/components/examples/style-guide-2.tsx | 257 ------ .../src/components/examples/style-guide-3.tsx | 232 ----- .../forms/checkbox/checkbox.component.tsx | 51 -- .../form-provider/form-control.component.tsx | 14 - .../form-provider/form-item.component.tsx | 81 -- .../components/forms/form-provider/index.tsx | 42 - packages/ui/src/components/forms/index.ts | 12 - .../forms/input/input-currency.component.tsx | 56 -- .../forms/input/input-number.component.tsx | 65 -- .../forms/input/input-password.component.tsx | 101 --- .../forms/input/input.component.tsx | 41 - .../picker/generate-picker.component.tsx | 190 ---- .../ui/src/components/forms/picker/index.tsx | 24 - .../forms/styles/checkbox.style.css | 213 ----- .../forms/styles/form-item.style.css | 61 -- .../components/forms/styles/form.style.css | 7 - .../forms/styles/input-number.style.css | 264 ------ .../components/forms/styles/input.style.css | 236 ----- .../forms/styles/picker.style copy.css | 647 -------------- .../components/forms/styles/picker.style.css | 746 ---------------- .../components/forms/styles/switch.style.css | 398 --------- .../forms/styles/textarea.style.css | 192 ---- .../forms/switch/switch.component.tsx | 62 -- .../forms/textarea/textarea.component.tsx | 36 - .../ui/src/components/forms/types/index.ts | 105 --- packages/ui/src/components/index.ts | 12 - packages/ui/src/index.ts | 3 - packages/ui/src/providers/ui-provider.tsx | 10 - packages/ui/src/utils/cn.ts | 11 - pnpm-lock.yaml | 827 +----------------- 45 files changed, 3 insertions(+), 6612 deletions(-) delete mode 100644 apps/web/src/apps/modules/example/showcase/components/checkbox.showcase.tsx delete mode 100644 apps/web/src/apps/modules/example/showcase/components/date-picker.showcase.tsx delete mode 100644 apps/web/src/apps/modules/example/showcase/components/form.showcase.tsx delete mode 100644 apps/web/src/apps/modules/example/showcase/components/input.showcase.tsx delete mode 100644 apps/web/src/apps/modules/example/showcase/components/switch.showcase.tsx delete mode 100644 apps/web/src/apps/modules/example/showcase/showcase.tsx delete mode 100644 packages/ui/src/components/button/button.tsx delete mode 100644 packages/ui/src/components/examples/counter-example.tsx delete mode 100644 packages/ui/src/components/examples/date-example.tsx delete mode 100644 packages/ui/src/components/examples/encryption-example.tsx delete mode 100644 packages/ui/src/components/examples/header-example.tsx delete mode 100644 packages/ui/src/components/examples/style-guide-1.tsx delete mode 100644 packages/ui/src/components/examples/style-guide-2.tsx delete mode 100644 packages/ui/src/components/examples/style-guide-3.tsx delete mode 100644 packages/ui/src/components/forms/checkbox/checkbox.component.tsx delete mode 100644 packages/ui/src/components/forms/form-provider/form-control.component.tsx delete mode 100644 packages/ui/src/components/forms/form-provider/form-item.component.tsx delete mode 100644 packages/ui/src/components/forms/form-provider/index.tsx delete mode 100644 packages/ui/src/components/forms/index.ts delete mode 100644 packages/ui/src/components/forms/input/input-currency.component.tsx delete mode 100644 packages/ui/src/components/forms/input/input-number.component.tsx delete mode 100644 packages/ui/src/components/forms/input/input-password.component.tsx delete mode 100644 packages/ui/src/components/forms/input/input.component.tsx delete mode 100644 packages/ui/src/components/forms/picker/generate-picker.component.tsx delete mode 100644 packages/ui/src/components/forms/picker/index.tsx delete mode 100644 packages/ui/src/components/forms/styles/checkbox.style.css delete mode 100644 packages/ui/src/components/forms/styles/form-item.style.css delete mode 100644 packages/ui/src/components/forms/styles/form.style.css delete mode 100644 packages/ui/src/components/forms/styles/input-number.style.css delete mode 100644 packages/ui/src/components/forms/styles/input.style.css delete mode 100644 packages/ui/src/components/forms/styles/picker.style copy.css delete mode 100644 packages/ui/src/components/forms/styles/picker.style.css delete mode 100644 packages/ui/src/components/forms/styles/switch.style.css delete mode 100644 packages/ui/src/components/forms/styles/textarea.style.css delete mode 100644 packages/ui/src/components/forms/switch/switch.component.tsx delete mode 100644 packages/ui/src/components/forms/textarea/textarea.component.tsx delete mode 100644 packages/ui/src/components/forms/types/index.ts delete mode 100644 packages/ui/src/providers/ui-provider.tsx delete mode 100644 packages/ui/src/utils/cn.ts diff --git a/apps/web/src/apps/modules/example/example.page.tsx b/apps/web/src/apps/modules/example/example.page.tsx index eff47fa..452de27 100644 --- a/apps/web/src/apps/modules/example/example.page.tsx +++ b/apps/web/src/apps/modules/example/example.page.tsx @@ -1,9 +1,3 @@ -import Showcase from './showcase/showcase'; - export default function ExamplePage() { - return ( -
- -
- ); + return
; } diff --git a/apps/web/src/apps/modules/example/showcase/components/checkbox.showcase.tsx b/apps/web/src/apps/modules/example/showcase/components/checkbox.showcase.tsx deleted file mode 100644 index 2439f6c..0000000 --- a/apps/web/src/apps/modules/example/showcase/components/checkbox.showcase.tsx +++ /dev/null @@ -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 ( -
- {/* 1. VARIANT COMPARISON */} -
-
-

Checkbox Variants

-

Dua tipe visual utama: Outlined (default) dan Filled.

-
-
-
- Outlined (Default) -
- - -
-
-
- Filled -
- - -
-
-
-
- - {/* 2. STATUS MATRIX (OVERRIDABLE) */} -
-
-

Status Matrix

-

- Warna akan berubah otomatis berdasarkan status (Error, Warning, Success, Info). - {overrideStatus && ( - [Overridden by Prop: {overrideStatus}] - )} -

-
-
- {/* Outlined Status */} -
- - - - - -
-
-
- - {/* 3. CONTENT & LAYOUT FEATURES */} -
-
-

Rich Content & States

-

- Mendukung konten kompleks di dalam label dan berbagai state interaksi. -

-
-
- {/* Column A: Complex Labels */} -
- Label Variations - -
- Terms of Service - I have read and agree to the privacy policy. -
-
- Bold Label Text} /> -
- - {/* Column B: Interactive States */} -
- Disabled States -
- - - -
-
- - {/* Column C: Edge Cases */} -
- Layout Config -
- - - No Label Prop - -
- - - - Live Children Label - - -
-
-
-
- ); -} diff --git a/apps/web/src/apps/modules/example/showcase/components/date-picker.showcase.tsx b/apps/web/src/apps/modules/example/showcase/components/date-picker.showcase.tsx deleted file mode 100644 index 7a3a8f4..0000000 --- a/apps/web/src/apps/modules/example/showcase/components/date-picker.showcase.tsx +++ /dev/null @@ -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; -}) => ( -
-
-

{title}

- {description &&

{description}

} -
-
{children}
-
-); - -const Card = ({ label, code, children }: { label: string; code?: string; children: React.ReactNode }) => ( -
-
- - {code && {code}} -
-
{children}
-
-); - -export default function PickerShowcase({ status }: { status: InputStatusType }) { - return ( -
-
- {/* Header */} -
-

Component Picker Showcase

-

- Fully typed, Tailwind-styled, and robust date manipulation components. -

-
- - {/* 1. Single Pickers */} -
- - - - - - - - - - - - - - - - - - - - - - - -
- - {/* 2. Range Pickers */} -
- - - - - - - - - - - - - - - - - - - - - - - -
- - {/* 3. Validation States */} -
- - - This field is required. - - - - - Warning: Date is in the past. - - - - - - - -
- - -
-
-
- - {/* 4. Advanced & Customization */} -
- - - - - - - - - - - - - - - -
- - {/* 5. STATIC CALENDAR (Picker Panel) */} -
- {/* Basic Calendar */} -
- -
- -
-
-
- - {/* Calendar with State & Time */} -
- -
- {/* Visual Calendar */} -
- { - console.log('Selected:', new DateUtils(date as any).format('YYYY-MM-DD HH:mm:ss')); - }} - /> -
- - {/* Info Text */} -
-

Info:

-

- Komponen Calendar ini adalah Panel dasar. Sangat berguna untuk sidebar, - dashboard widget, atau form yang membutuhkan pemilihan tanggal yang selalu terlihat. -

-
-
-
-
-
-
-
- ); -} diff --git a/apps/web/src/apps/modules/example/showcase/components/form.showcase.tsx b/apps/web/src/apps/modules/example/showcase/components/form.showcase.tsx deleted file mode 100644 index 77e1192..0000000 --- a/apps/web/src/apps/modules/example/showcase/components/form.showcase.tsx +++ /dev/null @@ -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 ( -
-

Test Migrasi @rc-component/form

- -
- {/* Case 1: Text Input Biasa + Validasi Required */} - - - - - {/* Case 2: Email + Validasi Format */} - - - - - {/* Case 3: Password + Validasi Panjang */} - - - - - {/* Tombol Aksi */} -
- - - -
-
-
- ); -} diff --git a/apps/web/src/apps/modules/example/showcase/components/input.showcase.tsx b/apps/web/src/apps/modules/example/showcase/components/input.showcase.tsx deleted file mode 100644 index 4655398..0000000 --- a/apps/web/src/apps/modules/example/showcase/components/input.showcase.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import { Input, InputPassword, InputNumber, InputCurrency, InputStatusType, TextArea } from '@repo/ui'; - -// Helper untuk label kolom -const Label = ({ children }: { children: React.ReactNode }) => ( -
{children}
-); - -// Helper untuk prefix/suffix visual -const Fix = ({ children }: { children: React.ReactNode }) => {children}; - -export default function InputShowCase({ status }: { status?: InputStatusType }) { - return ( -
- {/* --- SECTION 1: OUTLINED VARIANT (DEFAULT) --- */} -
-

Outlined Variant (Standard)

-
-
- - - - - - -
-
- - - -
- - -
-
-
- - {/* ROW 3: COMPLEX DATA TABLE (Center Panel) */} -
- -
- Line Item Entries (001 - 005) -
- - -
-
-
- - - - - - - - - - - - - {[10, 20, 30, 40, 50].map((item, idx) => ( - - - - - - - - - ))} - -
ItemGL AccountCost Center - Amount (LC) - Ind.Status
{item} -
11000{idx}
-
Petty Cash - Main Office
-
-
CC-HEAD-01
-
- {(item * 1500000).toLocaleString('id-ID')} - {idx % 2 === 0 ? 'S' : 'H'} - {idx === 2 ? 'Review' : 'Valid'} -
-
-
-
-

Total Debit

-

IDR 450.000.000

-
-
-

Total Credit

-

IDR 450.000.000

-
-
-
- - {/* MESSAGE LOGS / ACTIVITY */} -
- -
- {[ - { 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) => ( -
- {log.t} - - {log.u}: {log.m} - -
- ))} -
-
- -
-
- + DROP FILES HERE -
-
- 📄 invoice_001.pdf × -
-
-
-
-
- - - ); -} diff --git a/packages/ui/src/components/forms/checkbox/checkbox.component.tsx b/packages/ui/src/components/forms/checkbox/checkbox.component.tsx deleted file mode 100644 index 41fec30..0000000 --- a/packages/ui/src/components/forms/checkbox/checkbox.component.tsx +++ /dev/null @@ -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((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 ( - - ); -}); - -Checkbox.displayName = 'Checkbox'; diff --git a/packages/ui/src/components/forms/form-provider/form-control.component.tsx b/packages/ui/src/components/forms/form-provider/form-control.component.tsx deleted file mode 100644 index 9f2d84f..0000000 --- a/packages/ui/src/components/forms/form-provider/form-control.component.tsx +++ /dev/null @@ -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({ children, ...props }: FormProps) { - return {children}; -} diff --git a/packages/ui/src/components/forms/form-provider/form-item.component.tsx b/packages/ui/src/components/forms/form-provider/form-item.component.tsx deleted file mode 100644 index e06ecb0..0000000 --- a/packages/ui/src/components/forms/form-provider/form-item.component.tsx +++ /dev/null @@ -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 - * - * - * - * ``` - * - * @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} [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 ( - - {(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 -
- {/* LABEL SECTION */} - {label && ( - - )} - - {/* INPUT CONTROL */} -
{childNode}
- - {/* ERROR / WARNING MESSAGE */} - {(hasError || hasWarning) && ( -
{hasError ? meta.errors[0] : meta.warnings[0]}
- )} -
- ); - }} -
- ); -} diff --git a/packages/ui/src/components/forms/form-provider/index.tsx b/packages/ui/src/components/forms/form-provider/index.tsx deleted file mode 100644 index 5a9d50f..0000000 --- a/packages/ui/src/components/forms/form-provider/index.tsx +++ /dev/null @@ -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 ( - props: FormProps & { ref?: React.ForwardedRef }, -) => 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 }; diff --git a/packages/ui/src/components/forms/index.ts b/packages/ui/src/components/forms/index.ts deleted file mode 100644 index 3e09210..0000000 --- a/packages/ui/src/components/forms/index.ts +++ /dev/null @@ -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"; \ No newline at end of file diff --git a/packages/ui/src/components/forms/input/input-currency.component.tsx b/packages/ui/src/components/forms/input/input-currency.component.tsx deleted file mode 100644 index fc56df1..0000000 --- a/packages/ui/src/components/forms/input/input-currency.component.tsx +++ /dev/null @@ -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 ( - - ); -}; diff --git a/packages/ui/src/components/forms/input/input-number.component.tsx b/packages/ui/src/components/forms/input/input-number.component.tsx deleted file mode 100644 index c223e20..0000000 --- a/packages/ui/src/components/forms/input/input-number.component.tsx +++ /dev/null @@ -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(null); - * 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} 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 = () => ( - - - - - -); - -const DownIcon = () => ( - - - - - -); - -export const InputNumber = forwardRef((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 ( - } - downHandler={} - /> - ); -}); - -InputNumber.displayName = 'InputNumber'; diff --git a/packages/ui/src/components/forms/input/input-password.component.tsx b/packages/ui/src/components/forms/input/input-password.component.tsx deleted file mode 100644 index 7411982..0000000 --- a/packages/ui/src/components/forms/input/input-password.component.tsx +++ /dev/null @@ -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 = () => ( - - - - -); - -/** - * Eye Off Icon for visibility toggle - * @returns JSX Element - */ -const EyeOffIcon = () => ( - - - - -); - -/** - * 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 ; - } - - const combinedSuffix = ( -
- {/* Suffix User */} - {suffix && {suffix}} - - {/* Visibility Toggle Button */} - {visibilityToggle && ( - - )} -
- ); - - return ( - - ); -}; diff --git a/packages/ui/src/components/forms/input/input.component.tsx b/packages/ui/src/components/forms/input/input.component.tsx deleted file mode 100644 index adb4b46..0000000 --- a/packages/ui/src/components/forms/input/input.component.tsx +++ /dev/null @@ -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((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 ; -}); - -Input.displayName = 'Input'; diff --git a/packages/ui/src/components/forms/picker/generate-picker.component.tsx b/packages/ui/src/components/forms/picker/generate-picker.component.tsx deleted file mode 100644 index c7d1de1..0000000 --- a/packages/ui/src/components/forms/picker/generate-picker.component.tsx +++ /dev/null @@ -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 { - Picker: React.ForwardRefExoticComponent & React.RefAttributes>; - RangePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - Calendar: React.ForwardRefExoticComponent & React.RefAttributes>; - - DatePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - WeekPicker: React.ForwardRefExoticComponent & React.RefAttributes>; - MonthPicker: React.ForwardRefExoticComponent & React.RefAttributes>; - QuarterPicker: React.ForwardRefExoticComponent & React.RefAttributes>; - YearPicker: React.ForwardRefExoticComponent & React.RefAttributes>; - TimePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - - DateRangePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - WeekRangePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - MonthRangePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - QuarterRangePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - YearRangePicker: React.ForwardRefExoticComponent & React.RefAttributes>; - TimeRangePicker: React.ForwardRefExoticComponent & React.RefAttributes>; -} - -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( - generateConfig: GenerateConfig, -): PickerGenerateReturns { - // 1. Generic Picker - const Picker = forwardRef>((props, ref) => { - const { status, className, locale, prefixCls = COMPONENT_PREFIX, ...restProps } = props; - return ( - - ref={ref} - prefixCls={prefixCls} - generateConfig={generateConfig} - locale={locale || enUS} - className={getStatusClassName(prefixCls, className, status, props.disabled)} - prevIcon={} - nextIcon={} - superPrevIcon={} - superNextIcon={} - transitionName={`rc-slide-up`} - {...restProps} - /> - ); - }); - Picker.displayName = 'Picker'; - - // 2. Generic Range Picker - const RangePicker = forwardRef>((props, ref) => { - const { status, className, locale, prefixCls = COMPONENT_PREFIX, ...restProps } = props; - return ( - - 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>((props, ref) => { - const { locale, prefixCls = COMPONENT_PREFIX, ...restProps } = props; - return ( - - ref={ref} - prefixCls={prefixCls} - generateConfig={generateConfig} - locale={locale || enUS} - {...restProps} - /> - ); - }); - Calendar.displayName = 'Calendar'; - - // ================== Specific Pickers ================== - const DatePicker = forwardRef>((props, ref) => ( - - )); - DatePicker.displayName = 'DatePicker'; - - const TimePicker = forwardRef>((props, ref) => ( - - )); - TimePicker.displayName = 'TimePicker'; - - const WeekPicker = forwardRef>((props, ref) => ( - - )); - WeekPicker.displayName = 'WeekPicker'; - - const MonthPicker = forwardRef>((props, ref) => ( - - )); - MonthPicker.displayName = 'MonthPicker'; - - const QuarterPicker = forwardRef>((props, ref) => ( - - )); - QuarterPicker.displayName = 'QuarterPicker'; - - const YearPicker = forwardRef>((props, ref) => ( - - )); - YearPicker.displayName = 'YearPicker'; - - // ================== Specific Range Pickers ================== - - const DateRangePicker = forwardRef>((props, ref) => ( - - )); - DateRangePicker.displayName = 'DateRangePicker'; - - const TimeRangePicker = forwardRef>((props, ref) => ( - - )); - TimeRangePicker.displayName = 'TimeRangePicker'; - - const WeekRangePicker = forwardRef>((props, ref) => ( - - )); - WeekRangePicker.displayName = 'WeekRangePicker'; - - const MonthRangePicker = forwardRef>((props, ref) => ( - - )); - MonthRangePicker.displayName = 'MonthRangePicker'; - - const QuarterRangePicker = forwardRef>((props, ref) => ( - - )); - QuarterRangePicker.displayName = 'QuarterRangePicker'; - - const YearRangePicker = forwardRef>((props, ref) => ( - - )); - YearRangePicker.displayName = 'YearRangePicker'; - - return { - Picker, - RangePicker, - Calendar, - DatePicker, - WeekPicker, - MonthPicker, - QuarterPicker, - YearPicker, - TimePicker, - DateRangePicker, - WeekRangePicker, - MonthRangePicker, - QuarterRangePicker, - YearRangePicker, - TimeRangePicker, - }; -} diff --git a/packages/ui/src/components/forms/picker/index.tsx b/packages/ui/src/components/forms/picker/index.tsx deleted file mode 100644 index 2ac0be0..0000000 --- a/packages/ui/src/components/forms/picker/index.tsx +++ /dev/null @@ -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(dayjsGenerateConfig); diff --git a/packages/ui/src/components/forms/styles/checkbox.style.css b/packages/ui/src/components/forms/styles/checkbox.style.css deleted file mode 100644 index d6017fe..0000000 --- a/packages/ui/src/components/forms/styles/checkbox.style.css +++ /dev/null @@ -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); - } - } -} diff --git a/packages/ui/src/components/forms/styles/form-item.style.css b/packages/ui/src/components/forms/styles/form-item.style.css deleted file mode 100644 index 651982d..0000000 --- a/packages/ui/src/components/forms/styles/form-item.style.css +++ /dev/null @@ -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); - } -} diff --git a/packages/ui/src/components/forms/styles/form.style.css b/packages/ui/src/components/forms/styles/form.style.css deleted file mode 100644 index be6f5bc..0000000 --- a/packages/ui/src/components/forms/styles/form.style.css +++ /dev/null @@ -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'; diff --git a/packages/ui/src/components/forms/styles/input-number.style.css b/packages/ui/src/components/forms/styles/input-number.style.css deleted file mode 100644 index 32cf33d..0000000 --- a/packages/ui/src/components/forms/styles/input-number.style.css +++ /dev/null @@ -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; - } -} diff --git a/packages/ui/src/components/forms/styles/input.style.css b/packages/ui/src/components/forms/styles/input.style.css deleted file mode 100644 index 167dab8..0000000 --- a/packages/ui/src/components/forms/styles/input.style.css +++ /dev/null @@ -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); - } -} diff --git a/packages/ui/src/components/forms/styles/picker.style copy.css b/packages/ui/src/components/forms/styles/picker.style copy.css deleted file mode 100644 index 05f4567..0000000 --- a/packages/ui/src/components/forms/styles/picker.style copy.css +++ /dev/null @@ -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); - } -} diff --git a/packages/ui/src/components/forms/styles/picker.style.css b/packages/ui/src/components/forms/styles/picker.style.css deleted file mode 100644 index 26f174a..0000000 --- a/packages/ui/src/components/forms/styles/picker.style.css +++ /dev/null @@ -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); - } -} diff --git a/packages/ui/src/components/forms/styles/switch.style.css b/packages/ui/src/components/forms/styles/switch.style.css deleted file mode 100644 index ccfa4f0..0000000 --- a/packages/ui/src/components/forms/styles/switch.style.css +++ /dev/null @@ -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; - } -} diff --git a/packages/ui/src/components/forms/styles/textarea.style.css b/packages/ui/src/components/forms/styles/textarea.style.css deleted file mode 100644 index d9f21af..0000000 --- a/packages/ui/src/components/forms/styles/textarea.style.css +++ /dev/null @@ -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); - } -} diff --git a/packages/ui/src/components/forms/switch/switch.component.tsx b/packages/ui/src/components/forms/switch/switch.component.tsx deleted file mode 100644 index ba5186e..0000000 --- a/packages/ui/src/components/forms/switch/switch.component.tsx +++ /dev/null @@ -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 = () => ( - -); - -export const Switch = forwardRef((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 ( - - ); -}); - -Switch.displayName = 'Switch'; diff --git a/packages/ui/src/components/forms/textarea/textarea.component.tsx b/packages/ui/src/components/forms/textarea/textarea.component.tsx deleted file mode 100644 index fe662a1..0000000 --- a/packages/ui/src/components/forms/textarea/textarea.component.tsx +++ /dev/null @@ -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-` 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 - *