fix: add element/weekend color controls to CSS Variables panel, color-first layout

Today Highlight, Past Days, Saturday and Sunday now also appear as their
own groups in the CSS Variables panel, bound to the same profile fields
as the existing Element/Weekend Colors controls so both stay in sync.
Every row now shows the color swatch before its label.

v1.113.1
This commit is contained in:
mARTin-B78 2026-07-08 20:51:01 +02:00
parent 02b2e40649
commit 5510197cf4
3 changed files with 72 additions and 35 deletions

View File

@ -2,6 +2,14 @@
All notable changes to this project are documented in this file. All notable changes to this project are documented in this file.
## [1.113.1] - 2026-07-08
### Changed
- CSS Variables panel: added the existing "Today Highlight", "Past Days", "Saturday" and
"Sunday" color controls as their own groups (bound to the same profile fields as the
standalone Element/Weekend Colors sections, so both stay in sync).
- CSS Variables panel: every row now shows the color swatch before its label.
## [1.113.0] - 2026-07-08 ## [1.113.0] - 2026-07-08
### Added ### Added

View File

@ -1,6 +1,6 @@
{ {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.113.0", "version": "1.113.1",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -147,8 +147,25 @@ function ExtraTimezonesEditor({
// All customizable color custom-properties defined in globals.css :root, grouped for the // All customizable color custom-properties defined in globals.css :root, grouped for the
// "Styling" tab's CSS Variables editor. Overrides are stored as a flat { "--var-name": "#hex" } // "Styling" tab's CSS Variables editor. Overrides are stored as a flat { "--var-name": "#hex" }
// map in profile.customCssVars and applied on top of containerStyle in WeeklyView. // map in profile.customCssVars and applied on top of containerStyle in WeeklyView. Entries with
const CSS_VARIABLE_GROUPS: { title: string; vars: { name: string; label: string; default: string }[] }[] = [ // a `profileKey` instead read/write that scalar profile field directly (same fields the
// "Element Colors" / "Weekend Highlight Colors" controls elsewhere in this tab use), so both
// controls for the same setting always stay in sync.
const CSS_VARIABLE_GROUPS: { title: string; vars: { name: string; label: string; default: string; profileKey?: string }[] }[] = [
{
title: "Element Colors",
vars: [
{ name: "todayHighlightColor", label: "Today Highlight", default: "#f0fafa", profileKey: "todayHighlightColor" },
{ name: "pastDayColor", label: "Past Days", default: "#a6a6a7", profileKey: "pastDayColor" },
],
},
{
title: "Weekend Highlight Colors",
vars: [
{ name: "weekendColorSat", label: "Saturday", default: "#666666", profileKey: "weekendColorSat" },
{ name: "weekendColorSun", label: "Sunday", default: "#dc2626", profileKey: "weekendColorSun" },
],
},
{ {
title: "Base Colors", title: "Base Colors",
vars: [ vars: [
@ -256,6 +273,7 @@ function CssVariablesEditor({
const de = profile.language === "de"; const de = profile.language === "de";
const vars: Record<string, string> = profile.customCssVars || {}; const vars: Record<string, string> = profile.customCssVars || {};
const debounceTimer = useRef<NodeJS.Timeout | null>(null); const debounceTimer = useRef<NodeJS.Timeout | null>(null);
const fieldDebounceTimers = useRef<Record<string, NodeJS.Timeout>>({});
const setVar = (name: string, value: string) => { const setVar = (name: string, value: string) => {
const next = { ...(profile.customCssVars || {}), [name]: value }; const next = { ...(profile.customCssVars || {}), [name]: value };
@ -264,6 +282,12 @@ function CssVariablesEditor({
debounceTimer.current = setTimeout(() => saveSetting("customCssVars", next), 500); debounceTimer.current = setTimeout(() => saveSetting("customCssVars", next), 500);
}; };
const setProfileField = (key: string, value: string) => {
setProfile((p: any) => ({ ...p, [key]: value }));
if (fieldDebounceTimers.current[key]) clearTimeout(fieldDebounceTimers.current[key]);
fieldDebounceTimers.current[key] = setTimeout(() => saveSetting(key, value), 500);
};
const reset = () => { const reset = () => {
setProfile((p: any) => ({ ...p, customCssVars: {} })); setProfile((p: any) => ({ ...p, customCssVars: {} }));
saveSetting("customCssVars", {}); saveSetting("customCssVars", {});
@ -318,39 +342,44 @@ function CssVariablesEditor({
{group.title} {group.title}
</div> </div>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "6px 12px" }}> <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "6px 12px" }}>
{group.vars.map((v) => ( {group.vars.map((v) => {
<div const value = v.profileKey ? (profile[v.profileKey] || v.default) : (vars[v.name] || v.default);
key={v.name} const onChange = (e: React.ChangeEvent<HTMLInputElement>) =>
title={v.name} v.profileKey ? setProfileField(v.profileKey, e.target.value) : setVar(v.name, e.target.value);
style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: "8px" }} return (
> <div
<span key={v.name}
style={{ title={v.name}
fontSize: "0.72rem", style={{ display: "flex", alignItems: "center", gap: "8px" }}
color: "var(--weekly-settings-label)",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
> >
{v.label} <input
</span> type="color"
<input value={value}
type="color" onChange={onChange}
value={vars[v.name] || v.default} style={{
onChange={(e) => setVar(v.name, e.target.value)} width: "32px",
style={{ height: "22px",
width: "32px", cursor: "pointer",
height: "22px", border: "1px solid var(--weekly-settings-input-border)",
cursor: "pointer", borderRadius: "4px",
border: "1px solid var(--weekly-settings-input-border)", background: "transparent",
borderRadius: "4px", flexShrink: 0,
background: "transparent", }}
flexShrink: 0, />
}} <span
/> style={{
</div> fontSize: "0.72rem",
))} color: "var(--weekly-settings-label)",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
>
{v.label}
</span>
</div>
);
})}
</div> </div>
</div> </div>
))} ))}