Skip to content

Commit

Permalink
Split color pickers into single and multiple
Browse files Browse the repository at this point in the history
The single color picker binds to the user input unlike the multiple one.
  • Loading branch information
Rian8337 committed Sep 8, 2023
1 parent b3bc820 commit da78fad
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 62 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import { Resettable } from "../../structures/resettable/Resettable";
import "./ColorEditor.css";
import "./MultipleColorEditor.css";

interface Props {
/**
Expand All @@ -16,24 +16,34 @@ interface Props {
/**
* The configuration that the input is responsible for.
*/
resettable: Resettable<string | undefined>;
resettable: Resettable<string[]>;

/**
* The label beside the color input box.
*/
inputLabel?: string;

/**
* Whether to accept multiple colors. Defaults to `false`.
*/
acceptMultipleColors?: boolean;
}

export default function ColorEditor(props: Props) {
const { title, description, resettable, inputLabel, acceptMultipleColors } =
props;
export default function MultipleColorEditor(props: Props) {
const { title, description, resettable, inputLabel } = props;
const [hexCode, setHexCode] = useState("#FFFFFF");

// Introduce additional hooks to convert the value from an array.
const defaultValue = resettable.defaultValue[0];
const [value, setValue] = useState(defaultValue);

const modifyValue = (value = defaultValue) => {
setValue(value);

resettable.setValue(value.split(",").map((v) => v.trim()));
};

const resetValue = () => {
setValue(defaultValue);

resettable.reset();
};

return (
<div className="json-item-editor">
<div className="json-item-editor-title">{title}</div>
Expand All @@ -51,18 +61,17 @@ export default function ColorEditor(props: Props) {
<input
className="json-item-editor-input"
type="text"
value={resettable.value}
maxLength={acceptMultipleColors ? undefined : 7}
value={value}
onChange={(event) => {
resettable.setValue(event.target.value || undefined);
modifyValue(event.target.value || undefined);
}}
/>

<input
className="json-item-editor-input"
type="reset"
onClick={() => {
resettable.reset();
resetValue();
}}
/>
</div>
Expand Down
80 changes: 80 additions & 0 deletions src/components/editors/SingleColorEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Resettable } from "../../structures/resettable/Resettable";
import { validateColor } from "../../utils/validators";

interface Props {
/**
* The title of the input.
*/
title: string;

/**
* The description of the input.
*/
description?: string;

/**
* The configuration that the input is responsible for.
*/
resettable: Resettable<string | undefined>;
}

export default function SingleColorEditor(props: Props) {
const { title, description, resettable } = props;

return (
<div className="json-item-editor">
<div className="json-item-editor-title">{title}</div>
{description ? (
<div className="json-item-editor-description">
{description}
</div>
) : null}

<div className="json-item-editor-flex-container">
<input
type="color"
// The default color of a color input is black.
// (ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color#providing_a_default_color)
value={
resettable.value && validateColor(resettable.value)
? resettable.value
: "#000000"
}
onChange={(event) => {
resettable.setValue(
event.target.value.toUpperCase() || undefined
);
}}
/>

<input
className="json-item-editor-input"
type="text"
value={resettable.value ?? ""}
maxLength={7}
onChange={(event) => {
const value = event.target.value;

if (value) {
resettable.setValue(
validateColor(value)
? value.toUpperCase()
: value
);
} else {
resettable.reset();
}
}}
/>

<input
className="json-item-editor-input"
type="reset"
onClick={() => {
resettable.reset();
}}
/>
</div>
</div>
);
}
4 changes: 2 additions & 2 deletions src/components/groups/skin/Color/MenuItemDefaultColor.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useContext } from "react";
import { MenuItemDefaultColorContext } from "../../../../hooks/Color/MenuItemDefaultColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function MenuItemDefaultColor() {
const ctx = useContext(MenuItemDefaultColorContext);

return (
<ColorEditor
<SingleColorEditor
title="Unselected Color"
description="The color of a beatmapset card when it is not selected."
resettable={ctx}
Expand Down
4 changes: 2 additions & 2 deletions src/components/groups/skin/Color/MenuItemDefaultTextColor.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useContext } from "react";
import { MenuItemDefaultTextColorContext } from "../../../../hooks/Color/MenuItemDefaultTextColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function MenuItemDefaultTextColor() {
const ctx = useContext(MenuItemDefaultTextColorContext);

return (
<ColorEditor
<SingleColorEditor
title="Unselected Text Color"
description="The color of the text inside a beatmap card when it is unselected."
resettable={ctx}
Expand Down
4 changes: 2 additions & 2 deletions src/components/groups/skin/Color/MenuItemOnTouchColor.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useContext } from "react";
import { MenuItemOnTouchColorContext } from "../../../../hooks/Color/MenuItemOnTouchColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function MenuItemOnTouchColor() {
const ctx = useContext(MenuItemOnTouchColorContext);

return (
<ColorEditor
<SingleColorEditor
title="Selected Color"
description="The color of a beatmapset card when it is selected."
resettable={ctx}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useContext } from "react";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";
import { MenuItemSelectedTextColorContext } from "../../../../hooks/Color/MenuItemSelectedTextColorContext";

export default function MenuItemSelectedTextColor() {
const ctx = useContext(MenuItemSelectedTextColorContext);

return (
<ColorEditor
<SingleColorEditor
title="Selected Text Color"
description="The color of the text inside a beatmap card when it is selected."
resettable={ctx}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useContext } from "react";
import { MenuItemVersionsDefaultColorContext } from "../../../../hooks/Color/MenuItemVersionsDefaultColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function MenuItemVersionsDefaultColor() {
const ctx = useContext(MenuItemVersionsDefaultColorContext);

return (
<ColorEditor
<SingleColorEditor
title="Unselected Card Color"
description="The color of a beatmap card when it is unselected."
resettable={ctx}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useContext } from "react";
import { MenuItemVersionsSelectedColorContext } from "../../../../hooks/Color/MenuItemVersionsSelectedColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function MenuItemVersionsSelectedColor() {
const ctx = useContext(MenuItemVersionsSelectedColorContext);

return (
<ColorEditor
<SingleColorEditor
title="Selected Card Color"
description="The color of a beatmap card when it is selected."
resettable={ctx}
Expand Down
34 changes: 4 additions & 30 deletions src/components/groups/skin/ComboColor/ColorList.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,16 @@
import { useContext, useState } from "react";
import { useContext } from "react";
import { ComboColorsContext } from "../../../../hooks/ComboColor/ComboColorsContext";
import ColorEditor from "../../../editors/ColorEditor";
import MultipleColorEditor from "../../../editors/MultipleColorEditor";

export default function ColorList() {
const ctx = useContext(ComboColorsContext);

// Introduce additional hooks to convert the value from an array.
const defaultValue = ctx.defaultValue[0];
const [value, setValue] = useState(defaultValue);

const modifyValue = (value = defaultValue) => {
setValue(value);

ctx.setValue(value.split(",").map((v) => v.trim()));
};

const resetValue = () => {
setValue(defaultValue);

ctx.reset();
};

return (
<ColorEditor
<MultipleColorEditor
title="Combo Colors"
description="The color order will determine the color appearance order in-game."
inputLabel="Colors"
acceptMultipleColors={true}
resettable={{
defaultValue,
value,
reset: resetValue,
isDefault: ctx.isDefault,
setValue: modifyValue,
saveToJSON: (json) => {
ctx.saveToJSON(json);
},
}}
resettable={ctx}
/>
);
}
4 changes: 2 additions & 2 deletions src/components/groups/skin/Slider/SliderBodyColor.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useContext } from "react";
import { SliderBodyColorContext } from "../../../../hooks/Slider/SliderBodyColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function SliderBodyColor() {
const ctx = useContext(SliderBodyColorContext);

return <ColorEditor title="Color" resettable={ctx} />;
return <SingleColorEditor title="Color" resettable={ctx} />;
}
4 changes: 2 additions & 2 deletions src/components/groups/skin/Slider/SliderBorderColor.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useContext } from "react";
import { SliderBorderColorContext } from "../../../../hooks/Slider/SliderBorderColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function SliderBorderColor() {
const ctx = useContext(SliderBorderColorContext);

return <ColorEditor title="Color" resettable={ctx} />;
return <SingleColorEditor title="Color" resettable={ctx} />;
}
4 changes: 2 additions & 2 deletions src/components/groups/skin/Slider/SliderHintColor.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useContext } from "react";
import { SliderHintColorContext } from "../../../../hooks/Slider/SliderHintColorContext";
import ColorEditor from "../../../editors/ColorEditor";
import SingleColorEditor from "../../../editors/SingleColorEditor";

export default function SliderHintColor() {
const ctx = useContext(SliderHintColorContext);

return <ColorEditor title="Color" resettable={ctx} />;
return <SingleColorEditor title="Color" resettable={ctx} />;
}

0 comments on commit da78fad

Please sign in to comment.