Skip to content

Commit 83bef8e

Browse files
committed
feat: add "Edit this page" link
1 parent ef50b2b commit 83bef8e

File tree

10 files changed

+100
-5
lines changed

10 files changed

+100
-5
lines changed

docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,30 @@ Navigating to a lesson that specifies `autoReload` will always reload the previe
133133
Specified which folder from the `src/templates/` directory should be used as the basis for the code. See the "[Code templates](/guides/creating-content/#code-templates)" guide for a detailed explainer.
134134
<PropertyTable inherited type="string" />
135135

136+
#### `editPageLink`
137+
Display a link in lesson for editing the page content.
138+
The value is a URL pattern where `:path` is replaced with the lesson's location relative to the `src/content/tutorial`.
139+
140+
<PropertyTable inherited type="string|false" />
141+
142+
```yaml
143+
editPageLink: https://github.com/stackblitz/tutorialkit/blob/main/packages/template/src/content/tutorial/:path
144+
```
145+
146+
The inherited value can be disabled in specific parts using `false`.
147+
148+
```yaml
149+
editPageLink: false
150+
```
151+
152+
:::tip
153+
Note that Github will try to automatically render the `.md` files when linked to.
154+
You can instruct Github to show the source code instead by adding `plain=1` query parameter.
155+
156+
```diff
157+
-editPageLink: https://github.com/stackblitz/tutorialkit/blob/main/packages/template/src/content/tutorial/:path
158+
+editPageLink: https://github.com/stackblitz/tutorialkit/blob/main/packages/template/src/content/tutorial/:path?plain=1
159+
```
160+
161+
:::
162+
Loading

docs/tutorialkit.dev/src/content/docs/reference/theming.mdx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,20 @@ The navigation cards are the cards at the bottom of a lesson to navigate to the
316316
| `--tk-elements-navCard-iconColor` | The icon color of the navigation card. |
317317
| `--tk-elements-navCard-iconColorHover` | The icon color of the navigation card when hovering. |
318318

