feat(q-2-scheme): 添加中性色板并优化自定义颜色展示

- 在Q2Baseline类型中添加neutralSwatch字段
- 将custom重命名为customColors以提高语义清晰度
- 优化预览组件中色板的展示样式,添加标签和间距
- 更新Builder组件处理自定义颜色的映射逻辑
This commit is contained in:
徐涛 2025-07-20 07:54:17 +08:00
parent edc2a0546e
commit afaa7d25de
4 changed files with 31 additions and 9 deletions

View File

@ -9,7 +9,7 @@ import { VSegmentedControl } from '../../../components/VSegmentedControl';
import { SchemeContent } from '../../../models'; import { SchemeContent } from '../../../models';
import { Q2SchemeSource, Q2SchemeStorage } from '../../../q-2-scheme'; import { Q2SchemeSource, Q2SchemeStorage } from '../../../q-2-scheme';
import { useUpdateScheme } from '../../../stores/schemes'; import { useUpdateScheme } from '../../../stores/schemes';
import { isNilOrEmpty } from '../../../utls'; import { isNilOrEmpty, mapToObject } from '../../../utls';
import { ColorEntry, IdenticalColorEntry } from '../ColorEntry'; import { ColorEntry, IdenticalColorEntry } from '../ColorEntry';
import styles from './Builder.module.css'; import styles from './Builder.module.css';
@ -220,7 +220,16 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
console.log('[Generated scheme]', generatedScheme); console.log('[Generated scheme]', generatedScheme);
updateScheme((prev) => { updateScheme((prev) => {
prev.schemeStorage.source = source; prev.schemeStorage.source = source;
prev.schemeStorage.scheme = generatedScheme[0]; prev.schemeStorage.scheme = {
light: {
...generatedScheme[0].light,
customColors: mapToObject(generatedScheme[0].light.customColors),
},
dark: {
...generatedScheme[0].dark,
customColors: mapToObject(generatedScheme[0].dark.customColors),
},
};
prev.schemeStorage.cssVariables = generatedScheme[1]; prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.cssAutoSchemeVariables = generatedScheme[2]; prev.schemeStorage.cssAutoSchemeVariables = generatedScheme[2];
prev.schemeStorage.scssVariables = generatedScheme[3]; prev.schemeStorage.scssVariables = generatedScheme[3];

View File

@ -39,7 +39,11 @@
grid-template-columns: repeat(16, 1fr); grid-template-columns: repeat(16, 1fr);
gap: var(--spacing-xs); gap: var(--spacing-xs);
.preview_swatch_cell { .preview_swatch_cell {
height: 1em; padding: var(--spacing-xs) var(--spacing-s);
.swatch_label {
font-size: var(--font-size-s);
filter: invert(100%);
}
} }
} }
.preview_cell { .preview_cell {

View File

@ -69,7 +69,14 @@ const PreviewSwatchLine: FC<PreviewSwatchLineProps> = ({ swatch }) => {
for (const key of keys(swatch)) { for (const key of keys(swatch)) {
const color = swatch[key]; const color = swatch[key];
collection.push( collection.push(
<div className={styles.preview_swatch_cell} style={{ backgroundColor: `#${color}` }} />, <div
className={styles.preview_swatch_cell}
style={{ backgroundColor: `#${color}` }}
key={key}>
<span className={styles.swatch_label} style={{ color: `#${color}` }}>
{key}
</span>
</div>,
); );
} }
return collection; return collection;
@ -88,7 +95,7 @@ const PreviewSet: FC<PreviewSetProps> = ({ name, colorUnit }) => {
<> <>
<PreviewLine name={name} unit={colorUnit.root} /> <PreviewLine name={name} unit={colorUnit.root} />
<PreviewLine name={`${name} Surface`} unit={colorUnit.surface} /> <PreviewLine name={`${name} Surface`} unit={colorUnit.surface} />
<PreviewSwatchLine name={name} swatch={colorUnit.swatch} /> <PreviewSwatchLine swatch={colorUnit.swatch} />
</> </>
); );
}; };
@ -100,16 +107,16 @@ interface PreviewBlockProps {
const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => { const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => {
const customSets = useMemo(() => { const customSets = useMemo(() => {
const colors = keys(baseline.custom); const colors = keys(baseline.customColors);
const elements: ReactNode[] = []; const elements: ReactNode[] = [];
for (const key of colors) { for (const key of colors) {
const color = baseline.custom[key]; const color = baseline.customColors[key];
elements.push(<PreviewSet name={capitalize(key)} colorUnit={color} />); elements.push(<PreviewSet name={capitalize(key)} colorUnit={color} />);
} }
return elements; return elements;
}, [baseline.custom]); }, [baseline.customColors]);
return ( return (
<div className={styles.preview_block} style={{ backgroundColor: `#${baseline.surface.root}` }}> <div className={styles.preview_block} style={{ backgroundColor: `#${baseline.surface.root}` }}>
@ -140,6 +147,7 @@ const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => {
Outline Variant Outline Variant
</PreviewCell> </PreviewCell>
</div> </div>
<PreviewSwatchLine swatch={baseline.neutralSwatch} />
{customSets} {customSets}
</div> </div>
); );

View File

@ -25,6 +25,7 @@ export type Q2Baseline = {
neutralVariant: Q2ColorUnit; neutralVariant: Q2ColorUnit;
surface: Q2ColorUnit; surface: Q2ColorUnit;
surfaceVariant: Q2ColorUnit; surfaceVariant: Q2ColorUnit;
neutralSwatch: Record<string, string>;
danger: Q2ColorUnit; danger: Q2ColorUnit;
success: Q2ColorUnit; success: Q2ColorUnit;
warn: Q2ColorUnit; warn: Q2ColorUnit;
@ -33,7 +34,7 @@ export type Q2Baseline = {
overlay: string; overlay: string;
outline: string; outline: string;
outlineVariant: string; outlineVariant: string;
custom: Record<string, Q2ColorUnit>; customColors: Record<string, Q2ColorUnit>;
}; };
export type Q2Scheme = { export type Q2Scheme = {