Skip to content

Commit 1e8dfe3

Browse files
omachalaOndrej Machala
andauthored
fix: expose heroshot/virtual types export (#25)
Expose virtual module TypeScript declarations via `heroshot/virtual` export. Users can now add to tsconfig.json: ```json { "compilerOptions": { "types": ["heroshot/virtual"] } } ``` This provides type support for: - `virtual:heroshot-manifest` (Vite) - `@heroshot/manifest` (Docusaurus) --------- Co-authored-by: Ondrej Machala <[email protected]>
1 parent 3f312ac commit 1e8dfe3

File tree

11 files changed

+151
-71
lines changed

11 files changed

+151
-71
lines changed

.changeset/virtual-types-export.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'heroshot': patch
3+
---
4+
5+
Add `heroshot/virtual` TypeScript types for virtual module imports

docs/.vitepress/config.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,23 @@ export default defineConfig({
159159
{
160160
text: 'Integrations',
161161
items: [
162-
{ text: 'VitePress', link: '/docs/integrations/vitepress' },
163-
{ text: 'Docusaurus', link: '/docs/integrations/docusaurus' },
164-
{ text: 'MkDocs', link: '/docs/integrations/mkdocs' },
165-
{ text: 'React', link: '/docs/integrations/react' },
166-
{ text: 'Vue', link: '/docs/integrations/vue' },
167-
{ text: 'Markdown', link: '/docs/integrations/markdown' },
168-
{ text: 'GitBook', link: '/docs/integrations/gitbook' },
162+
{
163+
text: 'Docs',
164+
items: [
165+
{ text: 'VitePress', link: '/docs/integrations/vitepress' },
166+
{ text: 'Docusaurus', link: '/docs/integrations/docusaurus' },
167+
{ text: 'MkDocs', link: '/docs/integrations/mkdocs' },
168+
{ text: 'GitBook', link: '/docs/integrations/gitbook' },
169+
],
170+
},
171+
{
172+
text: 'UI Frameworks',
173+
items: [
174+
{ text: 'React', link: '/docs/integrations/react' },
175+
{ text: 'Vue', link: '/docs/integrations/vue' },
176+
{ text: 'Markdown', link: '/docs/integrations/markdown' },
177+
],
178+
},
169179
],
170180
},
171181
],

docs/.vitepress/theme/components/IntegrationTabs.vue

Lines changed: 99 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,18 @@ const codeBlocks = {
1414
vitepress: {
1515
step1: {
1616
lang: 'bash',
17-
raw: 'npm install heroshot',
18-
html: '<span class="hl-cmd">npm</span> install heroshot',
17+
raw: 'npm install heroshot\nheroshot',
18+
html: '<span class="hl-cmd">npm</span> install heroshot\nheroshot',
1919
},
2020
step2: {
2121
lang: 'ts',
22-
raw: `// .vitepress/config.ts
23-
import { heroshot } from 'heroshot/plugins/vite';
22+
file: '.vitepress/config.ts',
23+
raw: `import { heroshot } from 'heroshot/plugins/vite';
2424
2525
export default defineConfig({
2626
vite: { plugins: [heroshot()] }
2727
});`,
28-
html: `<span class="hl-comment">// .vitepress/config.ts</span>
29-
<span class="hl-keyword">import</span> { heroshot } <span class="hl-keyword">from</span> <span class="hl-string">'heroshot/plugins/vite'</span>;
28+
html: `<span class="hl-keyword">import</span> { heroshot } <span class="hl-keyword">from</span> <span class="hl-string">'heroshot/plugins/vite'</span>;
3029
3130
<span class="hl-keyword">export default</span> <span class="hl-fn">defineConfig</span>({
3231
vite: { plugins: [<span class="hl-fn">heroshot</span>()] }
@@ -52,17 +51,16 @@ import { Heroshot } from 'heroshot/vue';
5251
docusaurus: {
5352
step1: {
5453
lang: 'bash',
55-
raw: 'npm install heroshot',
56-
html: '<span class="hl-cmd">npm</span> install heroshot',
54+
raw: 'npm install heroshot\nheroshot',
55+
html: '<span class="hl-cmd">npm</span> install heroshot\nheroshot',
5756
},
5857
step2: {
5958
lang: 'ts',
60-
raw: `// docusaurus.config.ts
61-
plugins: [
59+
file: 'docusaurus.config.ts',
60+
raw: `plugins: [
6261
['heroshot/plugins/docusaurus', {}]
6362
]`,
64-
html: `<span class="hl-comment">// docusaurus.config.ts</span>
65-
plugins: [
63+
html: `plugins: [
6664
[<span class="hl-string">'heroshot/plugins/docusaurus'</span>, {}]
6765
]`,
6866
},
@@ -79,17 +77,16 @@ plugins: [
7977
mkdocs: {
8078
step1: {
8179
lang: 'bash',
82-
raw: 'pip install heroshot',
83-
html: '<span class="hl-cmd">pip</span> install heroshot',
80+
raw: 'npm install heroshot\nheroshot',
81+
html: '<span class="hl-cmd">npm</span> install heroshot\nheroshot',
8482
},
8583
step2: {
8684
lang: 'yaml',
87-
raw: `# mkdocs.yml
88-
plugins:
85+
file: 'mkdocs.yml',
86+
raw: `plugins:
8987
- macros:
9088
modules: [heroshot]`,
91-
html: `<span class="hl-comment"># mkdocs.yml</span>
92-
<span class="hl-attr">plugins</span>:
89+
html: `<span class="hl-attr">plugins</span>:
9390
- <span class="hl-attr">macros</span>:
9491
<span class="hl-attr">modules</span>: [heroshot]`,
9592
},
@@ -126,7 +123,7 @@ function copyCode(code: string, event: MouseEvent) {
126123
<!-- VitePress -->
127124
<div v-show="activeTab === 'vitepress'" class="tab-panel">
128125
<div class="code-section">
129-
<p class="code-label">1. Install the package</p>
126+
<p class="code-label" data-step="1">Install</p>
130127
<div class="code-block">
131128
<div class="code-header">
132129
<span class="lang">{{ codeBlocks.vitepress.step1.lang }}</span>
@@ -140,10 +137,10 @@ function copyCode(code: string, event: MouseEvent) {
140137
</div>
141138
</div>
142139
<div class="code-section">
143-
<p class="code-label">2. Add the Vite plugin</p>
140+
<p class="code-label" data-step="2">Configure</p>
144141
<div class="code-block">
145142
<div class="code-header">
146-
<span class="lang">{{ codeBlocks.vitepress.step2.lang }}</span>
143+
<span class="file">{{ codeBlocks.vitepress.step2.file }}</span>
147144
<button
148145
class="copy"
149146
title="Copy Code"
@@ -154,7 +151,7 @@ function copyCode(code: string, event: MouseEvent) {
154151
</div>
155152
</div>
156153
<div class="code-section">
157-
<p class="code-label">3. Use the component</p>
154+
<p class="code-label" data-step="3">Use</p>
158155
<div class="code-block">
159156
<div class="code-header">
160157
<span class="lang">{{ codeBlocks.vitepress.step3.lang }}</span>
@@ -173,7 +170,7 @@ function copyCode(code: string, event: MouseEvent) {
173170
<!-- Docusaurus -->
174171
<div v-show="activeTab === 'docusaurus'" class="tab-panel">
175172
<div class="code-section">
176-
<p class="code-label">1. Install the package</p>
173+
<p class="code-label" data-step="1">Install</p>
177174
<div class="code-block">
178175
<div class="code-header">
179176
<span class="lang">{{ codeBlocks.docusaurus.step1.lang }}</span>
@@ -187,10 +184,10 @@ function copyCode(code: string, event: MouseEvent) {
187184
</div>
188185
</div>
189186
<div class="code-section">
190-
<p class="code-label">2. Add the plugin</p>
187+
<p class="code-label" data-step="2">Configure</p>
191188
<div class="code-block">
192189
<div class="code-header">
193-
<span class="lang">{{ codeBlocks.docusaurus.step2.lang }}</span>
190+
<span class="file">{{ codeBlocks.docusaurus.step2.file }}</span>
194191
<button
195192
class="copy"
196193
title="Copy Code"
@@ -201,7 +198,7 @@ function copyCode(code: string, event: MouseEvent) {
201198
</div>
202199
</div>
203200
<div class="code-section">
204-
<p class="code-label">3. Use the component</p>
201+
<p class="code-label" data-step="3">Use</p>
205202
<div class="code-block">
206203
<div class="code-header">
207204
<span class="lang">{{ codeBlocks.docusaurus.step3.lang }}</span>
@@ -220,7 +217,7 @@ function copyCode(code: string, event: MouseEvent) {
220217
<!-- MkDocs -->
221218
<div v-show="activeTab === 'mkdocs'" class="tab-panel">
222219
<div class="code-section">
223-
<p class="code-label">1. Install the package</p>
220+
<p class="code-label" data-step="1">Install</p>
224221
<div class="code-block">
225222
<div class="code-header">
226223
<span class="lang">{{ codeBlocks.mkdocs.step1.lang }}</span>
@@ -234,10 +231,10 @@ function copyCode(code: string, event: MouseEvent) {
234231
</div>
235232
</div>
236233
<div class="code-section">
237-
<p class="code-label">2. Add the macro module</p>
234+
<p class="code-label" data-step="2">Configure</p>
238235
<div class="code-block">
239236
<div class="code-header">
240-
<span class="lang">{{ codeBlocks.mkdocs.step2.lang }}</span>
237+
<span class="file">{{ codeBlocks.mkdocs.step2.file }}</span>
241238
<button
242239
class="copy"
243240
title="Copy Code"
@@ -248,7 +245,7 @@ function copyCode(code: string, event: MouseEvent) {
248245
</div>
249246
</div>
250247
<div class="code-section">
251-
<p class="code-label">3. Use the macro</p>
248+
<p class="code-label" data-step="3">Use</p>
252249
<div class="code-block">
253250
<div class="code-header">
254251
<span class="lang">{{ codeBlocks.mkdocs.step3.lang }}</span>
@@ -307,16 +304,23 @@ function copyCode(code: string, event: MouseEvent) {
307304
}
308305
309306
.tabs-content {
307+
position: relative;
310308
background: var(--vp-c-bg);
311309
border-radius: 12px;
312310
padding: 24px;
313311
border: 1px solid var(--vp-c-divider);
314312
}
315313
316314
.tab-panel {
317-
display: flex;
318-
flex-direction: column;
319-
gap: 16px;
315+
display: grid;
316+
grid-template-columns: repeat(3, 1fr);
317+
gap: 20px;
318+
}
319+
320+
@media (max-width: 900px) {
321+
.tab-panel {
322+
grid-template-columns: 1fr;
323+
}
320324
}
321325
322326
.code-section {
@@ -325,13 +329,56 @@ function copyCode(code: string, event: MouseEvent) {
325329
gap: 8px;
326330
}
327331
332+
.code-section .code-block {
333+
flex: 1;
334+
display: flex;
335+
flex-direction: column;
336+
}
337+
338+
.code-section .code-block pre {
339+
flex: 1;
340+
}
341+
328342
.code-label {
329-
font-size: 14px;
343+
display: flex;
344+
align-items: center;
345+
gap: 12px;
346+
font-size: 15px;
330347
font-weight: 600;
331348
color: var(--vp-c-text-1);
332349
margin: 0;
333350
}
334351
352+
.code-label::before {
353+
content: '';
354+
display: flex;
355+
align-items: center;
356+
justify-content: center;
357+
width: 28px;
358+
height: 28px;
359+
background: var(--vp-c-brand-soft);
360+
border-radius: 8px;
361+
flex-shrink: 0;
362+
background-repeat: no-repeat;
363+
background-position: center;
364+
background-size: 16px;
365+
}
366+
367+
/* Install icon - download arrow */
368+
.code-label[data-step='1']::before {
369+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ea580c' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4'/%3E%3C/svg%3E");
370+
}
371+
372+
/* Configure icon - gear */
373+
.code-label[data-step='2']::before {
374+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ea580c' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
375+
}
376+
377+
/* Use icon - code brackets */
378+
.code-label[data-step='3']::before {
379+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%23ea580c' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4'/%3E%3C/svg%3E");
380+
}
381+
335382
.code-block {
336383
position: relative;
337384
border-radius: 8px;
@@ -358,6 +405,12 @@ function copyCode(code: string, event: MouseEvent) {
358405
text-transform: uppercase;
359406
}
360407
408+
.code-header .file {
409+
font-size: 12px;
410+
font-weight: 500;
411+
color: var(--vp-c-text-3);
412+
}
413+
361414
.code-header .copy {
362415
width: 24px;
363416
height: 24px;
@@ -441,10 +494,9 @@ function copyCode(code: string, event: MouseEvent) {
441494
}
442495
443496
.learn-more {
444-
display: inline-flex;
445-
align-items: center;
446-
gap: 4px;
447-
margin-top: 8px;
497+
position: absolute;
498+
top: 24px;
499+
right: 24px;
448500
font-size: 14px;
449501
font-weight: 500;
450502
color: var(--vp-c-brand-1);
@@ -459,6 +511,15 @@ function copyCode(code: string, event: MouseEvent) {
459511
content: ' \2192';
460512
}
461513
514+
@media (max-width: 900px) {
515+
.learn-more {
516+
position: static;
517+
display: block;
518+
margin-top: 16px;
519+
text-align: right;
520+
}
521+
}
522+
462523
@media (max-width: 640px) {
463524
.tabs-header {
464525
gap: 6px;

docs/.vitepress/theme/showcase.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
.integrations-section {
132132
max-width: 1152px;
133133
margin: 48px auto 64px;
134-
padding: 32px 48px 48px;
134+
padding: 32px 0 48px;
135135
}
136136

137137
.integrations-section h2 {

docs/docs/cli.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,15 @@ Opens the visual picker - a browser where you point and click to define screensh
146146
heroshot config [options]
147147
```
148148

149+
| Option | Description |
150+
| --------- | -------------------------------------- |
151+
| `--reset` | Clear existing session and start fresh |
152+
| `--only` | Only run config, skip sync afterwards |
153+
154+
#### Color scheme preview
155+
149156
| Option | Description |
150157
| --------- | ---------------------------------------------- |
151-
| `--reset` | Clear existing session and start fresh |
152-
| `--only` | Only run config, skip sync afterwards |
153158
| `--light` | Force light mode (prefers-color-scheme: light) |
154159
| `--dark` | Force dark mode (prefers-color-scheme: dark) |
155160

@@ -159,7 +164,6 @@ By default, heroshot captures **both** light and dark variants of each screensho
159164
The capture behavior is controlled by `browser.colorScheme` in your config:
160165

161166
- **undefined** (default): Captures both `-light` and `-dark` variants
162-
- **auto**: Uses browser's color scheme preference
163167
- **light** / **dark**: Captures single variant only
164168
:::
165169

0 commit comments

Comments
 (0)