@@ -5,6 +5,9 @@ description: "Examples showing how to utilize TutorialKit APIs"
5
5
6
6
import { Tabs , TabItem } from ' @astrojs/starlight/components' ;
7
7
8
+ TutorialKit's API can be used in custom components to provide highly custom experience in the tutorials.
9
+ Below are listed few examples to solve real-world use cases. See [ TutorialKit API] ( /reference/tutorialkit-api/ ) for API documentation.
10
+
8
11
## Access tutorial state
9
12
10
13
In this example we'll read contents of ` index.js ` using Tutorial Store APIs.
@@ -74,7 +77,7 @@ function verifyIndexJs(code: string) {
74
77
</TabItem >
75
78
<TabItem label = " content.mdx" >
76
79
77
- ``` mdx title=" title=" src/content/tutorial/chapter/part/lesson/content.mdx"
80
+ ``` mdx title="src/content/tutorial/chapter/part/lesson/content.mdx"
78
81
---
79
82
type: lesson
80
83
title: TutorialKit API usage example
@@ -129,9 +132,9 @@ export default function TerminalWriter() {
129
132
}
130
133
```
131
134
132
- </TabItem >
135
+ </TabItem >
133
136
134
- <TabItem label = " content.mdx" >
137
+ <TabItem label = " content.mdx" >
135
138
136
139
``` mdx title="src/content/tutorial/chapter/part/lesson/content.mdx"
137
140
---
@@ -148,11 +151,110 @@ Fix <code>counter.js</code> and run the tests!
148
151
<TerminalWriter client :load />
149
152
```
150
153
151
- </TabItem >
152
-
154
+ </TabItem >
153
155
</Tabs >
154
156
155
157
## Provide feedback to user when lesson is solved
156
158
157
- ## How to watch a file for changes
159
+ In this example we'll congratulate user when they solve the lesson code.
160
+
161
+ Every time user edits the ` math.js ` , we run ` node check-lesson.js ` in the webcontainer and see if the process exits with non-erroneous exit code.
162
+ Once the exit code indicates success, we inform user with message.
163
+
164
+ <a class = " my-4 inline-block" href = " https://stackblitz.com/edit/stackblitz-starters-b9ie5x?file=src/components/LessonChecker.tsx&file=src/templates/default/check-lesson.mjs&file=src/content/tutorial/1-basics/1-introduction/1-welcome/content.mdx" >
165
+ <img alt = " Open in StackBlitz" src = " https://developer.stackblitz.com/img/open_in_stackblitz.svg" />
166
+ </a >
167
+
168
+ <Tabs >
169
+ <TabItem label = " LessonChecker.tsx" >
170
+
171
+ ``` tsx title="src/components/LessonChecker.tsx"
172
+ import { Dialog } from ' @tutorialkit/react' ;
173
+ import { useEffect , useState } from ' react' ;
174
+ import { webcontainer } from ' tutorialkit:core' ;
175
+ import tutorialStore from ' tutorialkit:store' ;
176
+
177
+ export default function LessonChecker() {
178
+ const [success, setSuccess] = useState (false );
179
+
180
+ useEffect (() => {
181
+ let timeout: ReturnType <typeof setTimeout > | undefined = undefined ;
182
+
183
+ const unsubscribe = tutorialStore .onDocumentChanged (' /math.js' , () => {
184
+ clearTimeout (timeout );
185
+
186
+ timeout = setTimeout (async () => {
187
+ if (await checkLesson ()) {
188
+ setSuccess (true );
189
+ unsubscribe ();
190
+ }
191
+ }, 250 );
192
+ });
193
+
194
+ return function cleanup() {
195
+ unsubscribe ();
196
+ clearTimeout (timeout );
197
+ };
198
+ }, []);
199
+
200
+ return (
201
+ <>
202
+ { success && (
203
+ <Dialog title = " Lesson complete" confirmText = " OK" onClose = { () => setSuccess (false )} >
204
+ Lesson complete, congratulations! 🎉
205
+ </Dialog >
206
+ )}
207
+ </>
208
+ );
209
+ }
210
+
211
+ async function checkLesson(): Promise <boolean > {
212
+ const webcontainerInstance = await webcontainer ;
213
+ const process = await webcontainerInstance .spawn (' node' , [' ./check-lesson.mjs' ]);
158
214
215
+ const exitCode = await process .exit ;
216
+
217
+ return exitCode === 0 ;
218
+ }
219
+ ```
220
+
221
+ </TabItem >
222
+
223
+ <TabItem label = " check-lesson.mjs" >
224
+
225
+ ``` js title="src/templates/default/check-lesson.mjs"
226
+ import * as math from ' ./math.js' ;
227
+
228
+ if (math .sum (25 , 32 ) !== 57 ) {
229
+ process .exit (1 );
230
+ }
231
+
232
+ if (math .multiply (3 , 25 ) !== 75 ) {
233
+ process .exit (1 );
234
+ }
235
+
236
+ process .exit (0 );
237
+ ```
238
+
239
+ </TabItem >
240
+
241
+ <TabItem label = " content.mdx" >
242
+
243
+ ``` mdx title="src/content/tutorial/chapter/part/lesson/content.mdx"
244
+ ---
245
+ type: lesson
246
+ title: TutorialKit API usage example
247
+ focus: /math.js
248
+ ---
249
+
250
+ import LessonChecker from ' @components/LessonChecker' ;
251
+
252
+ # TutorialKit API usage example
253
+
254
+ Solve <code >math.js</code > and you'll see notification about completed lesson!
255
+
256
+ <LessonChecker client :load />
257
+ ```
258
+
259
+ </TabItem >
260
+ </Tabs >
0 commit comments