f13fc37b5a
Layout - the panel is a cascade of columns: the rail's tabs, the tab's chips, the open chip's sub-chips, then the ruler. A child column no longer hides the column it came from (TEMP -> COLOR TEMP keeps TEMP visible); chips stack one per row instead of wrapping - FRAME's WATERMARK opens its own column, so the frame chips stay put - CREATE RECIPES gets the wide column its two-up form needs WB colour swatches - the ruler draws a colour box under the slider that follows the value: COLOR TEMP is the Kelvin colour (Tanner Helland), TINT runs green -10 -> neutral 0 -> magenta +10 HDF EFFECT - knee 0.55..0.85 -> 0.45..0.75, blur 0.004+0.015n -> 0.006+0.024n of the width, screen alpha 0.15+0.35n -> 0.28+0.52n: a wide halo on the highlights instead of a hairline glow. Web copy of toneShader only — the phone keeps its own tuning. Tabs - rail order is PRESETS, FAVORITED, WB, LIGHT, FX, FRAME, CREATE RECIPES
38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import type { MsgKey } from '../i18n/vi';
|
|
import { useI18n } from '../i18n/I18nProvider';
|
|
|
|
// The app's seven tabs. WB leads LIGHT — white balance is the first thing the
|
|
// eye corrects, and the web rail draws them in the order the panel opens. The
|
|
// rail is a single column on desktop and becomes the bottom bar under 860px
|
|
// (see styles/app.css).
|
|
export type TabId = 'presets' | 'favorited' | 'wb' | 'light' | 'fx' | 'frame' | 'create';
|
|
|
|
export const TABS: { id: TabId; label: MsgKey; glyph: string }[] = [
|
|
{ id: 'presets', label: 'tab.presets', glyph: '◉' },
|
|
{ id: 'favorited', label: 'tab.favorited', glyph: '★' },
|
|
{ id: 'wb', label: 'tab.wb', glyph: '◐' },
|
|
{ id: 'light', label: 'tab.light', glyph: '☀' },
|
|
{ id: 'fx', label: 'tab.fx', glyph: '✦' },
|
|
{ id: 'frame', label: 'tab.frame', glyph: '▣' },
|
|
{ id: 'create', label: 'tab.create', glyph: '✎' },
|
|
];
|
|
|
|
export function ToolRail({ tab, onTab }: { tab: TabId; onTab: (tab: TabId) => void }) {
|
|
const { t } = useI18n();
|
|
return (
|
|
<nav className="rail" aria-label="tool tabs">
|
|
{TABS.map((entry) => (
|
|
<button
|
|
key={entry.id}
|
|
type="button"
|
|
aria-pressed={tab === entry.id}
|
|
onClick={() => onTab(entry.id)}
|
|
>
|
|
<span className="glyph" aria-hidden="true">{entry.glyph}</span>
|
|
{t(entry.label)}
|
|
</button>
|
|
))}
|
|
</nav>
|
|
);
|
|
}
|