feat(q-2-scheme): 添加 q_scheme_select_options 方法并重构预览组件布局
This commit is contained in:
@@ -3,6 +3,7 @@ import { includes, isEmpty, isNil } from 'lodash-es';
|
||||
import { useActionState, useCallback, useMemo, useState } from 'react';
|
||||
import { useColorFunction } from '../../../ColorFunctionContext';
|
||||
import { FloatColorPicker } from '../../../components/FloatColorPicker';
|
||||
import { HSegmentedControl } from '../../../components/HSegmentedControl';
|
||||
import { NotificationType, useNotification } from '../../../components/Notifications';
|
||||
import { ScrollArea } from '../../../components/ScrollArea';
|
||||
import { VSegmentedControl } from '../../../components/VSegmentedControl';
|
||||
@@ -84,6 +85,15 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
|
||||
}
|
||||
return [];
|
||||
}, []);
|
||||
const schemeStrategies = useMemo(() => {
|
||||
try {
|
||||
if (!colorFn) throw 'Web Assembly functions is not available';
|
||||
return colorFn.q_scheme_select_options();
|
||||
} catch (e) {
|
||||
console.error('[Q scheme builder]', e);
|
||||
}
|
||||
return [];
|
||||
}, []);
|
||||
|
||||
// Custom Colors processing
|
||||
const originalColors = useMemo(() => {
|
||||
@@ -127,18 +137,9 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
|
||||
|
||||
// collect scheme settings
|
||||
const schemeSetting = new SchemeSetting(
|
||||
new ColorShifting(
|
||||
Number(formData.get('hover_chroma')) / 100,
|
||||
Number(formData.get('hover_lightness')) / 100,
|
||||
),
|
||||
new ColorShifting(
|
||||
Number(formData.get('active_chroma')) / 100,
|
||||
Number(formData.get('active_lightness')) / 100,
|
||||
),
|
||||
new ColorShifting(
|
||||
Number(formData.get('focus_chroma')) / 100,
|
||||
Number(formData.get('focus_lightness')) / 100,
|
||||
),
|
||||
new ColorShifting(0, 0),
|
||||
new ColorShifting(0, 0),
|
||||
new ColorShifting(0, 0),
|
||||
new ColorShifting(
|
||||
Number(formData.get('disabled_chroma')) / 100,
|
||||
Number(formData.get('disabled_lightness')) / 100,
|
||||
@@ -406,63 +407,6 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
|
||||
<h5 className={styles.segment_title}>Automated parameters</h5>
|
||||
<label style={{ gridColumn: 2 }}>Chroma shifting</label>
|
||||
<label style={{ gridColumn: 3 }}>Lightness shifting</label>
|
||||
<label className={styles.label}>Hover</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="hover_chroma"
|
||||
defaultValue={((defaultSetting?.hover.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="hover_lightness"
|
||||
defaultValue={((defaultSetting?.hover.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<label className={styles.label}>Active</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="active_chroma"
|
||||
defaultValue={((defaultSetting?.active.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="active_lightness"
|
||||
defaultValue={((defaultSetting?.active.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<label className={styles.label}>Focus</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="focus_chroma"
|
||||
defaultValue={((defaultSetting?.focus.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="focus_lightness"
|
||||
defaultValue={((defaultSetting?.focus.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<label className={styles.label}>Disabled</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
@@ -518,6 +462,14 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
|
||||
defaultValue={defaultSetting?.wacg_follows}
|
||||
/>
|
||||
</div>
|
||||
<label className={styles.label}>Generate scheme</label>
|
||||
<div style={{ gridColumn: '2 / span 2' }}>
|
||||
<HSegmentedControl
|
||||
options={schemeStrategies}
|
||||
name="scheme_select"
|
||||
defaultValue={defaultSetting?.scheme_select}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.button_row} style={{ gridColumn: '2 / span 2' }}>
|
||||
<button type="submit" className="primary">
|
||||
Build Scheme
|
||||
|
||||
@@ -24,9 +24,21 @@
|
||||
.preview_unit {
|
||||
width: inherit;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
.preview_surface {
|
||||
width: inherit;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: var(--spacing-xs);
|
||||
.surface_block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-xs);
|
||||
justify-content: stretch;
|
||||
}
|
||||
}
|
||||
.preview_indi_block {
|
||||
width: inherit;
|
||||
display: grid;
|
||||
|
||||
@@ -39,23 +39,14 @@ interface PreviewLineProps {
|
||||
|
||||
const PreviewLine: FC<PreviewLineProps> = ({ name, unit }) => {
|
||||
return (
|
||||
<div className={styles.preview_unit}>
|
||||
<>
|
||||
<PreviewCell bg={unit.root} fg={unit.onRoot}>
|
||||
{name}
|
||||
</PreviewCell>
|
||||
<PreviewCell bg={unit.hover} fg={unit.onRoot}>
|
||||
{name} Hover
|
||||
</PreviewCell>
|
||||
<PreviewCell bg={unit.active} fg={unit.onRoot}>
|
||||
{name} Active
|
||||
</PreviewCell>
|
||||
<PreviewCell bg={unit.focus} fg={unit.onRoot}>
|
||||
{name} Focus
|
||||
</PreviewCell>
|
||||
<PreviewCell bg={unit.disabled} fg={unit.onDisabled}>
|
||||
{name} Disabled
|
||||
</PreviewCell>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -93,8 +84,10 @@ interface PreviewSetProps {
|
||||
const PreviewSet: FC<PreviewSetProps> = ({ name, colorUnit }) => {
|
||||
return (
|
||||
<>
|
||||
<PreviewLine name={name} unit={colorUnit.root} />
|
||||
<PreviewLine name={`${name} Surface`} unit={colorUnit.surface} />
|
||||
<div className={styles.preview_unit}>
|
||||
<PreviewLine name={name} unit={colorUnit.root} />
|
||||
<PreviewLine name={`${name} Surface`} unit={colorUnit.surface} />
|
||||
</div>
|
||||
<PreviewSwatchLine swatch={colorUnit.swatch} />
|
||||
</>
|
||||
);
|
||||
@@ -119,8 +112,8 @@ const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => {
|
||||
}, [baseline.customColors]);
|
||||
|
||||
return (
|
||||
<div className={styles.preview_block} style={{ backgroundColor: `#${baseline.surface.root}` }}>
|
||||
<h2 style={{ color: `#${baseline.surface.onRoot}` }}>{title}</h2>
|
||||
<div className={styles.preview_block} style={{ backgroundColor: `#${baseline.background}` }}>
|
||||
<h2 style={{ color: `#${baseline.foreground}` }}>{title}</h2>
|
||||
<PreviewSet name="Primary" colorUnit={baseline.primary} />
|
||||
{baseline.secondary && <PreviewSet name="Secondary" colorUnit={baseline.secondary} />}
|
||||
{baseline.tertiary && <PreviewSet name="Tertiary" colorUnit={baseline.tertiary} />}
|
||||
@@ -129,10 +122,17 @@ const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => {
|
||||
<PreviewSet name="Success" colorUnit={baseline.success} />
|
||||
<PreviewSet name="Warn" colorUnit={baseline.warn} />
|
||||
<PreviewSet name="Info" colorUnit={baseline.info} />
|
||||
<PreviewLine name="Neutral" unit={baseline.neutral} />
|
||||
<PreviewLine name="Neutral Variant" unit={baseline.neutralVariant} />
|
||||
<PreviewLine name="Surface" unit={baseline.surface} />
|
||||
<PreviewLine name="Surface Variant" unit={baseline.surfaceVariant} />
|
||||
<div className={styles.preview_unit}>
|
||||
<PreviewLine name="Neutral" unit={baseline.neutral} />
|
||||
<PreviewLine name="Neutral Variant" unit={baseline.neutralVariant} />
|
||||
</div>
|
||||
<div className={styles.preview_surface}>
|
||||
{baseline.surface.map((surfaceSet, index) => (
|
||||
<div className={styles.surface_block} key={index}>
|
||||
<PreviewLine key={index} name={`Surface ${index + 1}`} unit={surfaceSet} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className={styles.preview_indi_block}>
|
||||
<PreviewCell bg={baseline.shadow} fg={baseline.neutralVariant.onRoot}>
|
||||
Shadow
|
||||
|
||||
@@ -2,9 +2,6 @@ import { QSchemeSetting } from './q-scheme';
|
||||
|
||||
export type Q2ColorSet = {
|
||||
root: string;
|
||||
hover: string;
|
||||
active: string;
|
||||
focus: string;
|
||||
disabled: string;
|
||||
onRoot: string;
|
||||
onDisabled: string;
|
||||
@@ -23,13 +20,14 @@ export type Q2Baseline = {
|
||||
accent: Q2ColorUnit | null;
|
||||
neutral: Q2ColorSet;
|
||||
neutralVariant: Q2ColorSet;
|
||||
surface: Q2ColorSet;
|
||||
surfaceVariant: Q2ColorSet;
|
||||
surface: Q2ColorSet[];
|
||||
neutralSwatch: Record<string, string>;
|
||||
danger: Q2ColorUnit;
|
||||
success: Q2ColorUnit;
|
||||
warn: Q2ColorUnit;
|
||||
info: Q2ColorUnit;
|
||||
foreground: string;
|
||||
background: string;
|
||||
shadow: string;
|
||||
overlay: string;
|
||||
outline: string;
|
||||
|
||||
Reference in New Issue
Block a user