feat: add clear icon styles and functionality for input and textarea components

This commit is contained in:
Firman Ramdhani
2026-01-28 10:58:06 +07:00
parent c39a8eb175
commit c021df8012
2 changed files with 185 additions and 50 deletions
@@ -41,6 +41,63 @@
pointer-events: none;
}
/* =========================================
CLEAR ICON
Tombol (x) untuk reset value
========================================= */
.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 sesuai global */
line-height: 1;
cursor: pointer;
/* Colors & Transition */
color: var(--color-gray-400); /* Warna default (abu muda) */
transition: color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
/* Visibility Control (Opacity lebih smooth dari display:none jika mau animasi) */
/* Tapi untuk simplicity sesuai request, kita pakai logic display/visibility standar */
visibility: visible;
}
/* Hover State: Lebih gelap agar user tahu bisa diklik */
.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;
/* Alternatif jika ingin layout tetap terjaga tapi invisible:
visibility: hidden;
pointer-events: none;
*/
}
/* Placement Helper:
Biasanya clear icon muncul di dalam suffix atau menggantikan suffix.
Jika dia berdiri sendiri sebagai sibling terakhir:
*/
.rc-input-affix-wrapper .rc-input-clear-icon {
margin-left: 0.5rem; /* ~8px spacing dari text */
z-index: 2; /* Pastikan di atas layer lain */
}
/* =========================================
AFFIX WRAPPER (PREFIX / SUFFIX) SETUP
========================================= */
@@ -1,16 +1,13 @@
@layer components {
/* =========================================
TEXTAREA STYLES
BASE STYLE: TEXTAREA (Standalone)
========================================= */
.rc-textarea {
/* Tambahan wajib untuk menjamin lebar akurat */
box-sizing: border-box;
display: block;
width: 100%;
/* Menggunakan Variable Dimensi Textarea */
/* Global Variables */
min-height: var(--textarea-min-height);
padding: var(--textarea-padding-y) var(--textarea-padding-x);
@@ -18,158 +15,239 @@
line-height: 1.5;
color: var(--input-text);
/* Default Background */
/* Default Base (akan di-override jika ada wrapper) */
background-color: var(--input-bg);
border: 1px solid transparent;
border-radius: var(--input-radius);
/* Transisi standar */
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
outline: none;
resize: vertical;
}
/* Placeholder Styling */
.rc-textarea::placeholder {
color: var(--input-placeholder);
opacity: 1; /* Firefox fix */
opacity: 1;
}
/* Disabled State */
.rc-textarea:disabled,
.rc-textarea[disabled] {
/* 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;
opacity: 1; /* iOS fix */
pointer-events: none;
}
/* =========================================
WRAPPER (untuk showCount)
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;
}
/* =========================================
1. VARIANT: OUTLINED
LOGIC MATRIX: [VARIANT] x [STATUS]
Target: .rc-textarea (standalone) AND .rc-textarea-affix-wrapper (wrapped)
========================================= */
/* ------------------------------------------------
1. VARIANT: OUTLINED
------------------------------------------------ */
/* --- Default --- */
.rc-textarea.textarea-variant-outlined.textarea-status-default {
.textarea-variant-outlined.textarea-status-default {
background-color: var(--input-bg);
border-color: var(--input-border);
}
.rc-textarea.textarea-variant-outlined.textarea-status-default:hover:not(:disabled) {
/* Hover */
.textarea-variant-outlined.textarea-status-default:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
border-color: var(--input-border-hover);
}
.rc-textarea.textarea-variant-outlined.textarea-status-default:focus {
/* Focus (Standalone OR Wrapper Focused) */
.rc-textarea.textarea-variant-outlined.textarea-status-default:focus,
.rc-textarea-affix-wrapper.textarea-variant-outlined.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 --- */
.rc-textarea.textarea-variant-outlined.textarea-status-error {
background-color: var(--input-bg);
.textarea-variant-outlined.textarea-status-error {
border-color: var(--color-error-500);
z-index: 1;
}
.rc-textarea.textarea-variant-outlined.textarea-status-error:hover:not(:disabled),
.rc-textarea.textarea-variant-outlined.textarea-status-error:focus {
.textarea-variant-outlined.textarea-status-error:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
border-color: var(--color-error-600);
}
.rc-textarea.textarea-variant-outlined.textarea-status-error:focus,
.rc-textarea-affix-wrapper.textarea-variant-outlined.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 --- */
.rc-textarea.textarea-variant-outlined.textarea-status-warning {
background-color: var(--input-bg);
.textarea-variant-outlined.textarea-status-warning {
border-color: var(--color-warning-500);
z-index: 1;
}
.rc-textarea.textarea-variant-outlined.textarea-status-warning:hover:not(:disabled),
.rc-textarea.textarea-variant-outlined.textarea-status-warning:focus {
.textarea-variant-outlined.textarea-status-warning:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
border-color: var(--color-warning-600);
}
.rc-textarea.textarea-variant-outlined.textarea-status-warning:focus,
.rc-textarea-affix-wrapper.textarea-variant-outlined.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 --- */
.rc-textarea.textarea-variant-outlined.textarea-status-success {
background-color: var(--input-bg);
.textarea-variant-outlined.textarea-status-success {
border-color: var(--color-success-500);
z-index: 1;
}
.rc-textarea.textarea-variant-outlined.textarea-status-success:hover:not(:disabled),
.rc-textarea.textarea-variant-outlined.textarea-status-success:focus {
.textarea-variant-outlined.textarea-status-success:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
border-color: var(--color-success-600);
}
.rc-textarea.textarea-variant-outlined.textarea-status-success:focus,
.rc-textarea-affix-wrapper.textarea-variant-outlined.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 --- */
.rc-textarea.textarea-variant-outlined.textarea-status-info {
background-color: var(--input-bg);
.textarea-variant-outlined.textarea-status-info {
border-color: var(--color-info-500);
z-index: 1;
}
.rc-textarea.textarea-variant-outlined.textarea-status-info:hover:not(:disabled),
.rc-textarea.textarea-variant-outlined.textarea-status-info:focus {
.textarea-variant-outlined.textarea-status-info:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
border-color: var(--color-info-600);
}
.rc-textarea.textarea-variant-outlined.textarea-status-info:focus,
.rc-textarea-affix-wrapper.textarea-variant-outlined.textarea-status-info.rc-textarea-affix-wrapper-focused {
border-color: var(--color-info-600);
box-shadow: 0 0 0 3px var(--color-info-100);
}
/* =========================================
/* ------------------------------------------------
2. VARIANT: FILLED
========================================= */
------------------------------------------------ */
/* --- Default Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-default {
.textarea-variant-filled.textarea-status-default {
background-color: var(--input-bg);
border-color: var(--input-border);
}
.rc-textarea.textarea-variant-filled.textarea-status-default:hover:not(:disabled) {
.textarea-variant-filled.textarea-status-default:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
border-color: var(--input-border-hover);
}
.rc-textarea.textarea-variant-filled.textarea-status-default:focus {
.rc-textarea.textarea-variant-filled.textarea-status-default:focus,
.rc-textarea-affix-wrapper.textarea-variant-filled.textarea-status-default.rc-textarea-affix-wrapper-focused {
border-color: var(--focus-border-color);
box-shadow: 0 0 0 3px var(--focus-ring-color);
}
/* --- Error Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-error {
.textarea-variant-filled.textarea-status-error {
background-color: var(--color-error-50);
border-color: var(--color-error-500);
}
.rc-textarea.textarea-variant-filled.textarea-status-error:focus {
background-color: var(--input-bg); /* Reset ke putih saat typing */
.rc-textarea.textarea-variant-filled.textarea-status-error:focus,
.rc-textarea-affix-wrapper.textarea-variant-filled.textarea-status-error.rc-textarea-affix-wrapper-focused {
background-color: var(--input-bg);
box-shadow: 0 0 0 3px var(--color-error-100);
}
/* --- Warning Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-warning {
.textarea-variant-filled.textarea-status-warning {
background-color: var(--color-warning-50);
border-color: var(--color-warning-500);
}
.rc-textarea.textarea-variant-filled.textarea-status-warning:focus {
.rc-textarea.textarea-variant-filled.textarea-status-warning:focus,
.rc-textarea-affix-wrapper.textarea-variant-filled.textarea-status-warning.rc-textarea-affix-wrapper-focused {
background-color: var(--input-bg);
box-shadow: 0 0 0 3px var(--color-warning-100);
}
/* --- Success Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-success {
.textarea-variant-filled.textarea-status-success {
background-color: var(--color-success-50);
border-color: var(--color-success-500);
}
.rc-textarea.textarea-variant-filled.textarea-status-success:focus {
.rc-textarea.textarea-variant-filled.textarea-status-success:focus,
.rc-textarea-affix-wrapper.textarea-variant-filled.textarea-status-success.rc-textarea-affix-wrapper-focused {
background-color: var(--input-bg);
box-shadow: 0 0 0 3px var(--color-success-100);
}
/* --- Info Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-info {
.textarea-variant-filled.textarea-status-info {
background-color: var(--color-info-50);
border-color: var(--color-info-500);
}
.rc-textarea.textarea-variant-filled.textarea-status-info:focus {
.rc-textarea.textarea-variant-filled.textarea-status-info:focus,
.rc-textarea-affix-wrapper.textarea-variant-filled.textarea-status-info.rc-textarea-affix-wrapper-focused {
background-color: var(--input-bg);
box-shadow: 0 0 0 3px var(--color-info-100);
}