From 9e7d6b317e59a9d46f4421af74f907ffa6307f4b Mon Sep 17 00:00:00 2001 From: PEDZEO Date: Tue, 20 Jan 2026 18:27:05 +0300 Subject: [PATCH] Enhance ColorPicker component with RGB support and improved styling - Added RGB value updates on color input changes and preset selections. - Refactored RGB sliders to always be visible, enhancing user experience across devices. - Improved range input styles for better accessibility and visual feedback. - Updated number input fields for RGB values to hide spinners and ensure a cleaner look. --- src/components/ColorPicker.tsx | 138 +++++++++++++++++++-------------- src/styles/globals.css | 72 ++++++++++++++--- 2 files changed, 142 insertions(+), 68 deletions(-) diff --git a/src/components/ColorPicker.tsx b/src/components/ColorPicker.tsx index 6b90673..9dbefd1 100644 --- a/src/components/ColorPicker.tsx +++ b/src/components/ColorPicker.tsx @@ -87,6 +87,7 @@ export function ColorPicker({ value, onChange, label, description, disabled }: C const handleColorInputChange = (e: React.ChangeEvent) => { const newColor = e.target.value setLocalValue(newColor) + setRgb(hexToRgb(newColor)) onChange(newColor) } @@ -102,8 +103,9 @@ export function ColorPicker({ value, onChange, label, description, disabled }: C if (newValue === '' || newValue.match(/^#[0-9A-Fa-f]{0,6}$/)) { setLocalValue(newValue) - // Only trigger onChange for valid complete hex + // Only trigger onChange and update RGB for valid complete hex if (newValue.match(/^#[0-9A-Fa-f]{6}$/)) { + setRgb(hexToRgb(newValue)) onChange(newValue) } } @@ -111,6 +113,7 @@ export function ColorPicker({ value, onChange, label, description, disabled }: C const handlePresetClick = (color: string) => { setLocalValue(color) + setRgb(hexToRgb(color)) onChange(color) setIsOpen(false) } @@ -178,71 +181,90 @@ export function ColorPicker({ value, onChange, label, description, disabled }: C {/* Dropdown with presets and RGB sliders */} {isOpen && ( -
- {/* RGB Sliders - shown in Telegram instead of native picker */} - {isTelegram && ( -
-
RGB
-
- {/* Red */} -
- R - handleRgbChange('r', parseInt(e.target.value))} - className="flex-1 h-2 rounded-full appearance-none cursor-pointer" - style={{ - background: `linear-gradient(to right, rgb(0,${rgb.g},${rgb.b}), rgb(255,${rgb.g},${rgb.b}))`, - }} - /> - {rgb.r} -
- {/* Green */} -
- G - handleRgbChange('g', parseInt(e.target.value))} - className="flex-1 h-2 rounded-full appearance-none cursor-pointer" - style={{ - background: `linear-gradient(to right, rgb(${rgb.r},0,${rgb.b}), rgb(${rgb.r},255,${rgb.b}))`, - }} - /> - {rgb.g} -
- {/* Blue */} -
- B - handleRgbChange('b', parseInt(e.target.value))} - className="flex-1 h-2 rounded-full appearance-none cursor-pointer" - style={{ - background: `linear-gradient(to right, rgb(${rgb.r},${rgb.g},0), rgb(${rgb.r},${rgb.g},255))`, - }} - /> - {rgb.b} -
+
+ {/* RGB Sliders - always visible on all devices */} +
+
RGB
+
+ {/* Red */} +
+ R + handleRgbChange('r', parseInt(e.target.value))} + className="flex-1 h-3 sm:h-2 rounded-full appearance-none cursor-pointer touch-pan-x" + style={{ + background: `linear-gradient(to right, rgb(0,${rgb.g},${rgb.b}), rgb(255,${rgb.g},${rgb.b}))`, + }} + /> + handleRgbChange('r', Math.min(255, Math.max(0, parseInt(e.target.value) || 0)))} + className="w-14 sm:w-12 text-xs text-center bg-dark-700 border border-dark-600 rounded px-1 py-1 text-dark-200" + /> +
+ {/* Green */} +
+ G + handleRgbChange('g', parseInt(e.target.value))} + className="flex-1 h-3 sm:h-2 rounded-full appearance-none cursor-pointer touch-pan-x" + style={{ + background: `linear-gradient(to right, rgb(${rgb.r},0,${rgb.b}), rgb(${rgb.r},255,${rgb.b}))`, + }} + /> + handleRgbChange('g', Math.min(255, Math.max(0, parseInt(e.target.value) || 0)))} + className="w-14 sm:w-12 text-xs text-center bg-dark-700 border border-dark-600 rounded px-1 py-1 text-dark-200" + /> +
+ {/* Blue */} +
+ B + handleRgbChange('b', parseInt(e.target.value))} + className="flex-1 h-3 sm:h-2 rounded-full appearance-none cursor-pointer touch-pan-x" + style={{ + background: `linear-gradient(to right, rgb(${rgb.r},${rgb.g},0), rgb(${rgb.r},${rgb.g},255))`, + }} + /> + handleRgbChange('b', Math.min(255, Math.max(0, parseInt(e.target.value) || 0)))} + className="w-14 sm:w-12 text-xs text-center bg-dark-700 border border-dark-600 rounded px-1 py-1 text-dark-200" + />
- )} +
Preset colors
-
+
{PRESET_COLORS.map((preset) => (