Skip to content

Commit

Permalink
feat: basic theme builder layout with qualitative scale customization (
Browse files Browse the repository at this point in the history
  • Loading branch information
ramenhog authored Oct 22, 2024
1 parent bb4d6b0 commit dac4af3
Show file tree
Hide file tree
Showing 6 changed files with 438 additions and 13 deletions.
6 changes: 2 additions & 4 deletions demo/ts/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ class App extends React.Component<any, AppState> {
super(props);

this.state = {
route: window.location.hash.substr(1),
route: window.location.hash.slice(1),
};

if (this.state.route === "") {
Expand Down Expand Up @@ -281,9 +281,7 @@ class App extends React.Component<any, AppState> {
</main>
</>
) : (
<main style={mainStyle}>
<Child />
</main>
<Child />
)}
</div>
</div>
Expand Down
9 changes: 0 additions & 9 deletions demo/ts/components/theme-builder.tsx

This file was deleted.

84 changes: 84 additions & 0 deletions demo/ts/components/theme-builder/config-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from "react";
import { VictoryThemeDefinition } from "victory-core/lib";

type ConfigPreviewProps = {
config: VictoryThemeDefinition;
onClose: () => void;
};

const containerStyles: React.CSSProperties = {
position: "fixed",
top: 0,
right: 0,
bottom: 0,
width: "100%",
padding: 20,
backgroundColor: "rgba(255, 255, 255, 0.9)",
zIndex: 1000,
};

const copyButtonContainerStyles: React.CSSProperties = {
display: "flex",
alignItems: "center",
gap: 10,
marginBottom: 20,
};

const copyStatusStyles: React.CSSProperties = {
color: "#666",
fontSize: 12,
fontStyle: "italic",
};

const codeStyles: React.CSSProperties = {
overflow: "auto",
maxHeight: 600,
border: "1px solid #ccc",
padding: 10,
backgroundColor: "#f9f9f9",
};

const closeButtonStyles: React.CSSProperties = {
position: "absolute",
top: 10,
right: 10,
background: "transparent",
border: "none",
fontSize: "20px",
cursor: "pointer",
};

const ConfigPreview = ({ config, onClose }: ConfigPreviewProps) => {
const [copyStatus, setCopyStatus] = React.useState<string | null>(null);

const handleCopyThemeConfig = () => {
navigator.clipboard
.writeText(JSON.stringify(config, null, 2))
.then(() => {
setCopyStatus("Copied successfully.");
return "Theme config copied to clipboard";
})
.catch(() => {
setCopyStatus("Failed to copy.");
});
};

const handleClose = () => {
onClose();
};

return (
<div style={containerStyles}>
<div style={copyButtonContainerStyles}>
<button onClick={handleCopyThemeConfig}>Copy Theme Config</button>
{copyStatus && <span style={copyStatusStyles}>{copyStatus}</span>}
</div>
<h2>Theme Config Preview</h2>
<pre style={codeStyles}>{JSON.stringify(config, null, 2)}</pre>
<button onClick={handleClose} style={closeButtonStyles}>
&times;
</button>
</div>
);
};
export default ConfigPreview;
76 changes: 76 additions & 0 deletions demo/ts/components/theme-builder/custom-options.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from "react";
import { ThemeOption } from ".";
import ConfigPreview from "./config-preview";

type ColorChangeArgs = {
event: React.ChangeEvent<HTMLInputElement>;
index: number;
colorScale: string;
};

type CustomOptionsProps = {
activeTheme: ThemeOption;
onColorChange: (args: ColorChangeArgs) => void;
};

const colorContainer: React.CSSProperties = {
display: "grid",
gridTemplateColumns: "repeat(4, 1fr)",
gap: 20,
};

const colorPickerStyles: React.CSSProperties = {
width: 50,
height: 50,
};

const CustomOptions = ({ activeTheme, onColorChange }: CustomOptionsProps) => {
const [showThemeConfigPreview, setShowThemeConfigPreview] =
React.useState(false);

const onThemeConfigPreviewOpen = () => {
setShowThemeConfigPreview(true);
};

const onThemeConfigPreviewClose = () => {
setShowThemeConfigPreview(false);
};
return (
<>
<div>
<button onClick={onThemeConfigPreviewOpen}>
See Custom Config JSON
</button>
<section>
<h2>Color Scales</h2>
<h3>Qualitative</h3>
<div style={colorContainer}>
{activeTheme.config?.palette?.qualitative?.map((color, index) => (
<input
key={index}
style={colorPickerStyles}
type="color"
value={color}
onChange={(event) =>
onColorChange({
event,
index,
colorScale: "qualitative",
})
}
/>
))}
</div>
</section>
</div>

{showThemeConfigPreview && activeTheme.config && (
<ConfigPreview
config={activeTheme.config}
onClose={onThemeConfigPreviewClose}
/>
)}
</>
);
};
export default CustomOptions;
Loading

0 comments on commit dac4af3

Please sign in to comment.