Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: migrate theme builder to docs #2987

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4d37a76
refactor(theme-builder): move theme builder dir to docs
ramenhog Nov 21, 2024
d3f0836
refactor(theme-builder): styles to use docs tailwind
ramenhog Nov 21, 2024
15c1395
refactor: remove old demo app
ramenhog Nov 21, 2024
819e55f
refactor: remove legacy deps from demo app
ramenhog Nov 21, 2024
772d86d
refactor: remove demo overrides from eslint
ramenhog Nov 21, 2024
1a9195a
refactor(theme-builder): use prism-react-renderer instead of react-sy…
ramenhog Nov 21, 2024
0b235c2
refactor: add theme builder to nav and remove demos from linter
ramenhog Nov 21, 2024
4541fc4
Feat: add theme builder base and box plot chart controls (#2989)
ramenhog Nov 26, 2024
d5f2b06
feat: add color scale overrides and final polish (#2990)
ramenhog Dec 2, 2024
fd196c9
Feat: theme builder palette fixes (#2992)
ramenhog Dec 2, 2024
52470ac
Feat: theme builder new UI (#3000)
ramenhog Dec 6, 2024
5161901
Feat: theme builder responsiveness (#3004)
ramenhog Dec 12, 2024
2a440af
Feat: theme builder custom colorscale overrides (#3005)
ramenhog Dec 12, 2024
3affd3d
Feat: theme builder preview settings (#3007)
ramenhog Dec 13, 2024
a99c340
Feat: theme builder refactor axis panel (#3010)
ramenhog Dec 16, 2024
6cd78f5
Feat: theme builder export panel updates (#3012)
ramenhog Dec 18, 2024
e9bb7fa
feat(theme-builder): allow users to choose which options to include i…
ramenhog Dec 19, 2024
4a0ea3e
Feat: theme builder default slider (#3020)
ramenhog Dec 20, 2024
a92c32b
Merge branch 'main' into feat/theme-builder-docs-migration
ramenhog Jan 6, 2025
8d90c9a
fix: lint error
ramenhog Jan 6, 2025
e40c77b
fix: lint error
ramenhog Jan 6, 2025
8e4f9ee
Refactor examples so we can support multiple per chart type (#3017)
carbonrobot Jan 7, 2025
945e97e
fix: lint errors
ramenhog Jan 7, 2025
03b9a51
feat(theme-builder): simplify color picker (#3028)
ramenhog Jan 10, 2025
1078fdc
feat(theme-builder): improve toggle accessibility (#3029)
ramenhog Jan 10, 2025
b81e09c
feat(theme-builder): keep config in local storage (#3032)
ramenhog Jan 13, 2025
7033602
feat(theme-builder): default chart + axis type (#3035)
ramenhog Jan 13, 2025
dc1c31e
feat(theme-builder): code editor (#3037)
ramenhog Jan 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
refactor(theme-builder): move theme builder dir to docs
  • Loading branch information
ramenhog committed Nov 21, 2024
commit 4d37a76a5cf108b92842602d1b9580b3d73a95c7
55 changes: 55 additions & 0 deletions website/src/pages/themes/_components/accordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from "react";
import clsx from "clsx";
import { FaChevronDown } from "react-icons/fa";

type AccordionProps = {
id: string;
title: string;
children: React.ReactNode;
defaultOpen?: boolean;
};

const Accordion = ({
id,
title,
children,
defaultOpen = false,
}: AccordionProps) => {
const [isOpen, setIsOpen] = React.useState(defaultOpen);

const toggleAccordion = () => {
setIsOpen(!isOpen);
};

return (
<div id={id} className="group">
<h2 id={`${id}-heading`}>
<button
type="button"
className={clsx(
"flex items-center justify-between w-full px-5 py-3 text-sm font-bold rtl:text-right text-gray-500 border border-b-0 border-gray-200 gap-3 group-last:border-b",
{ "group-last:border-b-0": isOpen },
)}
aria-expanded="true"
aria-controls={`${id}-body`}
onClick={toggleAccordion}
>
<span>{title}</span>
<FaChevronDown
className={clsx("w-3 h-3 shrink-0", { "rotate-180 ": isOpen })}
/>
</button>
</h2>
<div
id={`${id}-body`}
className={isOpen ? "block" : "hidden"}
aria-labelledby={`${id}-heading`}
>
<div className="p-5 border border-b-0 border-gray-200 group-last:border-b">
{children}
</div>
</div>
</div>
);
};
export default Accordion;
35 changes: 35 additions & 0 deletions website/src/pages/themes/_components/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react";

type ButtonProps = {
onClick: () => void;
children: React.ReactNode;
className?: string;
ariaLabel?: string;
disabled?: boolean;
};

const Button = ({
onClick,
children,
className = "",
ariaLabel = "",
disabled = false,
...props
}: ButtonProps) => {
const baseClasses =
"py-2 px-5 border-0 rounded-md cursor-pointer text-sm bg-primary text-white hover:bg-secondary disabled:bg-gray-200 disabled:cursor-not-allowed";

return (
<button
onClick={onClick}
disabled={disabled}
aria-label={ariaLabel || undefined}
className={`${baseClasses} ${className}`}
{...props}
>
{children}
</button>
);
};

export default Button;
101 changes: 101 additions & 0 deletions website/src/pages/themes/_components/color-picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from "react";
import { TiPencil } from "react-icons/ti";
import clsx from "clsx";

type ColorPickerProps = {
label?: string;
color: string;
id: string;
onColorChange: (color: string) => void;
showColorName?: boolean;
className?: string;
};

const ColorPicker = ({
label,
color,
id,
onColorChange,
showColorName = false,
className,
}: ColorPickerProps) => {
const [isPickerOpen, setIsPickerOpen] = React.useState(false);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (onColorChange) {
onColorChange(event.target.value);
}
};

return (
<fieldset className={className}>
{label && (
<label className="block mb-1 text-sm text-gray-900 dark:text-white font-bold">
{label}
</label>
)}
<div
className={clsx("relative inline-flex rounded-full group/swatch", {
"border-2 border-gray-200 p-0.5 cursor-pointer justify-between bg-gray-100":
showColorName,
})}
>
<div className="flex items-center">
<div className="relative">
<div
className={clsx(
"block w-[35px] h-[35px] rounded-full cursor-pointer transition-all justify-center items-center after:content-[''] after:block after:w-full after:h-full after:rounded-[inherit] after:bg-currentColor",
{
"outline-2 border-2 border-white outline outline-gray-200":
!showColorName,
},
{ "w-[30px] h-[30px] p-0.5": showColorName },
)}
style={{
color,
}}
/>
{!showColorName && (
<div
className={`absolute top-0 left-0 w-full h-full text-white flex justify-center items-center text-xl rounded-full opacity-0 group-hover/swatch:opacity-100 ${
isPickerOpen ? "opacity-100" : ""
}`}
>
<TiPencil />
</div>
)}
</div>
{showColorName && (
<span
className={
"text-sm font-medium text-gray-900 uppercase ml-2 cursor-pointer"
}
>
{color}
</span>
)}
</div>
{showColorName && (
<div
className={`text-gray-300 flex justify-center items-center text-xl rounded-full place-items-end ml-6 mr-1`}
>
<TiPencil />
</div>
)}
<input
id={id}
className={`absolute top-0 left-0 w-full h-full cursor-pointer opacity-0 z-10 group-hover/swatch:border-currentColor ${
isPickerOpen ? "border-currentColor" : ""
}`}
type="color"
value={color}
onChange={handleChange}
onFocus={() => setIsPickerOpen(true)}
onBlur={() => setIsPickerOpen(false)}
/>
</div>
</fieldset>
);
};

export default ColorPicker;
81 changes: 81 additions & 0 deletions website/src/pages/themes/_components/color-scale-options.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from "react";
import Select from "./select";
import ColorPicker from "./color-picker";
import { ColorScalePropType, VictoryThemeDefinition } from "victory";

export type ColorChangeArgs = {
newColor: string;
index: number;
colorScale: string;
};

type ColorScaleOptionsProps = {
palette?: VictoryThemeDefinition["palette"];
activeColorScale?: ColorScalePropType;
onColorChange: (args: ColorChangeArgs) => void;
onColorScaleChange: (colorScale: string) => void;
};

const colorScales = [
{
label: "Qualitative",
value: "qualitative",
},
{
label: "Heatmap",
value: "heatmap",
},
{
label: "Warm",
value: "warm",
},
{
label: "Cool",
value: "cool",
},
{
label: "Red",
value: "red",
},
{
label: "Green",
value: "green",
},
];

const ColorScaleOptions = ({
activeColorScale,
palette,
onColorChange,
onColorScaleChange,
}: ColorScaleOptionsProps) => {
return (
<section>
<Select
id="color-scale-select"
value={activeColorScale as string}
onChange={onColorScaleChange}
options={colorScales}
label="Color Scale"
className="mb-5"
/>
<div className="flex flex-wrap gap-3">
{palette?.[activeColorScale as string]?.map((color, i) => (
<ColorPicker
key={i}
color={color}
id={`color-${i}`}
onColorChange={(newColor) =>
onColorChange({
newColor,
index: i,
colorScale: activeColorScale as string,
})
}
/>
))}
</div>
</section>
);
};
export default ColorScaleOptions;
Loading