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; 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 AFFIX WRAPPER (PREFIX / SUFFIX) SETUP
========================================= */ ========================================= */
@@ -1,16 +1,13 @@
@layer components { @layer components {
/* ========================================= /* =========================================
TEXTAREA STYLES BASE STYLE: TEXTAREA (Standalone)
========================================= */ ========================================= */
.rc-textarea { .rc-textarea {
/* Tambahan wajib untuk menjamin lebar akurat */
box-sizing: border-box; box-sizing: border-box;
display: block; display: block;
width: 100%; width: 100%;
/* Menggunakan Variable Dimensi Textarea */ /* Global Variables */
min-height: var(--textarea-min-height); min-height: var(--textarea-min-height);
padding: var(--textarea-padding-y) var(--textarea-padding-x); padding: var(--textarea-padding-y) var(--textarea-padding-x);
@@ -18,158 +15,239 @@
line-height: 1.5; line-height: 1.5;
color: var(--input-text); color: var(--input-text);
/* Default Background */ /* Default Base (akan di-override jika ada wrapper) */
background-color: var(--input-bg); background-color: var(--input-bg);
border: 1px solid transparent; border: 1px solid transparent;
border-radius: var(--input-radius); border-radius: var(--input-radius);
/* Transisi standar */
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
outline: none; outline: none;
resize: vertical; resize: vertical;
} }
/* Placeholder Styling */
.rc-textarea::placeholder { .rc-textarea::placeholder {
color: var(--input-placeholder); color: var(--input-placeholder);
opacity: 1; /* Firefox fix */ opacity: 1;
} }
/* Disabled State */ /* Disabled State (Standalone) */
.rc-textarea:disabled, .rc-textarea:disabled {
.rc-textarea[disabled] {
background-color: var(--disabled-bg) !important; background-color: var(--disabled-bg) !important;
color: var(--disabled-text); color: var(--disabled-text);
border-color: var(--disabled-border) !important; border-color: var(--disabled-border) !important;
cursor: not-allowed; 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 { .rc-textarea-affix-wrapper {
width: 100%; width: 100%;
position: relative; position: relative;
display: inline-block; 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 --- */ /* --- Default --- */
.rc-textarea.textarea-variant-outlined.textarea-status-default { .textarea-variant-outlined.textarea-status-default {
background-color: var(--input-bg); background-color: var(--input-bg);
border-color: var(--input-border); 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); 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); border-color: var(--focus-border-color);
box-shadow: 0 0 0 3px var(--focus-ring-color); box-shadow: 0 0 0 3px var(--focus-ring-color);
z-index: 1;
} }
/* --- Error --- */ /* --- Error --- */
.rc-textarea.textarea-variant-outlined.textarea-status-error { .textarea-variant-outlined.textarea-status-error {
background-color: var(--input-bg);
border-color: var(--color-error-500); border-color: var(--color-error-500);
z-index: 1;
} }
.rc-textarea.textarea-variant-outlined.textarea-status-error:hover:not(:disabled), .textarea-variant-outlined.textarea-status-error:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
.rc-textarea.textarea-variant-outlined.textarea-status-error:focus { 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); border-color: var(--color-error-600);
box-shadow: 0 0 0 3px var(--color-error-100); box-shadow: 0 0 0 3px var(--color-error-100);
} }
/* --- Warning --- */ /* --- Warning --- */
.rc-textarea.textarea-variant-outlined.textarea-status-warning { .textarea-variant-outlined.textarea-status-warning {
background-color: var(--input-bg);
border-color: var(--color-warning-500); border-color: var(--color-warning-500);
z-index: 1;
} }
.rc-textarea.textarea-variant-outlined.textarea-status-warning:hover:not(:disabled), .textarea-variant-outlined.textarea-status-warning:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
.rc-textarea.textarea-variant-outlined.textarea-status-warning:focus { 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); border-color: var(--color-warning-600);
box-shadow: 0 0 0 3px var(--color-warning-100); box-shadow: 0 0 0 3px var(--color-warning-100);
} }
/* --- Success --- */ /* --- Success --- */
.rc-textarea.textarea-variant-outlined.textarea-status-success { .textarea-variant-outlined.textarea-status-success {
background-color: var(--input-bg);
border-color: var(--color-success-500); border-color: var(--color-success-500);
z-index: 1;
} }
.rc-textarea.textarea-variant-outlined.textarea-status-success:hover:not(:disabled), .textarea-variant-outlined.textarea-status-success:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
.rc-textarea.textarea-variant-outlined.textarea-status-success:focus { 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); border-color: var(--color-success-600);
box-shadow: 0 0 0 3px var(--color-success-100); box-shadow: 0 0 0 3px var(--color-success-100);
} }
/* --- Info --- */ /* --- Info --- */
.rc-textarea.textarea-variant-outlined.textarea-status-info { .textarea-variant-outlined.textarea-status-info {
background-color: var(--input-bg);
border-color: var(--color-info-500); border-color: var(--color-info-500);
z-index: 1;
} }
.rc-textarea.textarea-variant-outlined.textarea-status-info:hover:not(:disabled), .textarea-variant-outlined.textarea-status-info:hover:not(:disabled):not(.rc-textarea-affix-wrapper-disabled) {
.rc-textarea.textarea-variant-outlined.textarea-status-info:focus { 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); border-color: var(--color-info-600);
box-shadow: 0 0 0 3px var(--color-info-100); box-shadow: 0 0 0 3px var(--color-info-100);
} }
/* ========================================= /* ------------------------------------------------
2. VARIANT: FILLED 2. VARIANT: FILLED
========================================= */ ------------------------------------------------ */
/* --- Default Filled --- */ /* --- Default Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-default { .textarea-variant-filled.textarea-status-default {
background-color: var(--input-bg); background-color: var(--input-bg);
border-color: var(--input-border); 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); 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); border-color: var(--focus-border-color);
box-shadow: 0 0 0 3px var(--focus-ring-color); box-shadow: 0 0 0 3px var(--focus-ring-color);
} }
/* --- Error Filled --- */ /* --- Error Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-error { .textarea-variant-filled.textarea-status-error {
background-color: var(--color-error-50); background-color: var(--color-error-50);
border-color: var(--color-error-500); border-color: var(--color-error-500);
} }
.rc-textarea.textarea-variant-filled.textarea-status-error:focus { .rc-textarea.textarea-variant-filled.textarea-status-error:focus,
background-color: var(--input-bg); /* Reset ke putih saat typing */ .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); box-shadow: 0 0 0 3px var(--color-error-100);
} }
/* --- Warning Filled --- */ /* --- Warning Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-warning { .textarea-variant-filled.textarea-status-warning {
background-color: var(--color-warning-50); background-color: var(--color-warning-50);
border-color: var(--color-warning-500); 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); background-color: var(--input-bg);
box-shadow: 0 0 0 3px var(--color-warning-100); box-shadow: 0 0 0 3px var(--color-warning-100);
} }
/* --- Success Filled --- */ /* --- Success Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-success { .textarea-variant-filled.textarea-status-success {
background-color: var(--color-success-50); background-color: var(--color-success-50);
border-color: var(--color-success-500); 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); background-color: var(--input-bg);
box-shadow: 0 0 0 3px var(--color-success-100); box-shadow: 0 0 0 3px var(--color-success-100);
} }
/* --- Info Filled --- */ /* --- Info Filled --- */
.rc-textarea.textarea-variant-filled.textarea-status-info { .textarea-variant-filled.textarea-status-info {
background-color: var(--color-info-50); background-color: var(--color-info-50);
border-color: var(--color-info-500); 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); background-color: var(--input-bg);
box-shadow: 0 0 0 3px var(--color-info-100); box-shadow: 0 0 0 3px var(--color-info-100);
} }