@@ -13,15 +13,15 @@ import Editor, { EDITOR_BACKGROUND_COLOR, EDITOR_GUTTER_COLOR } from 'docs/src/c
13
13
import { babelConfig , importResolver } from 'docs/src/components/Playground/renderConfig'
14
14
import ComponentControls from '../ComponentControls'
15
15
import ComponentExampleTitle from './ComponentExampleTitle'
16
- import ContributionPrompt from '../ContributionPrompt'
17
- import SourceCodeManager , { SourceCodeType } from './SourceCodeManager'
16
+ import SourceManager , { SourceManagerRenderProps } from './SourceCodeManager'
18
17
import { ThemeInput , ThemePrepared } from 'src/themes/types'
19
18
import { mergeThemeVariables } from '../../../../../src/lib/mergeThemes'
20
19
import { ThemeContext } from '../../../context/theme-context'
21
20
import CodeSnippet from '../../CodeSnippet'
22
- import formatCode from '../../../utils/formatCode'
23
21
24
- export interface ComponentExampleProps extends RouteComponentProps < any , any > {
22
+ export interface ComponentExampleProps
23
+ extends RouteComponentProps < any , any > ,
24
+ SourceManagerRenderProps {
25
25
title : React . ReactNode
26
26
description ?: React . ReactNode
27
27
examplePath : string
@@ -34,7 +34,6 @@ interface ComponentExampleState {
34
34
componentVariables : Object
35
35
handleMouseLeave : ( ) => void
36
36
handleMouseMove : ( ) => void
37
- sourceCode : string
38
37
showCode : boolean
39
38
showRtl : boolean
40
39
showTransparent : boolean
@@ -48,19 +47,13 @@ const childrenStyle: React.CSSProperties = {
48
47
maxWidth : pxToRem ( 500 ) ,
49
48
}
50
49
51
- const codeTypeApiButtonLabels : { [ key in SourceCodeType ] : string } = {
52
- normal : 'Children API' ,
53
- shorthand : 'Shorthand API' ,
54
- }
55
-
56
50
const disabledStyle = { opacity : 0.5 , pointerEvents : 'none' }
57
51
58
52
/**
59
53
* Renders a `component` and the raw `code` that produced it.
60
54
* Allows toggling the the raw `code` code block.
61
55
*/
62
56
class ComponentExample extends React . Component < ComponentExampleProps , ComponentExampleState > {
63
- sourceCodeMgr : SourceCodeManager
64
57
anchorName : string
65
58
kebabExamplePath : string
66
59
KnobsComponent : any
@@ -71,7 +64,6 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
71
64
componentVariables : { } ,
72
65
handleMouseLeave : _ . noop ,
73
66
handleMouseMove : _ . noop ,
74
- sourceCode : '' ,
75
67
showCode : false ,
76
68
showRtl : false ,
77
69
showTransparent : false ,
@@ -97,14 +89,12 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
97
89
98
90
componentWillMount ( ) {
99
91
const { examplePath } = this . props
100
- this . sourceCodeMgr = new SourceCodeManager ( examplePath )
101
92
this . anchorName = examplePathToHash ( examplePath )
102
93
103
94
this . setState ( {
104
95
handleMouseLeave : this . handleMouseLeave ,
105
96
handleMouseMove : this . handleMouseMove ,
106
97
showCode : this . isActiveHash ( ) ,
107
- sourceCode : this . sourceCodeMgr . currentCode ,
108
98
} )
109
99
}
110
100
@@ -216,16 +206,16 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
216
206
if ( title ) _ . invoke ( this . context , 'onPassed' , null , this . props )
217
207
}
218
208
219
- copyJSX = ( ) => {
220
- copyToClipboard ( this . state . sourceCode )
209
+ copySourceCode = ( ) => {
210
+ copyToClipboard ( this . props . currentCode )
211
+
221
212
this . setState ( { copiedCode : true } )
222
213
setTimeout ( ( ) => this . setState ( { copiedCode : false } ) , 1000 )
223
214
}
224
215
225
- resetJSX = ( ) => {
226
- if ( this . sourceCodeMgr . originalCodeHasChanged && confirm ( 'Lose your changes?' ) ) {
227
- this . sourceCodeMgr . resetToOriginalCode ( )
228
- this . updateAndRenderSourceCode ( )
216
+ resetSourceCode = ( ) => {
217
+ if ( confirm ( 'Lose your changes?' ) ) {
218
+ this . props . handleCodeReset ( )
229
219
}
230
220
}
231
221
@@ -239,16 +229,6 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
239
229
240
230
hasKnobs = ( ) => _ . includes ( knobsContext . keys ( ) , this . getKnobsFilename ( ) )
241
231
242
- renderExampleFromCode = ( ) : JSX . Element => {
243
- const { sourceCode } = this . state
244
-
245
- if ( sourceCode == null ) {
246
- return this . renderMissingExample ( )
247
- }
248
-
249
- return < SourceRender . Consumer > { ( { element } ) => element } </ SourceRender . Consumer >
250
- }
251
-
252
232
renderElement = ( element : React . ReactElement < any > ) => {
253
233
const { examplePath } = this . props
254
234
const { showRtl, componentVariables, themeName } = this . state
@@ -269,16 +249,6 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
269
249
)
270
250
}
271
251
272
- renderMissingExample = ( ) : JSX . Element => {
273
- const missingExamplePath = `./docs/src/examples/${ this . sourceCodeMgr . currentPath } .tsx`
274
- return (
275
- < ContributionPrompt >
276
- Looks like we're need an example file at:
277
- < p > { missingExamplePath } </ p >
278
- </ ContributionPrompt >
279
- )
280
- }
281
-
282
252
handleKnobChange = knobs => {
283
253
this . setState ( prevState => ( {
284
254
knobs : {
@@ -312,85 +282,58 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
312
282
313
283
getDisplayName = ( ) => this . props . examplePath . split ( '/' ) [ 1 ]
314
284
315
- handleChangeCode = ( sourceCode : string ) => {
316
- this . sourceCodeMgr . currentCode = sourceCode
317
- this . updateAndRenderSourceCode ( )
285
+ handleCodeApiChange = apiType => ( ) => {
286
+ this . props . handleCodeAPIChange ( apiType )
318
287
}
319
288
320
- updateAndRenderSourceCode = ( ) => {
321
- this . setState ( { sourceCode : this . sourceCodeMgr . currentCode } )
289
+ handleCodeLanguageChange = language => ( ) => {
290
+ this . props . handleCodeLanguageChange ( language )
322
291
}
323
292
324
- setApiCodeType = ( codeType : SourceCodeType ) => {
325
- this . sourceCodeMgr . codeType = codeType
326
- this . updateAndRenderSourceCode ( )
327
- }
328
-
329
- renderApiCodeMenu = ( ) : JSX . Element => {
330
- const { sourceCode } = this . state
331
- const lineCount = sourceCode && sourceCode . match ( / ^ / gm) ! . length
332
-
333
- const menuItems = [ SourceCodeType . shorthand , SourceCodeType . normal ] . map ( codeType => {
334
- // we disable the menu button for Children API in case we don't have the example for it
335
- const disabled =
336
- codeType === SourceCodeType . normal && ! this . sourceCodeMgr . isCodeValidForType ( codeType )
337
-
338
- return {
339
- active : this . sourceCodeMgr . codeType === codeType ,
340
- disabled,
341
- key : codeType ,
342
- onClick : this . setApiCodeType . bind ( this , codeType ) ,
343
- content : (
293
+ renderAPIsMenu = ( ) : JSX . Element => {
294
+ const menuItems = _ . map ( this . props . codeAPIs , ( { active, enabled, name } , type ) => (
295
+ < Menu . Item
296
+ active = { active }
297
+ content = {
344
298
< span >
345
- { codeTypeApiButtonLabels [ codeType ] }
346
- { disabled && < em > (not supported)</ em > }
299
+ { name }
300
+ { enabled && < em > (not supported)</ em > }
347
301
</ span >
348
- ) ,
349
- }
350
- } )
351
-
352
- return (
353
- // match code editor background and gutter size and colors
354
- < div style = { { background : EDITOR_BACKGROUND_COLOR } as React . CSSProperties } >
355
- < div
356
- style = {
357
- {
358
- borderLeft : `${ lineCount > 9 ? 41 : 34 } px solid ${ EDITOR_GUTTER_COLOR } ` ,
359
- paddingBottom : '1rem' ,
360
- } as React . CSSProperties
361
- }
362
- >
363
- < Menu size = "small" inverted secondary pointing items = { menuItems } />
364
- </ div >
365
- </ div >
366
- )
367
- }
368
-
369
- canBePrettified = ( ) => {
370
- const { sourceCode } = this . state
302
+ }
303
+ disabled = { ! enabled }
304
+ key = { type }
305
+ onClick = { this . handleCodeApiChange ( type ) }
306
+ />
307
+ ) )
371
308
372
- try {
373
- return sourceCode !== formatCode ( sourceCode )
374
- } catch ( err ) {
375
- return false
376
- }
309
+ return < Menu . Menu > { menuItems } </ Menu . Menu >
377
310
}
378
311
379
- handleFormat = ( ) => {
380
- const { sourceCode } = this . state
312
+ renderLanguagesMenu = ( ) : JSX . Element => {
313
+ const { currentLanguage } = this . props
381
314
382
- this . handleChangeCode ( formatCode ( sourceCode ) )
315
+ return (
316
+ < Menu . Menu position = "right" >
317
+ < Menu . Item
318
+ active = { currentLanguage === 'js' }
319
+ content = "JavaScript"
320
+ onClick = { this . handleCodeLanguageChange ( 'js' ) }
321
+ />
322
+ < Menu . Item
323
+ active = { currentLanguage === 'ts' }
324
+ content = "TypeScript"
325
+ onClick = { this . handleCodeLanguageChange ( 'ts' ) }
326
+ />
327
+ </ Menu . Menu >
328
+ )
383
329
}
384
330
385
331
renderCodeEditorMenu = ( ) : JSX . Element => {
332
+ const { canBeFormatted, handleCodeFormat, wasChanged } = this . props
386
333
const { copiedCode } = this . state
387
- const { originalCodeHasChanged, currentPath } = this . sourceCodeMgr
388
- const codeEditorStyle : React . CSSProperties = {
389
- position : 'absolute' ,
390
- margin : 0 ,
391
- top : '2px' ,
392
- right : '0.5rem' ,
393
- }
334
+
335
+ // TODO: !!!!
336
+ const currentPath = ''
394
337
395
338
// get component name from file path:
396
339
// elements/Button/Types/ButtonButtonExample
@@ -403,30 +346,30 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
403
346
] . join ( '' )
404
347
405
348
return (
406
- < Menu size = "small" secondary inverted text style = { codeEditorStyle } >
349
+ < Menu size = "small" secondary inverted floated = "right" text >
407
350
< SourceRender . Consumer >
408
351
{ ( { error } ) => (
409
352
< Menu . Item
410
- icon = { ( error && 'bug' ) || ( this . canBePrettified ( ) ? 'magic' : 'check' ) }
353
+ icon = { ( error && 'bug' ) || ( canBeFormatted ? 'magic' : 'check' ) }
411
354
color = { error ? 'red' : undefined }
412
355
active = { error }
413
356
content = "Prettier"
414
- onClick = { this . handleFormat }
415
- style = { ! this . canBePrettified ( ) ? disabledStyle : undefined }
357
+ onClick = { handleCodeFormat }
358
+ style = { ! canBeFormatted ? disabledStyle : undefined }
416
359
/>
417
360
) }
418
361
</ SourceRender . Consumer >
419
362
< Menu . Item
420
- style = { ! originalCodeHasChanged ? disabledStyle : undefined }
363
+ style = { ! wasChanged ? disabledStyle : undefined }
421
364
icon = "refresh"
422
365
content = "Reset"
423
- onClick = { this . resetJSX }
366
+ onClick = { this . resetSourceCode }
424
367
/>
425
368
< Menu . Item
426
369
active = { copiedCode } // to show the color
427
370
icon = { copiedCode ? { color : 'green' , name : 'check' } : 'copy' }
428
371
content = "Copy"
429
- onClick = { this . copyJSX }
372
+ onClick = { this . copySourceCode }
430
373
/>
431
374
< Menu . Item
432
375
style = { { border : 'none' } }
@@ -440,20 +383,33 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
440
383
}
441
384
442
385
renderJSX = ( ) => {
443
- const { showCode, sourceCode } = this . state
386
+ const { currentCode = '' , handleCodeChange } = this . props
387
+ const { showCode } = this . state
444
388
445
- if ( ! showCode ) return null
389
+ const lineCount = currentCode . match ( / ^ / gm ) ! . length
446
390
447
- return (
448
- < div >
449
- { this . renderApiCodeMenu ( ) }
391
+ return showCode ? (
392
+ // match code editor background and gutter size and colors
393
+ < div style = { { background : EDITOR_BACKGROUND_COLOR } as React . CSSProperties } >
394
+ < div
395
+ style = {
396
+ {
397
+ borderLeft : `${ lineCount > 9 ? 41 : 34 } px solid ${ EDITOR_GUTTER_COLOR } ` ,
398
+ paddingBottom : '2.6rem' ,
399
+ } as React . CSSProperties
400
+ }
401
+ >
402
+ < Menu attached = "top" size = "small" inverted secondary pointing >
403
+ { this . renderAPIsMenu ( ) }
404
+ { this . renderLanguagesMenu ( ) }
405
+ </ Menu >
450
406
451
- < div >
452
407
{ this . renderCodeEditorMenu ( ) }
453
- < Editor value = { sourceCode } onChange = { this . handleChangeCode } />
454
408
</ div >
409
+
410
+ < Editor value = { currentCode } onChange = { handleCodeChange } />
455
411
</ div >
456
- )
412
+ ) : null
457
413
}
458
414
459
415
renderError = ( ) => {
@@ -549,7 +505,7 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
549
505
}
550
506
551
507
render ( ) {
552
- const { children, description, title } = this . props
508
+ const { children, currentCode , description, title } = this . props
553
509
const {
554
510
handleMouseLeave,
555
511
handleMouseMove,
@@ -559,11 +515,11 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
559
515
showRtl,
560
516
showTransparent,
561
517
showVariables,
562
- sourceCode,
563
518
} = this . state
564
519
565
520
const isActive = this . isActiveHash ( ) || this . isActiveState ( )
566
- const currentExamplePath = this . sourceCodeMgr . currentPath
521
+ // TODO: !!!!!!!!!!
522
+ const currentExamplePath = ''
567
523
568
524
const exampleStyle : React . CSSProperties = {
569
525
position : 'relative' ,
@@ -624,7 +580,7 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
624
580
< SourceRender
625
581
babelConfig = { babelConfig }
626
582
knobs = { knobs }
627
- source = { sourceCode }
583
+ source = { currentCode }
628
584
render = { this . renderElement }
629
585
renderHtml = { showCode }
630
586
resolver = { importResolver }
@@ -647,7 +603,7 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
647
603
} ) ,
648
604
} }
649
605
>
650
- { this . renderExampleFromCode ( ) }
606
+ < SourceRender . Consumer > { ( { element } ) => element } </ SourceRender . Consumer >
651
607
</ Grid . Column >
652
608
)
653
609
} }
@@ -668,7 +624,11 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
668
624
669
625
const ComponentExampleWithTheme = props => (
670
626
< ThemeContext . Consumer >
671
- { ( { themeName } ) => < ComponentExample { ...props } themeName = { themeName } /> }
627
+ { ( { themeName } ) => (
628
+ < SourceManager examplePath = { props . examplePath } >
629
+ { codeProps => < ComponentExample { ...props } { ...codeProps } themeName = { themeName } /> }
630
+ </ SourceManager >
631
+ ) }
672
632
</ ThemeContext . Consumer >
673
633
)
674
634
0 commit comments