feat: enhance UI components with improved styling and interactions
This commit is contained in:
+61
-31
@@ -5,24 +5,57 @@ const Toolbar: React.FC = () => {
|
||||
const { tool, setTool, showGrid, setShowGrid, zoom, setZoom } = useCanvasStore();
|
||||
|
||||
const tools = [
|
||||
{ id: 'select', icon: '↖', label: 'Select (V)' },
|
||||
{ id: 'code', icon: '{ }', label: 'Code Block (C)' },
|
||||
{ id: 'text', icon: 'T', label: 'Text (T)' },
|
||||
{ id: 'arrow', icon: '→', label: 'Arrow (A)' },
|
||||
{
|
||||
id: 'select',
|
||||
label: 'Select (V)',
|
||||
icon: (
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122" />
|
||||
</svg>
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'code',
|
||||
label: 'Code Block (C)',
|
||||
icon: (
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
|
||||
</svg>
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'text',
|
||||
label: 'Text (T)',
|
||||
icon: (
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h7" />
|
||||
</svg>
|
||||
)
|
||||
},
|
||||
{
|
||||
id: 'arrow',
|
||||
label: 'Arrow (A)',
|
||||
icon: (
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
|
||||
</svg>
|
||||
)
|
||||
},
|
||||
] as const;
|
||||
|
||||
return (
|
||||
<div className="w-14 bg-neutral-800 border-r border-neutral-700 flex flex-col items-center py-4 gap-2">
|
||||
{/* Tools */}
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="absolute bottom-6 left-1/2 -translate-x-1/2 flex items-center gap-2 p-2 rounded-2xl bg-neutral-900/90 backdrop-blur-xl border border-white/10 shadow-2xl shadow-black/50 z-50">
|
||||
|
||||
{/* Tools Group */}
|
||||
<div className="flex items-center gap-1">
|
||||
{tools.map(({ id, icon, label }) => (
|
||||
<button
|
||||
key={id}
|
||||
onClick={() => setTool(id)}
|
||||
className={`w-10 h-10 rounded flex items-center justify-center text-lg transition-colors ${
|
||||
className={`w-10 h-10 rounded-xl flex items-center justify-center transition-all duration-200 ${
|
||||
tool === id
|
||||
? 'bg-blue-600 text-white'
|
||||
: 'text-neutral-400 hover:bg-neutral-700 hover:text-white'
|
||||
? 'bg-blue-600 text-white shadow-lg shadow-blue-500/25 scale-100 ring-1 ring-blue-500/50'
|
||||
: 'text-neutral-400 hover:text-white hover:bg-white/5 active:scale-95'
|
||||
}`}
|
||||
title={label}
|
||||
>
|
||||
@@ -31,15 +64,15 @@ const Toolbar: React.FC = () => {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="h-px w-8 bg-neutral-600 my-2" />
|
||||
<div className="w-px h-6 bg-white/10 mx-2" />
|
||||
|
||||
{/* Grid toggle */}
|
||||
{/* Grid Toggle */}
|
||||
<button
|
||||
onClick={() => setShowGrid(!showGrid)}
|
||||
className={`w-10 h-10 rounded flex items-center justify-center transition-colors ${
|
||||
className={`w-10 h-10 rounded-xl flex items-center justify-center transition-all duration-200 ${
|
||||
showGrid
|
||||
? 'bg-neutral-600 text-white'
|
||||
: 'text-neutral-400 hover:bg-neutral-700 hover:text-white'
|
||||
? 'bg-white/10 text-white ring-1 ring-white/20'
|
||||
: 'text-neutral-400 hover:text-white hover:bg-white/5 active:scale-95'
|
||||
}`}
|
||||
title="Toggle Grid (⌘;)"
|
||||
>
|
||||
@@ -48,30 +81,27 @@ const Toolbar: React.FC = () => {
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
{/* Spacer */}
|
||||
<div className="flex-1" />
|
||||
|
||||
{/* Zoom controls */}
|
||||
<div className="flex flex-col gap-1">
|
||||
{/* Zoom Controls */}
|
||||
<div className="flex items-center gap-1 bg-white/5 rounded-xl p-1 ml-1">
|
||||
<button
|
||||
onClick={() => setZoom(zoom + 0.1)}
|
||||
className="w-10 h-10 rounded flex items-center justify-center text-neutral-400 hover:bg-neutral-700 hover:text-white transition-colors"
|
||||
title="Zoom In (⌘+)"
|
||||
onClick={() => setZoom(zoom - 0.1)}
|
||||
className="w-8 h-8 rounded-lg flex items-center justify-center text-neutral-400 hover:text-white hover:bg-white/10 transition-colors"
|
||||
title="Zoom Out (⌘-)"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v6m3-3H7" />
|
||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 12H4" />
|
||||
</svg>
|
||||
</button>
|
||||
<div className="text-xs text-neutral-400 text-center py-1">
|
||||
<div className="w-12 text-xs font-medium text-neutral-300 text-center select-none tabular-nums">
|
||||
{Math.round(zoom * 100)}%
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setZoom(zoom - 0.1)}
|
||||
className="w-10 h-10 rounded flex items-center justify-center text-neutral-400 hover:bg-neutral-700 hover:text-white transition-colors"
|
||||
title="Zoom Out (⌘-)"
|
||||
onClick={() => setZoom(zoom + 0.1)}
|
||||
className="w-8 h-8 rounded-lg flex items-center justify-center text-neutral-400 hover:text-white hover:bg-white/10 transition-colors"
|
||||
title="Zoom In (⌘+)"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM13 10H7" />
|
||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user