Skip to content

Commit

Permalink
fix: themeConfig type & form re-design
Browse files Browse the repository at this point in the history
  • Loading branch information
ObservedObserver committed Oct 7, 2023
1 parent cfcafd8 commit 9b0253d
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 234 deletions.
2 changes: 1 addition & 1 deletion packages/graphic-walker/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kanaries/graphic-walker",
"version": "0.4.17",
"version": "0.4.19",
"scripts": {
"dev:front_end": "vite --host",
"dev": "npm run dev:front_end",
Expand Down
3 changes: 2 additions & 1 deletion packages/graphic-walker/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import BinPanel from './fields/datasetFields/binPanel';
import { ErrorContext } from './utils/reportError';
import { ErrorBoundary } from "react-error-boundary";
import Errorpanel from './components/errorpanel';
import { GWGlobalConfig } from './vis/theme';

export interface IGWProps {
dataSource?: IRow[];
Expand All @@ -46,7 +47,7 @@ export interface IGWProps {
fieldKeyGuard?: boolean;
/** @default "vega" */
themeKey?: IThemeKey;
themeConfig?: VegaGlobalConfig;
themeConfig?: GWGlobalConfig;
dark?: IDarkMode;
storeRef?: React.MutableRefObject<IGlobalStore | null>;
computation?: IComputationFunction;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';

export function ConfigItemContainer (props: { children?: React.ReactNode; className?: string }) {
return <div className="border border-gray-50 dark:border-gray-700 p-4 m-4 rounded-lg">
{props.children}
</div>
}

export function ConfigItemContent (props: { children?: React.ReactNode }) {
return <div className="border-t border-gray-50 dark:border-gray-700 mt-4 pt-4">
{props.children}
</div>
}

export function ConfigItemHeader (props: { children?: React.ReactNode }) {
return <div className="text-xs text-gray-500 dark:text-gray-400 font-medium">
{props.children}
</div>
}

export function ConfigItemTitle (props: { children?: React.ReactNode }) {
return <h2 className="text-xl text-gray-800 dark:text-gray-50 font-medium">
{props.children}
</h2>
}
323 changes: 174 additions & 149 deletions packages/graphic-walker/src/components/visualConfig/index.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function Checkbox(props: { inputKey: string; title: string; value: boolean; onCh
<div className="flex justify-center items-center space-x-1 text-xs">
<input
type="checkbox"
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600"
className="h-4 w-4 rounded border-gray-300 dark:border-gray-600 text-indigo-600 dark:text-indigo-300 focus:ring-0 bg-gray-50 dark:bg-gray-900"
checked={props.value}
id={`${props.inputKey}`}
aria-describedby={`${props.inputKey}_label`}
Expand Down Expand Up @@ -178,7 +178,7 @@ export function RangeScale(props: {
}}
type="number"
disabled={!props.enableMinDomain}
className="block w-full rounded-md border-0 py-1 px-2 text-gray-900 dark:text-white shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 dark:bg-zinc-900 dark:border-gray-700 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
className="block w-full rounded-md border-0 py-1 px-2 text-gray-900 dark:text-white shadow-sm ring-1 ring-inset ring-gray-300 dark:ring-gray-600 placeholder:text-gray-400 dark:bg-zinc-900 dark:border-gray-700 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 disabled:opacity-50"
/>
</div>
<div className="flex flex-col space-y-1 items-start">
Expand All @@ -198,7 +198,7 @@ export function RangeScale(props: {
}}
type="number"
disabled={!props.enableMaxDomain}
className="block w-full rounded-md border-0 py-1 px-2 text-gray-900 dark:text-white shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 dark:bg-zinc-900 dark:border-gray-700 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
className="block w-full rounded-md border-0 py-1 px-2 text-gray-900 dark:text-white shadow-sm ring-1 ring-inset ring-gray-300 dark:ring-gray-600 placeholder:text-gray-400 dark:bg-zinc-900 dark:border-gray-700 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 disabled:opacity-50"
/>
</div>
<div className="flex flex-col space-y-1 items-start w-48">
Expand Down
35 changes: 17 additions & 18 deletions packages/graphic-walker/src/utils/useTheme.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
import { IThemeKey } from '../interfaces';
import { builtInThemes, getColorPalette, getPrimaryColor } from '../vis/theme';

const isPlainObject = (a): a is object => typeof a === 'object' && !(a instanceof Array);
type PlainObject = { [key: string]: any };

const clone = <T>(a: T) => {
if (isPlainObject(a)) {
if (a === null) return a;
return Object.fromEntries(Object.keys(a).map((k) => [k, clone(a[k])]));
const isPlainObject = (obj: any): obj is PlainObject => {
return obj && typeof obj === 'object' && obj.constructor === Object;
};

const clone = <T>(a: T): T => {
if (Array.isArray(a)) {
return a.map(clone) as any;
} else if (isPlainObject(a)) {
return { ...a };
}
return a;
};

const merge = (a: any, b: any) => {
const deepMerge = (a: PlainObject, b: PlainObject): PlainObject => {
if (isPlainObject(a) && isPlainObject(b)) {
const result = clone(a);
Object.keys(b).forEach((k) => {
result[k] = merge(result[k], b[k]);
const result = { ...a };
Object.keys(b).forEach((key) => {
result[key] = isPlainObject(result[key]) ? deepMerge(result[key], b[key]) : b[key];
});
return result;
}
return b;
};

const merge2 = (...a: any[]) => {
if (a.length === 0) return undefined;
if (a.length === 1) return a[0];
let result = merge(a[0], a[1]);
for (let i = 2; i < a.length; i++) {
result = merge(result, a[i]);
}
return result;
const deepMergeAll = (...objects: PlainObject[]): PlainObject => {
return objects.reduce((acc, obj) => deepMerge(acc, obj), {});
};

export function getTheme(props: { themeKey?: IThemeKey; themeConfig?: any; primaryColor?: string; colorPalette?: string; mediaTheme: 'dark' | 'light' }) {
const { themeConfig, themeKey, mediaTheme, colorPalette, primaryColor } = props;
const presetConfig = themeConfig ?? builtInThemes[themeKey ?? 'vega'];
const colorConfig = primaryColor ? getPrimaryColor(primaryColor) : {};
const paletteConfig = colorPalette ? getColorPalette(colorPalette) : {};
const config = merge2(presetConfig, colorConfig, paletteConfig)?.[mediaTheme];
const config = deepMergeAll(presetConfig, colorConfig, paletteConfig)?.[mediaTheme];
return config;
}
91 changes: 29 additions & 62 deletions packages/graphic-walker/src/vis/theme.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
import { VegaGlobalConfig } from '../interfaces';

export type GWGlobalConfig<
T extends VegaGlobalConfig = VegaGlobalConfig & {
scale: {
continuous: {
range: string[];
};
};
}
> = {
light: T;
dark: T;
};

const DEFAULT_COLOR = '#5B8FF9';
const DARK_COMMON_DESIGN = {
background: 'transparent',
Expand Down Expand Up @@ -28,7 +43,7 @@ export const VegaTheme = {
dark: DARK_COMMON_DESIGN,
} as const;

export const AntVTheme = {
export const AntVTheme: GWGlobalConfig = {
light: {
area: { fill: DEFAULT_COLOR },
bar: { fill: DEFAULT_COLOR },
Expand All @@ -37,42 +52,17 @@ export const AntVTheme = {
point: { stroke: DEFAULT_COLOR },
rect: { fill: DEFAULT_COLOR },
tick: { stroke: DEFAULT_COLOR },
boxplot: { fill: DEFAULT_COLOR },
errorbar: { stroke: DEFAULT_COLOR },
errorband: { fill: DEFAULT_COLOR },
arc: { fill: DEFAULT_COLOR },
background: 'transparent',
range: {
category: [
"#5B8FF9",
"#61DDAA",
"#65789B",
"#F6BD16",
"#7262FD",
"#78D3F8",
"#9661BC",
"#F6903D",
"#008685",
"#F08BB4",
],
diverging: ["#7b3294", "#c2a5cf", "#f7f7f7", "#a6dba0", "#008837"],
heatmap: ["#0d0887", "#46039f", "#7201a8", "#9c179e", "#bd3786", "#d8576b", "#ed7953", "#fb9f3a", "#fdca26", "#f0f921"],
// ordinal: [
// '#B8E1FF',
// // '#9AC5FF',
// // '#7DAAFF',
// // '#5B8FF9',
// // '#3D76DD',
// // '#085EC0',
// // '#0047A5',
// // '#00318A',
// '#001D70'
// ],
// ordinal: 'blues',
category: ['#5B8FF9', '#61DDAA', '#65789B', '#F6BD16', '#7262FD', '#78D3F8', '#9661BC', '#F6903D', '#008685', '#F08BB4'],
diverging: ['#7b3294', '#c2a5cf', '#f7f7f7', '#a6dba0', '#008837'],
heatmap: ['#0d0887', '#46039f', '#7201a8', '#9c179e', '#bd3786', '#d8576b', '#ed7953', '#fb9f3a', '#fdca26', '#f0f921'],
ramp: ['#EBCCFF', '#CCB0FF', '#AE95FF', '#907BFF', '#7262FD', '#5349E0', '#2F32C3', '#001BA7', '#00068C'],
},
// scale for geo only
scale: {
continuous: { range: ["#d4d4e8", "#3b196f"] },
continuous: { range: ['#d4d4e8', '#3b196f'] },
},
},
dark: {
Expand All @@ -84,44 +74,21 @@ export const AntVTheme = {
point: { stroke: DEFAULT_COLOR },
rect: { fill: DEFAULT_COLOR },
tick: { stroke: DEFAULT_COLOR },
boxplot: { fill: DEFAULT_COLOR },
errorbar: { stroke: DEFAULT_COLOR },
errorband: { fill: DEFAULT_COLOR },
arc: { fill: DEFAULT_COLOR },
range: {
category: [
"#5B8FF9",
"#61DDAA",
"#65789B",
"#F6BD16",
"#7262FD",
"#78D3F8",
"#9661BC",
"#F6903D",
"#008685",
"#F08BB4",
],
diverging: ["#7b3294", "#c2a5cf", "#f7f7f7", "#a6dba0", "#008837"],
heatmap: ["#0d0887", "#46039f", "#7201a8", "#9c179e", "#bd3786", "#d8576b", "#ed7953", "#fb9f3a", "#fdca26", "#f0f921"],
ramp: [
"#EBCCFF",
"#CCB0FF",
"#AE95FF",
"#907BFF",
"#7262FD",
"#5349E0",
"#2F32C3",
"#001BA7",
"#00068C"
],
category: ['#5B8FF9', '#61DDAA', '#65789B', '#F6BD16', '#7262FD', '#78D3F8', '#9661BC', '#F6903D', '#008685', '#F08BB4'],
diverging: ['#7b3294', '#c2a5cf', '#f7f7f7', '#a6dba0', '#008837'],
heatmap: ['#0d0887', '#46039f', '#7201a8', '#9c179e', '#bd3786', '#d8576b', '#ed7953', '#fb9f3a', '#fdca26', '#f0f921'],
ramp: ['#EBCCFF', '#CCB0FF', '#AE95FF', '#907BFF', '#7262FD', '#5349E0', '#2F32C3', '#001BA7', '#00068C'],
},
// scale for geo only
scale: {
continuous: { range: ["#d4d4e8", "#3b196f"] },
continuous: { range: ['#d4d4e8', '#3b196f'] },
},
},
} as const;
};

export const builtInThemes: { [themeKey: string]: { light: any; dark: any } } = {
export const builtInThemes: { [themeKey: string]: { light: VegaGlobalConfig; dark: VegaGlobalConfig } } = {
vega: VegaTheme,
g2: AntVTheme,
};
Expand Down

1 comment on commit 9b0253d

@vercel
Copy link

@vercel vercel bot commented on 9b0253d Oct 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.