Compare commits

...

4 Commits

Author SHA1 Message Date
徐涛
b18ef4ea4c fix(scheme): 修复输出 CSS 变量时缺少分号的问题 2026-01-15 13:07:18 +08:00
徐涛
04d7c76e2f fix(baseline): 确保 neutral_lightest 的亮度高于 neutral_darkest,必要时进行交换 2026-01-15 13:02:33 +08:00
徐涛
672e0e7c63 fix(preview): 添加对 baseline.surface 的数组检查以避免潜在错误 2026-01-15 11:46:45 +08:00
徐涛
d91a8eb341 feat(builder): 添加 SchemeSelect 支持并更新默认设置
fix(preview): 更新 PreviewBlock 组件的前景色属性
2026-01-15 10:56:14 +08:00
4 changed files with 25 additions and 15 deletions

View File

@@ -147,6 +147,13 @@ impl Baseline {
settings: &Arc<SchemeSetting>, settings: &Arc<SchemeSetting>,
is_dark: bool, is_dark: bool,
) -> Self { ) -> Self {
// Ensure neutral_lightest has higher lightness than neutral_darkest, swap if necessary
let (neutral_lightest, neutral_darkest) = if neutral_lightest.l >= neutral_darkest.l {
(*neutral_lightest, *neutral_darkest)
} else {
(*neutral_darkest, *neutral_lightest)
};
let (final_secondary, final_tertiary, final_accent) = match settings.expand_method { let (final_secondary, final_tertiary, final_accent) = match settings.expand_method {
ColorExpand::Complementary => { ColorExpand::Complementary => {
let sec_color = secondary.cloned().or(Some(primary.complementary())); let sec_color = secondary.cloned().or(Some(primary.complementary()));
@@ -209,7 +216,7 @@ impl Baseline {
} else { } else {
neutral_lightest.l neutral_lightest.l
}; };
let neutral_swatch = Arc::new(NeutralSwatch::new(*neutral_lightest, *neutral_darkest)); let neutral_swatch = Arc::new(NeutralSwatch::new(neutral_lightest, neutral_darkest));
let outline_color = neutral_swatch.get(if is_dark { 0.25 } else { 0.7 }); let outline_color = neutral_swatch.get(if is_dark { 0.25 } else { 0.7 });
let outline_variant_color = neutral_swatch.get(if is_dark { 0.2 } else { 0.8 }); let outline_variant_color = neutral_swatch.get(if is_dark { 0.2 } else { 0.8 });
let shadow_color = neutral_swatch.get(0.1); let shadow_color = neutral_swatch.get(0.1);
@@ -308,13 +315,13 @@ impl Baseline {
let (foreground, background) = if is_dark { let (foreground, background) = if is_dark {
// Dark mode: foreground = neutral_lightest, background = neutral_darkest with +10% lightness // Dark mode: foreground = neutral_lightest, background = neutral_darkest with +10% lightness
let background_darkest = Oklch { let background_darkest = Oklch {
l: (neutral_darkest.l * 1.2).min(1.0), l: (neutral_darkest.l * 1.3).min(1.0),
..*neutral_darkest ..neutral_darkest
}; };
(*neutral_lightest, background_darkest) (neutral_lightest, background_darkest)
} else { } else {
// Light mode: foreground = neutral_darkest, background = neutral_lightest // Light mode: foreground = neutral_darkest, background = neutral_lightest
(*neutral_darkest, *neutral_lightest) (neutral_darkest, neutral_lightest)
}; };
Self { Self {

View File

@@ -148,7 +148,7 @@ impl SchemeExport for QScheme2 {
collection.push(format!("--color-{key}: light-dark(#{light}, #{dark});")); collection.push(format!("--color-{key}: light-dark(#{light}, #{dark});"));
} }
(Some(color), None) | (None, Some(color)) => { (Some(color), None) | (None, Some(color)) => {
collection.push(format!("--color-{key}: #{color}")); collection.push(format!("--color-{key}: #{color};"));
} }
(None, None) => {} (None, None) => {}
} }

View File

@@ -1,4 +1,4 @@
import { capitalize, keys } from 'lodash-es'; import { capitalize, isArray, keys } from 'lodash-es';
import { FC, ReactNode, useMemo } from 'react'; import { FC, ReactNode, useMemo } from 'react';
import { useColorFunction } from '../../../ColorFunctionContext'; import { useColorFunction } from '../../../ColorFunctionContext';
import { ScrollArea } from '../../../components/ScrollArea'; import { ScrollArea } from '../../../components/ScrollArea';
@@ -127,11 +127,12 @@ const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => {
<PreviewLine name="Neutral Variant" unit={baseline.neutralVariant} /> <PreviewLine name="Neutral Variant" unit={baseline.neutralVariant} />
</div> </div>
<div className={styles.preview_surface}> <div className={styles.preview_surface}>
{baseline.surface.map((surfaceSet, index) => ( {isArray(baseline.surface) &&
<div className={styles.surface_block} key={index}> baseline.surface.map((surfaceSet, index) => (
<PreviewLine key={index} name={`Surface ${index + 1}`} unit={surfaceSet} /> <div className={styles.surface_block} key={index}>
</div> <PreviewLine key={index} name={`Surface ${index + 1}`} unit={surfaceSet} />
))} </div>
))}
</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}>
@@ -140,10 +141,10 @@ const PreviewBlock: FC<PreviewBlockProps> = ({ baseline, title }) => {
<PreviewCell bg={baseline.overlay} fg={baseline.neutralVariant.onRoot}> <PreviewCell bg={baseline.overlay} fg={baseline.neutralVariant.onRoot}>
Overlay Overlay
</PreviewCell> </PreviewCell>
<PreviewCell bg={baseline.outline} fg={baseline.surface.onRoot}> <PreviewCell bg={baseline.outline} fg={baseline.foreground}>
Outline Outline
</PreviewCell> </PreviewCell>
<PreviewCell bg={baseline.outlineVariant} fg={baseline.surface.onRoot}> <PreviewCell bg={baseline.outlineVariant} fg={baseline.foreground}>
Outline Variant Outline Variant
</PreviewCell> </PreviewCell>
</div> </div>

View File

@@ -1,4 +1,4 @@
import { ColorExpand, ColorShifting, SchemeSetting, WACGSetting } from 'color-module'; import { ColorExpand, ColorShifting, SchemeSelect, SchemeSetting, WACGSetting } from 'color-module';
import { every, isEmpty, isNil } from 'lodash-es'; import { every, isEmpty, isNil } from 'lodash-es';
import { useActionState, useMemo } from 'react'; import { useActionState, useMemo } from 'react';
import { useColorFunction } from '../../../ColorFunctionContext'; import { useColorFunction } from '../../../ColorFunctionContext';
@@ -53,6 +53,7 @@ export function QSchemeBuilder({ scheme, onBuildCompleted }: QSchemeBuilderProps
), ),
scheme.schemeStorage.source?.setting?.expand_method ?? defaultValues.expand_method, scheme.schemeStorage.source?.setting?.expand_method ?? defaultValues.expand_method,
scheme.schemeStorage.source?.setting?.wacg_follows ?? defaultValues.wacg_follows, scheme.schemeStorage.source?.setting?.wacg_follows ?? defaultValues.wacg_follows,
scheme.schemeStorage.source?.setting?.scheme_select ?? defaultValues.scheme_select,
); );
return defaultValues; return defaultValues;
} catch (e) { } catch (e) {
@@ -103,6 +104,7 @@ export function QSchemeBuilder({ scheme, onBuildCompleted }: QSchemeBuilderProps
), ),
Number(formData.get('expanding')) as ColorExpand, Number(formData.get('expanding')) as ColorExpand,
Number(formData.get('wacg')) as WACGSetting, Number(formData.get('wacg')) as WACGSetting,
SchemeSelect.Both,
); );
const dumpedSetting = schemeSetting.toJsValue() as QSchemeSetting; const dumpedSetting = schemeSetting.toJsValue() as QSchemeSetting;
return [ return [