fix: align Add task input with task text column

SomedayAddTask now accepts showProjectIcons and showTaskCheckboxes props.
The bottom add-task row renders as a flex layout with matching spacers
for the icon column (18px) and checkbox column (16px), so the input
field left-edge exactly aligns with the task name column. Right-padding
keeps the input from extending into the provider icon column.

v1.109.1
This commit is contained in:
mARTin-B78 2026-05-11 12:40:23 +02:00
parent b53eff9fd1
commit 74268edb85
2 changed files with 70 additions and 40 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.109.0", "version": "1.109.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

@ -8557,6 +8557,8 @@ export default function WeeklyView() {
{listToDelete !== list.id && <SomedayAddTask {listToDelete !== list.id && <SomedayAddTask
listId={list.id} listId={list.id}
darkMode={darkMode} darkMode={darkMode}
showProjectIcons={effectiveShowProjectIcons}
showTaskCheckboxes={effectiveShowTaskCheckboxes}
onAdd={async (title) => { onAdd={async (title) => {
const occupiedSlots = list.tasks.map(t => t.somedaySlotIndex).filter(s => s !== null && s !== undefined) as number[]; const occupiedSlots = list.tasks.map(t => t.somedaySlotIndex).filter(s => s !== null && s !== undefined) as number[];
let nextFreeSlot = 0; let nextFreeSlot = 0;
@ -9825,12 +9827,16 @@ function SomedayAddTask({
onCancel, onCancel,
slotIdx, slotIdx,
darkMode, darkMode,
showProjectIcons,
showTaskCheckboxes,
}: { }: {
listId: string; listId: string;
onAdd: (title: string) => void; onAdd: (title: string) => void;
onCancel?: () => void; onCancel?: () => void;
slotIdx?: number; slotIdx?: number;
darkMode?: boolean; darkMode?: boolean;
showProjectIcons?: boolean;
showTaskCheckboxes?: boolean;
}) { }) {
const [title, setTitle] = useState(""); const [title, setTitle] = useState("");
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
@ -9850,25 +9856,66 @@ function SomedayAddTask({
} }
}, [slotIdx]); }, [slotIdx]);
// Bottom-of-list "Add task..." gets an input-style background so it reads
// as a real input. The inline slot-editor (slotIdx !== undefined) keeps the
// transparent look so it visually matches the surrounding task rows.
const isBottomAddInput = slotIdx === undefined; const isBottomAddInput = slotIdx === undefined;
if (isBottomAddInput) {
// Render as a flex row that mirrors the task item layout so the input
// aligns exactly with the task text column (icon spacer + checkbox spacer + input).
return ( return (
<li <li
className="weekly-task-item minimal" className="weekly-task-item minimal"
style={{ style={{ margin: "0", listStyle: "none", width: "100%", padding: "4px 24px 4px 8px" }}
margin: isBottomAddInput ? "0 24px 0 0.5rem" : "0",
listStyle: "none",
width: "100%"
}}
> >
<form <form
onSubmit={(e) => { onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}
e.preventDefault(); style={{ display: "flex", alignItems: "center", gap: "4px", width: "100%" }}
handleSubmit(); >
{/* Icon column spacer — matches task item icon column */}
{showProjectIcons && <span style={{ width: "18px", minWidth: "18px", flexShrink: 0 }} />}
{/* Checkbox spacer — matches task item checkbox column */}
{showTaskCheckboxes && <span style={{ width: "16px", minWidth: "16px", flexShrink: 0 }} />}
<input
ref={inputRef}
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
onBlur={handleSubmit}
onKeyDown={(e) => {
if (e.key === "Escape") {
setTitle("");
if (onCancel) onCancel();
else e.currentTarget.blur();
}
}} }}
className="weekly-task-text"
style={{
flex: 1,
border: `1px solid ${darkMode ? "#374151" : "#e5e7eb"}`,
background: darkMode ? "#1f2937" : "#ffffff",
color: darkMode ? "#f9fafb" : "#111827",
padding: "4px 8px",
borderRadius: "4px",
fontSize: "0.9375rem",
outline: "none",
height: "26px",
boxSizing: "border-box",
}}
placeholder="Add task..."
data-someday-add-input={listId}
/>
</form>
</li>
);
}
// Inline slot editor: transparent, no border
return (
<li
className="weekly-task-item minimal"
style={{ margin: "0", listStyle: "none", width: "100%" }}
>
<form
onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}
style={{ width: "100%" }} style={{ width: "100%" }}
> >
<input <input
@ -9885,21 +9932,7 @@ function SomedayAddTask({
} }
}} }}
className="weekly-task-text" className="weekly-task-text"
style={isBottomAddInput style={{
? {
width: "100%",
border: `1px solid ${darkMode ? "#374151" : "#e5e7eb"}`,
background: darkMode ? "#1f2937" : "#ffffff",
color: darkMode ? "#f9fafb" : "#111827",
padding: "4px 8px",
borderRadius: "4px",
fontSize: "0.9375rem",
outline: "none",
height: "26px",
display: "block",
boxSizing: "border-box",
}
: {
width: "100%", width: "100%",
border: "none", border: "none",
background: "transparent", background: "transparent",
@ -9908,10 +9941,7 @@ function SomedayAddTask({
outline: "none", outline: "none",
height: "auto", height: "auto",
display: "block", display: "block",
} }}
}
placeholder={isBottomAddInput ? "Add task..." : ""}
data-someday-add-input={isBottomAddInput ? listId : undefined}
/> />
</form> </form>
</li> </li>