slidev-theme-cyberpunk-ide 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -0
- package/UNLICENSE +24 -0
- package/components/.gitkeep +0 -0
- package/components/Callout.vue +37 -0
- package/components/IdeFrame.vue +115 -0
- package/components/Tooltip.vue +55 -0
- package/layouts/cover.vue +26 -0
- package/layouts/default.vue +12 -0
- package/layouts/intro.vue +7 -0
- package/layouts/section.vue +9 -0
- package/package.json +60 -0
- package/public/callouts/LICENSE +7 -0
- package/public/callouts/brain.png +0 -0
- package/public/callouts/bulb.png +0 -0
- package/public/callouts/clean.png +0 -0
- package/public/callouts/code.png +0 -0
- package/public/callouts/fire.png +0 -0
- package/public/callouts/paper.png +0 -0
- package/public/fonts/LICENSE +93 -0
- package/public/fonts/Monaspace Neon Var.woff2 +0 -0
- package/public/fonts/Monaspace Radon Var.woff2 +0 -0
- package/setup/mermaid.ts +34 -0
- package/setup/shiki.ts +44 -0
- package/styles/index.ts +3 -0
- package/styles/layout.css +785 -0
- package/vite.config.ts +146 -0
package/README.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# slidev-theme-cyberpunk-ide
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/slidev-theme-cyberpunk-ide)
|
|
4
|
+
|
|
5
|
+
A cyberpunk IDE-style theme for [Slidev](https://github.com/slidevjs/slidev), designed for teaching computer science. Each slide looks like a file open in a dark IDE, complete with title bar, tab bar, and status bar.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Add the following frontmatter to your `slides.md`:
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
---
|
|
13
|
+
theme: cyberpunk-ide
|
|
14
|
+
---
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Fonts
|
|
18
|
+
|
|
19
|
+
The theme uses **Monaspace Neon** (body and code) and **Monaspace Radon** (comments in code blocks). Both variable fonts are bundled with the theme — no manual download or configuration required. They are licensed under the [SIL Open Font License 1.1](public/fonts/LICENSE).
|
|
20
|
+
|
|
21
|
+
## Layouts
|
|
22
|
+
|
|
23
|
+
### `cover` (default for slide 1)
|
|
24
|
+
|
|
25
|
+
Title slide with a cyberpunk grid background, scan lines, and an animated gradient on the heading.
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
---
|
|
29
|
+
layout: cover
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Course Title
|
|
33
|
+
|
|
34
|
+
Subtitle or description
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Optional named slots:**
|
|
38
|
+
|
|
39
|
+
| Slot | Position | Purpose |
|
|
40
|
+
| ---------------- | ------------ | -------------------------- |
|
|
41
|
+
| `::logo::` | Top-left | School or institution logo |
|
|
42
|
+
| `::logo-right::` | Top-right | Department or course logo |
|
|
43
|
+
| `::sponsors::` | Bottom strip | Sponsor / partner logos |
|
|
44
|
+
|
|
45
|
+
The top bar is only rendered if at least one of `logo` or `logo-right` is provided. The sponsors strip is only rendered if `sponsors` is provided.
|
|
46
|
+
|
|
47
|
+
```markdown
|
|
48
|
+
---
|
|
49
|
+
layout: cover
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
# Course Title
|
|
53
|
+
|
|
54
|
+
Subtitle
|
|
55
|
+
|
|
56
|
+
::logo::
|
|
57
|
+
<img src="/logo-school.png" alt="School" />
|
|
58
|
+
|
|
59
|
+
::logo-right::
|
|
60
|
+
<img src="/logo-dept.png" alt="Department" />
|
|
61
|
+
|
|
62
|
+
::sponsors::
|
|
63
|
+
<img src="/sponsor1.png" alt="Sponsor A" />
|
|
64
|
+
<img src="/sponsor2.png" alt="Sponsor B" />
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Images are automatically constrained (`max-height: 44px` for logos, `28px` for sponsors). Place image files in your presentation's `public/` folder and reference them with a leading `/`.
|
|
68
|
+
|
|
69
|
+
### `default`
|
|
70
|
+
|
|
71
|
+
Standard content slide wrapped in the IDE (title bar, tab bar, editor area, status bar).
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
---
|
|
75
|
+
filename: algorithms.py # tab name and title bar — default: main.py
|
|
76
|
+
language: Python # status bar right — default: Python
|
|
77
|
+
branch: 03/recursion # status bar left — default: main
|
|
78
|
+
repo: ComputerScience101 # status bar left (repo name) — default: cyberpunk-ide
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
# Slide title
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `section`
|
|
85
|
+
|
|
86
|
+
Full-screen section divider with a grid background and a glowing accent line.
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
---
|
|
90
|
+
layout: section
|
|
91
|
+
section: Module 2 # label shown above the title — default: Modulo
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
# *Chapter* Title
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Wrap a word in `*...*` (em) to apply the neon purple accent color.
|
|
98
|
+
|
|
99
|
+
## Tab bar
|
|
100
|
+
|
|
101
|
+
The tab bar shows one chip-style tab per slide, auto-scrolling to keep the active one visible. Clicking any tab navigates to that slide.
|
|
102
|
+
|
|
103
|
+
### Hiding slides from the tab bar
|
|
104
|
+
|
|
105
|
+
By default, slides with `layout: cover` or `layout: section` are **hidden** from the tab bar (they don't have IDE chrome anyway).
|
|
106
|
+
|
|
107
|
+
To **show all slides** including cover and section slides:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
---
|
|
111
|
+
# in the presentation headmatter (first slide)
|
|
112
|
+
themeConfig:
|
|
113
|
+
tabsShowAll: true
|
|
114
|
+
---
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
To **hide a specific slide** from the tab bar regardless of the global setting:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
---
|
|
121
|
+
hideTab: true
|
|
122
|
+
---
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Status bar
|
|
126
|
+
|
|
127
|
+
| Position | Content | Frontmatter key | Default |
|
|
128
|
+
| -------- | -------------------------------- | --------------- | --------------------------- |
|
|
129
|
+
| Left | Repo name (GitHub icon) | `repo` | `cyberpunk-ide` |
|
|
130
|
+
| Left | Branch / topic (git branch icon) | `branch` | `main` |
|
|
131
|
+
| Right | Language | `language` | `Python` |
|
|
132
|
+
| Right | Encoding | — | `UTF-8` (fixed) |
|
|
133
|
+
| Right | Slide counter | — | `current / total` (dynamic) |
|
|
134
|
+
|
|
135
|
+
## Line numbers
|
|
136
|
+
|
|
137
|
+
Line numbers are **enabled by default** by the theme. The scope of control is:
|
|
138
|
+
|
|
139
|
+
| Level | How |
|
|
140
|
+
| -------------------------------- | ---------------------------------- |
|
|
141
|
+
| Whole presentation (disable) | `lineNumbers: false` in headmatter |
|
|
142
|
+
| Single code block (disable) | ` ```python {lineNumbers:false} ` |
|
|
143
|
+
| Single code block (custom start) | ` ```python {startLine:10} ` |
|
|
144
|
+
|
|
145
|
+
## Syntax highlighting
|
|
146
|
+
|
|
147
|
+
Code blocks use the **Tokyo Night** theme via Shiki. Comment tokens are automatically rendered in **Monaspace Radon** (cursive/calligraphic style) to visually distinguish them from code.
|
|
148
|
+
|
|
149
|
+
## Callouts
|
|
150
|
+
|
|
151
|
+
Six callout types are available for highlighting definitions, tips, warnings, and learning objectives.
|
|
152
|
+
|
|
153
|
+
```markdown
|
|
154
|
+
:::definition Definition
|
|
155
|
+
An **algorithm** is a finite sequence of unambiguous instructions.
|
|
156
|
+
:::
|
|
157
|
+
|
|
158
|
+
:::info Useful Information
|
|
159
|
+
You can use `len()` to get the length of any sequence.
|
|
160
|
+
:::
|
|
161
|
+
|
|
162
|
+
:::warning Warning
|
|
163
|
+
Do not modify a list while iterating over it.
|
|
164
|
+
:::
|
|
165
|
+
|
|
166
|
+
:::clean Clean Code
|
|
167
|
+
Use descriptive names: `number_of_students` is better than `n`.
|
|
168
|
+
:::
|
|
169
|
+
|
|
170
|
+
:::code Python Syntax
|
|
171
|
+
`for item in list:` iterates without using indices.
|
|
172
|
+
:::
|
|
173
|
+
|
|
174
|
+
:::learn What You Will Learn
|
|
175
|
+
In this module you will see **recursion** in action.
|
|
176
|
+
:::
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
| Type | Color | Use for |
|
|
180
|
+
| ------------ | ------ | ---------------------------- |
|
|
181
|
+
| `definition` | brown | Formal definitions |
|
|
182
|
+
| `info` | yellow | Tips and notes |
|
|
183
|
+
| `warning` | red | Pitfalls and gotchas |
|
|
184
|
+
| `clean` | cyan | Best practices / clean code |
|
|
185
|
+
| `code` | grey | Syntax reminders / code tips |
|
|
186
|
+
| `learn` | purple | Learning objectives |
|
|
187
|
+
|
|
188
|
+
**Custom icon and color** — each callout accepts optional `icon` and `color` props to override the preset:
|
|
189
|
+
|
|
190
|
+
```markdown
|
|
191
|
+
<Callout type="info" title="Nota" icon="i-ph-star" color="#9ece6a">
|
|
192
|
+
|
|
193
|
+
Custom icon (any UnoCSS / Phosphor icon class) and hex color.
|
|
194
|
+
|
|
195
|
+
</Callout>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> Icons used by the presets (`paper.png`, `bulb.png`, etc.) must be present in `public/callouts/` of the presentation folder.
|
|
199
|
+
|
|
200
|
+
## Glossary tooltips
|
|
201
|
+
|
|
202
|
+
Add a `glossary` map to a slide's frontmatter to automatically wrap matching terms with interactive tooltips. Hovering (or focusing) the term shows its definition inline.
|
|
203
|
+
|
|
204
|
+
```yaml
|
|
205
|
+
---
|
|
206
|
+
filename: recursion.py
|
|
207
|
+
glossary:
|
|
208
|
+
algorithm: A finite sequence of **unambiguous** instructions that solves a problem
|
|
209
|
+
recursion: A technique where a function calls `itself` to solve sub-problems
|
|
210
|
+
base case: The condition that stops the recursion, preventing a stack overflow
|
|
211
|
+
---
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Definitions support inline formatting: `**bold**`, `*italic*`, `` `code` ``.
|
|
215
|
+
|
|
216
|
+
Terms inside fenced code blocks and inline code spans are left untouched.
|
package/UNLICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
|
2
|
+
|
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
4
|
+
distribute this software, either in source code form or as a compiled
|
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
6
|
+
means.
|
|
7
|
+
|
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
9
|
+
of this software dedicate any and all copyright interest in the
|
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
|
11
|
+
of the public at large and to the detriment of our heirs and
|
|
12
|
+
successors. We intend this dedication to be an overt act of
|
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
14
|
+
software under copyright law.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
For more information, please refer to <https://unlicense.org/>
|
|
File without changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
type?: string
|
|
4
|
+
title: string
|
|
5
|
+
icon?: string
|
|
6
|
+
color?: string
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const presets: Record<string, { icon: string; color: string }> = {
|
|
10
|
+
definition: { icon: '/callouts/paper.png', color: '#a9836e' },
|
|
11
|
+
info: { icon: '/callouts/bulb.png', color: '#e0af68' },
|
|
12
|
+
warning: { icon: '/callouts/fire.png', color: '#f7768e' },
|
|
13
|
+
clean: { icon: '/callouts/clean.png', color: '#7dcfff' },
|
|
14
|
+
code: { icon: '/callouts/code.png', color: '#565f89' },
|
|
15
|
+
learn: { icon: '/callouts/brain.png', color: '#bb9af7' },
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const preset = props.type ? presets[props.type] : undefined
|
|
19
|
+
const resolvedColor = props.color ?? preset?.color ?? '#7dcfff'
|
|
20
|
+
const resolvedIcon = props.icon ?? preset?.icon ?? 'i-ph-info'
|
|
21
|
+
|
|
22
|
+
// true = UnoCSS icon class, false = image path
|
|
23
|
+
const isUnoIcon = resolvedIcon.startsWith('i-')
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<div class="callout" :data-type="type" :style="{ '--callout-color': resolvedColor }">
|
|
28
|
+
<div class="callout-header">
|
|
29
|
+
<span v-if="isUnoIcon" class="callout-icon" :class="resolvedIcon" />
|
|
30
|
+
<img v-else class="callout-icon" :src="resolvedIcon" aria-hidden="true" />
|
|
31
|
+
<span class="callout-title">{{ title }}</span>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="callout-body">
|
|
34
|
+
<slot />
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</template>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { configs } from '@slidev/client'
|
|
3
|
+
import { useNav } from '@slidev/client'
|
|
4
|
+
import { computed, nextTick, ref, watch } from 'vue'
|
|
5
|
+
|
|
6
|
+
withDefaults(defineProps<{
|
|
7
|
+
filename?: string
|
|
8
|
+
language?: string
|
|
9
|
+
branch?: string
|
|
10
|
+
repo?: string
|
|
11
|
+
}>(), {
|
|
12
|
+
filename: 'main.py',
|
|
13
|
+
language: 'Python',
|
|
14
|
+
branch: 'main',
|
|
15
|
+
repo: 'cyberpunk-ide',
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const { slides, currentPage, total, go } = useNav()
|
|
19
|
+
|
|
20
|
+
// themeConfig.tabsShowAll: true → show every slide in the tab bar
|
|
21
|
+
// default (false/unset) → hide slides with layout cover or section
|
|
22
|
+
const tabsShowAll = computed(() => {
|
|
23
|
+
const v = configs.themeConfig?.tabsShowAll
|
|
24
|
+
return v === true || v === 'true' || v === 1
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const visibleSlides = computed(() => {
|
|
28
|
+
return slides.value.filter((slide) => {
|
|
29
|
+
const fm = slide?.meta?.slide?.frontmatter ?? {}
|
|
30
|
+
// Per-slide explicit opt-out
|
|
31
|
+
if (fm.hideTab === true || fm.hideTab === 'true') return false
|
|
32
|
+
// Global filter: skip cover/section layouts unless tabsShowAll is set
|
|
33
|
+
if (!tabsShowAll.value) {
|
|
34
|
+
const layout = (slide?.meta as any)?.layout ?? fm.layout
|
|
35
|
+
if (layout === 'cover' || layout === 'section') return false
|
|
36
|
+
}
|
|
37
|
+
return true
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
function slideFilename(no: number): string {
|
|
42
|
+
const slide = slides.value.find(s => s.no === no)
|
|
43
|
+
return slide?.meta?.slide?.frontmatter?.filename ?? `slide-${no}.md`
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const tabbarEl = ref<HTMLElement>()
|
|
47
|
+
|
|
48
|
+
watch(currentPage, async () => {
|
|
49
|
+
await nextTick()
|
|
50
|
+
const active = tabbarEl.value?.querySelector<HTMLElement>('.ide-tab.active')
|
|
51
|
+
if (active) active.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' })
|
|
52
|
+
}, { immediate: true })
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<template>
|
|
56
|
+
<div class="ide-frame">
|
|
57
|
+
|
|
58
|
+
<!-- Title Bar -->
|
|
59
|
+
<div class="ide-titlebar">
|
|
60
|
+
<div class="ide-traffic-lights">
|
|
61
|
+
<span class="traffic-close" />
|
|
62
|
+
<span class="traffic-minimize" />
|
|
63
|
+
<span class="traffic-maximize" />
|
|
64
|
+
</div>
|
|
65
|
+
<div class="ide-titlebar-text">{{ filename }} — Cyberpunk IDE</div>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<!-- Tab Bar -->
|
|
69
|
+
<div ref="tabbarEl" class="ide-tabbar">
|
|
70
|
+
<div
|
|
71
|
+
v-for="slide in visibleSlides"
|
|
72
|
+
:key="slide.no"
|
|
73
|
+
class="ide-tab"
|
|
74
|
+
:class="{ active: slide.no === currentPage }"
|
|
75
|
+
@click="go(slide.no)"
|
|
76
|
+
>
|
|
77
|
+
<span class="ide-tab-icon">⬡</span>
|
|
78
|
+
<span class="ide-tab-name">{{ slideFilename(slide.no) }}</span>
|
|
79
|
+
<span class="ide-tab-close">×</span>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<!-- Editor -->
|
|
84
|
+
<div class="ide-editor">
|
|
85
|
+
<div class="ide-gutter" />
|
|
86
|
+
<div class="ide-content">
|
|
87
|
+
<slot />
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<!-- Status Bar -->
|
|
92
|
+
<div class="ide-statusbar">
|
|
93
|
+
<div class="status-left">
|
|
94
|
+
<span class="status-item">
|
|
95
|
+
<span class="i-ph-github-logo status-icon" />
|
|
96
|
+
{{ repo }}
|
|
97
|
+
</span>
|
|
98
|
+
<span class="status-sep">›</span>
|
|
99
|
+
<span class="status-item">
|
|
100
|
+
<span class="i-ph-git-branch status-icon" />
|
|
101
|
+
{{ branch }}
|
|
102
|
+
</span>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="status-right">
|
|
105
|
+
<span class="status-item">{{ language }}</span>
|
|
106
|
+
<span class="status-item">UTF-8</span>
|
|
107
|
+
<span class="status-item">
|
|
108
|
+
<span class="i-ph-hash status-icon" />
|
|
109
|
+
{{ currentPage }} / {{ total }}
|
|
110
|
+
</span>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
</div>
|
|
115
|
+
</template>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{ text: string }>()
|
|
5
|
+
|
|
6
|
+
function escapeHtml(s: string): string {
|
|
7
|
+
return s
|
|
8
|
+
.replace(/&/g, '&')
|
|
9
|
+
.replace(/</g, '<')
|
|
10
|
+
.replace(/>/g, '>')
|
|
11
|
+
.replace(/"/g, '"')
|
|
12
|
+
.replace(/'/g, ''')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const rendered = computed(() =>
|
|
16
|
+
escapeHtml(props.text)
|
|
17
|
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|
18
|
+
.replace(/`(.*?)`/g, '<code>$1</code>')
|
|
19
|
+
.replace(/`(.*?)`/g, '<code>$1</code>')
|
|
20
|
+
.replace(/\*(.*?)\*/g, '<em>$1</em>'),
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const boxRef = ref<HTMLElement>()
|
|
24
|
+
|
|
25
|
+
function adjust() {
|
|
26
|
+
const box = boxRef.value
|
|
27
|
+
if (!box) return
|
|
28
|
+
|
|
29
|
+
// Reset so we measure the natural position
|
|
30
|
+
box.style.left = ''
|
|
31
|
+
box.style.right = ''
|
|
32
|
+
box.style.transform = ''
|
|
33
|
+
|
|
34
|
+
const rect = box.getBoundingClientRect()
|
|
35
|
+
|
|
36
|
+
// Clamp horizontally inside the viewport
|
|
37
|
+
if (rect.right > window.innerWidth - 8) {
|
|
38
|
+
box.style.left = 'auto'
|
|
39
|
+
box.style.right = '0'
|
|
40
|
+
box.style.transform = 'none'
|
|
41
|
+
}
|
|
42
|
+
else if (rect.left < 8) {
|
|
43
|
+
box.style.left = '0'
|
|
44
|
+
box.style.right = 'auto'
|
|
45
|
+
box.style.transform = 'none'
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<span class="cp-tooltip-trigger" tabindex="0" @mouseenter="adjust" @focus="adjust">
|
|
52
|
+
<slot />
|
|
53
|
+
<span ref="boxRef" class="cp-tooltip-box" v-html="rendered" />
|
|
54
|
+
</span>
|
|
55
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="slidev-layout cover">
|
|
3
|
+
<div class="cover-bracket-tl" />
|
|
4
|
+
<div class="cover-bracket-br" />
|
|
5
|
+
|
|
6
|
+
<!-- Top bar: logo slots (only rendered if used) -->
|
|
7
|
+
<div v-if="$slots.logo || $slots['logo-right']" class="cover-topbar">
|
|
8
|
+
<div class="cover-logo-left">
|
|
9
|
+
<slot name="logo" />
|
|
10
|
+
</div>
|
|
11
|
+
<div class="cover-logo-right">
|
|
12
|
+
<slot name="logo-right" />
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<!-- Main content -->
|
|
17
|
+
<div class="cover-inner">
|
|
18
|
+
<slot />
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<!-- Bottom sponsors strip (only rendered if used) -->
|
|
22
|
+
<div v-if="$slots.sponsors" class="cover-sponsors">
|
|
23
|
+
<slot name="sponsors" />
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="slidev-layout default">
|
|
3
|
+
<IdeFrame
|
|
4
|
+
:filename="$frontmatter.filename ?? 'main.py'"
|
|
5
|
+
:language="$frontmatter.language ?? 'Python'"
|
|
6
|
+
:branch="$frontmatter.branch ?? 'main'"
|
|
7
|
+
:repo="$frontmatter.repo ?? 'cyberpunk-ide'"
|
|
8
|
+
>
|
|
9
|
+
<slot />
|
|
10
|
+
</IdeFrame>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "slidev-theme-cyberpunk-ide",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A cyberpunk IDE-style Slidev theme for teaching computer science",
|
|
5
|
+
"author": "Marco Farina",
|
|
6
|
+
"license": "Unlicense",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"slidev-theme",
|
|
10
|
+
"slidev"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/marcofarina/slidev-theme-cyberpunk-ide.git"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/marcofarina/slidev-theme-cyberpunk-ide",
|
|
17
|
+
"files": [
|
|
18
|
+
"components/",
|
|
19
|
+
"layouts/",
|
|
20
|
+
"public/",
|
|
21
|
+
"setup/",
|
|
22
|
+
"styles/",
|
|
23
|
+
"vite.config.ts",
|
|
24
|
+
"README.md",
|
|
25
|
+
"UNLICENSE"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18.0.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "slidev build example.md",
|
|
32
|
+
"dev": "slidev example.md --open",
|
|
33
|
+
"export": "slidev export example.md",
|
|
34
|
+
"screenshot": "slidev export example.md --format png"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@slidev/types": "^52.14.1"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@slidev/cli": "^52.14.1",
|
|
41
|
+
"@types/markdown-it-container": "^4.0.0",
|
|
42
|
+
"markdown-it-container": "^4.0.0"
|
|
43
|
+
},
|
|
44
|
+
"//": "Learn more: https://sli.dev/guide/write-theme.html",
|
|
45
|
+
"slidev": {
|
|
46
|
+
"colorSchema": "dark",
|
|
47
|
+
"defaults": {
|
|
48
|
+
"lineNumbers": true,
|
|
49
|
+
"fonts": {
|
|
50
|
+
"sans": "Monaspace Neon",
|
|
51
|
+
"mono": "Monaspace Neon",
|
|
52
|
+
"local": [
|
|
53
|
+
"Monaspace Neon",
|
|
54
|
+
"Monaspace Radon"
|
|
55
|
+
],
|
|
56
|
+
"provider": "none"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<a href="https://www.flaticon.com/free-icons/brain" title="brain icons">Brain icons created by Freepik - Flaticon</a>
|
|
2
|
+
<a href="https://www.flaticon.com/free-icons/idea" title="idea icons">Idea icons created by Freepik - Flaticon</a>
|
|
3
|
+
<a href="https://www.flaticon.com/free-icons/clean" title="clean icons">Clean icons created by Freepik - Flaticon</a>
|
|
4
|
+
<a href="https://www.flaticon.com/free-icons/keyboard-key" title="keyboard-key icons">Keyboard-key icons created by
|
|
5
|
+
littleicon - Flaticon</a>
|
|
6
|
+
<a href="https://www.flaticon.com/free-icons/fire" title="fire icons">Fire icons created by pocike - Flaticon</a>
|
|
7
|
+
<a href="https://www.flaticon.com/free-icons/scroll" title="scroll icons">Scroll icons created by Freepik - Flaticon</a>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|