build method
Composes theme-scaled navigation and chrome around the stable page slot.
Implementation
@override
Widget build(BuildContext context) {
final theme = CarpenterTheme.of(context);
final gap = context.units(theme.spacing.small);
Widget heading(bool compact) => Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
if (!compact) ...[
CarpenterText.title(applicationLabel),
SizedBox(height: gap),
CarpenterControl(
semanticLabel: '$workspaceLabel. $workspaceCaption',
onTap: onWorkspacePressed,
builder: (context, state) => DecoratedBox(
decoration: BoxDecoration(
color: state.hovered || state.focused
? theme.overlay.hovered
: theme.surface.base,
border: Border.all(
color: state.focused
? theme.focus.color
: theme.overlay.border,
width: context.units(theme.focus.width),
),
borderRadius: BorderRadius.circular(
context.units(theme.shapes.radius(ShapeRole.rounded)),
),
),
child: Padding(
padding: EdgeInsets.all(gap),
child: Row(
children: [
CarpenterIcon(workspaceIcon),
SizedBox(width: gap),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
CarpenterText.label(workspaceLabel, maxLines: 2),
CarpenterText.caption(
workspaceCaption,
colorRole: ContentColorRole.secondary,
),
],
),
),
const CarpenterIcon(GravityIcons.chevronsExpandVertical),
],
),
),
),
),
] else
CarpenterIconButton(
icon: workspaceIcon,
semanticLabel: '$workspaceLabel. $workspaceCaption',
onPressed: onWorkspacePressed,
prominence: ActionProminence.ghost,
),
if ((compact ? navigation.compactHeader : navigation.header)
case final Widget header) ...[
SizedBox(height: gap),
header,
],
],
);
final sidebar = CarpenterSidebarData(
sections: navigation.sections,
selectedId: navigation.selectedId,
onSelected: navigation.onSelected,
semanticLabel: navigation.semanticLabel,
header: heading(false),
compactHeader: heading(true),
footer: navigation.footer,
compactFooter: navigation.compactFooter,
);
final root = CarpenterRootLayout(
sidebar: sidebar,
sidebarExpanded: sidebarExpanded,
onSidebarExpandedChanged: onSidebarExpandedChanged,
sidebarVisible: sidebarVisible,
sidebarOpen: sidebarOpen,
onSidebarOpenChanged: onSidebarOpenChanged,
viewportPolicy: viewportPolicy,
headerBuilder: _header,
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
?notice,
?activity,
Expanded(key: const ValueKey('workspace-body'), child: body),
?footer,
],
),
);
return CallbackShortcuts(
bindings: {
if (searchAction?.shortcut != null && searchAction!.isEnabled)
searchAction!.shortcut!: searchAction!.onInvoke!,
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
?nativeTitleBar,
Expanded(key: const ValueKey('workspace-root'), child: root),
],
),
);
}