feat(flutter/library): card + row widgets (artist/album/track)
HorizontalScrollRow takes an optional shared ScrollController so multi-row sections (Most played: 3 rows) couple their scroll like the web HorizontalScrollRow.svelte. Cards fall back to the synced album-fallback.svg when coverUrl is empty.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../theme/theme_extension.dart';
|
||||
|
||||
/// Mirrors the web HorizontalScrollRow: a labeled section that scrolls
|
||||
/// horizontally. Multi-row sections share one [controller] so they
|
||||
/// scroll together.
|
||||
class HorizontalScrollRow extends StatelessWidget {
|
||||
const HorizontalScrollRow({
|
||||
required this.title,
|
||||
required this.children,
|
||||
this.height = 200,
|
||||
this.controller,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final List<Widget> children;
|
||||
final double height;
|
||||
final ScrollController? controller;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
|
||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 8),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontFamily: fs.display.fontFamily,
|
||||
fontSize: 18,
|
||||
color: fs.parchment,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: height,
|
||||
child: ListView(
|
||||
controller: controller,
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user