Center each habit layout on its completion action
This commit is contained in:
@@ -21,6 +21,8 @@ export function HabitChart({
|
||||
due = true,
|
||||
id,
|
||||
headingLevel = 4,
|
||||
trackingMethod,
|
||||
checkInId,
|
||||
}: {
|
||||
name: string;
|
||||
method: string;
|
||||
@@ -38,9 +40,33 @@ export function HabitChart({
|
||||
due?: boolean;
|
||||
id?: string;
|
||||
headingLevel?: 3 | 4;
|
||||
trackingMethod?: "manual" | "count" | "tasks";
|
||||
checkInId?: string;
|
||||
}) {
|
||||
const headingId = useId();
|
||||
const Heading = `h${headingLevel}` as const;
|
||||
if (trackingMethod) return (
|
||||
<section className={`ds-habit-chart ds-goal ds-goal--${trackingMethod}`} id={id} aria-labelledby={headingId} style={{ "--habit-color": color } as CSSProperties}>
|
||||
<header className="ds-goal-heading">
|
||||
<div className="ds-goal-title">
|
||||
{trackingMethod === "manual" && children}
|
||||
<Heading id={headingId} className="type-title">
|
||||
{trackingMethod === "manual" ? <label htmlFor={checkInId}>{name}</label> : name}
|
||||
</Heading>
|
||||
</div>
|
||||
{headingActions}
|
||||
</header>
|
||||
{(!due || schedule !== "Every day") && <p className="ds-goal-schedule">{due ? schedule : `Not scheduled today · ${schedule}`}</p>}
|
||||
{editor}
|
||||
{trackingMethod === "count" && <div className="ds-goal-count">{children}<span className="ds-goal-unit">{unit}</span></div>}
|
||||
{trackingMethod === "tasks" && <div className="ds-goal-tasks">
|
||||
{due && target > 0 && <p className="ds-goal-task-progress" role="status">{value} / {target} completed</p>}
|
||||
{tasks}
|
||||
</div>}
|
||||
{calendar}
|
||||
</section>
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="ds-habit-chart" id={id} aria-labelledby={headingId} style={{ "--habit-color": color } as CSSProperties}>
|
||||
<header className="ds-habit-chart-heading">
|
||||
|
||||
@@ -56,19 +56,20 @@ export function SectionHeading({
|
||||
export function Checkbox({
|
||||
label,
|
||||
description,
|
||||
hideLabel = false,
|
||||
className = "",
|
||||
...props
|
||||
}: Omit<InputHTMLAttributes<HTMLInputElement>, "type"> & { label: string; description?: string }) {
|
||||
}: Omit<InputHTMLAttributes<HTMLInputElement>, "type"> & { label: string; description?: string; hideLabel?: boolean }) {
|
||||
const descriptionId = useId();
|
||||
return (
|
||||
<label className={`ds-checkbox ${className}`}>
|
||||
<input
|
||||
type="checkbox"
|
||||
aria-label={description ? label : undefined}
|
||||
aria-label={description || hideLabel ? label : undefined}
|
||||
{...props}
|
||||
aria-describedby={[props["aria-describedby"], description ? descriptionId : undefined].filter(Boolean).join(" ") || undefined}
|
||||
/>
|
||||
<span className="ds-checkbox-copy">
|
||||
<span className={`ds-checkbox-copy${hideLabel ? " ds-visually-hidden" : ""}`}>
|
||||
<span className="ds-checkbox-label">{label}</span>
|
||||
{description && <span id={descriptionId} className="ds-checkbox-description">{description}</span>}
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user