Completed palette editor, ui overhaul.
Test and Build / test-and-build (push) Failing after 2m44s

This commit is contained in:
Jay
2026-03-23 08:24:44 -04:00
parent 9fec89949b
commit 5f6d0f43ee
33 changed files with 2713 additions and 611 deletions
+180 -50
View File
@@ -1,17 +1,32 @@
import type { Dispatch } from "react";
import { Hex as HexColor } from "colorlib";
import { randomId } from "@/util";
export type PaletteMode = "normal" | "select" | "reorder";
export interface PaletteColor {
id: string;
name: string;
hex: string;
hex: HexColor;
}
export interface ColorNameUpdate {
id: string;
name: string;
}
export interface ColorValueUpdate {
id: string;
hex: HexColor;
}
export interface PaletteCard {
id: string;
name: string;
colors: PaletteColor[];
selectedColorId: string | null;
inToolkitMode: boolean;
selectedColorIds: string[];
}
export interface PaletteCardState {
@@ -22,64 +37,165 @@ export interface PaletteCardState {
export type PaletteCardAction =
| { type: "SET_CARD_NAME"; payload: string }
| { type: "SET_SELECTED_COLOR"; payload: string | null }
| { type: "SET_COLOR_NAME"; payload: ColorNameUpdate }
| { type: "SET_COLOR_VALUE"; payload: ColorValueUpdate }
| { type: "SET_COLOR_VALUE_SILENT"; payload: ColorValueUpdate }
| { type: "COMMIT_TO_HISTORY"; payload: PaletteCard }
| { type: "SET_SELECTED_COLORS"; payload: string[] }
| { type: "SELECT_ALL" }
| { type: "CLEAR_SELECTION" }
| { type: "DELETE_SELECTED_COLORS" }
| { type: "DUPLICATE_SELECTED_COLORS" }
| { type: "ADD_COLOR" }
| { type: "DELETE_SELECTED_COLOR" }
| { type: "DUPLICATE_SELECTED_COLOR" }
| { type: "REORDER_COLORS"; payload: PaletteColor[] }
| { type: "TOGGLE_TOOLKIT_MODE" }
| { type: "UNDO" }
| { type: "REDO" };
const pushToHistory = (state: PaletteCardState, newPresent: PaletteCard) => {
return {
...state,
history: [state.present, ...state.history],
future: [],
present: newPresent,
};
};
export function paletteCardReducer(
state: PaletteCardState,
action: PaletteCardAction,
): PaletteCardState {
const pushToHistory = (state: PaletteCardState, newPresent: PaletteCard) => {
return {
...state,
history: [state.present, ...state.history],
future: [],
present: newPresent,
};
};
switch (action.type) {
case "SET_CARD_NAME":
state = pushToHistory(state, { ...state.present, name: action.payload });
return state;
case "SET_SELECTED_COLOR":
// TODO: Implement
return state;
case "SET_COLOR_NAME": {
let changed = false;
const colors = state.present.colors.map((c) => {
if (c.id !== action.payload.id) return c;
changed = true;
return { ...c, name: action.payload.name };
});
if (!changed) return state;
return pushToHistory(state, { ...state.present, colors });
}
case "ADD_COLOR":
// TODO: Implement
return state;
case "SET_COLOR_VALUE": {
let changed = false;
const colors = state.present.colors.map((c) => {
if (c.id !== action.payload.id) return c;
changed = true;
return { ...c, hex: action.payload.hex };
});
if (!changed) return state;
return pushToHistory(state, { ...state.present, colors });
}
case "DELETE_SELECTED_COLOR":
// TODO: Implement
return state;
case "SET_COLOR_VALUE_SILENT": {
let changed = false;
const colors = state.present.colors.map((c) => {
if (c.id !== action.payload.id) return c;
changed = true;
return { ...c, hex: action.payload.hex };
});
if (!changed) return state;
return {
...state,
present: { ...state.present, colors },
};
}
case "DUPLICATE_SELECTED_COLOR":
// TODO: Implement
return state;
case "COMMIT_TO_HISTORY": {
return {
...state,
history: [action.payload, ...state.history],
};
}
case "SET_SELECTED_COLORS":
return {
...state,
present: { ...state.present, selectedColorIds: action.payload },
};
case "SELECT_ALL":
return {
...state,
present: {
...state.present,
selectedColorIds: state.present.colors.map((c) => c.id),
},
};
case "CLEAR_SELECTION":
return {
...state,
present: { ...state.present, selectedColorIds: [] },
};
case "ADD_COLOR": {
const newColor: PaletteColor = {
id: randomId(),
name: "New Color",
hex: HexColor.from_code("000000"),
};
return pushToHistory(state, {
...state.present,
colors: [...state.present.colors, newColor],
});
}
case "DELETE_SELECTED_COLORS": {
if (state.present.selectedColorIds.length === 0) return state;
const ids = new Set(state.present.selectedColorIds);
return pushToHistory(state, {
...state.present,
colors: state.present.colors.filter((c) => !ids.has(c.id)),
selectedColorIds: [],
});
}
case "DUPLICATE_SELECTED_COLORS": {
if (state.present.selectedColorIds.length === 0) return state;
const ids = new Set(state.present.selectedColorIds);
const next: PaletteColor[] = [];
for (const color of state.present.colors) {
next.push(color);
if (ids.has(color.id)) {
next.push({ ...color, id: randomId() });
}
}
return pushToHistory(state, {
...state.present,
colors: next,
});
}
case "REORDER_COLORS":
// TODO: Implement
return state;
return pushToHistory(state, {
...state.present,
colors: action.payload,
});
case "TOGGLE_TOOLKIT_MODE":
// TODO: Implement
return state;
case "UNDO": {
if (state.history.length === 0) return state;
const [prev, ...rest] = state.history;
return {
present: prev,
history: rest,
future: [state.present, ...state.future],
};
}
case "UNDO":
// TODO: Implement
return state;
case "REDO":
// TODO: Implement
return state;
case "REDO": {
if (state.future.length === 0) return state;
const [next, ...rest] = state.future;
return {
present: next,
history: [state.present, ...state.history],
future: rest,
};
}
default:
return state;
@@ -88,12 +204,17 @@ export function paletteCardReducer(
export interface PaletteCardActions {
setCardName: (name: string) => void;
setSelectedColor: (id: string | null) => void;
setColorName: (id: string, name: string) => void;
setColorValue: (id: string, hex: HexColor) => void;
setColorValueSilent: (id: string, hex: HexColor) => void;
commitToHistory: (card: PaletteCard) => void;
setSelectedColors: (id: string[]) => void;
selectAll: () => void;
clearSelection: () => void;
addColor: () => void;
deleteSelectedColor: () => void;
duplicateSelectedColor: () => void;
deleteSelectedColors: () => void;
duplicateSelectedColors: () => void;
reorderColors: (colors: PaletteColor[]) => void;
toggleToolkitMode: () => void;
undo: () => void;
redo: () => void;
}
@@ -103,15 +224,24 @@ export function createPaletteCardActions(
): PaletteCardActions {
return {
setCardName: (name) => dispatch({ type: "SET_CARD_NAME", payload: name }),
setSelectedColor: (id) =>
dispatch({ type: "SET_SELECTED_COLOR", payload: id }),
setColorName: (id, name) =>
dispatch({ type: "SET_COLOR_NAME", payload: { id, name } }),
setColorValue: (id, hex) =>
dispatch({ type: "SET_COLOR_VALUE", payload: { id, hex } }),
setColorValueSilent: (id, hex) =>
dispatch({ type: "SET_COLOR_VALUE_SILENT", payload: { id, hex } }),
commitToHistory: (card) =>
dispatch({ type: "COMMIT_TO_HISTORY", payload: card }),
setSelectedColors: (ids) =>
dispatch({ type: "SET_SELECTED_COLORS", payload: ids }),
selectAll: () => dispatch({ type: "SELECT_ALL" }),
clearSelection: () => dispatch({ type: "CLEAR_SELECTION" }),
addColor: () => dispatch({ type: "ADD_COLOR" }),
deleteSelectedColor: () => dispatch({ type: "DELETE_SELECTED_COLOR" }),
duplicateSelectedColor: () =>
dispatch({ type: "DUPLICATE_SELECTED_COLOR" }),
deleteSelectedColors: () => dispatch({ type: "DELETE_SELECTED_COLORS" }),
duplicateSelectedColors: () =>
dispatch({ type: "DUPLICATE_SELECTED_COLORS" }),
reorderColors: (colors) =>
dispatch({ type: "REORDER_COLORS", payload: colors }),
toggleToolkitMode: () => dispatch({ type: "TOGGLE_TOOLKIT_MODE" }),
undo: () => dispatch({ type: "UNDO" }),
redo: () => dispatch({ type: "REDO" }),
};