Simplify habit creation with editable starters and compact colors

This commit is contained in:
syntaxbullet
2026-09-05 07:51:22 +02:00
parent a2f5616b96
commit 9f8154e412
3 changed files with 130 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
import { useId } from "react";
import { useId, useState } from "react";
import { HABIT_COLORS, progressShade } from "./calendar-model";
import { Field } from "./Field";
@@ -41,19 +41,36 @@ export function HabitColorPicker({
value,
onChange,
mode = "demo",
compact = false,
}: {
value: string;
onChange: (color: string) => void;
mode?: "demo" | "create" | "edit";
compact?: boolean;
}) {
const id = useId();
const [expanded, setExpanded] = useState(false);
const showDetails = !compact || expanded;
const valid = isHabitColor(value);
return (
<fieldset className="ds-color-picker" aria-describedby={`${id}-hint`}>
<legend>Habit color</legend>
<p id={`${id}-hint`} className="ds-footnote">
Choose a suggested shade or enter a custom color for this habit’s calendar.
{showDetails ? "Choose a suggested shade or enter a custom color for this habit’s calendar." : "Choose a color for your habit."}
</p>
{compact && (
<>
<div className="ds-color-swatches ds-color-swatches--compact" role="group" aria-label="Suggested colors">
{HABIT_PALETTES.map((palette) => (
<button key={palette.name} type="button" aria-label={`${palette.name} ${palette.colors[0]}`} aria-pressed={value.toLowerCase() === palette.colors[0]} title={palette.name} onClick={() => onChange(palette.colors[0])}>
<span style={{ backgroundColor: palette.colors[0] }}>{value.toLowerCase() === palette.colors[0] ? "✓" : ""}</span>
</button>
))}
</div>
<button type="button" className="ds-button ds-button--text" aria-expanded={expanded} aria-controls={`${id}-details`} onClick={() => setExpanded(!expanded)}>{expanded ? "Fewer colors" : "More colors"}</button>
</>
)}
<div id={`${id}-details`} hidden={!showDetails}>
<div className="ds-color-palettes">
{HABIT_PALETTES.map((palette) => (
<div
@@ -112,6 +129,7 @@ export function HabitColorPicker({
)}
</Field>
</div>
</div>
{valid && (
<div
className="ds-color-live-preview"