Import source: src/components/RightPanel/ColorsSection

Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
arsam
2026-09-18 23:17:08 +03:30
parent 8f7490beb4
commit 79989d9529
@@ -0,0 +1,73 @@
import { useRef } from 'react';
import { useQR } from '../../context/QRContext';
import { ColorSwatch } from '../ui/ColorSwatch';
import { QR_COLORS, BG_COLORS } from '../../config/styleOptions';
export function ColorsSection() {
const { state, dispatch } = useQR();
const qrPickerRef = useRef<HTMLInputElement>(null);
const bgPickerRef = useRef<HTMLInputElement>(null);
return (
<div className="flex flex-col gap-4">
<h3 className="text-[14px] font-semibold" style={{ color: 'var(--text-secondary)' }}>Colors</h3>
<div className="flex flex-col gap-2">
<span className="text-[13px]" style={{ color: 'var(--text-muted)' }}>QR Code</span>
<div className="flex gap-2 flex-wrap items-center">
{QR_COLORS.map(color => (
<ColorSwatch key={color} color={color === 'rainbow' ? null : color}
isRainbow={color === 'rainbow'} selected={state.qrColor === color}
onClick={() => dispatch({ type: 'SET_QR_COLOR', payload: color })} />
))}
{/* Custom picker */}
<button
onClick={() => qrPickerRef.current?.click()}
title="Custom color"
className="relative w-9 h-9 rounded-full flex-shrink-0 cursor-pointer transition-transform hover:scale-110 flex items-center justify-center"
style={{ background: 'var(--bg-elevated)', border: '2px dashed var(--border-hover)', outline: !QR_COLORS.includes(state.qrColor) ? '2px solid #7C6FE0' : 'none', outlineOffset: '2px' }}
>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" style={{ color: 'var(--text-secondary)' }}>
<circle cx="7" cy="7" r="5.5" stroke="currentColor" strokeWidth="1.3"/>
<path d="M4 7h6M7 4v6" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>
</svg>
<input ref={qrPickerRef} type="color" value={QR_COLORS.includes(state.qrColor) ? '#000000' : state.qrColor}
onChange={e => dispatch({ type: 'SET_QR_COLOR', payload: e.target.value })}
className="absolute inset-0 opacity-0 w-full h-full cursor-pointer" style={{ borderRadius: '50%' }} />
</button>
</div>
{!QR_COLORS.includes(state.qrColor) && (
<div className="flex items-center gap-2">
<div className="w-4 h-4 rounded-full border border-[var(--border-sub)]" style={{ background: state.qrColor }} />
<span className="text-[12px] font-mono" style={{ color: 'var(--text-muted)' }}>{state.qrColor}</span>
</div>
)}
</div>
<div className="flex flex-col gap-2">
<span className="text-[13px]" style={{ color: 'var(--text-muted)' }}>Background</span>
<div className="flex gap-2 flex-wrap items-center">
{BG_COLORS.map((color, i) => (
<ColorSwatch key={i} color={color} selected={state.bgColor === color}
onClick={() => dispatch({ type: 'SET_BG_COLOR', payload: color })} />
))}
{/* Custom bg picker */}
<button
onClick={() => bgPickerRef.current?.click()}
title="Custom background color"
className="relative w-9 h-9 rounded-full flex-shrink-0 cursor-pointer transition-transform hover:scale-110 flex items-center justify-center"
style={{ background: 'var(--bg-elevated)', border: '2px dashed var(--border-hover)', outline: state.bgColor !== null && !BG_COLORS.includes(state.bgColor) ? '2px solid #7C6FE0' : 'none', outlineOffset: '2px' }}
>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" style={{ color: 'var(--text-secondary)' }}>
<circle cx="7" cy="7" r="5.5" stroke="currentColor" strokeWidth="1.3"/>
<path d="M4 7h6M7 4v6" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/>
</svg>
<input ref={bgPickerRef} type="color" value={state.bgColor && !BG_COLORS.includes(state.bgColor) ? state.bgColor : '#ffffff'}
onChange={e => dispatch({ type: 'SET_BG_COLOR', payload: e.target.value })}
className="absolute inset-0 opacity-0 w-full h-full cursor-pointer" style={{ borderRadius: '50%' }} />
</button>
</div>
</div>
</div>
);
}