基本完成M2 Scheme的预览。

This commit is contained in:
徐涛 2025-02-10 09:51:15 +08:00
parent 2f51a80c91
commit 2c47369772
3 changed files with 141 additions and 2 deletions

View File

@ -2,6 +2,8 @@ import { isEqual, isNil } from 'lodash-es';
import { useState } from 'react'; import { useState } from 'react';
import { Tab } from '../../components/Tab'; import { Tab } from '../../components/Tab';
import { SchemeExport } from './Export'; import { SchemeExport } from './Export';
import { M2SchemeBuilder } from './m2-scheme/Builder';
import { M2SchemePreview } from './m2-scheme/Preview';
const tabOptions = [ const tabOptions = [
{ title: 'Overview', id: 'overview' }, { title: 'Overview', id: 'overview' },
@ -21,8 +23,10 @@ export function M2Scheme({ scheme }: M3SchemeProps) {
return ( return (
<> <>
<Tab tabs={tabOptions} activeTab={activeTab} onActive={setActiveTab} /> <Tab tabs={tabOptions} activeTab={activeTab} onActive={setActiveTab} />
{isEqual(activeTab, 'overview') && <div>Preview</div>} {isEqual(activeTab, 'overview') && <M2SchemePreview scheme={scheme} />}
{isEqual(activeTab, 'builder') && <div>Builder</div>} {isEqual(activeTab, 'builder') && (
<M2SchemeBuilder scheme={scheme} onBuildComplete={() => setActiveTab('overview')} />
)}
{isEqual(activeTab, 'export') && <SchemeExport scheme={scheme} />} {isEqual(activeTab, 'export') && <SchemeExport scheme={scheme} />}
</> </>
); );

View File

@ -0,0 +1,41 @@
@layer pages {
.preview_layout {
padding: var(--spacing-s) var(--spacing-m);
width: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--spacing-m);
}
.preview_block {
width: inherit;
padding: var(--spacing-m) var(--spacing-m);
display: flex;
flex-direction: column;
gap: var(--spacing-m);
font-size: var(--font-size-s);
line-height: 1.1em;
h4 {
font-size: var(--font-size-m);
font-weight: bold;
line-height: 1.7em;
}
}
.horizontal_set {
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: stretch;
gap: 0;
}
.color_block {
padding: var(--spacing-s) var(--spacing-xs);
flex: 1;
display: flex;
flex-direction: column;
gap: var(--spacing-xs);
.wacg {
font-size: var(--font-size-xxs);
}
}
}

View File

@ -0,0 +1,94 @@
import { useMemo } from 'react';
import { useColorFunction } from '../../../ColorFunctionContext';
import { ScrollArea } from '../../../components/ScrollArea';
import { Baseline, ColorSet, MaterialDesign2SchemeStorage } from '../../../material-2-scheme';
import { SchemeContent } from '../../../models';
import styles from './Preview.module.css';
type M2SchemeFunctionColorProps = {
title: string;
color: ColorSet;
};
function M2SchemeFunctionColor({ title, color }: M2SchemeFunctionColorProps) {
const { colorFn } = useColorFunction();
const rootWacgRatio = useMemo(() => {
try {
return colorFn?.wacg_relative_contrast(color.on, color.root) ?? null;
} catch (e) {
console.error('[calc root wacg]', e);
}
return null;
}, [colorFn, color.on, color.root]);
const variantWacgRatio = useMemo(() => {
try {
return colorFn?.wacg_relative_contrast(color.on, color.variant) ?? null;
} catch (e) {
console.error('[calc variant wacg]', e);
}
return null;
}, [colorFn, color.on, color.variant]);
return (
<div className={styles.horizontal_set}>
<div
className={styles.color_block}
style={{ backgroundColor: `#${color.root}`, color: `#${color.on}` }}>
<span>{title}</span>
<span className={styles.wacg}>WACG: {rootWacgRatio?.toFixed(2)}</span>
</div>
<div
className={styles.color_block}
style={{ backgroundColor: `#${color.variant}`, color: `#${color.on}` }}>
<span>{title} Variant</span>
<span className={styles.wacg}>WACG: {variantWacgRatio?.toFixed(2)}</span>
</div>
<div
className={styles.color_block}
style={{ backgroundColor: `#${color.on}`, color: `#${color.root}` }}>
On {title}
</div>
</div>
);
}
type PreviewBlockProps = {
title: string;
baseline: Baseline;
};
function PreviewBlock({ title, baseline }: PreviewBlockProps) {
return (
<div
className={styles.preview_block}
style={{
backgroundColor: `#${baseline.background.root}`,
color: `#${baseline.background.on}`,
}}>
<h4>{title} Scheme</h4>
<M2SchemeFunctionColor title="Primary" color={baseline.primary} />
<M2SchemeFunctionColor title="Secondary" color={baseline.secondary} />
<M2SchemeFunctionColor title="Error" color={baseline.error} />
<M2SchemeFunctionColor title="Background" color={baseline.background} />
<M2SchemeFunctionColor title="Surface" color={baseline.surface} />
{Object.entries(baseline.custom_colors).map(([name, set], index) => (
<M2SchemeFunctionColor key={index} title={name} color={set} />
))}
</div>
);
}
type M2SchemePreviewProps = {
scheme: SchemeContent<MaterialDesign2SchemeStorage>;
};
export function M2SchemePreview({ scheme }: M2SchemePreviewProps) {
return (
<ScrollArea enableY>
<div className={styles.preview_layout}>
<PreviewBlock title="Light" baseline={scheme.schemeStorage.scheme?.light} />
<PreviewBlock title="Dark" baseline={scheme.schemeStorage.scheme?.dark} />
</div>
</ScrollArea>
);
}