// AUTO-GENERATED widget — matches web .data-row import 'package:flutter/material.dart'; import 'package:inou_app/design/inou_theme.dart'; import 'package:inou_app/design/inou_text.dart'; /// Expandable data row (for imaging, labs, etc.) class InouDataRow extends StatefulWidget { final String label; final String? meta; final String? date; final String? value; final bool isExpandable; final List? children; final Widget? leading; final Widget? trailing; final VoidCallback? onTap; final bool initiallyExpanded; const InouDataRow({ super.key, required this.label, this.meta, this.date, this.value, this.isExpandable = false, this.children, this.leading, this.trailing, this.onTap, this.initiallyExpanded = false, }); @override State createState() => _InouDataRowState(); } class _InouDataRowState extends State { late bool _expanded; @override void initState() { super.initState(); _expanded = widget.initiallyExpanded; } @override Widget build(BuildContext context) { return Column( children: [ InkWell( onTap: widget.isExpandable ? () => setState(() => _expanded = !_expanded) : widget.onTap, child: Container( padding: const EdgeInsets.symmetric( horizontal: InouTheme.spaceLg, vertical: InouTheme.spaceMd, ), decoration: const BoxDecoration( border: Border( bottom: BorderSide( color: InouTheme.border, style: BorderStyle.solid, ), ), ), child: Row( children: [ if (widget.isExpandable) SizedBox( width: 20, child: Text( _expanded ? '−' : '+', style: TextStyle( color: InouTheme.textMuted, fontSize: 14, fontFamily: 'monospace', ), ), ) else if (widget.leading == null) const SizedBox(width: 32), if (widget.leading != null) ...[ widget.leading!, const SizedBox(width: 12), ], Expanded( child: Text( widget.label, style: InouText.body.copyWith( fontWeight: FontWeight.w500, ), ), ), if (widget.value != null) Text( widget.value!, style: TextStyle( fontFamily: 'SF Mono', fontSize: 13, color: InouTheme.text, ), ), if (widget.meta != null) ...[ const SizedBox(width: 16), Text( widget.meta!, style: InouText.bodySmall.copyWith( color: InouTheme.textMuted, ), ), ], if (widget.date != null) ...[ const SizedBox(width: 16), Text( widget.date!, style: TextStyle( fontFamily: 'SF Mono', fontSize: 12, color: InouTheme.textMuted, ), ), ], if (widget.trailing != null) ...[ const SizedBox(width: 8), widget.trailing!, ], ], ), ), ), if (_expanded && widget.children != null) Container( color: InouTheme.bg, child: Column(children: widget.children!), ), ], ); } } /// Child row (indented) class InouChildRow extends StatelessWidget { final String label; final String? value; final String? meta; final Widget? trailing; final Color? valueColor; const InouChildRow({ super.key, required this.label, this.value, this.meta, this.trailing, this.valueColor, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric( horizontal: InouTheme.spaceLg, vertical: InouTheme.spaceMd, ), decoration: const BoxDecoration( border: Border( bottom: BorderSide( color: InouTheme.border, style: BorderStyle.solid, ), ), ), child: Row( children: [ const SizedBox(width: InouTheme.spaceXxxl), // 48px indent per styleguide Expanded( child: Text( label, style: InouText.body, ), ), if (value != null) Text( value!, style: TextStyle( fontFamily: 'SF Mono', fontSize: 13, color: valueColor ?? InouTheme.text, ), ), if (meta != null) ...[ const SizedBox(width: 16), Text( meta!, style: InouText.bodySmall.copyWith(color: InouTheme.textMuted), ), ], if (trailing != null) ...[ const SizedBox(width: 8), trailing!, ], ], ), ); } } /// Icon for notes/vitals class InouNoteIcon extends StatelessWidget { final String emoji; final Color color; const InouNoteIcon({ super.key, required this.emoji, required this.color, }); @override Widget build(BuildContext context) { return Container( width: 32, height: 32, decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(6), ), alignment: Alignment.center, child: Text(emoji, style: const TextStyle(fontSize: 16)), ); } }