feat(frontend): restyle format picker and add file size to the config card

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 16:01:37 +02:00
co-authored by Claude Sonnet 5
parent 7c58e50c11
commit 994d70aa62
2 changed files with 83 additions and 14 deletions
+20 -12
View File
@@ -1,4 +1,5 @@
import { File as FileIcon } from '@phosphor-icons/react';
import { formatBytes } from '../utils/formatBytes.js';
const QUALITY_FORMATS = ['jpg', 'jpeg', 'webp', 'avif', 'tiff'];
const ICON_SIZES = [16, 32, 48, 256, 512];
@@ -7,21 +8,28 @@ const DEFAULT_ICON_SIZE = 256;
export function FileConfigCard({ item, index, t, onTargetFormatChange, onQualityChange, onIconSizeChange }) {
return (
<li className="file-config-card">
<FileIcon size={24} weight="regular" />
<span className="file-config-name">{item.file.name}</span>
<div className="file-tile-header">
<FileIcon size={24} weight="regular" />
<span className="file-tile-name">{item.file.name}</span>
<span className="file-tile-size">{formatBytes(item.file.size)}</span>
</div>
{item.targets.length > 0 ? (
<div className="file-config-controls">
<select
value={item.targetFormat ?? ''}
onChange={(event) => onTargetFormatChange(index, event.target.value)}
>
{item.targets.map((target) => (
<option key={target} value={target}>
{target}
</option>
))}
</select>
<div className="format-select-group">
<select
className="format-select"
value={item.targetFormat ?? ''}
onChange={(event) => onTargetFormatChange(index, event.target.value)}
>
{item.targets.map((target) => (
<option key={target} value={target}>
{target}
</option>
))}
</select>
{item.targetFormat && <span className="format-badge">{item.targetFormat.toUpperCase()}</span>}
</div>
{QUALITY_FORMATS.includes(item.targetFormat) && (
<label>
+63 -2
View File
@@ -59,11 +59,26 @@
border-radius: 8px;
}
.file-config-name {
font-weight: 500;
.file-tile-header {
display: flex;
align-items: center;
gap: 0.5rem;
flex: 1 1 100%;
}
.file-tile-name {
font-weight: 500;
flex: 1 1 auto;
overflow-wrap: anywhere;
}
.file-tile-size {
font-size: 0.875rem;
color: var(--color-foreground);
opacity: 0.65;
white-space: nowrap;
}
.file-config-controls {
display: flex;
flex-direction: column;
@@ -71,6 +86,52 @@
flex: 1 1 100%;
}
.file-config-controls label {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
}
.format-select-group {
display: flex;
align-items: center;
gap: 0.5rem;
}
.format-select {
appearance: none;
background-color: var(--color-background);
color: var(--color-foreground);
border: 1px solid var(--color-border);
border-radius: 8px;
padding: 0.5rem 2rem 0.5rem 0.75rem;
font-weight: 500;
min-height: 44px;
background-image:
linear-gradient(45deg, transparent 50%, var(--color-foreground) 50%),
linear-gradient(135deg, var(--color-foreground) 50%, transparent 50%);
background-position:
calc(100% - 17px) calc(1.15em),
calc(100% - 12px) calc(1.15em);
background-size: 5px 5px, 5px 5px;
background-repeat: no-repeat;
}
.format-select:focus-visible {
border-color: var(--color-ring);
}
.format-badge {
background: var(--color-muted);
color: var(--color-primary);
border-radius: 999px;
padding: 0.25rem 0.6rem;
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0.03em;
}
.convert-button {
background: var(--color-accent);
color: var(--color-on-primary);