slidev-theme-underglow 0.1.0 → 0.1.1

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 CHANGED
@@ -2,26 +2,11 @@
2
2
 
3
3
  [![NPM version](https://img.shields.io/npm/v/slidev-theme-underglow?color=3AB9D4&label=)](https://www.npmjs.com/package/slidev-theme-underglow)
4
4
 
5
- A (...) theme for [Slidev](https://github.com/slidevjs/slidev).
6
-
7
- <!--
8
- Learn more about how to write a theme:
9
- https://sli.dev/guide/write-theme.html
10
- --->
11
-
12
- <!--
13
- run `npm run dev` to check out the slides for more details of how to start writing a theme
14
- -->
15
-
16
- <!--
17
- Put some screenshots here to demonstrate your theme
18
-
19
- Live demo: [...]
20
- -->
5
+ A Slidev theme with gradient underglow effects.
21
6
 
22
7
  ## Install
23
8
 
24
- Add the following frontmatter to your `slides.md`. Start Slidev then it will prompt you to install the theme automatically.
9
+ Add the following frontmatter to your `slides.md`. Slidev will prompt you to install the theme automatically.
25
10
 
26
11
  <pre><code>---
27
12
  theme: <b>underglow</b>
@@ -29,44 +14,146 @@ theme: <b>underglow</b>
29
14
 
30
15
  Learn more about [how to use a theme](https://sli.dev/guide/theme-addon#use-theme).
31
16
 
32
- ## Theme Configuration
17
+ ## Configuration
33
18
 
34
- You can customize the theme's gradient colors using `themeConfig` in your frontmatter:
19
+ ### Colors
20
+
21
+ Customize the theme's gradient colors:
35
22
 
36
23
  ```yaml
37
24
  ---
38
25
  theme: underglow
39
26
  themeConfig:
40
- primary: '#7D1CFE' # Primary brand color (default: purple)
41
- middle: '#176AFA' # Middle transition color (default: blue)
42
- accent: '#01D393' # Accent color (default: green)
27
+ primary: '#7D1CFE' # Gradient start (default: purple)
28
+ middle: '#176AFA' # Middle color (default: blue)
29
+ accent: '#01D393' # Gradient end (default: green)
43
30
  ---
44
31
  ```
45
32
 
46
- ### Color Options
33
+ ### Footer
47
34
 
48
- - **`primary`**: The primary brand color (gradient start). Default: `#7D1CFE` (purple)
49
- - **`middle`**: The middle transition color. Default: `#176AFA` (blue)
50
- - **`accent`**: The accent color (gradient end). Default: `#01D393` (green)
35
+ The footer displays event info, logo, and page number. Configure in frontmatter:
51
36
 
52
- These colors are used throughout the theme for gradients, backgrounds, and visual effects.
37
+ ```yaml
38
+ ---
39
+ theme: underglow
40
+ event:
41
+ name: Event Name
42
+ date: Date
43
+ logo: URL to logo # Optional
44
+ ---
45
+ ```
46
+
47
+ To hide the footer on specific slides, use `hideFooter: true` in the slide frontmatter.
53
48
 
54
49
  ## Layouts
55
50
 
56
51
  This theme provides the following layouts:
57
52
 
58
- > TODO:
53
+ ### `default`
54
+
55
+ Standard layout with content vertically centered. Use for regular content slides.
56
+
57
+ ### `center`
58
+
59
+ Centers content both horizontally and vertically. Perfect for single statements or key points.
60
+
61
+ ### `cover`
62
+
63
+ Title slide layout with full-width content. Use for your presentation cover/title page.
64
+
65
+ ### `intro`
66
+
67
+ Speaker introduction layout with circular profile image and info display. Requires frontmatter:
68
+
69
+ ```yaml
70
+ ---
71
+ layout: intro
72
+ name: Your Name
73
+ jobTitle: Your Job Title
74
+ company: Your Company
75
+ website: your-website.com
76
+ image: /path/to/photo.jpg
77
+ ---
78
+ ```
79
+
80
+ ### `image-full`
81
+
82
+ Full-screen background image layout. Requires `image` in frontmatter:
83
+
84
+ ```yaml
85
+ ---
86
+ layout: image-full
87
+ image: /path/to/image.jpg
88
+ hideFooter: true # Optional
89
+ ---
90
+ ```
91
+
92
+ ### `quote`
93
+
94
+ Display large quotes with optional background image. Supports frontmatter:
95
+
96
+ ```yaml
97
+ ---
98
+ layout: quote
99
+ quote: "Your quote here"
100
+ subtitle: Attribution or source
101
+ link: https://optional-link.com # Optional
102
+ background: /path/to/image.jpg # Optional
103
+ overlayOpacity: 0.6 # Optional, default 0.6
104
+ ---
105
+ ```
106
+
107
+ ### `two-columns`
108
+
109
+ Split content into two columns. Use named slots:
110
+
111
+ ```md
112
+ ---
113
+ layout: two-columns
114
+ ---
115
+
116
+ # Header (spans both columns)
117
+
118
+ ::left::
119
+ Left column content
120
+
121
+ ::right::
122
+ Right column content
123
+ ```
124
+
125
+ ### `three-columns`
126
+
127
+ Split content into three columns. Use named slots:
128
+
129
+ ```md
130
+ ---
131
+ layout: three-columns
132
+ ---
133
+
134
+ # Header (spans all columns)
135
+
136
+ ::left::
137
+ Left column content
138
+
139
+ ::middle::
140
+ Middle column content
141
+
142
+ ::right::
143
+ Right column content
144
+ ```
59
145
 
60
146
  ## Components
61
147
 
62
- This theme provides the following components:
148
+ ### Footer
149
+
150
+ Automatically included in all layouts (except when `hideFooter: true`). Displays:
151
+ - Event name and date (if configured)
152
+ - Logo (if configured)
153
+ - Current slide number
63
154
 
64
- > TODO:
155
+ Configure via frontmatter (see [Configuration](#configuration)).
65
156
 
66
157
  ## Contributing
67
158
 
68
- - `npm install`
69
- - `npm run dev` to start theme preview of `example.md`
70
- - Edit the `example.md` and style to see the changes
71
- - `npm run export` to generate the preview PDF
72
- - `npm run screenshot` to generate the preview PNG
159
+ Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -40,7 +40,6 @@
40
40
 
41
41
  .footer-logo {
42
42
  height: 16px;
43
- width: 16px;
44
43
  margin: 0 4px;
45
44
  }
46
45
 
package/layouts/cover.vue CHANGED
@@ -6,7 +6,21 @@ import Footer from "../components/footer.vue";
6
6
  <div class="slidev-layout cover">
7
7
  <div class="my-auto w-full">
8
8
  <slot />
9
+ <p v-if="$frontmatter.speakers?.length" class="speakers">
10
+ {{ $frontmatter.speakers.map(s => s.name).join(' & ') }}
11
+ </p>
9
12
  </div>
10
13
  </div>
11
14
  <Footer />
12
15
  </template>
16
+
17
+ <style scoped>
18
+ .speakers {
19
+ width: 100%;
20
+ text-align: center;
21
+ font-size: 20px;
22
+ color: rgba(255, 255, 255, 0.6);
23
+ margin-top: 32px;
24
+ padding: 0;
25
+ }
26
+ </style>
package/layouts/intro.vue CHANGED
@@ -1,60 +1,112 @@
1
1
  <script setup>
2
+ import Footer from "../components/footer.vue";
2
3
  </script>
4
+
3
5
  <template>
4
- <div class="slidev-layout intro">
5
- <div class="my-auto w-full container">
6
- <div class="image-container">
7
- <span class="image-border"/>
8
- <img :alt="$frontmatter.name" :src="$frontmatter.image" class="image"/>
6
+ <!-- Single speaker -->
7
+ <div v-if="$frontmatter.speakers?.length === 1" class="slidev-layout intro">
8
+ <div class="my-auto w-full single-container">
9
+ <div class="image-container image-container--large">
10
+ <span class="image-border" />
11
+ <img :alt="$frontmatter.speakers[0].name" :src="$frontmatter.speakers[0].image" class="image" />
9
12
  </div>
10
13
  <div class="info-container">
11
14
  <h2 class="hello">Hello!</h2>
12
- <h1 class="name">{{ $frontmatter.name }}</h1>
13
- <p class="job-title">🚀&nbsp;&nbsp;{{ $frontmatter.jobTitle }}</p>
14
- <p class="job-title">🤝&nbsp;&nbsp;{{ $frontmatter.company }}</p>
15
- <p class="website">🔗&nbsp;&nbsp;<a :href=url>{{ $frontmatter.website }}</a></p>
16
- <div class="logos">
17
- <a v-for="logo in logos" :href="logo.link" target="_blank" style="border: 0">
18
- <img :alt="logo.alt" :src="logo.src" class="logo"/>
15
+ <h1 class="name">{{ $frontmatter.speakers[0].name }}</h1>
16
+ <p class="detail">🚀&nbsp;&nbsp;{{ $frontmatter.speakers[0].jobTitle }}</p>
17
+ <p class="detail">🤝&nbsp;&nbsp;{{ $frontmatter.speakers[0].company }}</p>
18
+ <p class="detail">🔗&nbsp;&nbsp;<a :href="$frontmatter.speakers[0].website">{{ $frontmatter.speakers[0].website }}</a></p>
19
+ <div v-if="$frontmatter.speakers[0].logos?.length" class="logos">
20
+ <a v-for="logo in $frontmatter.speakers[0].logos" :href="logo.link" target="_blank" style="border: 0">
21
+ <img :alt="logo.alt" :src="logo.src" class="logo" />
19
22
  </a>
20
23
  </div>
21
24
  </div>
22
25
  </div>
23
26
  </div>
27
+
28
+ <!-- Two speakers -->
29
+ <div v-else-if="$frontmatter.speakers?.length === 2" class="slidev-layout intro">
30
+ <div class="my-auto w-full two-container">
31
+ <div class="speaker-row">
32
+ <div class="info-container info-container--left">
33
+ <h1 class="name">{{ $frontmatter.speakers[0].name }}</h1>
34
+ <p class="detail">🚀&nbsp;&nbsp;{{ $frontmatter.speakers[0].jobTitle }}</p>
35
+ <p class="detail">🤝&nbsp;&nbsp;{{ $frontmatter.speakers[0].company }}</p>
36
+ <p class="detail">🔗&nbsp;&nbsp;<a :href="$frontmatter.speakers[0].website">{{ $frontmatter.speakers[0].website }}</a></p>
37
+ </div>
38
+ <div class="image-container image-container--small">
39
+ <span class="image-border" />
40
+ <img :alt="$frontmatter.speakers[0].name" :src="$frontmatter.speakers[0].image" class="image" />
41
+ </div>
42
+ </div>
43
+ <div class="speaker-row">
44
+ <div class="image-container image-container--small">
45
+ <span class="image-border" />
46
+ <img :alt="$frontmatter.speakers[1].name" :src="$frontmatter.speakers[1].image" class="image" />
47
+ </div>
48
+ <div class="info-container info-container--right">
49
+ <h1 class="name">{{ $frontmatter.speakers[1].name }}</h1>
50
+ <p class="detail">🚀&nbsp;&nbsp;{{ $frontmatter.speakers[1].jobTitle }}</p>
51
+ <p class="detail">🤝&nbsp;&nbsp;{{ $frontmatter.speakers[1].company }}</p>
52
+ <p class="detail">🔗&nbsp;&nbsp;<a :href="$frontmatter.speakers[1].website">{{ $frontmatter.speakers[1].website }}</a></p>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+
24
58
  <Footer />
25
59
  </template>
26
60
 
27
61
  <style scoped>
28
- .container {
29
- width: 100%;
30
-
62
+ /* ── Single speaker ── */
63
+ .single-container {
31
64
  display: flex;
32
65
  flex-flow: row;
33
66
  gap: 64px;
34
-
35
67
  align-items: center;
36
68
  justify-content: space-evenly;
37
69
  }
38
70
 
71
+ /* ── Two speakers ── */
72
+ .two-container {
73
+ display: flex;
74
+ flex-direction: column;
75
+ gap: 36px;
76
+ }
77
+
78
+ .speaker-row {
79
+ display: flex;
80
+ flex-flow: row;
81
+ gap: 48px;
82
+ align-items: center;
83
+ justify-content: center;
84
+ }
85
+
86
+ /* ── Shared ── */
39
87
  .image-container {
40
- display: inline-block;
88
+ position: relative;
89
+ flex-shrink: 0;
90
+ }
91
+
92
+ .image-container--large {
41
93
  width: 300px;
42
94
  height: 300px;
95
+ }
43
96
 
44
- position: relative;
97
+ .image-container--small {
98
+ width: 180px;
99
+ height: 180px;
45
100
  }
46
101
 
47
102
  .image-border {
48
103
  display: inline-block;
49
104
  width: 100%;
50
105
  height: 100%;
51
-
52
106
  position: absolute;
53
107
  top: 0;
54
108
  left: 0;
55
-
56
109
  border-radius: 50%;
57
-
58
110
  background: linear-gradient(90deg, var(--slidev-theme-color-primary), var(--slidev-theme-color-middle), var(--slidev-theme-color-accent));
59
111
  }
60
112
 
@@ -63,34 +115,49 @@
63
115
  width: 100%;
64
116
  height: 100%;
65
117
  padding: 6px;
66
-
67
118
  position: absolute;
68
119
  top: 0;
69
120
  left: 0;
70
-
71
121
  border-radius: 50%;
72
122
  object-fit: cover;
73
123
  }
74
124
 
75
125
  .info-container {
76
- height: 100%;
77
-
78
126
  display: flex;
79
127
  flex-direction: column;
80
- align-items: end;
81
128
  }
82
129
 
83
- .name, .hello, .job-title, .website {
130
+ .info-container--left {
131
+ align-items: flex-end;
132
+ text-align: right;
133
+ }
134
+
135
+ .info-container--right {
136
+ align-items: flex-start;
137
+ text-align: left;
138
+ }
139
+
140
+ .name, .hello, .detail {
84
141
  margin: 0;
85
142
  padding: 0;
86
143
  }
87
144
 
145
+ .hello {
146
+ margin-bottom: 8px;
147
+ }
148
+
88
149
  .name {
150
+ margin: 24px 0 16px;
151
+ }
152
+
153
+ .single-container .name {
89
154
  margin: 48px 0;
90
155
  }
91
156
 
92
- .job-title {
93
- margin-bottom: 12px;
157
+ .detail {
158
+ font-size: 20px;
159
+ line-height: 1.5;
160
+ padding-bottom: 8px;
94
161
  }
95
162
 
96
163
  .logos {
@@ -104,4 +171,4 @@
104
171
  display: inline-block;
105
172
  height: 56px;
106
173
  }
107
- </style>
174
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slidev-theme-underglow",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A gradient Slidev theme with customizable colors",
5
5
  "type": "module",
6
6
  "author": "Katharina Sick <https://ksick.dev>",
@@ -32,6 +32,12 @@
32
32
  "README.md",
33
33
  "LICENSE"
34
34
  ],
35
+ "scripts": {
36
+ "build": "slidev build example.md",
37
+ "dev": "slidev example.md --open",
38
+ "export": "slidev export example.md",
39
+ "screenshot": "slidev export example.md --format png"
40
+ },
35
41
  "dependencies": {
36
42
  "@slidev/types": "^52.11.5"
37
43
  },
@@ -47,11 +53,5 @@
47
53
  "mono": "Fira Code"
48
54
  }
49
55
  }
50
- },
51
- "scripts": {
52
- "build": "slidev build example.md",
53
- "dev": "slidev example.md --open",
54
- "export": "slidev export example.md",
55
- "screenshot": "slidev export example.md --format png"
56
56
  }
57
- }
57
+ }