319+
### Edit Page Link
320+
321+
The edit page link is shown above the navigation cards when configured by [`editPageLink` option](../configuration/#editpagelink).
322+
323+
![Edit Page Link](./images/theming-editpagelink.png)
324+
325+
| Token | Description |
326+
| ------------------------------------------- | --------------------------------------------------- |
327+
| `--tk-elements-editPageLink-textColor` | The text color of the edit page link |
328+
| `--tk-elements-editPageLink-textColorHover` | The text color of the edit page link when hovering. |
329+
| `--tk-elements-editPageLink-iconColor` | The icon color of the edit page link |
330+
| `--tk-elements-editPageLink-iconColorHover` | The icon color of the edit page link when hovering |
331+
| `--tk-elements-editPageLink-borderColor` | The border color of the edit page link |
332+
319333
### Breadcrumbs
320334

321335
The breadcrumbs are the navigation elements that show the path of the current lesson. The breadcrumbs are divided into multiple parts.

packages/astro/src/default/components/TutorialContent.astro

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,28 @@ interface Props {
88
}
99
1010
const { lesson } = Astro.props;
11-
const { Markdown, prev, next } = lesson;
11+
const { Markdown, editPageLink, prev, next } = lesson;
1212
---
1313

1414
<div class="h-full overflow-auto scrollbar-transparent p-8">
1515
<div class="markdown-content text-tk-elements-content-textColor">
1616
<Markdown />
1717
</div>
18+
19+
{
20+
editPageLink && (
21+
<div class="pb-4 mt-8 border-b border-tk-elements-editPageLink-borderColor">
22+
<a
23+
href={editPageLink}
24+
class="inline-flex flex-items-center text-tk-elements-editPageLink-textColor hover:text-tk-elements-editPageLink-textColorHover hover:underline"
25+
>
26+
<span class="icon i-ph-note-pencil pointer-events-none h-5 w-5 mr-2 text-tk-elements-editPageLink-iconColor group-hover:text-tk-elements-editPageLink-iconColorHover" />
27+
<span>Edit this page</span>
28+
</a>
29+
</div>
30+
)
31+
}
32+
1833
<div class="grid grid-cols-[1fr_1fr] gap-4 mt-8">
1934
<div class="flex">
2035
{prev && <NavCard lesson={prev} type="prev" />}

packages/astro/src/default/styles/variables.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,13 @@
241241
--tk-elements-navCard-iconColor: var(--tk-elements-app-textColor);
242242
--tk-elements-navCard-iconColorHover: var(--tk-text-accent);
243243

244+
/* Edit Page Link */
245+
--tk-elements-editPageLink-textColor: var(--tk-elements-app-textColor);
246+
--tk-elements-editPageLink-textColorHover: var(--tk-text-active);
247+
--tk-elements-editPageLink-iconColor: var(--tk-elements-app-textColor);
248+
--tk-elements-editPageLink-iconColorHover: var(--tk-text-accent);
249+
--tk-elements-editPageLink-borderColor: var(--tk-border-secondary);
250+
244251
/* Breadcrumb > Nav Button */
245252
--tk-elements-breadcrumbs-navButton-iconColor: var(--tk-text-secondary);
246253
--tk-elements-breadcrumbs-navButton-iconColorHover: var(--tk-text-active);

packages/astro/src/default/utils/content.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export async function getTutorial(): Promise<Tutorial> {
8181
const lesson: Lesson = {
8282
data,
8383
id: lessonId,
84+
filepath: id,
8485
order: -1,
8586
part: {
8687
id: partId,
@@ -241,7 +242,17 @@ export async function getTutorial(): Promise<Tutorial> {
241242
lesson.data = {
242243
...pick(
243244
[lesson.data, chapterMetadata, partMetadata, tutorialMetaData],
244-
['mainCommand', 'prepareCommands', 'previews', 'autoReload', 'template', 'terminal', 'editor', 'focus'],
245+
[
246+
'mainCommand',
247+
'prepareCommands',
248+
'previews',
249+
'autoReload',
250+
'template',
251+
'terminal',
252+
'editor',
253+
'focus',
254+
'editPageLink',
255+
],
245256
),
246257
...lesson.data,
247258
};
@@ -265,9 +276,11 @@ export async function getTutorial(): Promise<Tutorial> {
265276
href: joinPaths(baseURL, `/${partSlug}/${chapterSlug}/${nextLesson.slug}`),
266277
};
267278
}
268-
}
269279

270-
// console.log(inspect(_tutorial, undefined, Infinity, true));
280+
if (lesson.data.editPageLink && typeof lesson.data.editPageLink === 'string') {
281+
lesson.editPageLink = lesson.data.editPageLink.replace(':path', lesson.filepath);
282+
}
283+
}
271284

272285
return _tutorial;
273286
}

packages/theme/src/theme.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,13 @@ export const theme = {
248248
iconColor: 'var(--tk-elements-navCard-iconColor)',
249249
iconColorHover: 'var(--tk-elements-navCard-iconColorHover)',
250250
},
251+
editPageLink: {
252+
textColor: 'var(--tk-elements-editPageLink-textColor)',
253+
textColorHover: 'var(--tk-elements-editPageLink-textColorHover)',
254+
iconColor: 'var(--tk-elements-editPageLink-iconColor)',
255+
iconColorHover: 'var(--tk-elements-editPageLink-iconColorHover)',
256+
borderColor: 'var(--tk-elements-editPageLink-borderColor)',
257+
},
251258
breadcrumbs: {
252259
navButton: {
253260
iconColor: 'var(--tk-elements-breadcrumbs-navButton-iconColor)',

packages/types/src/entities/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export interface Lesson<T = unknown> {
4040
part: { id: string; title: string };
4141
chapter: { id: string; title: string };
4242
slug: string;
43+
filepath: string;
44+
editPageLink?: string;
4345
files: FilesRefList;
4446
solution: FilesRefList;
4547
next?: LessonLink;

packages/types/src/schemas/common.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,18 @@ export const webcontainerSchema = commandsSchema.extend({
151151
]),
152152
});
153153

154+
export const editPageLinkSchema = z.union([
155+
// pattern for creating the URL
156+
z.string(),
157+
158+
// `false` for disabling the edit link
159+
z.boolean(),
160+
]);
161+
154162
export const baseSchema = webcontainerSchema.extend({
155163
title: z.string(),
156164
slug: z.string().optional(),
165+
editPageLink: editPageLinkSchema.optional(),
157166
});
158167

159168
export type BaseSchema = z.infer<typeof baseSchema>;

packages/types/src/schemas/tutorial.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { z } from 'zod';
2-
import { webcontainerSchema } from './common.js';
2+
import { webcontainerSchema, editPageLinkSchema } from './common.js';
33

44
export const tutorialSchema = webcontainerSchema.extend({
55
type: z.literal('tutorial'),
66
logoLink: z.string().optional(),
7+
editPageLink: editPageLinkSchema.optional(),
78
parts: z.array(z.string()).optional(),
89
});
910

0 commit comments

Comments
 (0)