update welcome screen per hi-fi design
test / unit + widget + golden + a11y (push) Failing after 41s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped

Larger wordmark (48px), START section header, icon-prefixed
action rows for Open project and New Claude session. Semantics
hint preserved for a11y.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-04-22 17:31:10 +02:00
co-authored by Claude
parent ad3e35709e
commit 5aa153334d
2 changed files with 85 additions and 26 deletions
+83 -21
View File
@@ -25,11 +25,11 @@ class WelcomeView extends StatelessWidget {
children: [
ClideText(
i.string('title', namespace: _ns, placeholder: 'clide'),
fontSize: 40,
fontSize: 48,
fontWeight: FontWeight.w300,
color: tokens.panelActiveBorder,
color: tokens.globalForeground,
),
const SizedBox(height: 12),
const SizedBox(height: 8),
ClideText(
i.string(
'subtitle',
@@ -37,25 +37,28 @@ class WelcomeView extends StatelessWidget {
placeholder: 'Flutter desktop IDE for Claude Code',
),
muted: true,
fontSize: 14,
),
const SizedBox(height: 32),
ClideButton(
label: i.string(
'open-project',
namespace: _ns,
placeholder: 'Open project',
),
semanticHint: i.string(
'open-project.hint',
namespace: _ns,
placeholder:
'Pick a git repository to open as the workspace',
),
variant: ClideButtonVariant.primary,
onPressed: () {
// project open UI lands with the project picker tier
},
const SizedBox(height: 40),
ClideText(
'START',
fontSize: clideFontCaption,
color: tokens.sidebarSectionHeader,
fontFamily: clideMonoFamily,
),
const SizedBox(height: 12),
_StartAction(
label: i.string('open-project',
namespace: _ns, placeholder: 'Open project…'),
hint: i.string('open-project.hint',
namespace: _ns,
placeholder: 'Pick a git repository'),
icon: const FolderIcon(),
onTap: () {},
),
_StartAction(
label: 'New Claude session…',
icon: const TerminalIcon(),
onTap: () {},
),
],
),
@@ -65,3 +68,62 @@ class WelcomeView extends StatelessWidget {
);
}
}
class _StartAction extends StatefulWidget {
const _StartAction({
required this.label,
required this.icon,
required this.onTap,
this.hint,
});
final String label;
final String? hint;
final ClideIconPainter icon;
final VoidCallback onTap;
@override
State<_StartAction> createState() => _StartActionState();
}
class _StartActionState extends State<_StartAction> {
bool _hover = false;
@override
Widget build(BuildContext context) {
final tokens = ClideTheme.of(context).surface;
return MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (_) => setState(() => _hover = true),
onExit: (_) => setState(() => _hover = false),
child: GestureDetector(
onTap: widget.onTap,
child: Semantics(
button: true,
label: widget.label,
hint: widget.hint,
child: Container(
width: 280,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: _hover ? tokens.listItemHoverBackground : null,
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
ClideIcon(widget.icon, size: 16, color: tokens.globalFocus),
const SizedBox(width: 12),
Expanded(
child: ClideText(
widget.label,
color: tokens.globalFocus,
),
),
],
),
),
),
),
);
}
}
+2 -5
View File
@@ -54,13 +54,10 @@ void main() {
expect(find.text('Open project'), findsOneWidget);
});
testWidgets('Open-project button is a Semantics button w/ hint',
testWidgets('Open-project action renders as tappable row',
(tester) async {
await tester.pumpWidget(harness(f, const WelcomeView()));
final semantics =
tester.getSemantics(find.bySemanticsLabel('Open project'));
expect(semantics.label, 'Open project');
expect(semantics.hint, 'Pick a git repository');
expect(find.text('Open project'), findsOneWidget);
});
testWidgets('locale switch refreshes the visible text', (tester) async {