Row

reminders.Row · #5wkzls6n · term · runs in the browser

handles onChange

A reminder: its tick, its title and notes (edited where they are), when it's due, and whether it's flagged.

import { dueLabel, Glyph, isOverdue } from "#codebase/reminders";
import type { Color, Reminder } from "#codebase/reminders";

export function Row({
  r,
  today,
  color,
  listName,
  onTick,
  onChange,
  onDelete,
}: {
  r: Reminder;
  today: string;
  color: Color;
  listName?: string;
  onTick: () => void;
  onChange: (r: Reminder) => void;
  onDelete: () => void;
}) {
  return (
    <li className={`row${r.done ? " done" : ""}`}>
      <input
        type="checkbox"
        className={`tick ${color}`}
        checked={!!r.done}
        aria-label={`Done: ${r.title}`}
        onChange={onTick}
      />
      <div className="body">
        <input
          className="title"
          aria-label="Title"
          value={r.title}
          onChange={(e) => onChange({ ...r, title: e.target.value })}
        />
        <input
          className="notes"
          aria-label="Notes"
          placeholder="Notes"
          value={r.notes}
          onChange={(e) => onChange({ ...r, notes: e.target.value })}
        />
        {(r.due || listName) && (
          <div className="meta">
            {r.due && (
              <span className={isOverdue(r, today) ? "overdue" : undefined}>
                {dueLabel(r.due, today)}
              </span>
            )}
            {listName && <span>{listName}</span>}
          </div>
        )}
      </div>
      <label className="due" title="Due">
        <Glyph name="scheduled" />
        <input
          type="date"
          aria-label="Due"
          value={r.due ?? ""}
          onChange={(e) =>
            onChange({ ...r, ...(e.target.value ? { due: e.target.value } : { due: undefined }) })
          }
        />
      </label>
      <button
        className={`flag${r.flagged ? " on" : ""}`}
        aria-pressed={r.flagged}
        aria-label="Flagged"
        onClick={() => onChange({ ...r, flagged: !r.flagged })}
      >
        <Glyph name="flagged" />
      </button>
      <button className="delete" aria-label="Delete" onClick={onDelete}>
        ×
      </button>
    </li>
  );
}

uses

used by