Compare commits
9 Commits
9606106c45
...
8efb3ec318
Author | SHA1 | Date | |
---|---|---|---|
|
8efb3ec318 | ||
|
c4f703906e | ||
|
6dba92a2c5 | ||
|
4b4428fd3b | ||
|
1b41fb4d22 | ||
|
a3de0f961a | ||
|
79794ed0f7 | ||
|
20757a789a | ||
|
f9f984a1b4 |
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
40
src/color_functions/color_module.d.ts
vendored
40
src/color_functions/color_module.d.ts
vendored
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Binary file not shown.
39
src/color_functions/color_module_bg.wasm.d.ts
vendored
39
src/color_functions/color_module_bg.wasm.d.ts
vendored
|
@ -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;
|
||||
|
|
|
@ -193,6 +193,7 @@
|
|||
resize: none;
|
||||
}
|
||||
.input_wrapper {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
6
src/page-components/scheme/CorruptedScheme.module.css
Normal file
6
src/page-components/scheme/CorruptedScheme.module.css
Normal file
|
@ -0,0 +1,6 @@
|
|||
@layer pages {
|
||||
.corrupted {
|
||||
font-size: var(--font-size-xl);
|
||||
color: var(--color-danger);
|
||||
}
|
||||
}
|
8
src/page-components/scheme/CorruptedScheme.tsx
Normal file
8
src/page-components/scheme/CorruptedScheme.tsx
Normal 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>
|
||||
);
|
||||
}
|
3
src/page-components/scheme/M2Scheme.tsx
Normal file
3
src/page-components/scheme/M2Scheme.tsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function M2Scheme() {
|
||||
return <div>Material Design 2 Scheme</div>;
|
||||
}
|
3
src/page-components/scheme/M3Scheme.tsx
Normal file
3
src/page-components/scheme/M3Scheme.tsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function M3Scheme() {
|
||||
return <div>Material Design 3 Scheme</div>;
|
||||
}
|
3
src/page-components/scheme/QScheme.tsx
Normal file
3
src/page-components/scheme/QScheme.tsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function QScheme() {
|
||||
return <div>Q Scheme</div>;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
3
src/page-components/scheme/SwatchScheme.tsx
Normal file
3
src/page-components/scheme/SwatchScheme.tsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function SwatchScheme() {
|
||||
return <div>Swatch Scheme</div>;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user