Skip to content

Commit 9f64a6d

Browse files
committed
feat: ui improvements
1 parent c0fd446 commit 9f64a6d

2 files changed

Lines changed: 90 additions & 80 deletions

File tree

editor/src/App.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -650,8 +650,8 @@ export default function App() {
650650
return (
651651
<div className="h-screen flex flex-col bg-bg">
652652
{/* Top bar */}
653-
<header className="flex items-center justify-between px-4 py-2 border-b border-cell-border bg-bg shrink-0">
654-
<div className="flex items-center gap-4">
653+
<header className="flex flex-wrap items-start justify-between gap-x-6 gap-y-3 px-4 py-3 border-b border-cell-border bg-bg shrink-0">
654+
<div className="flex min-w-0 flex-wrap items-center gap-4">
655655
<h1 className="text-sm font-bold text-text tracking-tight">
656656
Stencil Editor
657657
</h1>
@@ -702,7 +702,7 @@ export default function App() {
702702
className="px-2 py-1 bg-input border border-border rounded text-sm text-text-secondary placeholder:text-text-faint focus:outline-none focus:border-accent w-64"
703703
/>
704704
</div>
705-
<div className="flex items-center gap-3">
705+
<div className="flex flex-1 min-w-[320px] flex-wrap items-start justify-end gap-3">
706706
<button
707707
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
708708
className="px-2 py-1 text-sm bg-elevated border border-border hover:border-border-strong rounded transition-colors"
@@ -721,18 +721,18 @@ export default function App() {
721721
)}
722722
<ImportButton onImport={handleImport} />
723723
{activeTab === 'editor' && (
724-
<DiscriminatorPicker
725-
isActive={mode === 'discriminator'}
726-
currentCell={schema.schema.discriminator.cell}
727-
cells={schema.schema.discriminator.cells}
728-
workbook={spreadsheet.workbook}
729-
sheetNames={spreadsheet.sheetNames}
730-
activeSheet={spreadsheet.activeSheet}
731-
onToggle={handleToggleDiscriminator}
732-
onAddRef={handleAddDiscriminatorRef}
733-
onRemoveCell={schema.removeDiscriminator}
734-
onClearAll={schema.clearDiscriminators}
735-
/>
724+
<DiscriminatorPicker
725+
isActive={mode === 'discriminator'}
726+
currentCell={schema.schema.discriminator.cell}
727+
cells={schema.schema.discriminator.cells}
728+
workbook={spreadsheet.workbook}
729+
sheetNames={spreadsheet.sheetNames}
730+
activeSheet={spreadsheet.activeSheet}
731+
onToggle={handleToggleDiscriminator}
732+
onAddRef={handleAddDiscriminatorRef}
733+
onRemoveCell={schema.removeDiscriminator}
734+
onClearAll={schema.clearDiscriminators}
735+
/>
736736
)}
737737
<ExportButton schema={schema.schema} />
738738
</div>

editor/src/components/DiscriminatorPicker.tsx

Lines changed: 75 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -53,84 +53,94 @@ export function DiscriminatorPicker({
5353
);
5454

5555
return (
56-
<div className="relative flex items-center gap-2">
57-
<button
58-
onClick={onToggle}
59-
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-colors ${
60-
isActive
61-
? 'bg-amber-500/20 text-amber-300 border border-amber-500/50'
62-
: currentCell
63-
? 'bg-elevated text-text-secondary border border-border-strong hover:border-border-strong'
64-
: 'bg-elevated text-text-secondary border border-border hover:border-border-strong'
65-
}`}
66-
title={isActive ? 'Click a cell to add as discriminator' : `Add discriminator cell (${cellSummary})`}
67-
>
68-
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
69-
<path
70-
strokeLinecap="round"
71-
strokeLinejoin="round"
72-
d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"
73-
/>
74-
</svg>
75-
{isActive ? (
76-
<span>Click a cell…</span>
77-
) : currentCell ? (
78-
<span>
79-
Discriminator:
80-
{' '}
81-
<span className="font-mono">{currentCell}</span>
82-
{count > 1 ? ` +${count - 1}` : ''}
83-
</span>
84-
) : (
85-
<span>Add Discriminator</span>
86-
)}
87-
</button>
88-
89-
<button
90-
type="button"
91-
onClick={() => setShowHeaderFooterForm((current) => !current)}
92-
className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium bg-elevated text-text-secondary border border-border hover:border-border-strong transition-colors"
93-
title="Add a header or footer discriminator"
94-
>
95-
<span>Header/Footer</span>
96-
</button>
56+
<div className="relative min-w-[300px] max-w-[480px] rounded-xl border border-border bg-surface/80 px-3 py-2">
57+
<div className="flex items-start justify-between gap-3">
58+
<div className="min-w-0">
59+
<div className="text-[11px] uppercase tracking-[0.18em] text-text-muted">Discriminator</div>
60+
<div className="mt-1 text-sm text-text">
61+
{currentCell ? (
62+
<span className="flex flex-wrap items-baseline gap-2">
63+
<span className="text-text-secondary">Primary</span>
64+
<span className="font-mono text-xs text-text">{currentCell}</span>
65+
{count > 1 && <span className="text-xs text-text-muted">+{count - 1} more</span>}
66+
</span>
67+
) : (
68+
<span className="text-text-secondary">No discriminator refs yet</span>
69+
)}
70+
</div>
71+
</div>
72+
73+
<div className="flex shrink-0 items-center gap-2">
74+
<button
75+
onClick={onToggle}
76+
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-colors ${
77+
isActive
78+
? 'bg-amber-500/20 text-amber-300 border border-amber-500/50'
79+
: currentCell
80+
? 'bg-elevated text-text-secondary border border-border-strong hover:border-border-strong'
81+
: 'bg-elevated text-text-secondary border border-border hover:border-border-strong'
82+
}`}
83+
title={isActive ? 'Click a cell to add as discriminator' : `Add discriminator cell (${cellSummary})`}
84+
>
85+
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
86+
<path
87+
strokeLinecap="round"
88+
strokeLinejoin="round"
89+
d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"
90+
/>
91+
</svg>
92+
<span>{isActive ? 'Pick Cell' : 'Cell Ref'}</span>
93+
</button>
94+
95+
<button
96+
type="button"
97+
onClick={() => setShowHeaderFooterForm((current) => !current)}
98+
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium border transition-colors ${
99+
showHeaderFooterForm
100+
? 'border-amber-500/50 bg-amber-500/15 text-amber-200'
101+
: 'bg-elevated text-text-secondary border-border hover:border-border-strong'
102+
}`}
103+
title="Add a header or footer discriminator"
104+
>
105+
<span>Header/Footer</span>
106+
</button>
107+
</div>
108+
</div>
97109

98110
{count > 0 && (
99-
<>
100-
<div className="flex items-center gap-1 max-w-[360px] overflow-x-auto">
101-
{discriminatorCells.map((cell) => (
102-
<span
103-
key={cell}
104-
className="inline-flex items-center gap-1 rounded-md border border-border bg-surface px-2 py-1 text-xs text-text"
111+
<div className="mt-3 flex flex-wrap items-center gap-2">
112+
{discriminatorCells.map((cell) => (
113+
<span
114+
key={cell}
115+
className="inline-flex max-w-full items-center gap-1 rounded-full border border-border bg-bg px-2.5 py-1 text-xs text-text"
116+
>
117+
<span className="truncate font-mono">{cell}</span>
118+
<button
119+
type="button"
120+
onClick={() => onRemoveCell(cell)}
121+
className="text-text-muted hover:text-red-300 transition-colors"
122+
title={`Remove discriminator ${cell}`}
105123
>
106-
<span className="font-mono">{cell}</span>
107-
<button
108-
type="button"
109-
onClick={() => onRemoveCell(cell)}
110-
className="text-text-muted hover:text-red-300 transition-colors"
111-
title={`Remove discriminator ${cell}`}
112-
>
113-
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
114-
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
115-
</svg>
116-
</button>
117-
</span>
118-
))}
119-
</div>
124+
<svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
125+
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
126+
</svg>
127+
</button>
128+
</span>
129+
))}
120130

121131
<button
122132
type="button"
123133
onClick={onClearAll}
124-
className="px-2 py-1 text-xs text-text-secondary hover:text-red-300 bg-elevated border border-border hover:border-border-strong rounded transition-colors"
134+
className="px-2 py-1 text-xs text-text-secondary hover:text-red-300 bg-elevated border border-border hover:border-border-strong rounded-full transition-colors"
125135
title="Remove all discriminator cells"
126136
>
127-
Clear
137+
Clear All
128138
</button>
129-
</>
139+
</div>
130140
)}
131141

132142
{showHeaderFooterForm && (
133-
<div className="absolute right-0 top-full z-20 mt-2 w-[360px] rounded-xl border border-border bg-surface p-3 shadow-2xl">
143+
<div className="absolute right-0 top-full z-20 mt-3 w-[360px] rounded-xl border border-border bg-surface p-3 shadow-2xl">
134144
<div className="mb-3 flex items-center justify-between">
135145
<div>
136146
<div className="text-xs font-medium text-text">Header/Footer Discriminator</div>

0 commit comments

Comments
 (0)