/// A note's metadata controls: the priority/status row and the generic /// dropdown behind it. /// /// Shared by both editing surfaces -- capture and the detail screen -- so the /// two cannot drift apart. Public only because Dart privacy is library-scoped. library; import 'package:flutter/material.dart'; import 'package:todo/data/note.dart'; /// A compact labelled dropdown for picking an enum value (priority/status). /// /// Generic over the enum type [T] so the same control drives both pickers /// without duplication; [labelOf] maps a value to its display string. class MetaDropdown extends StatelessWidget { /// Creates a dropdown showing [value] out of [values]. const MetaDropdown({ required this.label, required this.value, required this.values, required this.labelOf, required this.onChanged, super.key, }); /// Label shown above the control. final String label; /// Currently selected value. final T value; /// Every selectable value. final List values; /// Maps a value to its display string. final String Function(T) labelOf; /// Called with the newly picked value. final ValueChanged onChanged; @override Widget build(BuildContext context) { return InputDecorator( decoration: InputDecoration( labelText: label, isDense: true, border: const OutlineInputBorder(), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: value, isDense: true, isExpanded: true, items: [ for (final v in values) DropdownMenuItem(value: v, child: Text(labelOf(v))), ], onChanged: (v) { if (v != null) onChanged(v); }, ), ), ); } } /// A note's priority and status pickers, side by side. /// /// Lays the row out and nothing else: whether it is visible at all is /// [NoteFormChromeGate]'s job, not this widget's. class NoteMetaRow extends StatelessWidget { /// Creates the metadata row for the current values. const NoteMetaRow({ required this.priority, required this.status, required this.onPriorityChanged, required this.onStatusChanged, super.key, }); /// The note's current priority. final Priority priority; /// The note's current status. final Status status; /// Called with a newly picked priority. final ValueChanged onPriorityChanged; /// Called with a newly picked status. final ValueChanged onStatusChanged; @override Widget build(BuildContext context) { return Row( children: [ Expanded( child: MetaDropdown( label: 'Priority', value: priority, values: Priority.values, labelOf: (p) => p.label, onChanged: onPriorityChanged, ), ), const SizedBox(width: 12), Expanded( child: MetaDropdown( label: 'Status', value: status, values: Status.values, labelOf: (s) => s.label, onChanged: onStatusChanged, ), ), ], ); } }