@@ -9,9 +9,11 @@ import 'package:devtools_app_shared/utils.dart';
99import 'package:dtd/dtd.dart' ;
1010import 'package:flutter/material.dart' ;
1111
12+ import '../../../framework/scaffold/report_feedback_button.dart' ;
1213import '../../../shared/analytics/analytics.dart' as ga;
1314import '../../../shared/analytics/constants.dart' as gac;
1415import '../../../shared/editor/editor_client.dart' ;
16+ import '../../../shared/primitives/query_parameters.dart' ;
1517import '../../../shared/ui/common_widgets.dart' ;
1618import 'property_editor_controller.dart' ;
1719import 'property_editor_view.dart' ;
@@ -115,22 +117,29 @@ class _PropertyEditorConnectedPanelState
115117 Scrollbar (
116118 controller: scrollController,
117119 thumbVisibility: true ,
118- child: SingleChildScrollView (
119- controller: scrollController,
120- child: Padding (
121- padding: const EdgeInsets .fromLTRB (
122- denseSpacing,
123- defaultSpacing,
124- defaultSpacing, // Additional right padding for scroll bar.
125- defaultSpacing,
120+ child: Column (
121+ children: [
122+ Expanded (
123+ child: SingleChildScrollView (
124+ controller: scrollController,
125+ child: Padding (
126+ padding: const EdgeInsets .fromLTRB (
127+ denseSpacing,
128+ defaultSpacing,
129+ defaultSpacing, // Additional right padding for scroll bar.
130+ defaultSpacing,
131+ ),
132+ child: Column (
133+ crossAxisAlignment: CrossAxisAlignment .start,
134+ children: [
135+ PropertyEditorView (controller: widget.controller),
136+ ],
137+ ),
138+ ),
139+ ),
126140 ),
127- child: Column (
128- crossAxisAlignment: CrossAxisAlignment .start,
129- children: [
130- PropertyEditorView (controller: widget.controller),
131- ],
132- ),
133- ),
141+ const _PropertyEditorFooter (),
142+ ],
134143 ),
135144 ),
136145 if (shouldReconnect) const ReconnectingOverlay (),
@@ -140,3 +149,69 @@ class _PropertyEditorConnectedPanelState
140149 );
141150 }
142151}
152+
153+ class _PropertyEditorFooter extends StatelessWidget {
154+ const _PropertyEditorFooter ();
155+
156+ static const _footerHeight = 25.0 ;
157+
158+ @override
159+ Widget build (BuildContext context) {
160+ final theme = Theme .of (context);
161+ final colorScheme = theme.colorScheme;
162+ final documentationLink = _documentationLink ();
163+ return Container (
164+ decoration: BoxDecoration (
165+ color: colorScheme.surface,
166+ border: Border (top: BorderSide (color: Theme .of (context).focusColor)),
167+ ),
168+ height: _footerHeight,
169+ padding: const EdgeInsets .symmetric (vertical: densePadding),
170+ child: Row (
171+ crossAxisAlignment: CrossAxisAlignment .end,
172+ children: [
173+ if (documentationLink != null )
174+ Padding (
175+ padding: const EdgeInsets .only (left: denseSpacing),
176+ child: _DocsLink (
177+ documentationLink: documentationLink,
178+ color: colorScheme.onSurface,
179+ ),
180+ ),
181+ const Spacer (),
182+ ReportFeedbackButton (color: colorScheme.onSurface),
183+ ],
184+ ),
185+ );
186+ }
187+
188+ String ? _documentationLink () {
189+ final queryParams = DevToolsQueryParams .load ();
190+ final isEmbedded = queryParams.embedMode.embedded;
191+ if (! isEmbedded) return null ;
192+ const uriPrefix = 'https://docs.flutter.dev/tools/' ;
193+ const uriHash = '#property-editor' ;
194+ return '$uriPrefix ${queryParams .ide == 'VSCode' ? 'vs-code' : 'android-studio' }$uriHash ' ;
195+ }
196+ }
197+
198+ class _DocsLink extends StatelessWidget {
199+ const _DocsLink ({required this .documentationLink, required this .color});
200+
201+ final Color color;
202+ final String documentationLink;
203+
204+ @override
205+ Widget build (BuildContext context) {
206+ return LinkIconLabel (
207+ icon: Icons .library_books_outlined,
208+ link: GaLink (
209+ display: 'Docs' ,
210+ url: documentationLink,
211+ gaScreenName: gac.PropertyEditorSidebar .id,
212+ gaSelectedItemDescription: gac.PropertyEditorSidebar .documentationLink,
213+ ),
214+ color: color,
215+ );
216+ }
217+ }
0 commit comments