feat: Add Canvas dark theme styling and Setup page integration
Canvas Builder Visual Updates: - Update all Canvas components to use Atomaster dark theme - BaseNode: dark background (bg-dark-800), white text, primary selection glow - NodePalette: dark sidebar with hover states - NodeConfigPanel: dark inputs, labels, and panel background - ValidationPanel: semi-transparent error/warning panels with backdrop blur - ChatPanel: dark message area with themed welcome state - ExecuteDialog: dark modal with primary button styling - ConfigImporter: dark tabs, inputs, and file upload zone - TemplateSelector: dark cards with category pills and hover effects Setup Page Integration: - Add Configuration/Canvas Builder tab switcher - Canvas tab renders AtomizerCanvas full-height - Tabs styled to match Atomaster theme Build: Passes TypeScript and Vite build Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ function BaseNodeComponent({
|
||||
selected,
|
||||
icon,
|
||||
color,
|
||||
colorBg = 'bg-gray-50',
|
||||
colorBg = 'bg-dark-700',
|
||||
children,
|
||||
inputs = 1,
|
||||
outputs = 1,
|
||||
@@ -27,13 +27,13 @@ function BaseNodeComponent({
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
group relative px-4 py-3 rounded-xl border-2 min-w-[200px] bg-white
|
||||
group relative px-4 py-3 rounded-xl border-2 min-w-[200px] bg-dark-800
|
||||
transition-all duration-300 ease-out
|
||||
${selected
|
||||
? 'border-blue-500 shadow-xl shadow-blue-100 scale-[1.02]'
|
||||
: 'border-gray-200 shadow-md hover:shadow-lg hover:border-gray-300'}
|
||||
? 'border-primary-500 shadow-xl shadow-primary-500/20 scale-[1.02]'
|
||||
: 'border-dark-600 shadow-md hover:shadow-lg hover:border-dark-500'}
|
||||
${!isConfigured ? 'border-dashed opacity-80' : ''}
|
||||
${hasError ? 'border-red-400 shadow-red-100' : ''}
|
||||
${hasError ? 'border-red-500/70 shadow-red-500/20' : ''}
|
||||
`}
|
||||
style={{
|
||||
animation: 'nodeAppear 0.3s ease-out',
|
||||
@@ -42,9 +42,9 @@ function BaseNodeComponent({
|
||||
{/* Glow effect on selection */}
|
||||
{selected && (
|
||||
<div
|
||||
className="absolute inset-0 -z-10 rounded-xl opacity-20"
|
||||
className="absolute inset-0 -z-10 rounded-xl opacity-30"
|
||||
style={{
|
||||
background: 'radial-gradient(ellipse at center, #3b82f6 0%, transparent 70%)',
|
||||
background: 'radial-gradient(ellipse at center, #6366f1 0%, transparent 70%)',
|
||||
transform: 'scale(1.3)',
|
||||
}}
|
||||
/>
|
||||
@@ -56,9 +56,9 @@ function BaseNodeComponent({
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
className={`
|
||||
!w-4 !h-4 !border-2 !border-white !shadow-md
|
||||
!w-4 !h-4 !border-2 !border-dark-800 !shadow-md
|
||||
transition-all duration-200
|
||||
${selected ? '!bg-blue-500' : '!bg-gray-400 group-hover:!bg-gray-500'}
|
||||
${selected ? '!bg-primary-500' : '!bg-dark-400 group-hover:!bg-dark-300'}
|
||||
`}
|
||||
style={{ left: -8 }}
|
||||
/>
|
||||
@@ -74,16 +74,16 @@ function BaseNodeComponent({
|
||||
<span className={`text-lg ${color}`}>{icon}</span>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<span className="font-semibold text-gray-800 text-sm">{data.label}</span>
|
||||
<span className="font-semibold text-white text-sm">{data.label}</span>
|
||||
{!isConfigured && (
|
||||
<span className="ml-2 text-xs text-orange-500 animate-pulse">Needs config</span>
|
||||
<span className="ml-2 text-xs text-amber-400 animate-pulse">Needs config</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
{children && (
|
||||
<div className="text-sm text-gray-600 mt-2 pl-11">
|
||||
<div className="text-sm text-dark-300 mt-2 pl-11">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
@@ -95,14 +95,14 @@ function BaseNodeComponent({
|
||||
) : isConfigured ? (
|
||||
<span className="w-2 h-2 bg-green-500 rounded-full block" />
|
||||
) : (
|
||||
<span className="w-2 h-2 bg-orange-400 rounded-full block" />
|
||||
<span className="w-2 h-2 bg-amber-400 rounded-full block" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Errors */}
|
||||
{hasError && (
|
||||
<div className="mt-3 pt-2 border-t border-red-100">
|
||||
<p className="text-xs text-red-600 flex items-center gap-1">
|
||||
<div className="mt-3 pt-2 border-t border-red-500/30">
|
||||
<p className="text-xs text-red-400 flex items-center gap-1">
|
||||
<span>⚠</span>
|
||||
{data.errors?.[0]}
|
||||
</p>
|
||||
@@ -115,9 +115,9 @@ function BaseNodeComponent({
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
className={`
|
||||
!w-4 !h-4 !border-2 !border-white !shadow-md
|
||||
!w-4 !h-4 !border-2 !border-dark-800 !shadow-md
|
||||
transition-all duration-200
|
||||
${selected ? '!bg-blue-500' : '!bg-gray-400 group-hover:!bg-gray-500'}
|
||||
${selected ? '!bg-primary-500' : '!bg-dark-400 group-hover:!bg-dark-300'}
|
||||
`}
|
||||
style={{ right: -8 }}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user