修正大部分的编译错误。

This commit is contained in:
徐涛
2025-02-10 14:28:34 +08:00
parent 2144cd548a
commit 88e3d1f928
44 changed files with 429 additions and 381 deletions

View File

@@ -23,18 +23,18 @@ export function Darkens({ color, darkens, mix, step, maximum, copyMode }: Darken
switch (mix) {
case 'progressive':
for (let i = 1; i <= darkens; i++) {
const darkenColor = colorFn.darken(last(darkenColors), step);
const darkenColor = colorFn.darken(last(darkenColors) ?? '', step ?? 0);
darkenColors.push(darkenColor);
}
break;
case 'linear':
for (let i = 1; i <= darkens; i++) {
const darkenColor = colorFn.darken(color, step * i);
const darkenColor = colorFn.darken(color, (step ?? 0) * i);
darkenColors.push(darkenColor);
}
break;
case 'average': {
const interval = maximum / darkens / 100;
const interval = (maximum ?? 0) / darkens / 100;
for (let i = 1; i <= darkens; i++) {
const darkenColor = colorFn.darken(color, interval * i);
darkenColors.push(darkenColor);

View File

@@ -23,18 +23,18 @@ export function Lightens({ color, lightens, mix, step, maximum, copyMode }: Ligh
switch (mix) {
case 'progressive':
for (let i = 1; i <= lightens; i++) {
const lightenColor = colorFn.lighten(last(lightenColors), step);
const lightenColor = colorFn.lighten(last(lightenColors) ?? '', step ?? 0);
lightenColors.push(lightenColor);
}
break;
case 'linear':
for (let i = 1; i <= lightens; i++) {
const lightenColor = colorFn.lighten(color, step * i);
const lightenColor = colorFn.lighten(color, (step ?? 0) * i);
lightenColors.push(lightenColor);
}
break;
case 'average': {
const interval = maximum / lightens / 100;
const interval = (maximum ?? 0) / lightens / 100;
for (let i = 1; i <= lightens; i++) {
const lightenColor = colorFn.lighten(color, interval * i);
lightenColors.push(lightenColor);

View File

@@ -1,6 +1,8 @@
import { isEqual, isNil } from 'lodash-es';
import { useState } from 'react';
import { Tab } from '../../components/Tab';
import { MaterialDesign2SchemeStorage } from '../../material-2-scheme';
import { SchemeContent } from '../../models';
import { SchemeExport } from './Export';
import { M2SchemeBuilder } from './m2-scheme/Builder';
import { M2SchemePreview } from './m2-scheme/Preview';
@@ -11,18 +13,18 @@ const tabOptions = [
{ title: 'Exports', id: 'export' },
];
type M3SchemeProps = {
scheme: SchemeContent<MaterialDesign3SchemeStorage>;
type M2SchemeProps = {
scheme: SchemeContent<MaterialDesign2SchemeStorage>;
};
export function M2Scheme({ scheme }: M3SchemeProps) {
export function M2Scheme({ scheme }: M2SchemeProps) {
const [activeTab, setActiveTab] = useState<(typeof tabOptions)[number]['id']>(() =>
isNil(scheme.schemeStorage.scheme) ? 'builder' : 'overview',
);
return (
<>
<Tab tabs={tabOptions} activeTab={activeTab} onActive={setActiveTab} />
<Tab tabs={tabOptions} activeTab={activeTab} onActive={(v) => setActiveTab(v as string)} />
{isEqual(activeTab, 'overview') && <M2SchemePreview scheme={scheme} />}
{isEqual(activeTab, 'builder') && (
<M2SchemeBuilder scheme={scheme} onBuildComplete={() => setActiveTab('overview')} />

View File

@@ -2,6 +2,7 @@ import { isEqual, isNil } from 'lodash-es';
import { useState } from 'react';
import { Tab } from '../../components/Tab';
import { MaterialDesign3SchemeStorage } from '../../material-3-scheme';
import { SchemeContent } from '../../models';
import { SchemeExport } from './Export';
import { M3SchemeBuilder } from './m3-scheme/Builder';
import { M3SchemePreview } from './m3-scheme/Preview';
@@ -23,7 +24,7 @@ export function M3Scheme({ scheme }: M3SchemeProps) {
return (
<>
<Tab tabs={tabOptions} activeTab={activeTab} onActive={setActiveTab} />
<Tab tabs={tabOptions} activeTab={activeTab} onActive={(v) => setActiveTab(v as string)} />
{isEqual(activeTab, 'overview') && <M3SchemePreview scheme={scheme} />}
{isEqual(activeTab, 'builder') && (
<M3SchemeBuilder scheme={scheme} onBuildCompleted={() => setActiveTab('overview')} />

View File

@@ -24,7 +24,7 @@ export function QScheme({ scheme }: QSchemeProps) {
return (
<>
<Tab tabs={tabOptions} activeTab={activeTab} onActive={setActiveTab} />
<Tab tabs={tabOptions} activeTab={activeTab} onActive={(v) => setActiveTab(v as string)} />
{isEqual(activeTab, 'overview') && <QSchemePreview scheme={scheme} />}
{isEqual(activeTab, 'builder') && (
<QSchemeBuilder scheme={scheme} onBuildCompleted={() => setActiveTab('overview')} />

View File

@@ -24,7 +24,7 @@ export function SwatchScheme({ scheme }: SwatchSchemeProps) {
return (
<>
<Tab tabs={tabOptions} activeTab={activeTab} onActive={setActiveTab} />
<Tab tabs={tabOptions} activeTab={activeTab} onActive={(v) => setActiveTab(v as string)} />
{isEqual(activeTab, 'overview') && <SwatchSchemePreview scheme={scheme} />}
{isEqual(activeTab, 'builder') && (
<SwatchSchemeBuilder scheme={scheme} onBuildCompleted={() => setActiveTab('overview')} />

View File

@@ -36,60 +36,63 @@ export function M2SchemeBuilder({ scheme, onBuildComplete }: M2SchemeBuilderProp
[originalColors, newColors, deleted],
);
const [errMsg, handleSubmitAction] = useActionState((state, formData) => {
const errMsg = new Map<string, string>();
try {
const primaryColor = formData.get('primary');
if (isNil(primaryColor) || isEmpty(primaryColor)) {
errMsg.set('primary', 'Primary color is required');
}
const secondaryColor = formData.get('secondary');
if (isNil(secondaryColor) || isEmpty(secondaryColor)) {
errMsg.set('secondary', 'Secondary color is required');
}
const errorColor = formData.get('error');
if (isNil(errorColor) || isEmpty(errorColor)) {
errMsg.set('error', 'Error color is required');
}
if (!isEmpty(errMsg)) return errMsg;
const [errMsg, handleSubmitAction] = useActionState<Map<string, string>, FormData>(
(_state, formData) => {
const errMsg = new Map<string, string>();
try {
const primaryColor = formData.get('primary') as string;
if (isNil(primaryColor) || isEmpty(primaryColor)) {
errMsg.set('primary', 'Primary color is required');
}
const secondaryColor = formData.get('secondary') as string;
if (isNil(secondaryColor) || isEmpty(secondaryColor)) {
errMsg.set('secondary', 'Secondary color is required');
}
const errorColor = formData.get('error') as string;
if (isNil(errorColor) || isEmpty(errorColor)) {
errMsg.set('error', 'Error color is required');
}
if (!isEmpty(errMsg)) return errMsg;
const customColors: Record<string, string> = {};
for (const key of colorKeys) {
const name = formData.get(`name_${key}`) as string;
const color = formData.get(`color_${key}`) as string;
if (isNil(name) || isEmpty(name) || isNil(color) || isEmpty(color)) continue;
customColors[name] = color;
}
const generatedScheme = colorFn?.generate_material_design_2_scheme(
primaryColor,
secondaryColor,
errorColor,
customColors,
);
updateScheme((prev) => {
prev.schemeStorage.source = {
primary: primaryColor,
secondary: secondaryColor,
error: errorColor,
custom_colors: customColors,
};
prev.schemeStorage.scheme = merge(generatedScheme[0], {
light: { custom_colors: mapToObject(generatedScheme[0].light.custom_colors) },
dark: { custom_colors: mapToObject(generatedScheme[0].dark.custom_colors) },
const customColors: Record<string, string> = {};
for (const key of colorKeys) {
const name = formData.get(`name_${key}`) as string;
const color = formData.get(`color_${key}`) as string;
if (isNil(name) || isEmpty(name) || isNil(color) || isEmpty(color)) continue;
customColors[name] = color;
}
const generatedScheme = colorFn?.generate_material_design_2_scheme(
primaryColor,
secondaryColor,
errorColor,
customColors,
);
updateScheme((prev) => {
prev.schemeStorage.source = {
primary: primaryColor,
secondary: secondaryColor,
error: errorColor,
custom_colors: customColors,
};
prev.schemeStorage.scheme = merge(generatedScheme[0], {
light: { custom_colors: mapToObject(generatedScheme[0].light.custom_colors) },
dark: { custom_colors: mapToObject(generatedScheme[0].dark.custom_colors) },
});
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
onBuildComplete?.();
} catch (e) {
console.error('[generate m2 scheme]', e);
}
onBuildComplete?.();
} catch (e) {
console.error('[generate m2 scheme]', e);
}
return errMsg;
}, new Map<string, string>());
return errMsg;
},
new Map<string, string>(),
);
return (
<ScrollArea enableY>

View File

@@ -86,8 +86,8 @@ 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} />
<PreviewBlock title="Light" baseline={scheme.schemeStorage.scheme!.light} />
<PreviewBlock title="Dark" baseline={scheme.schemeStorage.scheme!.dark} />
</div>
</ScrollArea>
);

View File

@@ -36,64 +36,67 @@ export function M3SchemeBuilder({ scheme, onBuildCompleted }: M3SchemeBuilderPro
[originalColors, newColors, deleted],
);
const [errMsg, handleSubmitAction] = useActionState((state, formData) => {
const errMsg = new Map<string, string>();
const [errMsg, handleSubmitAction] = useActionState<Map<string, string>, FormData>(
(_state, formData) => {
const errMsg = new Map<string, string>();
try {
const sourceColor = formData.get('source');
if (isNil(sourceColor) || isEmpty(sourceColor)) {
errMsg.set('source', 'Source color is required');
}
const errorColor = formData.get('error');
if (isNil(errorColor) || isEmpty(errorColor)) {
errMsg.set('error', 'Error color is required');
}
if (!isEmpty(errMsg)) return errMsg;
try {
const sourceColor = formData.get('source') as string;
if (isNil(sourceColor) || isEmpty(sourceColor)) {
errMsg.set('source', 'Source color is required');
}
const errorColor = formData.get('error') as string;
if (isNil(errorColor) || isEmpty(errorColor)) {
errMsg.set('error', 'Error color is required');
}
if (!isEmpty(errMsg)) return errMsg;
const customColors: Record<string, string> = {};
for (const key of colorKeys) {
const name = formData.get(`name_${key}`) as string;
const color = formData.get(`color_${key}`) as string;
if (isNil(name) || isEmpty(name) || isNil(color) || isEmpty(color)) continue;
customColors[name] = color;
const customColors: Record<string, string> = {};
for (const key of colorKeys) {
const name = formData.get(`name_${key}`) as string;
const color = formData.get(`color_${key}`) as string;
if (isNil(name) || isEmpty(name) || isNil(color) || isEmpty(color)) continue;
customColors[name] = color;
}
const generatedScheme = colorFn?.generate_material_design_3_scheme(
sourceColor,
errorColor,
customColors,
);
updateScheme((prev) => {
prev.schemeStorage.source = {
source: sourceColor as string,
error: errorColor as string,
custom_colors: customColors,
};
prev.schemeStorage.scheme = {
white: generatedScheme[0].white,
black: generatedScheme[0].black,
light_baseline: {
...generatedScheme[0].light_baseline,
customs: mapToObject(generatedScheme[0].light_baseline.customs),
},
dark_baseline: {
...generatedScheme[0].dark_baseline,
customs: mapToObject(generatedScheme[0].dark_baseline.customs),
},
} as MaterialDesign3Scheme;
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
onBuildCompleted?.();
} catch (e) {
console.error('[generate m3 scheme]', e);
}
const generatedScheme = colorFn?.generate_material_design_3_scheme(
sourceColor,
errorColor,
customColors,
);
updateScheme((prev) => {
prev.schemeStorage.source = {
source: sourceColor as string,
error: errorColor as string,
custom_colors: customColors,
};
prev.schemeStorage.scheme = {
white: generatedScheme[0].white,
black: generatedScheme[0].black,
light_baseline: {
...generatedScheme[0].light_baseline,
customs: mapToObject(generatedScheme[0].light_baseline.customs),
},
dark_baseline: {
...generatedScheme[0].dark_baseline,
customs: mapToObject(generatedScheme[0].dark_baseline.customs),
},
} as MaterialDesign3Scheme;
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
onBuildCompleted?.();
} catch (e) {
console.error('[generate m3 scheme]', e);
}
return errMsg;
}, new Map<string, string>());
return errMsg;
},
new Map<string, string>(),
);
return (
<ScrollArea enableY>

View File

@@ -264,8 +264,8 @@ export function M3SchemePreview({ scheme }: M3SchemePreviewProps) {
return (
<ScrollArea enableY>
<div className={styles.preview_layout}>
<PreviewBlock title="Light Scheme" baseline={scheme.schemeStorage.scheme?.light_baseline} />
<PreviewBlock title="Dark Scheme" baseline={scheme.schemeStorage.scheme?.dark_baseline} />
<PreviewBlock title="Light Scheme" baseline={scheme.schemeStorage.scheme!.light_baseline} />
<PreviewBlock title="Dark Scheme" baseline={scheme.schemeStorage.scheme!.dark_baseline} />
</div>
</ScrollArea>
);

View File

@@ -82,102 +82,105 @@ export function QSchemeBuilder({ scheme, onBuildCompleted }: QSchemeBuilderProps
return [];
}, []);
const [errMsg, handleSubmitAction] = useActionState((state, formData) => {
const errMsg = new Map<string, string>();
const requiredFields = [
'primary',
'danger',
'success',
'warn',
'info',
'foreground',
'background',
];
for (const field of requiredFields) {
if (!formData.get(field)) {
errMsg.set(field, 'This color is required for scheme generating.');
const [errMsg, handleSubmitAction] = useActionState<Map<string, string>, FormData>(
(_state, formData) => {
const errMsg = new Map<string, string>();
const requiredFields = [
'primary',
'danger',
'success',
'warn',
'info',
'foreground',
'background',
];
for (const field of requiredFields) {
if (!formData.get(field)) {
errMsg.set(field, 'This color is required for scheme generating.');
}
}
}
if (!isEmpty(errMsg)) return errMsg;
try {
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(
Number(formData.get('disabled_chroma')) / 100,
Number(formData.get('disabled_lightness')) / 100,
),
new ColorShifting(
Number(formData.get('dark_chroma')) / 100,
Number(formData.get('dark_lightness')) / 100,
),
Number(formData.get('expanding')) as ColorExpand,
Number(formData.get('wacg')) as WACGSetting,
);
const dumpedSetting = schemeSetting.toJsValue() as QSchemeSetting;
if (!isEmpty(errMsg)) return errMsg;
try {
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(
Number(formData.get('disabled_chroma')) / 100,
Number(formData.get('disabled_lightness')) / 100,
),
new ColorShifting(
Number(formData.get('dark_chroma')) / 100,
Number(formData.get('dark_lightness')) / 100,
),
Number(formData.get('expanding')) as ColorExpand,
Number(formData.get('wacg')) as WACGSetting,
);
const dumpedSetting = schemeSetting.toJsValue() as QSchemeSetting;
const source: QSchemeSource = {
primary: defaultEmptyFormData(formData, 'primary', null),
secondary: defaultEmptyFormData(formData, 'secondary', undefined),
tertiary: defaultEmptyFormData(formData, 'tertiary', undefined),
accent: defaultEmptyFormData(formData, 'accent', undefined),
danger: defaultEmptyFormData(formData, 'danger', null),
success: defaultEmptyFormData(formData, 'success', null),
warning: defaultEmptyFormData(formData, 'warn', null),
info: defaultEmptyFormData(formData, 'info', null),
foreground: defaultEmptyFormData(formData, 'foreground', null),
background: defaultEmptyFormData(formData, 'background', null),
setting: dumpedSetting,
};
const generatedScheme = every([source.secondary, source.tertiary, source.accent], isNil)
? colorFn?.generate_q_scheme_automatically(
source.primary,
source.danger,
source.success,
source.warning,
source.info,
source.foreground,
source.background,
schemeSetting,
)
: colorFn?.generate_q_scheme_manually(
source.primary,
source.secondary ?? undefined,
source.tertiary ?? undefined,
source.accent ?? undefined,
source.danger,
source.success,
source.warning,
source.info,
source.foreground,
source.background,
schemeSetting,
);
updateScheme((prev) => {
prev.schemeStorage.source = source;
prev.schemeStorage.scheme = generatedScheme[0];
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
onBuildCompleted?.();
} catch (e) {
console.error('[build q scheme]', e);
}
const source: QSchemeSource = {
primary: defaultEmptyFormData(formData, 'primary', null),
secondary: defaultEmptyFormData(formData, 'secondary', null),
tertiary: defaultEmptyFormData(formData, 'tertiary', null),
accent: defaultEmptyFormData(formData, 'accent', null),
danger: defaultEmptyFormData(formData, 'danger', null),
success: defaultEmptyFormData(formData, 'success', null),
warning: defaultEmptyFormData(formData, 'warn', null),
info: defaultEmptyFormData(formData, 'info', null),
foreground: defaultEmptyFormData(formData, 'foreground', null),
background: defaultEmptyFormData(formData, 'background', null),
setting: dumpedSetting,
};
const generatedScheme = every([source.secondary, source.tertiary, source.accent], isNil)
? colorFn?.generate_q_scheme_automatically(
source.primary ?? '',
source.danger ?? '',
source.success ?? '',
source.warning ?? '',
source.info ?? '',
source.foreground ?? '',
source.background ?? '',
schemeSetting,
)
: colorFn?.generate_q_scheme_manually(
source.primary ?? '',
source.secondary ?? undefined,
source.tertiary ?? undefined,
source.accent ?? undefined,
source.danger ?? '',
source.success ?? '',
source.warning ?? '',
source.info ?? '',
source.foreground ?? '',
source.background ?? '',
schemeSetting,
);
updateScheme((prev) => {
prev.schemeStorage.source = source;
prev.schemeStorage.scheme = generatedScheme[0];
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
onBuildCompleted?.();
} catch (e) {
console.error('[build q scheme]', e);
}
return errMsg;
}, new Map<string, string>());
return errMsg;
},
new Map<string, string>(),
);
return (
<ScrollArea enableY>

View File

@@ -10,7 +10,12 @@ import { ScrollArea } from '../../../components/ScrollArea';
import { Switch } from '../../../components/Switch';
import { SchemeContent } from '../../../models';
import { useUpdateScheme } from '../../../stores/schemes';
import { QSwatchEntry, QSwatchSchemeSetting, SwatchSchemeStorage } from '../../../swatch_scheme';
import {
QSwatchEntry,
QSwatchSchemeSetting,
SwatchScheme,
SwatchSchemeStorage,
} from '../../../swatch_scheme';
import { mapToObject } from '../../../utls';
import { ColorEntry, IdenticalColorEntry } from '../ColorEntry';
import styles from './Builder.module.css';
@@ -64,75 +69,78 @@ export function SwatchSchemeBuilder({ scheme, onBuildCompleted }: SwatchSchemeBu
return null;
}, [scheme.schemeStorage.source]);
const [errMsg, handleSubmitAction] = useActionState((state, formData) => {
const errMsg = new Map<string, string>();
const [errMsg, handleSubmitAction] = useActionState<Map<string, string>, FormData>(
(_state, formData) => {
const errMsg = new Map<string, string>();
try {
const swatchAmount = Number(formData.get('amount'));
if (isNaN(swatchAmount) || swatchAmount <= 0) {
errMsg.set('amount', 'MUST be a positive number');
}
if (swatchAmount > 30) {
errMsg.set('amount', 'MUST be less than 30');
try {
const swatchAmount = Number(formData.get('amount'));
if (isNaN(swatchAmount) || swatchAmount <= 0) {
errMsg.set('amount', 'MUST be a positive number');
}
if (swatchAmount > 30) {
errMsg.set('amount', 'MUST be less than 30');
}
const minLightness = Number(formData.get('min_lightness'));
if (isNaN(minLightness) || minLightness < 0 || minLightness > 100) {
errMsg.set('min', 'MUST be a number between 0 and 100');
}
const maxLightness = Number(formData.get('max_lightness'));
if (isNaN(maxLightness) || maxLightness < 0 || maxLightness > 100) {
errMsg.set('max', 'MUST be a number between 0 and 100');
}
const includePrimary = isEqual(formData.get('include_primary'), 'true');
const darkConvertChroma = Number(formData.get('dark_chroma')) / 100.0;
const darkConvertLightness = Number(formData.get('dark_lightness')) / 100.0;
const swatchSetting = new SwatchSchemeSetting(
swatchAmount,
minLightness / 100.0,
maxLightness / 100.0,
includePrimary,
new ColorShifting(darkConvertChroma, darkConvertLightness),
);
const dumpedSettings = swatchSetting.toJsValue() as QSwatchSchemeSetting;
const entries: SwatchEntry[] = [];
for (const key of colorKeys) {
const name = String(formData.get(`name_${key}`));
const color = String(formData.get(`color_${key}`));
if (isEmpty(name) || isEmpty(color)) continue;
entries.push(new SwatchEntry(name, color));
}
const dumpedEntries = entries.map((entry) => entry.toJsValue() as QSwatchEntry);
if (isEmpty(entries)) {
errMsg.set('color', 'At least one color is required');
}
if (!isEmpty(errMsg)) return errMsg;
const generatedScheme = colorFn?.generate_swatch_scheme(entries, swatchSetting);
console.debug('[generated scheme]', generatedScheme);
updateScheme((prev) => {
prev.schemeStorage.source = {
colors: dumpedEntries,
setting: dumpedSettings,
};
prev.schemeStorage.scheme = mapToObject(generatedScheme[0]) as SwatchScheme;
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
onBuildCompleted?.();
} catch (e) {
console.error('[build swatch scheme]', e);
}
const minLightness = Number(formData.get('min_lightness'));
if (isNaN(minLightness) || minLightness < 0 || minLightness > 100) {
errMsg.set('min', 'MUST be a number between 0 and 100');
}
const maxLightness = Number(formData.get('max_lightness'));
if (isNaN(maxLightness) || maxLightness < 0 || maxLightness > 100) {
errMsg.set('max', 'MUST be a number between 0 and 100');
}
const includePrimary = isEqual(formData.get('include_primary'), 'true');
const darkConvertChroma = Number(formData.get('dark_chroma')) / 100.0;
const darkConvertLightness = Number(formData.get('dark_lightness')) / 100.0;
const swatchSetting = new SwatchSchemeSetting(
swatchAmount,
minLightness / 100.0,
maxLightness / 100.0,
includePrimary,
new ColorShifting(darkConvertChroma, darkConvertLightness),
);
const dumpedSettings = swatchSetting.toJsValue() as QSwatchSchemeSetting;
const entries: SwatchEntry[] = [];
for (const key of colorKeys) {
const name = String(formData.get(`name_${key}`));
const color = String(formData.get(`color_${key}`));
if (isEmpty(name) || isEmpty(color)) continue;
entries.push(new SwatchEntry(name, color));
}
const dumpedEntries = entries.map((entry) => entry.toJsValue() as QSwatchEntry);
if (isEmpty(entries)) {
errMsg.set('color', 'At least one color is required');
}
if (!isEmpty(errMsg)) return errMsg;
const generatedScheme = colorFn?.generate_swatch_scheme(entries, swatchSetting);
console.debug('[generated scheme]', generatedScheme);
updateScheme((prev) => {
prev.schemeStorage.source = {
colors: dumpedEntries,
setting: dumpedSettings,
};
prev.schemeStorage.scheme = mapToObject(generatedScheme[0]);
prev.schemeStorage.cssVariables = generatedScheme[1];
prev.schemeStorage.scssVariables = generatedScheme[2];
prev.schemeStorage.jsVariables = generatedScheme[3];
return prev;
});
onBuildCompleted?.();
} catch (e) {
console.error('[build swatch scheme]', e);
}
return errMsg;
}, new Map<string, string>());
return errMsg;
},
new Map<string, string>(),
);
return (
<ScrollArea enableY>

View File

@@ -54,12 +54,12 @@ export function SwatchSchemePreview({ scheme }: SwatchSchemePreviewProps) {
<h2>Light Scheme</h2>
<SchemeBlock
amount={scheme.schemeStorage.source?.setting?.amount ?? 0}
scheme={scheme.schemeStorage.scheme.light}
scheme={scheme.schemeStorage.scheme!.light}
/>
<h2>Dark Scheme</h2>
<SchemeBlock
amount={scheme.schemeStorage.source?.setting?.amount ?? 0}
scheme={scheme.schemeStorage.scheme.dark}
scheme={scheme.schemeStorage.scheme!.dark}
/>
</div>
</ScrollArea>

View File

@@ -23,18 +23,18 @@ export function Shades({ color, shades, mix, step, maximum, copyMode }: ShadesLi
switch (mix) {
case 'progressive':
for (let i = 1; i <= shades; i++) {
const shade = colorFn!.shade(last(genColors), step);
const shade = colorFn!.shade(last(genColors) ?? '', step ?? 0);
genColors.push(shade);
}
break;
case 'linear':
for (let i = 1; i <= shades; i++) {
const shade = colorFn!.shade(color, step * i);
const shade = colorFn!.shade(color, (step ?? 0) * i);
genColors.push(shade);
}
break;
case 'average': {
const interval = maximum / shades / 100;
const interval = (maximum ?? 0) / shades / 100;
for (let i = 1; i <= shades; i++) {
const shade = colorFn!.shade(color, interval * i);
genColors.push(shade);

View File

@@ -23,18 +23,18 @@ export function Tints({ color, tints, mix, step, maximum, copyMode }: TintsListP
switch (mix) {
case 'progressive':
for (let i = 1; i <= tints; i++) {
const tint = colorFn!.tint(last(genColors), step);
const tint = colorFn!.tint(last(genColors) ?? '', step ?? 0);
genColors.push(tint);
}
break;
case 'linear':
for (let i = 1; i <= tints; i++) {
const tint = colorFn!.tint(color, step * i);
const tint = colorFn!.tint(color, (step ?? 0) * i);
genColors.push(tint);
}
break;
case 'average': {
const interval = maximum / tints / 100;
const interval = (maximum ?? 0) / tints / 100;
for (let i = 1; i <= tints; i++) {
const tint = colorFn!.tint(color, interval * i);
genColors.push(tint);