refactor(ui): one canonical segment control (ChainSegments) everywhere
Some checks failed
Security / Security check (push) Failing after 1s
Some checks failed
Security / Security check (push) Failing after 1s
The same single-select choice pattern appeared as four widgets: audit's hover pills, the store's SegmentedButton, the store filter dialog's ChoiceChips, and the approvals TabBar (usertest finding #14 / night-log decision 'pill segment as canon'). The audit pattern is promoted to a shared ChainSegments widget (optional icons, hover, selected border, button+selected semantics) and all four sites use it; approvals switches lists via IndexedStack so both stay alive and switching does not refetch. Guard per the no-bugfix-without-a-guard rule: widget tests for selection + semantics, plus a canon sweep that bans TabBar/TabBarView/TabController/SegmentedButton/ChoiceChip from lib/ (comments exempt). Deliberately out of scope: the flow editor's Graph/Text/Run tabs live in the separate editor package. Studio 0.75.0; guide images regenerated, dark + light verified. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
bfd58baa75
commit
ed680c507a
9 changed files with 311 additions and 147 deletions
|
|
@ -365,25 +365,22 @@ class _StorePageState extends State<StorePage> {
|
|||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(bottom: ChainSpace.md),
|
||||
child: SegmentedButton<bool>(
|
||||
segments: [
|
||||
ButtonSegment(
|
||||
value: false,
|
||||
label: Text(l.storeSegmentModules),
|
||||
icon: const Icon(Icons.extension_outlined,
|
||||
size: 16),
|
||||
child: ChainSegments<bool>(
|
||||
items: [
|
||||
ChainSegmentItem(
|
||||
false,
|
||||
l.storeSegmentModules,
|
||||
icon: Icons.extension_outlined,
|
||||
),
|
||||
ButtonSegment(
|
||||
value: true,
|
||||
label: Text(l.storeSegmentStudio),
|
||||
icon:
|
||||
const Icon(Icons.palette_outlined, size: 16),
|
||||
ChainSegmentItem(
|
||||
true,
|
||||
l.storeSegmentStudio,
|
||||
icon: Icons.palette_outlined,
|
||||
),
|
||||
],
|
||||
selected: {_showStudio},
|
||||
showSelectedIcon: false,
|
||||
onSelectionChanged: (s) =>
|
||||
setState(() => _showStudio = s.first),
|
||||
value: _showStudio,
|
||||
onChanged: (v) =>
|
||||
setState(() => _showStudio = v),
|
||||
),
|
||||
),
|
||||
if (_aiThinking ||
|
||||
|
|
@ -1161,17 +1158,10 @@ class _FilterDialogState extends State<_FilterDialog> {
|
|||
List<({String value, String label})> items,
|
||||
String selected,
|
||||
void Function(String) onSelect,
|
||||
) => Wrap(
|
||||
spacing: ChainSpace.xs,
|
||||
runSpacing: ChainSpace.xs,
|
||||
children: [
|
||||
for (final i in items)
|
||||
_ChoiceChip(
|
||||
label: i.label,
|
||||
selected: selected == i.value,
|
||||
onSelected: () => onSelect(i.value),
|
||||
),
|
||||
],
|
||||
) => ChainSegments<String>(
|
||||
items: [for (final i in items) ChainSegmentItem(i.value, i.label)],
|
||||
value: selected,
|
||||
onChanged: onSelect,
|
||||
);
|
||||
return AlertDialog(
|
||||
title: Text(l.storeFilterLabel),
|
||||
|
|
@ -1569,31 +1559,6 @@ Up to 5 matches, ordered by best fit first. Use only module names that appear in
|
|||
}
|
||||
}
|
||||
|
||||
class _ChoiceChip extends StatelessWidget {
|
||||
final String label;
|
||||
final bool selected;
|
||||
final VoidCallback onSelected;
|
||||
|
||||
const _ChoiceChip({
|
||||
required this.label,
|
||||
required this.selected,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: ChainSpace.xs),
|
||||
child: ChoiceChip(
|
||||
label: Text(label),
|
||||
selected: selected,
|
||||
onSelected: (_) => onSelected(),
|
||||
showCheckmark: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Responsive grid — wraps to as many columns as the viewport
|
||||
/// allows. Cards are click-to-expand; install is also a top-
|
||||
/// level action so single-click installs are still possible.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue