@@ -21,7 +21,6 @@ import VoicingText from '../../scenery/js/accessibility/voicing/nodes/VoicingTex
2121import VBox from '../../scenery/js/layout/nodes/VBox.js' ;
2222import Node from '../../scenery/js/nodes/Node.js' ;
2323import RichText from '../../scenery/js/nodes/RichText.js' ;
24- import VStrut from '../../scenery/js/nodes/VStrut.js' ;
2524import allowLinksProperty from '../../scenery/js/util/allowLinksProperty.js' ;
2625import Dialog , { type DialogOptions } from '../../sun/js/Dialog.js' ;
2726import Tandem from '../../tandem/js/Tandem.js' ;
@@ -33,6 +32,7 @@ import packageJSON from './packageJSON.js';
3332import updateCheck from './updateCheck.js' ;
3433import UpdateNodes from './UpdateNodes.js' ;
3534import UpdateState from './UpdateState.js' ;
35+ import { ABOUT_DIALOG_LARGE_GAP_DELTA , ABOUT_DIALOG_MEDIUM_GAP_DELTA , ABOUT_DIALOG_SMALL_GAP , ABOUT_DIALOG_TEXT_LINE_SPACING } from './AboutDialogConstants.js' ;
3636
3737// constants
3838const MAX_WIDTH = 550 ; // Maximum width of elements in the dialog
@@ -74,16 +74,18 @@ export default class AboutDialog extends Dialog {
7474 const Brand : TBrand = phet . brand . Brand ;
7575 assert && assert ( Brand , 'Brand should exist by now' ) ;
7676
77- let children = [ ] ;
78-
79- const strutSize = 15 - 6 ; // 15 is the desired spacing, but we are including a spacing of 6 already.
77+ const children = [ ] ;
8078
8179 const titleText = new VoicingText ( nameStringProperty , {
8280 font : new PhetFont ( 2 * NOMINAL_FONT_SIZE ) ,
8381 maxWidth : MAX_WIDTH ,
8482
8583 // No accessibleParagraph because the content is already the accessibleName of the Dialog.
86- accessibleParagraph : null
84+ accessibleParagraph : null ,
85+
86+ layoutOptions : {
87+ bottomMargin : ABOUT_DIALOG_MEDIUM_GAP_DELTA
88+ }
8789 } ) ;
8890 children . push ( titleText ) ;
8991
@@ -99,7 +101,10 @@ export default class AboutDialog extends Dialog {
99101 if ( phet . chipper . buildTimestamp ) {
100102 children . push ( new VoicingText ( phet . chipper . buildTimestamp , {
101103 font : new PhetFont ( 0.65 * NOMINAL_FONT_SIZE ) ,
102- maxWidth : MAX_WIDTH
104+ maxWidth : MAX_WIDTH ,
105+ layoutOptions : {
106+ topMargin : ABOUT_DIALOG_MEDIUM_GAP_DELTA
107+ }
103108 } ) ) ;
104109 }
105110
@@ -140,17 +145,18 @@ export default class AboutDialog extends Dialog {
140145 offlineNode
141146 ] ,
142147 maxWidth : MAX_WIDTH ,
143- visibleProperty : allowLinksProperty
148+ visibleProperty : allowLinksProperty ,
149+ layoutOptions : {
150+ topMargin : ABOUT_DIALOG_MEDIUM_GAP_DELTA
151+ }
144152 } ) ;
145153
146154 children . push ( updatePanel ) ;
147155 }
148156
149- const brandChildren = [ ] ;
150-
151157 // Show the brand name, if it exists
152158 if ( Brand . name ) {
153- brandChildren . push ( new VoicingRichText ( Brand . name , {
159+ children . push ( new VoicingRichText ( Brand . name , {
154160 font : new PhetFont ( NOMINAL_FONT_SIZE ) ,
155161 supScale : 0.5 ,
156162 supYOffset : 3 ,
@@ -159,7 +165,11 @@ export default class AboutDialog extends Dialog {
159165 // Default behavior is to create an accessibleParagraph for this element
160166 // but it needs to be a heading instead.
161167 accessibleHeading : Brand . name ,
162- accessibleParagraph : null
168+ accessibleParagraph : null ,
169+
170+ layoutOptions : {
171+ topMargin : ABOUT_DIALOG_LARGE_GAP_DELTA
172+ }
163173 } ) ) ;
164174 }
165175
@@ -171,59 +181,54 @@ export default class AboutDialog extends Dialog {
171181
172182 const copyright = StringUtils . fillIn ( Brand . copyright , { year : year } ) ;
173183
174- brandChildren . push ( new VoicingText ( copyright , {
184+ children . push ( new VoicingText ( copyright , {
175185 font : new PhetFont ( 0.75 * NOMINAL_FONT_SIZE ) ,
176186 maxWidth : MAX_WIDTH
177187 } ) ) ;
178188 }
179189
180- if ( brandChildren . length > 0 ) {
181- children . push ( new VStrut ( strutSize ) ) ;
182- children = children . concat ( brandChildren ) ;
183- }
184-
185- const licenseChildren = [ ] ;
186-
187190 if ( Brand . license ) {
188191 const licenseStringProperty = new DerivedProperty ( [ allowLinksProperty ] , allowLinks => {
189192 return allowLinks ? Brand . license ! : Brand . licenseWithoutLinks ?? Brand . license ! ;
190193 } ) ;
191194
192- licenseChildren . push ( new VoicingText ( JoistFluent . license . titleStringProperty , {
195+ children . push ( new VoicingText ( JoistFluent . license . titleStringProperty , {
193196 font : new PhetFont ( { size : NOMINAL_FONT_SIZE , weight : 'bold' } ) ,
194197
195198 accessibleHeading : JoistFluent . license . titleStringProperty ,
196- accessibleParagraph : null
199+ accessibleParagraph : null ,
200+
201+ layoutOptions : {
202+ topMargin : ABOUT_DIALOG_LARGE_GAP_DELTA
203+ }
197204 } ) ) ;
198205
199206 // innerContent cannot embed links (xss vulnerability), so the accessible content uses the form of the
200207 // strings without any links
201208 const accessibleLicenseContent = Brand . licenseWithoutLinks ?? '' ;
202- licenseChildren . push ( new VoicingRichText ( licenseStringProperty , {
209+ children . push ( new VoicingRichText ( licenseStringProperty , {
203210 font : new PhetFont ( 0.75 * NOMINAL_FONT_SIZE ) ,
204211 align : 'left' as const ,
205212 lineWrap : MAX_WIDTH ,
206- leading : 1 , // to match the spacing in the CreditsNode between paragraphs
213+ leading : ABOUT_DIALOG_TEXT_LINE_SPACING ,
207214 accessibleParagraph : accessibleLicenseContent ,
208215 readingBlockNameResponse : RichText . getAccessibleStringProperty ( new TinyProperty ( accessibleLicenseContent ) , false ) ,
209216 links : true // allow the embedded links, because they are from a controlled source
210217 } ) ) ;
211218 }
212219
213- if ( licenseChildren . length > 0 ) {
214- children . push ( new VStrut ( strutSize ) ) ;
215- children = children . concat ( licenseChildren ) ;
216- }
217-
218220 let creditsNode : Node | null = null ;
219221
220222 // Add credits for specific brands
221223 if ( ( Brand . id === 'phet' || Brand . id === 'phet-io' ) ) {
222- children . push ( new VStrut ( strutSize ) ) ;
223224 creditsNode = new CreditsNode ( credits , {
224225 titleFont : new PhetFont ( { size : NOMINAL_FONT_SIZE , weight : 'bold' } ) ,
225226 textFont : new PhetFont ( 0.75 * NOMINAL_FONT_SIZE ) ,
226- maxWidth : MAX_WIDTH
227+ maxWidth : MAX_WIDTH ,
228+
229+ layoutOptions : {
230+ topMargin : ABOUT_DIALOG_LARGE_GAP_DELTA
231+ }
227232 } ) ;
228233 children . push ( creditsNode ) ;
229234 }
@@ -236,7 +241,10 @@ export default class AboutDialog extends Dialog {
236241 const linksParent = new VBox ( {
237242 spacing : 6 ,
238243 align : 'left' ,
239- maxWidth : MAX_WIDTH
244+ maxWidth : MAX_WIDTH ,
245+ layoutOptions : {
246+ topMargin : ABOUT_DIALOG_LARGE_GAP_DELTA
247+ }
240248 } ) ;
241249 children . push ( linksParent ) ;
242250
@@ -247,8 +255,6 @@ export default class AboutDialog extends Dialog {
247255 const links = Brand . getLinks ( packageJSON . name , locale ) ;
248256 const linksChildren : Node [ ] = [ ] ;
249257
250- linksChildren . push ( new VStrut ( strutSize ) ) ;
251-
252258 for ( let i = 0 ; i < links . length ; i ++ ) {
253259 const link = links [ i ] ;
254260
@@ -260,7 +266,8 @@ export default class AboutDialog extends Dialog {
260266 // This is PhET-iO instrumented because it is a keyboard navigation focusable element.
261267 const richText = new RichText ( stringProperty , {
262268 links : { url : link . url } , // RichText must fill in URL for link
263- font : new PhetFont ( NOMINAL_FONT_SIZE )
269+ font : new PhetFont ( NOMINAL_FONT_SIZE ) ,
270+ leading : ABOUT_DIALOG_TEXT_LINE_SPACING
264271 } ) ;
265272 richText . disposeEmitter . addListener ( ( ) => {
266273 stringProperty . dispose ( ) ;
@@ -274,7 +281,7 @@ export default class AboutDialog extends Dialog {
274281
275282 const content = new VBox ( {
276283 align : 'left' ,
277- spacing : 6 ,
284+ spacing : ABOUT_DIALOG_SMALL_GAP ,
278285 children : children ,
279286
280287 // pdom - accessible container for all AboutDialog content
0 commit comments