Raise the declared minimums in pubspec.yaml to what our deps already require: Flutter >=3.35.0 / Dart >=3.9.0 (was 3.19.0 / 3.5.0). alchemist 0.12 needs Flutter 3.32; Dart 3.9 first ships in Flutter 3.35, so 3.35 is the binding floor. Pin the exact build toolchain in .fvmrc (Flutter 3.44.1). Moving to the Dart 3.9 language level switches `dart format` to the new "tall" style and enables two new lints. This commit is the resulting mechanical churn, isolated from any behaviour change: - whole-tree `dart format` reformat (tall style) - `dart fix` for unnecessary_underscores + use_null_aware_elements No runtime behaviour change; `make test` green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
68 lines
2.1 KiB
Dart
68 lines
2.1 KiB
Dart
import 'dart:math' as math;
|
|
|
|
import 'package:clide/kernel/src/theme/controller.dart';
|
|
import 'package:clide/widgets/src/clide_tappable.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
class ClideSpine extends StatelessWidget {
|
|
const ClideSpine({super.key, required this.label, required this.onExpand, this.side = SpineSide.left, this.badgeCount = 0});
|
|
|
|
final String label;
|
|
final VoidCallback onExpand;
|
|
final SpineSide side;
|
|
final int badgeCount;
|
|
|
|
static const double width = 12;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final tokens = ClideTheme.of(context).surface;
|
|
final borderSide = BorderSide(color: tokens.dividerColor);
|
|
|
|
return Semantics(
|
|
button: true,
|
|
label: '$label — click to expand',
|
|
child: ClideTappable(
|
|
onTap: onExpand,
|
|
builder: (context, hovered, _) => Container(
|
|
width: ClideSpine.width,
|
|
decoration: BoxDecoration(
|
|
color: hovered ? tokens.sidebarItemHover : tokens.chromeBackground,
|
|
border: Border(left: side == SpineSide.right ? borderSide : BorderSide.none, right: side == SpineSide.left ? borderSide : BorderSide.none),
|
|
),
|
|
child: Stack(
|
|
children: [
|
|
Center(
|
|
child: Transform.rotate(
|
|
angle: side == SpineSide.left ? -math.pi / 2 : math.pi / 2,
|
|
child: Text(
|
|
label,
|
|
style: TextStyle(fontSize: 9, color: tokens.globalTextMuted, letterSpacing: 0.5),
|
|
maxLines: 1,
|
|
overflow: TextOverflow.clip,
|
|
),
|
|
),
|
|
),
|
|
if (badgeCount > 0)
|
|
Positioned(
|
|
top: 4,
|
|
left: 0,
|
|
right: 0,
|
|
child: Center(
|
|
child: Container(
|
|
width: 6,
|
|
height: 6,
|
|
decoration: BoxDecoration(color: tokens.statusInfo, shape: BoxShape.circle),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
enum SpineSide { left, right }
|