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 { useActionState, useCallback, useMemo, useState } from 'react';
|
||||||
import { useColorFunction } from '../../../ColorFunctionContext';
|
import { useColorFunction } from '../../../ColorFunctionContext';
|
||||||
import { FloatColorPicker } from '../../../components/FloatColorPicker';
|
import { FloatColorPicker } from '../../../components/FloatColorPicker';
|
||||||
|
import { HSegmentedControl } from '../../../components/HSegmentedControl';
|
||||||
import { NotificationType, useNotification } from '../../../components/Notifications';
|
import { NotificationType, useNotification } from '../../../components/Notifications';
|
||||||
import { ScrollArea } from '../../../components/ScrollArea';
|
import { ScrollArea } from '../../../components/ScrollArea';
|
||||||
import { VSegmentedControl } from '../../../components/VSegmentedControl';
|
import { VSegmentedControl } from '../../../components/VSegmentedControl';
|
||||||
@@ -84,6 +85,15 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
|
|||||||
}
|
}
|
||||||
return [];
|
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
|
// Custom Colors processing
|
||||||
const originalColors = useMemo(() => {
|
const originalColors = useMemo(() => {
|
||||||
@@ -127,18 +137,9 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
|
|||||||
|
|
||||||
// collect scheme settings
|
// collect scheme settings
|
||||||
const schemeSetting = new SchemeSetting(
|
const schemeSetting = new SchemeSetting(
|
||||||
new ColorShifting(
|
new ColorShifting(0, 0),
|
||||||
Number(formData.get('hover_chroma')) / 100,
|
new ColorShifting(0, 0),
|
||||||
Number(formData.get('hover_lightness')) / 100,
|
new ColorShifting(0, 0),
|
||||||
),
|
|
||||||
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(
|
new ColorShifting(
|
||||||
Number(formData.get('disabled_chroma')) / 100,
|
Number(formData.get('disabled_chroma')) / 100,
|
||||||
Number(formData.get('disabled_lightness')) / 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>
|
<h5 className={styles.segment_title}>Automated parameters</h5>
|
||||||
<label style={{ gridColumn: 2 }}>Chroma shifting</label>
|
<label style={{ gridColumn: 2 }}>Chroma shifting</label>
|
||||||
<label style={{ gridColumn: 3 }}>Lightness 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>
|
<label className={styles.label}>Disabled</label>
|
||||||
<div className="input_wrapper">
|
<div className="input_wrapper">
|
||||||
<input
|
<input
|
||||||
@@ -518,6 +462,14 @@ export function Q2SchemeBuilder({ scheme, onBuildCompleted }: Q2SchemeBuilderPro
|
|||||||
defaultValue={defaultSetting?.wacg_follows}
|
defaultValue={defaultSetting?.wacg_follows}
|
||||||
/>
|
/>
|
||||||
</div>
|
</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' }}>
|
<div className={styles.button_row} style={{ gridColumn: '2 / span 2' }}>
|
||||||
<button type="submit" className="primary">
|
<button type="submit" className="primary">
|
||||||
Build Scheme
|
Build Scheme
|
||||||
|
|||||||
@@ -24,9 +24,21 @@
|
|||||||
.preview_unit {
|
.preview_unit {
|
||||||
width: inherit;
|
width: inherit;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(5, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
gap: var(--spacing-xs);
|
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 {
|
.preview_indi_block {
|
||||||
width: inherit;
|
width: inherit;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -39,23 +39,14 @@ interface PreviewLineProps {
|
|||||||
|
|
||||||
const PreviewLine: FC<PreviewLineProps> = ({ name, unit }) => {
|
const PreviewLine: FC<PreviewLineProps> = ({ name, unit }) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.preview_unit}>
|
<>
|
||||||
<PreviewCell bg={unit.root} fg={unit.onRoot}>
|
<PreviewCell bg={unit.root} fg={unit.onRoot}>
|
||||||
{name}
|
{name}
|
||||||
</PreviewCell>
|
</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}>
|
<PreviewCell bg={unit.disabled} fg={unit.onDisabled}>
|
||||||
{name} Disabled
|
{name} Disabled
|
||||||
</PreviewCell>
|
</PreviewCell>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,8 +84,10 @@ interface PreviewSetProps {
|
|||||||
const PreviewSet: FC<PreviewSetProps> = ({ name, colorUnit }) => {
|
const PreviewSet: FC<PreviewSetProps> = ({ name, colorUnit }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PreviewLine name={name} unit={colorUnit.root} />
|
<div className={styles.preview_unit}>
|
||||||
<PreviewLine name={`${name} Surface`} unit={colorUnit.surface} />
|
<PreviewLine name={name} unit={colorUnit.root} />
|
||||||
|
<PreviewLine name={`${name} Surface`} unit={colorUnit.surface} />
|
||||||
|
</div>
|
||||||
<PreviewSwatchLine swatch={colorUnit.swatch} />
|
<PreviewSwatchLine swatch={colorUnit.swatch} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -119,8 +112,8 @@ const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => {
|
|||||||
}, [baseline.customColors]);
|
}, [baseline.customColors]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.preview_block} style={{ backgroundColor: `#${baseline.surface.root}` }}>
|
<div className={styles.preview_block} style={{ backgroundColor: `#${baseline.background}` }}>
|
||||||
<h2 style={{ color: `#${baseline.surface.onRoot}` }}>{title}</h2>
|
<h2 style={{ color: `#${baseline.foreground}` }}>{title}</h2>
|
||||||
<PreviewSet name="Primary" colorUnit={baseline.primary} />
|
<PreviewSet name="Primary" colorUnit={baseline.primary} />
|
||||||
{baseline.secondary && <PreviewSet name="Secondary" colorUnit={baseline.secondary} />}
|
{baseline.secondary && <PreviewSet name="Secondary" colorUnit={baseline.secondary} />}
|
||||||
{baseline.tertiary && <PreviewSet name="Tertiary" colorUnit={baseline.tertiary} />}
|
{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="Success" colorUnit={baseline.success} />
|
||||||
<PreviewSet name="Warn" colorUnit={baseline.warn} />
|
<PreviewSet name="Warn" colorUnit={baseline.warn} />
|
||||||
<PreviewSet name="Info" colorUnit={baseline.info} />
|
<PreviewSet name="Info" colorUnit={baseline.info} />
|
||||||
<PreviewLine name="Neutral" unit={baseline.neutral} />
|
<div className={styles.preview_unit}>
|
||||||
<PreviewLine name="Neutral Variant" unit={baseline.neutralVariant} />
|
<PreviewLine name="Neutral" unit={baseline.neutral} />
|
||||||
<PreviewLine name="Surface" unit={baseline.surface} />
|
<PreviewLine name="Neutral Variant" unit={baseline.neutralVariant} />
|
||||||
<PreviewLine name="Surface Variant" unit={baseline.surfaceVariant} />
|
</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}>
|
<div className={styles.preview_indi_block}>
|
||||||
<PreviewCell bg={baseline.shadow} fg={baseline.neutralVariant.onRoot}>
|
<PreviewCell bg={baseline.shadow} fg={baseline.neutralVariant.onRoot}>
|
||||||
Shadow
|
Shadow
|
||||||
|
|||||||
+3
-5
@@ -2,9 +2,6 @@ import { QSchemeSetting } from './q-scheme';
|
|||||||
|
|
||||||
export type Q2ColorSet = {
|
export type Q2ColorSet = {
|
||||||
root: string;
|
root: string;
|
||||||
hover: string;
|
|
||||||
active: string;
|
|
||||||
focus: string;
|
|
||||||
disabled: string;
|
disabled: string;
|
||||||
onRoot: string;
|
onRoot: string;
|
||||||
onDisabled: string;
|
onDisabled: string;
|
||||||
@@ -23,13 +20,14 @@ export type Q2Baseline = {
|
|||||||
accent: Q2ColorUnit | null;
|
accent: Q2ColorUnit | null;
|
||||||
neutral: Q2ColorSet;
|
neutral: Q2ColorSet;
|
||||||
neutralVariant: Q2ColorSet;
|
neutralVariant: Q2ColorSet;
|
||||||
surface: Q2ColorSet;
|
surface: Q2ColorSet[];
|
||||||
surfaceVariant: Q2ColorSet;
|
|
||||||
neutralSwatch: Record<string, string>;
|
neutralSwatch: Record<string, string>;
|
||||||
danger: Q2ColorUnit;
|
danger: Q2ColorUnit;
|
||||||
success: Q2ColorUnit;
|
success: Q2ColorUnit;
|
||||||
warn: Q2ColorUnit;
|
warn: Q2ColorUnit;
|
||||||
info: Q2ColorUnit;
|
info: Q2ColorUnit;
|
||||||
|
foreground: string;
|
||||||
|
background: string;
|
||||||
shadow: string;
|
shadow: string;
|
||||||
overlay: string;
|
overlay: string;
|
||||||
outline: string;
|
outline: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user