Compare commits

...

9 Commits

Author SHA1 Message Date
徐涛
8efb3ec318 将枚举换成整型值的输出。 2025-01-25 10:57:43 +08:00
徐涛
c4f703906e 增加获取Q Scheme默认配置功能。 2025-01-25 09:32:13 +08:00
徐涛
6dba92a2c5 修正SegmentControl解析Map格式的默认值。 2025-01-25 09:22:17 +08:00
徐涛
4b4428fd3b 增强SegmentControl系列组件对于Map的支持。 2025-01-25 08:56:57 +08:00
徐涛
1b41fb4d22 改进输入框包装器的样式。 2025-01-24 17:18:32 +08:00
徐涛
a3de0f961a 调整存储的Scheme内容。 2025-01-24 16:14:37 +08:00
徐涛
79794ed0f7 调整Scheme详细页面的布局。 2025-01-24 15:18:45 +08:00
徐涛
20757a789a 完善不可识别Scheme的警告页面。 2025-01-24 15:17:07 +08:00
徐涛
f9f984a1b4 重构Scheme编辑器结构。 2025-01-24 15:09:25 +08:00
29 changed files with 210 additions and 231 deletions

View File

@ -8,6 +8,7 @@ crate-type = ["cdylib"]
[dependencies]
color-name = "1.1.0"
enum-iterator = "2.1.0"
palette = { version = "0.7.6", features = ["serde"] }
serde = { version = "1.0.216", features = ["derive"] }
serde-wasm-bindgen = "0.6.5"

View File

