PluginProbe
Code Snippets / 4.0.0-beta.2
Code Snippets v4.0.0-beta.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / ManageMenu / BlueprintsDemo / BlueprintsDemo.tsx

BlueprintsDemo.tsx in Code Snippets 4.0.0-beta.2, at js/components/ManageMenu/BlueprintsDemo/BlueprintsDemo.tsx

142 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { useEffect, useRef } from 'react'
2 import { __ } from '@wordpress/i18n'
3 import { WithRestAPIContext } from '../../../hooks/useRestAPI'
4 import { ScreenMetaSlot } from '../../common/ScreenMetaSlot'
5 import { DemoPageHeader } from '../../common/demo/DemoPageHeader'
6 import { DemoSpotlight } from '../../common/demo/DemoSpotlight'
7 import { DemoCallout } from '../../common/demo/DemoCallout'
8 import { DemoUpsell } from '../../common/demo/DemoUpsell'
9 import { useMarkDemoSeen } from '../../common/demo/useDemoSeen'
10 import { BlueprintFormPanel } from './BlueprintFormPanel'
11 import { BlueprintSidebar } from './BlueprintSidebar'
12 import { GeneratedNotice } from './GeneratedNotice'
13 import { getCallout } from './callouts'
14 import { BLUEPRINT_DESCRIPTION, BLUEPRINT_TITLE, getSection } from './demoBlueprint'
15 import { useBlueprintsDemo } from './useBlueprintsDemo'
16 import { hasReached } from './types'
17 import type { DemoStage } from './types'
18
19 /**
20 * Only the steps that point at one particular control are spotlit. Filling in
21 * the three sections needs no dimming: the active tab and the panel crossfade
22 * already say where to look.
23 */
24 const STAGE_SPOTLIGHTS: Partial<Record<DemoStage, { target: string, padding?: number }>> = {
25 generating: { target: '.blueprint-form-sidebar__generate', padding: 8 },
26 generated: { target: '.blueprints-demo-generated', padding: 6 }
27 }
28
29 const STAGE_ANNOUNCEMENTS: Partial<Record<DemoStage, string>> = {
30 general: __('Filling in the general settings.', 'code-snippets'),
31 attributes: __('Adding the shortcode attributes.', 'code-snippets'),
32 output: __('Setting the shortcode output.', 'code-snippets'),
33 generating: __('Generating the code.', 'code-snippets'),
34 generated: __('The snippet has been generated.', 'code-snippets'),
35 finished: __('Demo complete.', 'code-snippets')
36 }
37
38 const BlueprintHeader: React.FC = () =>
39 <header className="blueprint-detail__header">
40 <div className="blueprint-detail__header-content">
41 <div>
42 <h2>{BLUEPRINT_TITLE}</h2>
43 <p>{BLUEPRINT_DESCRIPTION}</p>
44 </div>
45 </div>
46 </header>
47
48 // eslint-disable-next-line max-lines-per-function -- the page reads as one sequence.
49 const BlueprintsDemoPage: React.FC = () => {
50 const {
51 stage,
52 activeSection,
53 isFading,
54 sectionsBrowsable,
55 hasStarted,
56 isFinished,
57 reducedMotion,
58 selectSection,
59 play,
60 skip,
61 replay
62 } = useBlueprintsDemo()
63
64 const generatedRef = useRef<HTMLDivElement>(null)
65 const showGenerated = hasReached(stage, 'generated')
66 const markSeen = useMarkDemoSeen('blueprints')
67
68 useEffect(() => {
69 if (isFinished) {
70 markSeen()
71 }
72 }, [isFinished, markSeen])
73
74 useEffect(() => {
75 const behavior = reducedMotion ? 'auto' : 'smooth'
76
77 if ('generated' === stage) {
78 generatedRef.current?.scrollIntoView({ behavior, block: 'center' })
79 }
80
81 // Once the closing panel is in place, settle on the foot of the page so
82 // both it and the generated notice are in view together.
83 if ('finished' === stage) {
84 window.scrollTo({ top: document.body.scrollHeight, behavior })
85 }
86 }, [reducedMotion, stage])
87
88 return (
89 <>
90 <ScreenMetaSlot />
91
92 <DemoPageHeader
93 title={__('Blueprints', 'code-snippets')}
94 description={__('A guided walkthrough of Pro Blueprints. Press play and watch a shortcode blueprint fill itself in and generate a snippet.', 'code-snippets')}
95 hasStarted={hasStarted}
96 isFinished={isFinished}
97 onPlay={play}
98 onSkip={skip}
99 onReplay={replay}
100 />
101
102 <div className="blueprints-demo">
103 <div className="screen-reader-text" aria-live="polite">{STAGE_ANNOUNCEMENTS[stage]}</div>
104
105 <DemoCallout callout={getCallout(stage)} />
106
107 <DemoSpotlight {...STAGE_SPOTLIGHTS[stage]} />
108
109 <div className="blueprint-detail">
110 <BlueprintHeader />
111
112 <div className="blueprint-form-layout">
113 <BlueprintSidebar
114 activeSection={activeSection}
115 browsable={sectionsBrowsable}
116 generating={'generating' === stage}
117 onSelect={selectSection}
118 />
119
120 <BlueprintFormPanel section={getSection(activeSection)} isFading={isFading} />
121 </div>
122 </div>
123
124 {showGenerated && <GeneratedNotice ref={generatedRef} />}
125
126 {isFinished && <DemoUpsell
127 title={__('That was a demo — Blueprints build the code for you', 'code-snippets')}
128 onReplay={replay}
129 >
130 <p>{__('The whole walkthrough was scripted and ran inside this plugin. No code was generated and nothing was saved.', 'code-snippets')}</p>
131 <p>{__('Code Snippets Pro ships blueprints for shortcodes, post types, taxonomies, settings pages, and more — fill in the form and it writes the snippet for you.', 'code-snippets')}</p>
132 </DemoUpsell>}
133 </div>
134 </>
135 )
136 }
137
138 export const BlueprintsDemo: React.FC = () =>
139 <WithRestAPIContext>
140 <BlueprintsDemoPage />
141 </WithRestAPIContext>
142