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:
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user