@ -4,7 +4,6 @@ use baseline::Baseline;
use palette::FromColor;
use scheme_setting::{ColorExpand, WACGSetting};
use serde::Serialize;
use strum::IntoEnumIterator;
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
use crate::{errors, parse_option_to_oklch, parse_to_oklch};
@ -169,11 +168,11 @@ impl SchemeExport for QScheme {
#[wasm_bindgen]
pub fn q_scheme_color_expanding_methods() -> Result<JsValue, String> {
let methods = ColorExpand::iter()
let methods = enum_iterator::all::<ColorExpand>()
.map(|variant| {
serde_json::json!({
"label": variant.label(),
"value": variant.to_string(),
"value": variant as u8,
})
})
.collect::<Vec<_>>();
@ -183,14 +182,19 @@ pub fn q_scheme_color_expanding_methods() -> Result<JsValue, String> {
#[wasm_bindgen]
pub fn q_scheme_wacg_settings() -> Result<JsValue, String> {
let settings = WACGSetting::iter()
let settings = enum_iterator::all::<WACGSetting>()
.map(|setting| {
serde_json::json!({
"label": setting.label(),
"value": setting.to_string(),
"value": setting as u8,
})
})
.collect::<Vec<_>>();
serde_wasm_bindgen::to_value(&settings).map_err(|e| e.to_string())
}
#[wasm_bindgen]
pub fn q_scheme_default_settings() -> SchemeSetting {
SchemeSetting::default()
}

View File

@ -1,8 +1,9 @@
use std::ops::Mul;
use enum_iterator::Sequence;
use palette::Oklch;
use serde::{Deserialize, Serialize};
use strum::{Display, EnumIter, EnumString};
use strum::Display;
use wasm_bindgen::prelude::wasm_bindgen;
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
@ -68,9 +69,9 @@ pub struct SchemeSetting {
pub wacg_follows: WACGSetting,
}
#[derive(Debug, Clone, Copy, Display, EnumString, EnumIter, Serialize, Deserialize)]
#[strum(serialize_all = "lowercase")]
#[derive(Debug, Clone, Copy, Display, Sequence, Serialize, Deserialize)]
#[wasm_bindgen]
#[repr(u8)]
pub enum ColorExpand {
Complementary,
Analogous,
@ -95,9 +96,9 @@ impl ColorExpand {
}
}
#[derive(Debug, Clone, Copy, Display, EnumString, EnumIter, Serialize, Deserialize)]
#[strum(serialize_all = "lowercase")]
#[derive(Debug, Clone, Copy, Display, Sequence, Serialize, Deserialize)]
#[wasm_bindgen]
#[repr(u8)]
pub enum WACGSetting {
Fixed,
AutomaticAA,

View File

@ -2,6 +2,7 @@
/* eslint-disable */
export function q_scheme_color_expanding_methods(): any;
export function q_scheme_wacg_settings(): any;
export function q_scheme_default_settings(): SchemeSetting;
export function differ_in_rgb(color: string, other: string): RGBDifference;
export function relative_differ_in_rgb(color: string, other: string): RGBDifference;
export function differ_in_hsl(color: string, other: string): HSLDifference;
@ -143,6 +144,7 @@ export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly q_scheme_color_expanding_methods: () => [number, number, number];
readonly q_scheme_wacg_settings: () => [number, number, number];
readonly q_scheme_default_settings: () => number;
readonly differ_in_rgb: (a: number, b: number, c: number, d: number) => [number, number, number];
readonly relative_differ_in_rgb: (a: number, b: number, c: number, d: number) => [number, number, number];
readonly differ_in_hsl: (a: number, b: number, c: number, d: number) => [number, number, number];
@ -189,18 +191,6 @@ export interface InitOutput {
readonly __wbg_set_mixreversing_b_factor: (a: number, b: number) => void;
readonly __wbg_get_mixreversing_average: (a: number) => number;
readonly __wbg_set_mixreversing_average: (a: number, b: number) => void;
readonly __wbg_rgbdifference_free: (a: number, b: number) => void;
readonly __wbg_get_rgbdifference_r: (a: number) => number;
readonly __wbg_set_rgbdifference_r: (a: number, b: number) => void;
readonly __wbg_get_rgbdifference_g: (a: number) => number;
readonly __wbg_set_rgbdifference_g: (a: number, b: number) => void;
readonly __wbg_get_rgbdifference_b: (a: number) => number;
readonly __wbg_set_rgbdifference_b: (a: number, b: number) => void;
readonly __wbg_swatchentry_free: (a: number, b: number) => void;
readonly __wbg_get_swatchentry_name: (a: number) => [number, number];
readonly __wbg_set_swatchentry_name: (a: number, b: number, c: number) => void;
readonly __wbg_get_swatchentry_color: (a: number) => [number, number];
readonly __wbg_set_swatchentry_color: (a: number, b: number, c: number) => void;
readonly color_categories: () => [number, number, number];
readonly search_color_cards: (a: number, b: number, c: number, d: number) => [number, number, number];
readonly __wbg_colorshifting_free: (a: number, b: number) => void;
@ -228,6 +218,18 @@ export interface InitOutput {
readonly generate_q_scheme_automatically: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number) => [number, number, number];
readonly generate_q_scheme_manually: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number) => [number, number, number];
readonly generate_swatch_scheme: (a: number, b: number, c: number) => [number, number, number];
readonly __wbg_hsldifference_free: (a: number, b: number) => void;
readonly __wbg_get_hsldifference_hue: (a: number) => number;
readonly __wbg_set_hsldifference_hue: (a: number, b: number) => void;
readonly __wbg_get_hsldifference_saturation: (a: number) => number;
readonly __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
readonly __wbg_get_hsldifference_lightness: (a: number) => number;
readonly __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
readonly __wbg_swatchentry_free: (a: number, b: number) => void;
readonly __wbg_get_swatchentry_name: (a: number) => [number, number];
readonly __wbg_set_swatchentry_name: (a: number, b: number, c: number) => void;
readonly __wbg_get_swatchentry_color: (a: number) => [number, number];
readonly __wbg_set_swatchentry_color: (a: number, b: number, c: number) => void;
readonly lighten: (a: number, b: number, c: number) => [number, number, number, number];
readonly lighten_absolute: (a: number, b: number, c: number) => [number, number, number, number];
readonly darken: (a: number, b: number, c: number) => [number, number, number, number];
@ -249,6 +251,13 @@ export interface InitOutput {
readonly represent_hct: (a: number, b: number) => [number, number, number, number];
readonly hct_to_hex: (a: number, b: number, c: number) => [number, number, number, number];
readonly wacg_relative_contrast: (a: number, b: number, c: number, d: number) => [number, number, number];
readonly __wbg_rgbdifference_free: (a: number, b: number) => void;
readonly __wbg_get_rgbdifference_r: (a: number) => number;
readonly __wbg_set_rgbdifference_r: (a: number, b: number) => void;
readonly __wbg_get_rgbdifference_g: (a: number) => number;
readonly __wbg_set_rgbdifference_g: (a: number, b: number) => void;
readonly __wbg_get_rgbdifference_b: (a: number) => number;
readonly __wbg_set_rgbdifference_b: (a: number, b: number) => void;
readonly __wbg_swatchschemesetting_free: (a: number, b: number) => void;
readonly __wbg_get_swatchschemesetting_amount: (a: number) => number;
readonly __wbg_set_swatchschemesetting_amount: (a: number, b: number) => void;
@ -260,13 +269,6 @@ export interface InitOutput {
readonly __wbg_set_swatchschemesetting_include_primary: (a: number, b: number) => void;
readonly __wbg_get_swatchschemesetting_dark_convert: (a: number) => number;
readonly __wbg_set_swatchschemesetting_dark_convert: (a: number, b: number) => void;
readonly __wbg_hsldifference_free: (a: number, b: number) => void;
readonly __wbg_get_hsldifference_hue: (a: number) => number;
readonly __wbg_set_hsldifference_hue: (a: number, b: number) => void;
readonly __wbg_get_hsldifference_saturation: (a: number) => number;
readonly __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
readonly __wbg_get_hsldifference_lightness: (a: number) => number;
readonly __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_exn_store: (a: number) => void;

View File

@ -194,6 +194,14 @@ export function q_scheme_wacg_settings() {
return takeFromExternrefTable0(ret[0]);
}
/**
* @returns {SchemeSetting}
*/
export function q_scheme_default_settings() {
const ret = wasm.q_scheme_default_settings();
return SchemeSetting.__wrap(ret);
}
/**
* @param {string} color
* @param {string} other
@ -1681,6 +1689,14 @@ const SchemeSettingFinalization = (typeof FinalizationRegistry === 'undefined')
export class SchemeSetting {
static __wrap(ptr) {
ptr = ptr >>> 0;
const obj = Object.create(SchemeSetting.prototype);
obj.__wbg_ptr = ptr;
SchemeSettingFinalization.register(obj, obj.__wbg_ptr, obj);
return obj;
}
__destroy_into_raw() {
const ptr = this.__wbg_ptr;
this.__wbg_ptr = 0;

View File

@ -3,6 +3,7 @@
export const memory: WebAssembly.Memory;
export const q_scheme_color_expanding_methods: () => [number, number, number];
export const q_scheme_wacg_settings: () => [number, number, number];
export const q_scheme_default_settings: () => number;
export const differ_in_rgb: (a: number, b: number, c: number, d: number) => [number, number, number];
export const relative_differ_in_rgb: (a: number, b: number, c: number, d: number) => [number, number, number];
export const differ_in_hsl: (a: number, b: number, c: number, d: number) => [number, number, number];
@ -49,18 +50,6 @@ export const __wbg_get_mixreversing_b_factor: (a: number) => number;
export const __wbg_set_mixreversing_b_factor: (a: number, b: number) => void;
export const __wbg_get_mixreversing_average: (a: number) => number;
export const __wbg_set_mixreversing_average: (a: number, b: number) => void;
export const __wbg_rgbdifference_free: (a: number, b: number) => void;
export const __wbg_get_rgbdifference_r: (a: number) => number;
export const __wbg_set_rgbdifference_r: (a: number, b: number) => void;
export const __wbg_get_rgbdifference_g: (a: number) => number;
export const __wbg_set_rgbdifference_g: (a: number, b: number) => void;
export const __wbg_get_rgbdifference_b: (a: number) => number;
export const __wbg_set_rgbdifference_b: (a: number, b: number) => void;
export const __wbg_swatchentry_free: (a: number, b: number) => void;
export const __wbg_get_swatchentry_name: (a: number) => [number, number];
export const __wbg_set_swatchentry_name: (a: number, b: number, c: number) => void;
export const __wbg_get_swatchentry_color: (a: number) => [number, number];
export const __wbg_set_swatchentry_color: (a: number, b: number, c: number) => void;
export const color_categories: () => [number, number, number];
export const search_color_cards: (a: number, b: number, c: number, d: number) => [number, number, number];
export const __wbg_colorshifting_free: (a: number, b: number) => void;
@ -88,6 +77,18 @@ export const generate_material_design_2_scheme: (a: number, b: number, c: number
export const generate_q_scheme_automatically: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number) => [number, number, number];
export const generate_q_scheme_manually: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number) => [number, number, number];
export const generate_swatch_scheme: (a: number, b: number, c: number) => [number, number, number];
export const __wbg_hsldifference_free: (a: number, b: number) => void;
export const __wbg_get_hsldifference_hue: (a: number) => number;
export const __wbg_set_hsldifference_hue: (a: number, b: number) => void;
export const __wbg_get_hsldifference_saturation: (a: number) => number;
export const __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
export const __wbg_get_hsldifference_lightness: (a: number) => number;
export const __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
export const __wbg_swatchentry_free: (a: number, b: number) => void;
export const __wbg_get_swatchentry_name: (a: number) => [number, number];
export const __wbg_set_swatchentry_name: (a: number, b: number, c: number) => void;
export const __wbg_get_swatchentry_color: (a: number) => [number, number];
export const __wbg_set_swatchentry_color: (a: number, b: number, c: number) => void;
export const lighten: (a: number, b: number, c: number) => [number, number, number, number];
export const lighten_absolute: (a: number, b: number, c: number) => [number, number, number, number];
export const darken: (a: number, b: number, c: number) => [number, number, number, number];
@ -109,6 +110,13 @@ export const oklch_to_hex: (a: number, b: number, c: number) => [number, number,
export const represent_hct: (a: number, b: number) => [number, number, number, number];
export const hct_to_hex: (a: number, b: number, c: number) => [number, number, number, number];
export const wacg_relative_contrast: (a: number, b: number, c: number, d: number) => [number, number, number];
export const __wbg_rgbdifference_free: (a: number, b: number) => void;
export const __wbg_get_rgbdifference_r: (a: number) => number;
export const __wbg_set_rgbdifference_r: (a: number, b: number) => void;
export const __wbg_get_rgbdifference_g: (a: number) => number;
export const __wbg_set_rgbdifference_g: (a: number, b: number) => void;
export const __wbg_get_rgbdifference_b: (a: number) => number;
export const __wbg_set_rgbdifference_b: (a: number, b: number) => void;
export const __wbg_swatchschemesetting_free: (a: number, b: number) => void;
export const __wbg_get_swatchschemesetting_amount: (a: number) => number;
export const __wbg_set_swatchschemesetting_amount: (a: number, b: number) => void;
@ -120,13 +128,6 @@ export const __wbg_get_swatchschemesetting_include_primary: (a: number) => numbe
export const __wbg_set_swatchschemesetting_include_primary: (a: number, b: number) => void;
export const __wbg_get_swatchschemesetting_dark_convert: (a: number) => number;
export const __wbg_set_swatchschemesetting_dark_convert: (a: number, b: number) => void;
export const __wbg_hsldifference_free: (a: number, b: number) => void;
export const __wbg_get_hsldifference_hue: (a: number) => number;
export const __wbg_set_hsldifference_hue: (a: number, b: number) => void;
export const __wbg_get_hsldifference_saturation: (a: number) => number;
export const __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
export const __wbg_get_hsldifference_lightness: (a: number) => number;
export const __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
export const __wbindgen_malloc: (a: number, b: number) => number;
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
export const __wbindgen_exn_store: (a: number) => void;

View File

@ -193,6 +193,7 @@
resize: none;
}
.input_wrapper {
width: fit-content;
display: flex;
flex-direction: row;
align-items: center;

View File

@ -3,7 +3,10 @@
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--spacing-m);
gap: var(--spacing-xs);
.extended_input_wrapper {
width: 100%;
}
.rgb_input {
text-align: right;
text-transform: uppercase;

View File

@ -146,7 +146,7 @@ export function ColorComponentInput({ color, onChange }: ColorComponentInputProp
return (
<div className={styles.rgb_input}>
<div className={cx('input_wrapper')}>
<div className={cx('input_wrapper', styles.extended_input_wrapper)}>
<Icon icon="tabler:hash" />
<input type="text" value={hex} onChange={updateHex} className={styles.rgb_input} />
</div>

View File

@ -1,10 +1,12 @@
import cx from 'clsx';
import { isEqual, isNil } from 'lodash-es';
import { isEqual, isMap, isNil } from 'lodash-es';
import { useCallback, useRef, useState } from 'react';
import type { Option } from '../models';
import styles from './HSegmentedControl.module.css';
type HSegmentedControlProps = {
name?: string;
defaultValue?: Option['value'];
options?: Option[];
value?: Option['value'];
onChange?: (value: Option['value']) => void;
@ -12,12 +14,19 @@ type HSegmentedControlProps = {
};
export function HSegmentedControl({
name,
defaultValue,
options = [],
value,
onChange,
extendClassName,
}: HSegmentedControlProps) {
const [selected, setSelected] = useState(value ?? options[0].value ?? null);
const [selected, setSelected] = useState(
value ??
defaultValue ??
(isMap(options[0]) ? options[0].get('value') : options[0].value) ??
null,
);
const [sliderPosition, setSliderPosition] = useState(0);
const [sliderWidth, setSliderWidth] = useState(0);
const sliderRef = useRef<HTMLDivElement>(null);
@ -36,15 +45,19 @@ export function HSegmentedControl({
return (
<div className={cx(styles.segmented_control, extendClassName)}>
<div className={styles.options}>
{options.map((option, index) => (
<div
key={`${index}_${option.value}`}
className={cx(styles.option, isEqual(selected, option.value) && styles.selected)}
ref={(el) => (optionsRef.current[index] = el!)}
onClick={() => handleSelectAction(option.value, index)}>
{option.label}
</div>
))}
{options.map((option, index) => {
const label = isMap(option) ? option.get('label') : option.label;
const value = isMap(option) ? option.get('value') : option.value;
return (
<div
key={`${index}_${value}`}
className={cx(styles.option, isEqual(selected, value) && styles.selected)}
ref={(el) => (optionsRef.current[index] = el!)}
onClick={() => handleSelectAction(value, index)}>
{label}
</div>
);
})}
{!isNil(selected) && (
<div
className={styles.slider}
@ -53,6 +66,7 @@ export function HSegmentedControl({
/>
)}
</div>
{!isNil(name) && <input type="hidden" name={name} value={selected} />}
</div>
);
}

View File

@ -1,10 +1,12 @@
import cx from 'clsx';
import { isEqual, isNil } from 'lodash-es';
import { isEqual, isMap, isNil } from 'lodash-es';
import { useCallback, useRef, useState } from 'react';
import type { Option } from '../models';
import styles from './VSegmentedControl.module.css';
type VSegmentedControlProps = {
name?: string;
defaultValue?: Option['value'];
options?: Option[];
value?: Option['value'];
onChange?: (value: Option['value']) => void;
@ -12,12 +14,19 @@ type VSegmentedControlProps = {
};
export function VSegmentedControl({
name,
defaultValue,
options = [],
value,
onChange,
extendClassName,
}: VSegmentedControlProps) {
const [selected, setSelected] = useState(value ?? options[0].value ?? null);
const [selected, setSelected] = useState(
value ??
defaultValue ??
(isMap(options[0]) ? options[0].get('value') : options[0].value) ??
null,
);
const [sliderPosition, setSliderPosition] = useState(0);
const [sliderHeight, setSliderHeight] = useState(0);
const sliderRef = useRef<HTMLDivElement>(null);
@ -36,15 +45,19 @@ export function VSegmentedControl({
return (
<div className={cx(styles.segmented_control, extendClassName)}>
<div className={styles.options}>
{options.map((option, index) => (
<div
key={`${index}_${option.value}`}
className={cx(styles.option, isEqual(selected, option.value) && styles.selected)}
ref={(el) => (optionsRef.current[index] = el!)}
onClick={() => handleSelectAction(option.value, index)}>
{option.label}
</div>
))}
{options.map((option, index) => {
const label = isMap(option) ? option.get('label') : option.label;
const value = isMap(option) ? option.get('value') : option.value;
return (
<div
key={`${index}_${value}`}
className={cx(styles.option, isEqual(selected, value) && styles.selected)}
ref={(el) => (optionsRef.current[index] = el!)}
onClick={() => handleSelectAction(value, index)}>
{label}
</div>
);
})}
{!isNil(selected) && (
<div
className={styles.slider}
@ -53,6 +66,7 @@ export function VSegmentedControl({
/>
)}
</div>
{!isNil(name) && <input type="hidden" name={name} value={selected} />}
</div>
);
}

View File

@ -22,13 +22,13 @@ export type MaterialDesign2Scheme = {
};
export type MaterialDesign2SchemeSource = {
primary: string;
secondary: string;
error: string;
custom_colors: Record<string, string>;
primary: string | null;
secondary: string | null;
error: string | null;
custom_colors?: Record<string, string>;
};
export type MaterialDesign2SchemeStorage = {
source: MaterialDesign2SchemeSource;
scheme: MaterialDesign2Scheme;
source?: MaterialDesign2SchemeSource;
scheme?: MaterialDesign2Scheme;
};

View File

@ -46,12 +46,12 @@ export type MaterialDesign3Scheme = {
};
export type MaterialDesign3SchemeSource = {
source: string;
error: string;
custom_colors: Record<string, string>;
source: string | null;
error: string | null;
custom_colors?: Record<string, string>;
};
export type MaterialDesign3SchemeStorage = {
source: MaterialDesign3SchemeSource;
scheme: MaterialDesign3Scheme;
source?: MaterialDesign3SchemeSource;
scheme?: MaterialDesign3Scheme;
};

View File

@ -4,10 +4,12 @@ import { MaterialDesign3SchemeStorage } from './material-3-scheme';
import { QSchemeStorage } from './q-scheme';
import { SwatchSchemeStorage } from './swatch_scheme';
export type Option = {
label: string;
value: string | number | null;
};
export type Option =
| {
label: string;
value: string | number | null;
}
| Record<'label' | 'value', string | number | null>;
export type HarmonyColor = {
color: string;
@ -47,7 +49,7 @@ export function schemeType(
const useShort = short ?? false;
const foundType = find(SchemeTypeOptions, { value }) as SchemeTypeOption | undefined;
if (isNil(foundType)) {
return null;
return 'CORRUPTED';
}
return useShort ? foundType.short : foundType.label;
}

View File

@ -0,0 +1,6 @@
@layer pages {
.corrupted {
font-size: var(--font-size-xl);
color: var(--color-danger);
}
}

View File

@ -0,0 +1,8 @@
import styles from './CorruptedScheme.module.css';
export function CorruptedScheme() {
return (
<div className="center">
<div className={styles.corrupted}>Unrecognizable or corrupted scheme</div>
</div>
);
}

View File

@ -0,0 +1,3 @@
export function M2Scheme() {
return <div>Material Design 2 Scheme</div>;
}

View File

@ -0,0 +1,3 @@
export function M3Scheme() {
return <div>Material Design 3 Scheme</div>;
}

View File

@ -0,0 +1,3 @@
export function QScheme() {
return <div>Q Scheme</div>;
}

View File

@ -1,25 +0,0 @@
@layer pages {
.scheme_content {
flex: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: var(--spacing-m);
}
.series_row {
display: flex;
flex-direction: column;
gap: var(--spacing-s);
h4 {
padding-block: var(--spacing-xs);
font-size: var(--font-size-l);
}
ul {
display: flex;
flex-direction: row;
justify-content: flex-start;
flex-wrap: wrap;
gap: var(--spacing-l);
}
}
}

View File

@ -1,61 +0,0 @@
import { isArray } from 'lodash-es';
import { ColorStand } from '../../components/ColorStand';
import { SchemeSet } from '../../stores/schemes';
import styles from './SchemeContent.module.css';
type ColorSeriesProps = {
title: string;
series: SchemeSet['lightScheme' | 'darkScheme']['primary'];
simpleSeries?: boolean;
};
function ColorSeries({ title, series, simpleSeries = false }: ColorSeriesProps) {
return (
<div className={styles.series_row}>
<h4>{title}</h4>
<ul>
<ColorStand title="Normal" color={series?.normal} />
{simpleSeries ? (
<>
<ColorStand title="Lightness" color={series?.lighten} />
<ColorStand title="Darkness" color={series?.darken} />
</>
) : (
<>
<ColorStand title="Hover" color={series?.hover} />
<ColorStand title="Active" color={series?.active} />
<ColorStand title="Focus" color={series?.focus} />
<ColorStand title="Disabled" color={series?.disabled} />
</>
)}
</ul>
</div>
);
}
type SchemeContentProps = {
scheme: SchemeSet['lightScheme' | 'darkScheme'];
};
export function SchemeContent({ scheme }: SchemeContentProps) {
return (
<div className={styles.scheme_content}>
<ColorSeries title="Foreground Series" series={scheme.foreground} simpleSeries />
<ColorSeries title="Background Series" series={scheme.background} simpleSeries />
<ColorSeries title="Primary Series" series={scheme.primary} />
{isArray(scheme.secondary) ? (
scheme.secondary.map((cSet, index) => (
<ColorSeries title={`Secondary Series ${index + 1}`} series={cSet} />
))
) : (
<ColorSeries title="Secondary Series" series={scheme.secondary} />
)}
<ColorSeries title="Accent Series" series={scheme.accent} />
<ColorSeries title="Neutral Serias" series={scheme.neutral} />
<ColorSeries title="Success Series" series={scheme.success} />
<ColorSeries title="Danger Series" series={scheme.danger} />
<ColorSeries title="Warn Series" series={scheme.warning} />
<ColorSeries title="Info Series" series={scheme.info} />
</div>
);
}

View File

@ -1,17 +0,0 @@
@layer pages {
.scheme_view_layout {
flex: 1 0;
width: 100%;
padding: calc(var(--spacing) * 4) calc(var(--spacing) * 8);
display: flex;
flex-direction: column;
gap: var(--spacing-m);
overflow: hidden;
}
.preview_switch_container {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--spacing-m);
}
}

View File

@ -1,23 +0,0 @@
import { useState } from 'react';
import { Switch } from '../../components/Switch';
import { SchemeSet } from '../../stores/schemes';
import { SchemeContent } from './SchemeContent';
import styles from './SchemeView.module.css';
type SchemeViewProps = {
scheme: SchemeSet['lightScheme' | 'darkScheme'];
};
export function SchemeView({ scheme }: SchemeViewProps) {
const [enablePreview, setEnablePreview] = useState(false);
return (
<div className={styles.scheme_view_layout}>
<div className={styles.preview_switch_container}>
<span>Preview scheme</span>
<Switch onChange={(checked) => setEnablePreview(checked)} />
</div>
{enablePreview ? <div>SVG Preview</div> : <SchemeContent scheme={scheme} />}
</div>
);
}

View File

@ -0,0 +1,3 @@
export function SwatchScheme() {
return <div>Swatch Scheme</div>;
}

View File

@ -5,7 +5,7 @@
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--spacing-m);
gap: var(--spacing-xs);
overflow: hidden;
.badge_layout {
padding: var(--spacing-xs) var(--spacing-m);

View File

@ -1,10 +1,15 @@
import dayjs from 'dayjs';
import { isNil, set } from 'lodash-es';
import { useCallback, useEffect } from 'react';
import { useCallback, useEffect, useMemo } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { EditableDescription } from '../components/EditableDescription';
import { EditableTitle } from '../components/EditableTitle';
import { SchemeSign } from '../components/SchemeSign';
import { CorruptedScheme } from '../page-components/scheme/CorruptedScheme';
import { M2Scheme } from '../page-components/scheme/M2Scheme';
import { M3Scheme } from '../page-components/scheme/M3Scheme';
import { QScheme } from '../page-components/scheme/QScheme';
import { SwatchScheme } from '../page-components/scheme/SwatchScheme';
import { useScheme, useUpdateScheme } from '../stores/schemes';
import styles from './SchemeDetail.module.css';
@ -32,6 +37,20 @@ export function SchemeDetail() {
},
[id],
);
const schemeContent = useMemo(() => {
switch (scheme?.type) {
case 'q_scheme':
return <QScheme />;
case 'swatch_scheme':
return <SwatchScheme />;
case 'material_2':
return <M2Scheme />;
case 'material_3':
return <M3Scheme />;
default:
return <CorruptedScheme />;
}
}, [scheme]);
useEffect(() => {
if (isNil(scheme)) {
@ -49,6 +68,7 @@ export function SchemeDetail() {
</div>
</div>
<EditableDescription content={scheme?.description} onChange={updateDescription} />
{schemeContent}
</div>
);
}

View File

@ -29,8 +29,8 @@ export type Baseline = {
};
export type QScheme = {
light: Baseline;
dark: Baseline;
light: Baseline | null;
dark: Baseline | null;
};
export type QSchemeSetting = {
@ -44,20 +44,20 @@ export type QSchemeSetting = {
};
export type QSchemeSource = {
primary: string;
primary: string | null;
secondary: string | null;
tertiary: string | null;
accent: string | null;
danger: string;
success: string;
warning: string;
info: string;
foreground: string;
background: string;
setting: QSchemeSetting;
danger: string | null;
success: string | null;
warning: string | null;
info: string | null;
foreground: string | null;
background: strin | nullg;
setting: QSchemeSetting | null;
};
export type QSchemeStorage = {
source: QSchemeSource;
scheme: QScheme;
source?: QSchemeSource;
scheme?: QScheme;
};

View File

@ -7,10 +7,10 @@ export type SwatchScheme = {
export type SwatchSchemeSource = {
colors: SwatchEntry[];
setting: SwatchSchemeSetting;
setting: SwatchSchemeSetting | null;
};
export type SwatchSchemeStorage = {
source: SwatchSchemeSource;
scheme: SwatchScheme;
source?: SwatchSchemeSource;
scheme?: SwatchScheme;
};