Skip to content

Commit ae61993

Browse files
committed
feat: create-slidev-theme
1 parent 64b2826 commit ae61993

20 files changed

Lines changed: 610 additions & 1 deletion

File tree

packages/client/layouts/cover.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<template>
2+
<main class="layout-master cover">
3+
<slot />
4+
</main>
5+
</template>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Welcome to [Slidev](https://github.com/slidevjs/slidev)!
2+
3+
To start the slide show:
4+
5+
- `npm install`
6+
- `npm run dev`
7+
- visit http://localhost:3030
8+
9+
Edit the [slides.md](./slides.md) to see the changes.
10+
11+
Learn more about Slidev on [documentations](https://slidev.antfu.me/).

packages/create-theme/index.js

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/env node
2+
/* eslint-disable @typescript-eslint/no-var-requires */
3+
4+
// @ts-check
5+
const fs = require('fs')
6+
const path = require('path')
7+
const argv = require('minimist')(process.argv.slice(2))
8+
const { prompt } = require('enquirer')
9+
const { cyan, blue, yellow, bold, dim, green } = require('kolorist')
10+
const { version } = require('./package.json')
11+
const { basename } = require('path')
12+
13+
const cwd = process.cwd()
14+
15+
const renameFiles = {
16+
_gitignore: '.gitignore',
17+
_npmrc: '.npmrc',
18+
}
19+
20+
async function init() {
21+
console.log()
22+
console.log(` ${cyan('●') + blue('■') + yellow('▲')}`)
23+
console.log(`${bold(' Slidev') + dim(' Theme Creator')} ${blue(`v${version}`)}`)
24+
console.log()
25+
26+
let targetDir = argv._[0]
27+
if (!targetDir) {
28+
/**
29+
* @type {{ name: string }}
30+
*/
31+
const { name } = await prompt({
32+
type: 'input',
33+
name: 'name',
34+
message: 'Theme name:',
35+
initial: 'slidev-theme-starter',
36+
})
37+
targetDir = name
38+
}
39+
const packageName = await getValidPackageName(targetDir)
40+
const root = path.join(cwd, targetDir)
41+
42+
if (!fs.existsSync(root)) {
43+
fs.mkdirSync(root, { recursive: true })
44+
}
45+
else {
46+
const existing = fs.readdirSync(root)
47+
if (existing.length) {
48+
console.log(yellow(` Target directory "${targetDir}" is not empty.`))
49+
/**
50+
* @type {{ yes: boolean }}
51+
*/
52+
const { yes } = await prompt({
53+
type: 'confirm',
54+
name: 'yes',
55+
initial: 'Y',
56+
message: 'Remove existing files and continue?',
57+
})
58+
if (yes)
59+
emptyDir(root)
60+
61+
else
62+
return
63+
}
64+
}
65+
66+
console.log(dim(' Scaffolding Slidev theme in ') + targetDir + dim(' ...'))
67+
68+
prepareTemplate(root, path.join(__dirname, 'template'), packageName)
69+
70+
const pkgManager = (/pnpm/.test(process.env.npm_execpath) || /pnpm/.test(process.env.npm_config_user_agent))
71+
? 'pnpm'
72+
: /yarn/.test(process.env.npm_execpath) ? 'yarn' : 'npm'
73+
74+
const related = path.relative(cwd, root)
75+
76+
console.log(green(' Done.\n'))
77+
78+
console.log(dim('\n start it by:\n'))
79+
if (root !== cwd)
80+
console.log(blue(` cd ${bold(related)}`))
81+
82+
console.log(blue(` ${pkgManager === 'yarn' ? 'yarn' : `${pkgManager} install`}`))
83+
console.log(blue(` ${pkgManager === 'yarn' ? 'yarn dev' : `${pkgManager} run dev`}`))
84+
console.log()
85+
console.log(` ${cyan('●')} ${blue('■')} ${yellow('▲')}`)
86+
console.log()
87+
}
88+
89+
function prepareTemplate(root, templateDir, packageName) {
90+
const write = (file, content) => {
91+
const targetPath = renameFiles[file]
92+
? path.join(root, renameFiles[file])
93+
: path.join(root, file)
94+
if (content)
95+
fs.writeFileSync(targetPath, content)
96+
97+
else
98+
copy(path.join(templateDir, file), targetPath)
99+
}
100+
101+
const files = fs.readdirSync(templateDir)
102+
for (const file of files.filter(f => !['package.json', 'README.md'].includes(f)))
103+
write(file)
104+
105+
write(
106+
'package.json',
107+
JSON.stringify({
108+
name: packageName,
109+
version: '0.0.0',
110+
...require(path.join(templateDir, 'package.json')),
111+
}, null, 2),
112+
)
113+
114+
write(
115+
'README.md',
116+
fs
117+
.readFileSync(path.join(templateDir, 'README.md'), 'utf-8')
118+
.replace(/{{package-name}}/g, packageName)
119+
.replace(/{{name}}/g, getThemeName(packageName)),
120+
)
121+
}
122+
123+
function copy(src, dest) {
124+
const stat = fs.statSync(src)
125+
if (stat.isDirectory())
126+
copyDir(src, dest)
127+
128+
else
129+
fs.copyFileSync(src, dest)
130+
}
131+
132+
function getValidPackageName(projectName) {
133+
projectName = basename(projectName)
134+
if (!projectName.startsWith('slidev-theme-'))
135+
return `slidev-theme-${projectName}`
136+
return projectName
137+
}
138+
139+
function getThemeName(pkgName) {
140+
return pkgName.replace(/^slidev-theme-/, '')
141+
}
142+
143+
function copyDir(srcDir, destDir) {
144+
fs.mkdirSync(destDir, { recursive: true })
145+
for (const file of fs.readdirSync(srcDir)) {
146+
const srcFile = path.resolve(srcDir, file)
147+
const destFile = path.resolve(destDir, file)
148+
copy(srcFile, destFile)
149+
}
150+
}
151+
152+
function emptyDir(dir) {
153+
if (!fs.existsSync(dir))
154+
return
155+
156+
for (const file of fs.readdirSync(dir)) {
157+
const abs = path.resolve(dir, file)
158+
// baseline is Node 12 so can't use rmSync :(
159+
if (fs.lstatSync(abs).isDirectory()) {
160+
emptyDir(abs)
161+
fs.rmdirSync(abs)
162+
}
163+
else {
164+
fs.unlinkSync(abs)
165+
}
166+
}
167+
}
168+
169+
init().catch((e) => {
170+
console.error(e)
171+
})

packages/create-theme/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "create-slidev-theme",
3+
"version": "0.0.0-alpha.24",
4+
"description": "Create starter theme template for Slidev",
5+
"license": "MIT",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/slidevjs/slidev"
9+
},
10+
"funding": "https://github.com/sponsors/antfu",
11+
"author": "antfu <anthonyfu117@hotmail.com>",
12+
"main": "index.js",
13+
"bin": {
14+
"create-slidev-theme": "index.js"
15+
},
16+
"homepage": "https://github.com/slidevjs/slidev",
17+
"bugs": "https://github.com/slidevjs/slidev/issues",
18+
"dependencies": {
19+
"enquirer": "^2.3.6",
20+
"kolorist": "^1.4.1",
21+
"minimist": "^1.2.5"
22+
}
23+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# {{package-name}}
2+
3+
[![NPM version](https://img.shields.io/npm/v/{{package-name}}?color=3AB9D4&label=)](https://www.npmjs.com/package/{{package-name}})
4+
5+
A (...) theme for [Slidev](https://github.com/slidevjs/slidev).
6+
7+
<!--
8+
run `npm run dev` to check out the slides for more details of how to start writing a theme
9+
-->
10+
11+
<!--
12+
put some screenshots here to demonstrate your theme,
13+
-->
14+
15+
<!--
16+
Live demo: [...]
17+
-->
18+
19+
## Install
20+
21+
Add the following frontmatter to your `slides.md`. Start Slidev then it will prompt you to install the theme automatically.
22+
23+
<pre><code>---<br>theme: <b>{{name}}</b><br>---</code></pre>
24+
25+
Learn more about [how to use a theme](https://slidev.antfu.me/themes/).
26+
27+
## Layouts
28+
29+
This theme provides the following layouts:
30+
31+
> TODO:
32+
33+
## Components
34+
35+
This theme provides the following components:
36+
37+
> TODO:
38+
39+
## Contributing
40+
41+
- `npm install`
42+
- `npm run dev` to start theme preview of `example.md`
43+
- Edit the `example.md` and style to see the changes
44+
- `npm run export` to genreate the preview PDF
45+
- `npm run screenshot` to genrate the preview PNG
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
*.local
5+
index.html
6+
.remote-assets
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# for pnpm
2+
shamefully-hoist=true

packages/create-theme/template/components/.gitkeep

Whitespace-only changes.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
theme: none
3+
---
4+
5+
# Slidev Theme Starter
6+
7+
Presentation slides for developers
8+
9+
<div class="pt-12">
10+
<span @click="next" class="px-2 p-1 rounded cursor-pointer hover:bg-white hover:bg-opacity-10">
11+
Press Space for next page <carbon:arrow-right class="inline"/>
12+
</span>
13+
</div>
14+
15+
---
16+
17+
# What is Slidev?
18+
19+
Slidev is a slides maker and presenter designed for developers, consist of the following features
20+
21+
- 📝 **Text-based** - focus on the content with Markdown, and then style them later
22+
- 🎨 **Themable** - theme can be shared and used with npm packages
23+
- 🧑‍💻 **Developer Friendly** - code highlighting, live coding with autocompletion
24+
- 🤹 **Interactive** - embedding Vue components to enhance your expressions
25+
- 🎥 **Recording** - built-in recording and camera view
26+
- 📤 **Portable** - export into PDF, PNGs, or even a hostable SPA
27+
- 🛠 **Hackable** - anything possible on a webpage
28+
29+
<br>
30+
<br>
31+
32+
Read more about [Why Slidev?](https://slidev.antfu.me/guide/why)
33+
34+
35+
---
36+
37+
# Navigation
38+
39+
Hover on the bottom-left corner to see the navigation's controls panel
40+
41+
### Keyboard Shortcuts
42+
43+
| | |
44+
| --- | --- |
45+
| <kbd>space</kbd> / <kbd>tab</kbd> / <kbd>right</kbd> | next animation or slide |
46+
| <kbd>left</kbd> | previous animation or slide |
47+
| <kbd>up</kbd> | previous slide |
48+
| <kbd>down</kbd> | next slide |
49+
50+
---
51+
layout: image-right
52+
image: 'https://source.unsplash.com/collection/94734566/1920x1080'
53+
---
54+
55+
# Code
56+
57+
Use code snippets and get the highlighting directly!
58+
59+
```ts
60+
interface User {
61+
id: number
62+
firstName: string
63+
lastName: string
64+
role: string
65+
}
66+
67+
function updateUser(id: number, update: Partial<User>) {
68+
const user = getUser(id)
69+
const newUser = {...user, ...update}
70+
saveUser(id, newUser)
71+
}
72+
```
73+
74+
---
75+
layout: center
76+
class: "text-center"
77+
---
78+
79+
# Learn More
80+
81+
[Documentations](https://slidev.antfu.me) / [GitHub Repo](https://github.com/slidevjs/slidev)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<head>
2+
<link rel="preconnect" href="https://fonts.gstatic.com">
3+
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;600&family=Nunito+Sans:wght@200;400;600&display=swap" rel="stylesheet">
4+
</head>

0 commit comments

Comments
 (0)