├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── stale.yml └── workflows │ ├── autofix.yml │ ├── cr.yml │ ├── release.yml │ ├── smoke.yml │ └── test.yml ├── .gitignore ├── .gitpod.yml ├── .npmrc ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── assets ├── assets │ └── arrow-bottom-left.svg ├── demo-cover.png ├── favicon.png ├── logo-circle.png ├── logo-for-vscode.png ├── logo-mono-dark.svg ├── logo-mono.svg ├── logo-square.png ├── logo-title.png ├── logo-triangle.png ├── logo.png ├── logo.svg ├── og-image.png ├── screenshots │ ├── cover.png │ ├── covers.png │ ├── integrated-editor.png │ ├── navbar.png │ ├── presenter-mode.png │ ├── recording.png │ └── slides-overview.png ├── showcases │ └── composable-vue.png └── themes │ ├── default-1.png │ ├── default-2.png │ ├── default.png │ ├── placeholder.png │ └── seriph.png ├── cypress.config.ts ├── cypress ├── e2e │ └── examples │ │ ├── basic.spec.ts │ │ └── smoke.spec.ts ├── fixtures │ └── basic │ │ ├── components │ │ ├── DecorateWithLi.vue │ │ ├── WrapInClicks.vue │ │ ├── WrapInClicksDecorate.vue │ │ └── WrapInComponentInClicks.vue │ │ ├── global.vue │ │ ├── package.json │ │ ├── slides.md │ │ ├── sub │ │ ├── page1.md │ │ └── page2.md │ │ └── vite.config.ts └── tsconfig.json ├── demo ├── README.md ├── composable-vue │ ├── components │ │ ├── Connections.vue │ │ ├── DarkToggle.vue │ │ ├── Marker.vue │ │ ├── MarkerCore.vue │ │ ├── MarkerPattern.vue │ │ ├── MarkerTips.vue │ │ ├── NumBox.vue │ │ └── VueUse.vue │ ├── index.html │ ├── package.json │ ├── setup │ │ └── monaco.ts │ └── slides.md ├── starter │ ├── README.md │ ├── components │ │ └── Counter.vue │ ├── package.json │ ├── pages │ │ └── imported-slides.md │ ├── slides.md │ ├── snippets │ │ └── external.ts │ ├── style.css │ └── vite.config.ts └── vue-runner │ ├── package.json │ ├── setup │ ├── code-runners.ts │ └── shiki.ts │ └── slides.md ├── docs ├── .gitignore ├── .npmrc ├── .vitepress │ ├── addons.ts │ ├── config.ts │ ├── customizations.ts │ ├── pages.ts │ ├── showcases.ts │ ├── sidebar-gen.ts │ ├── theme │ │ ├── components │ │ │ ├── AddonGallery.vue │ │ │ ├── AddonInfo.vue │ │ │ ├── Demo.vue │ │ │ ├── DemoEditor.vue │ │ │ ├── DemoSlide.vue │ │ │ ├── Environment.vue │ │ │ ├── FeatureTag.vue │ │ │ ├── FeaturesAnimation.vue │ │ │ ├── FeaturesAnimationInner.vue │ │ │ ├── FeaturesOverview.vue │ │ │ ├── LandingPage.vue │ │ │ ├── Layout.vue │ │ │ ├── LinkCard.vue │ │ │ ├── LinkInline.vue │ │ │ ├── SeeAlso.vue │ │ │ ├── ShowCaseInfo.vue │ │ │ ├── ShowCases.vue │ │ │ ├── SlideContainer.vue │ │ │ ├── TheTweet.vue │ │ │ ├── ThemeGallery.vue │ │ │ └── ThemeInfo.vue │ │ ├── composables │ │ │ └── dark.ts │ │ ├── index.ts │ │ └── styles │ │ │ ├── custom.css │ │ │ ├── demo.css │ │ │ └── vars.css │ ├── themes.ts │ └── utils.ts ├── README.md ├── builtin │ ├── cli.md │ ├── components.md │ └── layouts.md ├── components.d.ts ├── custom │ ├── config-code-runners.md │ ├── config-context-menu.md │ ├── config-fonts.md │ ├── config-highlighter.md │ ├── config-katex.md │ ├── config-mermaid.md │ ├── config-monaco.md │ ├── config-parser.md │ ├── config-routes.md │ ├── config-shortcuts.md │ ├── config-transformers.md │ ├── config-unocss.md │ ├── config-vite.md │ ├── config-vue.md │ ├── directory-structure.md │ └── index.md ├── features │ ├── block-frontmatter.md │ ├── build-with-pdf.md │ ├── bundle-remote-assets.md │ ├── canvas-size.md │ ├── click-marker.md │ ├── code-block-line-numbers.md │ ├── code-block-max-height.md │ ├── code-groups.md │ ├── direction-variant.md │ ├── draggable.md │ ├── drawing.md │ ├── eject-theme.md │ ├── frontmatter-merging.md │ ├── global-layers.md │ ├── icons.md │ ├── import-snippet.md │ ├── importing-slides.md │ ├── index.data.ts │ ├── index.md │ ├── latex.md │ ├── line-highlighting.md │ ├── mdc.md │ ├── mermaid.md │ ├── monaco-editor.md │ ├── monaco-run.md │ ├── monaco-write.md │ ├── plantuml.md │ ├── prettier-plugin.md │ ├── recording.md │ ├── remote-access.md │ ├── rough-marker.md │ ├── shiki-magic-move.md │ ├── side-editor.md │ ├── slide-hook.md │ ├── slide-scope-style.md │ ├── slot-sugar.md │ ├── transform-component.md │ ├── twoslash.md │ ├── vscode-extension.md │ └── zoom-slide.md ├── guide │ ├── animations.md │ ├── component.md │ ├── exporting.md │ ├── faq.md │ ├── global-context.md │ ├── hosting.md │ ├── index.md │ ├── layout.md │ ├── syntax.md │ ├── theme-addon.md │ ├── ui.md │ ├── why.md │ ├── write-addon.md │ ├── write-layout.md │ └── write-theme.md ├── index.md ├── netlify.toml ├── package.json ├── public │ ├── assets │ │ ├── arrow-bottom-left.svg │ │ └── code-groups-demo.png │ ├── demo-cover.png │ ├── favicon.png │ ├── logo-circle.png │ ├── logo-for-vscode.png │ ├── logo-square.png │ ├── logo-title.png │ ├── logo-triangle.png │ ├── logo.png │ ├── logo.svg │ ├── og-image.png │ ├── screenshots │ │ ├── cover.png │ │ ├── covers.png │ │ ├── integrated-editor.png │ │ ├── navbar.png │ │ ├── presenter-mode.png │ │ ├── recording.png │ │ └── slides-overview.png │ ├── showcases │ │ └── composable-vue.png │ └── theme-placeholder.png ├── resources │ ├── addon-gallery.md │ ├── covers.md │ ├── learning.md │ ├── showcases.md │ └── theme-gallery.md ├── tsconfig.json ├── uno.config.ts └── vite.config.ts ├── eslint.config.js ├── netlify.toml ├── package.json ├── packages ├── client │ ├── App.vue │ ├── README.md │ ├── assets │ │ ├── favicon.png │ │ ├── logo-title-horizontal.png │ │ ├── logo.png │ │ └── logo.svg │ ├── builtin │ │ ├── Arrow.vue │ │ ├── AutoFitText.vue │ │ ├── CodeBlockWrapper.vue │ │ ├── CodeGroup.vue │ │ ├── KaTexBlockWrapper.vue │ │ ├── LightOrDark.vue │ │ ├── Link.vue │ │ ├── Mermaid.vue │ │ ├── Monaco.vue │ │ ├── PlantUml.vue │ │ ├── PoweredBySlidev.vue │ │ ├── RenderWhen.vue │ │ ├── ShikiMagicMove.vue │ │ ├── SlideCurrentNo.vue │ │ ├── SlidesTotal.vue │ │ ├── SlidevVideo.vue │ │ ├── Toc.vue │ │ ├── TocList.vue │ │ ├── Transform.vue │ │ ├── Tweet.vue │ │ ├── VAfter.ts │ │ ├── VClick.ts │ │ ├── VClickGap.vue │ │ ├── VClicks.ts │ │ ├── VDrag.vue │ │ ├── VDragArrow.vue │ │ ├── VSwitch.ts │ │ └── Youtube.vue │ ├── composables │ │ ├── useClicks.ts │ │ ├── useDarkMode.ts │ │ ├── useDragElements.ts │ │ ├── useDrawings.ts │ │ ├── useEmbeddedCtrl.ts │ │ ├── useHideCursorIdle.ts │ │ ├── useNav.ts │ │ ├── usePrintStyles.ts │ │ ├── useSlideBounds.ts │ │ ├── useSlideInfo.ts │ │ ├── useSwipeControls.ts │ │ ├── useTimer.ts │ │ ├── useTocTree.ts │ │ ├── useViewTransition.ts │ │ └── useWakeLock.ts │ ├── constants.ts │ ├── context.ts │ ├── env.ts │ ├── index.html │ ├── index.ts │ ├── internals │ │ ├── Badge.vue │ │ ├── ClicksSlider.vue │ │ ├── CodeRunner.vue │ │ ├── ContextMenu.vue │ │ ├── Controls.vue │ │ ├── DevicesSelectors.vue │ │ ├── DomElement.vue │ │ ├── DragControl.vue │ │ ├── Draggable.vue │ │ ├── DrawingControls.vue │ │ ├── DrawingLayer.vue │ │ ├── DrawingPreview.vue │ │ ├── ExportPdfTip.vue │ │ ├── FormCheckbox.vue │ │ ├── FormItem.vue │ │ ├── FormSlider.vue │ │ ├── Goto.vue │ │ ├── IconButton.vue │ │ ├── InfoDialog.vue │ │ ├── MenuButton.vue │ │ ├── Modal.vue │ │ ├── NavControls.vue │ │ ├── NoteDisplay.vue │ │ ├── NoteEditable.vue │ │ ├── NoteStatic.vue │ │ ├── PresenterMouse.vue │ │ ├── PrintContainer.vue │ │ ├── PrintSlide.vue │ │ ├── PrintSlideClick.vue │ │ ├── QuickOverview.vue │ │ ├── README.md │ │ ├── RecordingControls.vue │ │ ├── RecordingDialog.vue │ │ ├── ScreenCaptureMirror.vue │ │ ├── SegmentControl.vue │ │ ├── SelectList.vue │ │ ├── Settings.vue │ │ ├── ShadowRoot.vue │ │ ├── ShikiEditor.vue │ │ ├── SideEditor.vue │ │ ├── SlideContainer.vue │ │ ├── SlideLoading.vue │ │ ├── SlideWrapper.vue │ │ ├── SlidesShow.vue │ │ ├── SyncControls.vue │ │ ├── TitleIcon.vue │ │ ├── VerticalDivider.vue │ │ ├── WebCamera.vue │ │ └── types.ts │ ├── layoutHelper.ts │ ├── layouts │ │ ├── 404.vue │ │ ├── center.vue │ │ ├── cover.vue │ │ ├── default.vue │ │ ├── end.vue │ │ ├── error.vue │ │ ├── fact.vue │ │ ├── full.vue │ │ ├── iframe-left.vue │ │ ├── iframe-right.vue │ │ ├── iframe.vue │ │ ├── image-left.vue │ │ ├── image-right.vue │ │ ├── image.vue │ │ ├── intro.vue │ │ ├── none.vue │ │ ├── quote.vue │ │ ├── section.vue │ │ ├── statement.vue │ │ ├── two-cols-header.vue │ │ └── two-cols.vue │ ├── logic │ │ ├── color.ts │ │ ├── contextMenu.ts │ │ ├── dark.ts │ │ ├── overview.ts │ │ ├── recording.ts │ │ ├── route.ts │ │ ├── screenshot.ts │ │ ├── shortcuts.ts │ │ ├── slides.ts │ │ ├── snapshot.ts │ │ ├── transition.ts │ │ └── utils.ts │ ├── main.ts │ ├── modules │ │ ├── context.ts │ │ ├── mermaid.ts │ │ ├── v-click.ts │ │ ├── v-drag.ts │ │ ├── v-mark.ts │ │ └── v-motion.ts │ ├── package.json │ ├── pages │ │ ├── 404.vue │ │ ├── entry.vue │ │ ├── export.vue │ │ ├── notes.vue │ │ ├── overview.vue │ │ ├── play.vue │ │ ├── presenter.vue │ │ ├── presenter │ │ │ └── print.vue │ │ └── print.vue │ ├── setup │ │ ├── code-runners.ts │ │ ├── context-menu.ts │ │ ├── main.ts │ │ ├── mermaid.ts │ │ ├── monaco.ts │ │ ├── root.ts │ │ ├── routes.ts │ │ └── shortcuts.ts │ ├── shim-vue.d.ts │ ├── shim.d.ts │ ├── state │ │ ├── drawings.ts │ │ ├── index.ts │ │ ├── shared.ts │ │ ├── snapshot.ts │ │ ├── storage.ts │ │ └── syncState.ts │ ├── styles │ │ ├── code.css │ │ ├── index.css │ │ ├── katex.css │ │ ├── layouts-base.css │ │ ├── shiki-twoslash.css │ │ ├── transitions.css │ │ └── vars.css │ ├── uno.config.ts │ └── utils.ts ├── create-app │ ├── README.md │ ├── build.mjs │ ├── index.mjs │ ├── package.json │ └── template │ │ ├── README.md │ │ ├── _gitignore │ │ ├── _npmrc │ │ ├── components │ │ └── Counter.vue │ │ ├── netlify.toml │ │ ├── package.json │ │ └── vercel.json ├── create-theme │ ├── README.md │ ├── index.mjs │ ├── package.json │ └── template │ │ ├── .vscode │ │ └── extensions.json │ │ ├── README.md │ │ ├── _gitignore │ │ ├── _npmrc │ │ ├── components │ │ └── .gitkeep │ │ ├── example.md │ │ ├── layouts │ │ ├── cover.vue │ │ └── intro.vue │ │ ├── package.json │ │ ├── setup │ │ └── shiki.ts │ │ └── styles │ │ ├── index.ts │ │ └── layout.css ├── parser │ ├── README.md │ ├── package.json │ ├── src │ │ ├── config.ts │ │ ├── core.ts │ │ ├── fs.ts │ │ ├── index.ts │ │ └── utils.ts │ └── tsdown.config.ts ├── slidev │ ├── LICENSE │ ├── bin │ │ └── slidev.mjs │ ├── node │ │ ├── cli.ts │ │ ├── commands │ │ │ ├── build.ts │ │ │ ├── export.ts │ │ │ ├── serve.ts │ │ │ └── shared.ts │ │ ├── index.ts │ │ ├── integrations │ │ │ ├── addons.ts │ │ │ ├── drawings.ts │ │ │ ├── snapshots.ts │ │ │ └── themes.ts │ │ ├── options.ts │ │ ├── parser.ts │ │ ├── resolver.ts │ │ ├── setups │ │ │ ├── indexHtml.ts │ │ │ ├── katex.ts │ │ │ ├── load.ts │ │ │ ├── preparser.ts │ │ │ ├── shiki.ts │ │ │ ├── transformers.ts │ │ │ └── unocss.ts │ │ ├── syntax │ │ │ ├── markdown-it │ │ │ │ ├── index.ts │ │ │ │ ├── markdown-it-escape-code.ts │ │ │ │ ├── markdown-it-katex.ts │ │ │ │ ├── markdown-it-link.ts │ │ │ │ ├── markdown-it-shiki.ts │ │ │ │ └── markdown-it-v-drag.ts │ │ │ └── transform │ │ │ │ ├── code-wrapper.ts │ │ │ │ ├── in-page-css.ts │ │ │ │ ├── index.ts │ │ │ │ ├── katex-wrapper.ts │ │ │ │ ├── magic-move.ts │ │ │ │ ├── mermaid.ts │ │ │ │ ├── monaco.ts │ │ │ │ ├── plant-uml.ts │ │ │ │ ├── slot-sugar.ts │ │ │ │ ├── snippet.ts │ │ │ │ └── utils.ts │ │ ├── utils.ts │ │ ├── virtual │ │ │ ├── configs.ts │ │ │ ├── deprecated.ts │ │ │ ├── global-layers.ts │ │ │ ├── index.ts │ │ │ ├── layouts.ts │ │ │ ├── monaco-deps.ts │ │ │ ├── monaco-types.ts │ │ │ ├── nav-controls.ts │ │ │ ├── setups.ts │ │ │ ├── shiki.ts │ │ │ ├── slides.ts │ │ │ ├── styles.ts │ │ │ ├── titles.ts │ │ │ └── types.ts │ │ └── vite │ │ │ ├── common.ts │ │ │ ├── compilerFlagsVue.ts │ │ │ ├── components.ts │ │ │ ├── contextInjection.ts │ │ │ ├── extendConfig.ts │ │ │ ├── hmrPatch.ts │ │ │ ├── icons.ts │ │ │ ├── index.ts │ │ │ ├── inspect.ts │ │ │ ├── layoutWrapper.ts │ │ │ ├── loaders.ts │ │ │ ├── markdown.ts │ │ │ ├── monacoTypes.ts │ │ │ ├── monacoWrite.ts │ │ │ ├── remoteAssets.ts │ │ │ ├── serverRef.ts │ │ │ ├── staticCopy.ts │ │ │ ├── unocss.ts │ │ │ ├── userPlugins.ts │ │ │ └── vue.ts │ ├── package.json │ ├── template.md │ ├── tsconfig.json │ └── tsdown.config.ts ├── types │ ├── README.md │ ├── client.d.ts │ ├── index.d.ts │ ├── package.json │ ├── src │ │ ├── builtin-layouts.ts │ │ ├── cli.ts │ │ ├── clicks.ts │ │ ├── code-runner.ts │ │ ├── config.ts │ │ ├── context-menu.ts │ │ ├── env.ts │ │ ├── frontmatter.ts │ │ ├── hmr.ts │ │ ├── index.ts │ │ ├── options.ts │ │ ├── setups.ts │ │ ├── toc.ts │ │ ├── transform.ts │ │ ├── types.ts │ │ └── vite.ts │ └── tsdown.config.ts └── vscode │ ├── .vscodeignore │ ├── LICENSE │ ├── README.md │ ├── language-server │ ├── bin.ts │ ├── import-meta-url.ts │ ├── index.ts │ ├── languagePlugin.ts │ ├── prettierService.ts │ ├── protocol.ts │ └── volar-service-yaml.ts │ ├── package.json │ ├── schema │ ├── frontmatter.json │ └── headmatter.json │ ├── scripts │ ├── publish.ts │ └── schema.ts │ ├── src │ ├── commands.ts │ ├── composables │ │ ├── useDevServer.ts │ │ ├── useEditingSlideSource.ts │ │ ├── useFocusedSlideNo.ts │ │ ├── usePreviewState.ts │ │ ├── useProjectFromDoc.ts │ │ └── useServerDetector.ts │ ├── configs.ts │ ├── html │ │ ├── error.ts │ │ └── ready.ts │ ├── index.ts │ ├── languageClient.ts │ ├── projects.ts │ ├── utils │ │ ├── findPossibleEntries.ts │ │ ├── findShallowestPath.ts │ │ ├── getFirstDisplayedChild.ts │ │ ├── getSlideNo.ts │ │ ├── getSlidesTitle.ts │ │ └── toRelativePath.ts │ └── views │ │ ├── annotations.ts │ │ ├── foldings.ts │ │ ├── logger.ts │ │ ├── previewWebview.ts │ │ ├── projectsTree.ts │ │ ├── serverTerminal.ts │ │ └── slidesTree.ts │ ├── syntaxes │ ├── .vscode │ │ └── settings.json │ ├── codeblock-patch.ts │ ├── codeblock.json │ ├── language-configuration.json │ ├── markdown.json │ ├── slidev.example.md │ ├── slidev.tmLanguage.json │ └── tsconfig.json │ ├── tsconfig.json │ └── tsdown.config.ts ├── patches └── @hedgedoc__markdown-it-plugins@2.1.4.patch ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── demo.mjs ├── gen-layouts.ts ├── pack.mjs ├── publish.mjs ├── remove-overridden-deps.mjs └── update-versions.mjs ├── shim.d.ts ├── taze.config.ts ├── test ├── __snapshots__ │ ├── parser.test.ts.snap │ ├── transform-all.test.ts.snap │ ├── transform.test.ts.snap │ └── utils.test.ts.snap ├── _tutils.ts ├── fixtures │ ├── markdown │ │ ├── frontmatter.md │ │ ├── mdc.md │ │ ├── minimal.md │ │ ├── multi-entries.md │ │ └── sub │ │ │ ├── nested1-4.md │ │ │ ├── page1.md │ │ │ ├── page2.md │ │ │ └── pages3-4.md │ └── snippets │ │ └── snippet.ts ├── parser.test.ts ├── transform-all.test.ts ├── transform-magic-move.test.ts ├── transform.test.ts └── utils.test.ts ├── tsconfig.json └── tsdown.config.ts /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: antfu 2 | opencollective: slidev 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41E Bug report" 3 | about: Create a report to help us improve 4 | title: '' 5 | type: Bug 6 | labels: ['pending triage'] 7 | assignees: '' 8 | --- 9 | 10 | 11 | 12 | 13 | 14 | **Describe the bug** 15 | 16 | A clear and concise description of what the bug is. 17 | 18 | **Minimal reproduction** 19 | 20 | Steps to reproduce the behavior: 21 | 22 | 1. Go to '...' 23 | 2. Click on '....' 24 | 3. Scroll down to '....' 25 | 4. See the error 26 | 27 | You can use https://sli.dev/new to create a new project to reproduce the issue. 28 | 29 | **Environment** 30 | 31 | - Slidev version: 32 | - Browser: 33 | - OS: 34 | 35 | If you are using Slidev globally (i.e. `npx slidev` or `npm i -g slidev`), please try to reproduce the issue in a local project (i.e. `npm create slidev@latest`). 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Questions & Discussions 3 | url: https://github.com/slidevjs/slidev/discussions 4 | about: Use GitHub discussions for message-board style questions and discussions. 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U00002728 Feature request" 3 | about: Suggest an idea for this project 4 | title: '' 5 | type: Feature 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | daysUntilStale: 60 2 | daysUntilClose: 7 3 | exemptLabels: 4 | - pinned 5 | - security 6 | - no-stale 7 | - no stale 8 | - pr welcome 9 | - help wanted 10 | staleLabel: stale 11 | markComment: > 12 | This issue has been automatically marked as stale because it has not had 13 | recent activity. It will be closed if no further activity occurs. Thank you 14 | for your contributions. 15 | closeComment: false 16 | -------------------------------------------------------------------------------- /.github/workflows/autofix.yml: -------------------------------------------------------------------------------- 1 | name: autofix.ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | autofix: 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 10 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - name: Use Node.js lts/* 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: lts/* 25 | 26 | - name: Setup 27 | run: npm i -g @antfu/ni 28 | 29 | - name: Install 30 | run: nci 31 | env: 32 | CYPRESS_INSTALL_BINARY: 0 33 | 34 | - name: Lint 35 | run: nr lint --fix 36 | 37 | - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a 38 | -------------------------------------------------------------------------------- /.github/workflows/cr.yml: -------------------------------------------------------------------------------- 1 | # Continuous Releases provided by https://pkg.pr.new 2 | name: CR (Continuous Releases) 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | cr: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@v2 12 | 13 | - uses: actions/setup-node@v4 14 | with: 15 | node-version: lts/* 16 | 17 | - run: npm i -g @antfu/ni 18 | - run: nci 19 | 20 | - name: Build 21 | run: nr build 22 | 23 | - run: nlx pkg-pr-new publish './packages/create-app' './packages/client' './packages/create-theme' './packages/parser' './packages/slidev' './packages/types' --pnpm 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | release: 10 | permissions: 11 | id-token: write 12 | contents: write 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version: lts/* 21 | registry-url: https://registry.npmjs.org/ 22 | - run: npx changelogithub 23 | env: 24 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 25 | - run: npm i -g @antfu/ni 26 | - run: nci 27 | - run: nr ci:publish 28 | env: 29 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 30 | NPM_CONFIG_PROVENANCE: true 31 | 32 | - name: Publish to VSCE & OVSX 33 | run: npm run publish 34 | working-directory: ./packages/vscode 35 | env: 36 | VSCE_TOKEN: ${{secrets.VSCE_TOKEN}} 37 | OVSX_TOKEN: ${{secrets.OVSX_TOKEN}} 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .eslintcache 3 | .idea 4 | .nuxt 5 | .output 6 | .slidev 7 | .vite-inspect 8 | *-export 9 | *.local 10 | *.pdf 11 | assets/demo 12 | components.d.ts 13 | composable-vue-cn 14 | dist 15 | dist-ssr 16 | docs/.vitepress/@slidev 17 | docs/.vitepress/cache 18 | node_modules 19 | cypress/downloads 20 | packages/create-app/template/pages 21 | packages/create-app/template/slides.md 22 | packages/create-app/template/snippets 23 | packages/slidev/README.md 24 | packages/vscode/syntaxes/codeblock-patch.json 25 | slides-export.md 26 | *slides-export.pptx 27 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | # List the start up tasks. Learn more https://www.gitpod.io/docs/config-start-tasks/ 2 | tasks: 3 | - before: npm i -g pnpm 4 | init: | 5 | pnpm install 6 | pnpm build 7 | command: pnpm demo:dev 8 | 9 | # List the ports to expose. Learn more https://www.gitpod.io/docs/config-ports/ 10 | ports: 11 | - port: 3030 12 | onOpen: open-preview 13 | 14 | # List the VS Code extensions to install. Learn more https://www.gitpod.io/docs/vscode-extensions/ 15 | vscode: 16 | extensions: 17 | - antfu.vite 18 | - Vue.volar 19 | - antfu.iconify 20 | - dbaeumer.vscode-eslint 21 | - csstools.postcss 22 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | ignore-workspace-root-check=true 3 | strict-peer-dependencies=false 4 | link-workspace-packages=true 5 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "antfu.vite", 4 | "Vue.volar", 5 | "antfu.iconify", 6 | "dbaeumer.vscode-eslint", 7 | "antfu.unocss", 8 | "csstools.postcss", 9 | "antfu.pnpm-catalog-lens" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Run Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "autoAttachChildProcesses": true, 9 | "args": [ 10 | "--extensionDevelopmentPath=${workspaceFolder}/packages/vscode", 11 | "--folder-uri=${workspaceRoot}/packages/vscode/syntaxes" 12 | ], 13 | "outFiles": [ 14 | "${workspaceFolder}/packages/vscode/dist/**/*.js" 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-PRESENT Anthony Fu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/demo-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/demo-cover.png -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/favicon.png -------------------------------------------------------------------------------- /assets/logo-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/logo-circle.png -------------------------------------------------------------------------------- /assets/logo-for-vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/logo-for-vscode.png -------------------------------------------------------------------------------- /assets/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/logo-square.png -------------------------------------------------------------------------------- /assets/logo-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/logo-title.png -------------------------------------------------------------------------------- /assets/logo-triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/logo-triangle.png -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/logo.png -------------------------------------------------------------------------------- /assets/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/og-image.png -------------------------------------------------------------------------------- /assets/screenshots/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/screenshots/cover.png -------------------------------------------------------------------------------- /assets/screenshots/covers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/screenshots/covers.png -------------------------------------------------------------------------------- /assets/screenshots/integrated-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/screenshots/integrated-editor.png -------------------------------------------------------------------------------- /assets/screenshots/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/screenshots/navbar.png -------------------------------------------------------------------------------- /assets/screenshots/presenter-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/screenshots/presenter-mode.png -------------------------------------------------------------------------------- /assets/screenshots/recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/screenshots/recording.png -------------------------------------------------------------------------------- /assets/screenshots/slides-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/screenshots/slides-overview.png -------------------------------------------------------------------------------- /assets/showcases/composable-vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/showcases/composable-vue.png -------------------------------------------------------------------------------- /assets/themes/default-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/themes/default-1.png -------------------------------------------------------------------------------- /assets/themes/default-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/themes/default-2.png -------------------------------------------------------------------------------- /assets/themes/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/themes/default.png -------------------------------------------------------------------------------- /assets/themes/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/themes/placeholder.png -------------------------------------------------------------------------------- /assets/themes/seriph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/assets/themes/seriph.png -------------------------------------------------------------------------------- /cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'cypress' 2 | 3 | export default defineConfig({ 4 | e2e: { 5 | baseUrl: 'http://localhost:3041', 6 | chromeWebSecurity: false, 7 | specPattern: 'cypress/e2e/**/*.spec.*', 8 | supportFile: false, 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /cypress/e2e/examples/smoke.spec.ts: -------------------------------------------------------------------------------- 1 | context('Smoke test', () => { 2 | async function testAllSlides() { 3 | while (1) { 4 | let oldUrl, newUrl 5 | cy.get('body') 6 | .url() 7 | .then(url => (oldUrl = url)) 8 | .type(`{RightArrow}`) 9 | .wait(1000) 10 | .url() 11 | .then(url => (newUrl = url)) 12 | if (oldUrl === newUrl) 13 | break 14 | } 15 | } 16 | 17 | it('should throw no error in Play mode', async () => { 18 | cy.visit('/').wait(4000) 19 | await testAllSlides() 20 | }) 21 | 22 | it('should throw no error in Presenter mode', async () => { 23 | cy.visit('/presenter').wait(4000) 24 | await testAllSlides() 25 | }) 26 | 27 | it('should throw no error in Overview page', async () => { 28 | cy.visit('/overview').wait(4000) 29 | }) 30 | 31 | it('should throw no error in Entry page', async () => { 32 | cy.visit('/entry').wait(4000) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/components/DecorateWithLi.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/components/WrapInClicks.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/components/WrapInClicksDecorate.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/components/WrapInComponentInClicks.vue: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/global.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "nodemon -w '../../../packages/slidev/dist/*.js' --exec 'slidev --log=info --port=3041'", 5 | "build": "slidev build", 6 | "export": "slidev export" 7 | }, 8 | "devDependencies": { 9 | "@slidev/cli": "workspace:*", 10 | "@slidev/theme-default": "catalog:themes", 11 | "@slidev/theme-seriph": "catalog:themes", 12 | "@slidev/types": "workspace:*", 13 | "nodemon": "catalog:dev" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/sub/page1.md: -------------------------------------------------------------------------------- 1 | # Sub page 1 2 | 3 | $x+2$ 4 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/sub/page2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: cover 3 | --- 4 | 5 | # Sub page 2 6 | 7 | 8 | -------------------------------------------------------------------------------- /cypress/fixtures/basic/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | 3 | export default defineConfig({ 4 | build: { 5 | manifest: true, 6 | minify: false, 7 | }, 8 | }) 9 | -------------------------------------------------------------------------------- /cypress/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["cypress"], 5 | "noEmit": true 6 | }, 7 | "include": [ 8 | "../node_modules/cypress", 9 | "./**/*.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | The best way of understanding Slidev is to try it, with the following command: 2 | 3 | ```bash 4 | npm init slidev 5 | ``` 6 | 7 | Learn more: https://sli.dev 8 | -------------------------------------------------------------------------------- /demo/composable-vue/components/DarkToggle.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /demo/composable-vue/components/Marker.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /demo/composable-vue/components/MarkerCore.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /demo/composable-vue/components/MarkerPattern.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /demo/composable-vue/components/MarkerTips.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /demo/composable-vue/components/VueUse.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /demo/composable-vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /demo/composable-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "nodemon -w '../../packages/slidev/dist/*.mjs' --exec 'slidev --log=info'", 5 | "build": "slidev build", 6 | "export": "slidev export", 7 | "export:clicks": "slidev export --with-clicks" 8 | }, 9 | "devDependencies": { 10 | "@iconify-json/mdi": "catalog:icons", 11 | "@iconify-json/ri": "catalog:icons", 12 | "@slidev/cli": "workspace:*", 13 | "@slidev/theme-default": "catalog:themes", 14 | "@slidev/theme-seriph": "catalog:themes", 15 | "@slidev/types": "workspace:*", 16 | "nodemon": "catalog:dev" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /demo/composable-vue/setup/monaco.ts: -------------------------------------------------------------------------------- 1 | import { defineMonacoSetup } from '@slidev/types' 2 | 3 | export default defineMonacoSetup((monaco) => { 4 | monaco.languages.typescript.typescriptDefaults.addExtraLib( 5 | ` 6 | import { InjectionKey } from 'vue' 7 | export interface UserInfo { id: number; name: string } 8 | export const injectKeyUser: InjectionKey = Symbol() 9 | `, 10 | 'file:///root/context.ts', 11 | ) 12 | }) 13 | -------------------------------------------------------------------------------- /demo/starter/README.md: -------------------------------------------------------------------------------- 1 | See [../../packages/create-app/template/README.md](../../packages/create-app/template/README.md) 2 | -------------------------------------------------------------------------------- /demo/starter/components/Counter.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 38 | -------------------------------------------------------------------------------- /demo/starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slidev-demo", 3 | "private": true, 4 | "scripts": { 5 | "build": "slidev build", 6 | "dev": "nodemon -w '../../packages/slidev/dist/*.mjs' --exec \"slidev ./slides.md --open=false --log=info --inspect\"", 7 | "export": "slidev export", 8 | "export-notes": "slidev export-notes" 9 | }, 10 | "devDependencies": { 11 | "@slidev/cli": "workspace:*", 12 | "@slidev/theme-default": "catalog:themes", 13 | "@slidev/theme-seriph": "catalog:themes", 14 | "nodemon": "catalog:dev", 15 | "vue": "catalog:frontend" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo/starter/pages/imported-slides.md: -------------------------------------------------------------------------------- 1 | # Imported Slides 2 | 3 | You can split your slides.md into multiple files and organize them as you want using the `src` attribute. 4 | 5 | #### `slides.md` 6 | 7 | ```markdown 8 | # Page 1 9 | 10 | Page 2 from main entry. 11 | 12 | --- 13 | 14 | ## src: ./subpage.md 15 | ``` 16 | 17 |
18 | 19 | #### `subpage.md` 20 | 21 | ```markdown 22 | # Page 2 23 | 24 | Page 2 from another file. 25 | ``` 26 | 27 | [Learn more](https://sli.dev/guide/syntax.html#importing-slides) 28 | -------------------------------------------------------------------------------- /demo/starter/snippets/external.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | // #region snippet 4 | // Inside ./snippets/external.ts 5 | export function emptyArray(length: number) { 6 | return Array.from({ length }) 7 | } 8 | // #endregion snippet 9 | 10 | export function sayHello() { 11 | console.log('Hello from snippets/external.ts') 12 | } 13 | -------------------------------------------------------------------------------- /demo/starter/style.css: -------------------------------------------------------------------------------- 1 | /* add any global style here */ 2 | -------------------------------------------------------------------------------- /demo/starter/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | 3 | export default defineConfig({ 4 | plugins: [], 5 | }) 6 | -------------------------------------------------------------------------------- /demo/vue-runner/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "slidev build", 5 | "dev": "nodemon -w '../../packages/slidev/dist/*.mjs' --exec \"slidev ./slides.md --open=false --log=info --inspect\"", 6 | "export": "slidev export", 7 | "export-notes": "slidev export-notes" 8 | }, 9 | "devDependencies": { 10 | "@slidev/cli": "workspace:*", 11 | "@slidev/theme-default": "catalog:themes", 12 | "@slidev/theme-seriph": "catalog:themes", 13 | "@vue/compiler-sfc": "catalog:demo", 14 | "nodemon": "catalog:dev", 15 | "vue": "catalog:frontend" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /demo/vue-runner/setup/shiki.ts: -------------------------------------------------------------------------------- 1 | import type { ShikiSetupReturn } from '@slidev/types' 2 | import { defineShikiSetup } from '@slidev/types' 3 | 4 | export default defineShikiSetup((): ShikiSetupReturn => { 5 | return { 6 | langs: [ 7 | 'ts', 8 | 'js', 9 | 'vue', 10 | 'html', 11 | ], 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /demo/vue-runner/slides.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | # Simple Vue SFC Runner 6 | 7 | 8 | 9 | ```vue {monaco-run} 10 | 16 | 17 | 28 | ``` 29 | 30 | --- 31 | 32 | This is a demo to prove the extensibility of Slidev Code Runners. 33 | 34 | Refer to `./setup/monaco-runner.ts` for the implementation. 35 | 36 | Note that there is a lot of edge cases that this demo is not handling. Extra work is needed to make it production ready. 37 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vitepress/@slidev 4 | .vitepress/cache 5 | -------------------------------------------------------------------------------- /docs/.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/AddonGallery.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/DemoEditor.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 40 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/DemoSlide.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 27 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/Environment.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 25 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/FeaturesAnimation.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 14 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/LandingPage.vue: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/SeeAlso.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/ShowCases.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/components/ThemeGallery.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/composables/dark.ts: -------------------------------------------------------------------------------- 1 | import { useDark } from '@vueuse/core' 2 | 3 | export const isDark = useDark() 4 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import type { EnhanceAppContext } from 'vitepress' 2 | import TwoSlash from '@shikijs/vitepress-twoslash/client' 3 | import Theme from 'vitepress/theme' 4 | import Layout from './components/Layout.vue' 5 | 6 | import '@shikijs/vitepress-twoslash/style.css' 7 | import './styles/vars.css' 8 | import './styles/demo.css' 9 | import './styles/custom.css' 10 | import 'uno.css' 11 | import 'virtual:group-icons.css' 12 | 13 | export default { 14 | extends: Theme, 15 | enhanceApp({ app }: EnhanceAppContext) { 16 | app.use(TwoSlash as any) 17 | }, 18 | Layout, 19 | } 20 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles/custom.css: -------------------------------------------------------------------------------- 1 | .icon-btn { 2 | --uno: inline-block cursor-pointer select-none important-outline-none; 3 | --uno: opacity-75 transition duration-200 ease-in-out align-middle rounded p-2; 4 | --uno: hover-(opacity-100 bg-gray-400 bg-opacity-10); 5 | } 6 | 7 | .icon-btn.disabled { 8 | --uno: opacity-25 pointer-events-none; 9 | } 10 | 11 | .inline-icon-btn { 12 | --uno: text-primary-deep; 13 | --uno: inline-block rounded p-0.5 text-2xl align-middle; 14 | --uno: border border-primary border-opacity-20 border-solid; 15 | } 16 | 17 | kbd { 18 | --uno: border-rounded bg-$vp-c-gray-1 bg-opacity-10 px-1 py-.5; 19 | } 20 | 21 | [data-tweet-id] { 22 | border-radius: 13px; 23 | } 24 | -------------------------------------------------------------------------------- /docs/custom/config-katex.md: -------------------------------------------------------------------------------- 1 | # Configure KaTeX 2 | 3 | 4 | 5 | Create `./setup/katex.ts` with the following content: 6 | 7 | ```ts twoslash [setup/katex.ts] 8 | import { defineKatexSetup } from '@slidev/types' 9 | 10 | export default defineKatexSetup(() => { 11 | return { 12 | maxExpand: 2000, 13 | /* ... */ 14 | } 15 | }) 16 | ``` 17 | 18 | The return value should be the custom options for KaTeX. Refer to [KaTeX's documentation](https://katex.org/docs/options.html) or the type definition for the full options list. 19 | -------------------------------------------------------------------------------- /docs/custom/config-routes.md: -------------------------------------------------------------------------------- 1 | # Configure Routes 2 | 3 | 4 | 5 | Add custom pages to the Slidev app. 6 | 7 | ## Usage 8 | 9 | Create `./setup/routes.ts` with the following content: 10 | 11 | ```ts twoslash [./setup/routes.ts] 12 | import { defineRoutesSetup } from '@slidev/types' 13 | 14 | export default defineRoutesSetup((routes) => { 15 | return [ 16 | ...routes, 17 | { 18 | path: '/my-page', 19 | // ---cut-start--- 20 | // @ts-expect-error missing types 21 | // ---cut-end--- 22 | component: () => import('../pages/my-page.vue'), 23 | }, 24 | ] 25 | }) 26 | ``` 27 | 28 | Learn more about routes in the [Vue Router documentation](https://router.vuejs.org/). 29 | -------------------------------------------------------------------------------- /docs/custom/config-vue.md: -------------------------------------------------------------------------------- 1 | # Configure Vue App 2 | 3 | 4 | 5 | Slidev uses [Vue 3](https://v3.vuejs.org/) to render the application on the client side. You can extend the app to add custom plugins or configurations. 6 | 7 | Create `./setup/main.ts` with the following content: 8 | 9 | 10 | 11 | ```ts twoslash [setup/main.ts] 12 | import type { Plugin } from 'vue' 13 | declare const YourPlugin: Plugin 14 | // ---cut--- 15 | import { defineAppSetup } from '@slidev/types' 16 | 17 | export default defineAppSetup(({ app, router }) => { 18 | // Vue App 19 | app.use(YourPlugin) 20 | }) 21 | ``` 22 | 23 | This can also be used as the main entrance of your Slidev app to do some initializations before the app starts. 24 | 25 | Learn more: [Vue Application API](https://v3.vuejs.org/api/application-api.html#component). 26 | -------------------------------------------------------------------------------- /docs/features/block-frontmatter.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax 4 | relates: 5 | - features/prettier-plugin 6 | tags: [syntax] 7 | description: | 8 | Use a YAML code block as the frontmatter. 9 | --- 10 | 11 | # Block Frontmatter 12 | 13 | The usual way to define frontmatters of slides is concise, but may lack of highlighting and formatter support. To solve this, you can use a YAML block at the very beginning of the slide content as the frontmatter of the slide: 14 | 15 | ````md 16 | --- 17 | theme: default 18 | --- 19 | 20 | # Slide 1 21 | 22 | --- 23 | 24 | ```yaml 25 | layout: quote 26 | ``` 27 | 28 | # Slide 2 29 | 30 | --- 31 | 32 | # Slide 3 33 | ```` 34 | 35 | ::: warning About headmatter 36 | 37 | Headmatter in Slidev is exactly the usual called "frontmatter" of the a Markdown file, which is supported by most of the Markdown editors and formatters. So you can't use a YAML block as the headmatter of the whole slide deck. 38 | 39 | ::: 40 | -------------------------------------------------------------------------------- /docs/features/build-with-pdf.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/exporting 4 | - guide/hosting 5 | relates: 6 | - CLI export options: /builtin/cli#export 7 | - Headmatter export options: /custom/#headmatter 8 | tags: [export, build] 9 | description: | 10 | Generate a downloadable PDF along with your slides build. 11 | --- 12 | 13 | # Generate PDF when Building 14 | 15 | You can provide a downloadable PDF in your built slides with the following config in headmatter: 16 | 17 | ```md 18 | --- 19 | download: true 20 | --- 21 | ``` 22 | 23 | Slidev will generate a PDF file along with the build, and a download button will be displayed in the build. 24 | 25 | You can also provide a custom URL for the PDF. In that case, the rendering process will be skipped. 26 | 27 | ```md 28 | --- 29 | download: 'https://myside.com/my-talk.pdf' 30 | --- 31 | ``` 32 | 33 | This can also be done with the CLI option `--download` (`boolean` only). 34 | 35 | ```bash 36 | $ slidev build --download 37 | ``` 38 | 39 | When using the download option, you can also provide the export options via: 40 | 41 | - [CLI export options](/builtin/cli#export) 42 | - [Headmatter export options](/custom/#frontmatter-configures) 43 | -------------------------------------------------------------------------------- /docs/features/bundle-remote-assets.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - vite-plugin-remote-assets: https://github.com/antfu/vite-plugin-remote-assets 4 | tags: [build] 5 | description: | 6 | Download and bundle remote assets when building your slides. 7 | --- 8 | 9 | # Bundle Remote Assets 10 | 11 | Just like you would do in markdown, you can use images pointing to a remote or local URL. 12 | 13 | For remote assets, the built-in [`vite-plugin-remote-assets`](https://github.com/antfu/vite-plugin-remote-assets) will cache them onto the disk at first run, ensuring instant loading even for large images later on. 14 | 15 | ```md 16 | ![Remote Image](https://sli.dev/favicon.png) 17 | ``` 18 | 19 | For local assets, put them into the [`public` folder](/custom/directory-structure.html#public) and reference them with a **leading slash** (i.e., `/pic.png`, NOT `./pic.png`, which is relative to the working file). 20 | 21 | ```md 22 | ![Local Image](/pic.png) 23 | ``` 24 | 25 | If you want to apply custom sizes or styles, you can convert them to the `` tag: 26 | 27 | ```html 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /docs/features/canvas-size.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - guide/faq#adjust-size 4 | - features/zoom-slide 5 | - features/transform-component 6 | tags: [layout] 7 | description: | 8 | Set the size for all your slides. 9 | --- 10 | 11 | # Slide Canvas Size 12 | 13 | Slidev allows you to set the size of the slide canvas via the `canvasWidth` and `aspectRatio` options in the headmatter: 14 | 15 | ```md 16 | --- 17 | # aspect ratio for the slides 18 | aspectRatio: 16/9 19 | # real width of the canvas, unit in px 20 | canvasWidth: 980 21 | --- 22 | 23 | # Your slides here 24 | ``` 25 | 26 | To scale several slides in your presentation, you can use the `zoom` option: 27 | 28 | 29 | 30 | To adjust the size of some elements on your slides, you can use the `Transform` component: 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/features/code-block-line-numbers.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | tags: [codeblock] 5 | description: | 6 | Enable line numbering for all code blocks across the slides or individually. 7 | --- 8 | 9 | # Line Numbers 10 | 11 | You can enable line numbering for all code blocks across the slides by setting `lineNumbers: true` in the headmatter, or enable each code block individually by setting `lines: true`. 12 | 13 | You can also set the starting line for each code block and highlight the lines accordingly via `{startLine: number}`, which defaults to 1. 14 | 15 | ````md 16 | ```ts {6,7}{lines:true,startLine:5} 17 | function add( 18 | a: Ref | number, 19 | b: Ref | number 20 | ) { 21 | return computed(() => unref(a) + unref(b)) 22 | } 23 | ``` 24 | ```` 25 | 26 | Note that you can use `{*}` as a placeholder of : 27 | 28 | ````md 29 | ```ts {*}{lines:true,startLine:5} 30 | // ... 31 | ``` 32 | ```` 33 | -------------------------------------------------------------------------------- /docs/features/code-block-max-height.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | tags: [codeblock, layout] 5 | description: | 6 | Set a maximum height for a code block and enable scrolling. 7 | --- 8 | 9 | # Max Height 10 | 11 | If the code doesn't fit into one slide, you use the `maxHeight` to set a fixed height and enable scrolling: 12 | 13 | ````md 14 | ```ts {2|3|7|12}{maxHeight:'100px'} 15 | function add( 16 | a: Ref | number, 17 | b: Ref | number 18 | ) { 19 | return computed(() => unref(a) + unref(b)) 20 | } 21 | /// ...as many lines as you want 22 | const c = add(1, 2) 23 | ``` 24 | ```` 25 | 26 | Note that you can use `{*}` as a placeholder of : 27 | 28 | ````md 29 | ```ts {*}{maxHeight:'100px'} 30 | // ... 31 | ``` 32 | ```` 33 | -------------------------------------------------------------------------------- /docs/features/eject-theme.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/theme-addon 4 | tags: [theme, cli] 5 | description: | 6 | Eject the installed theme from your project to customize it. 7 | --- 8 | 9 | # Eject Theme 10 | 11 | If you want to get full control of the current theme, you can **eject** it to your local file system and modify it as you want. By running the following command 12 | 13 | ```bash 14 | $ slidev theme eject 15 | ``` 16 | 17 | It will eject the theme you are using currently into `./theme`, and change your frontmatter to 18 | 19 | ```yaml 20 | --- 21 | theme: ./theme 22 | --- 23 | ``` 24 | 25 | This could also be helpful if you want to make a theme based on an existing one. If you do, remember to mention the original theme and the author :) 26 | 27 | For more options of the `theme` command, please refer to the [Theme Command](../builtin/cli#theme) section. 28 | -------------------------------------------------------------------------------- /docs/features/frontmatter-merging.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#importing-slides 4 | - features/importing-slides 5 | tags: [syntax] 6 | description: | 7 | Merge frontmatter from multiple markdown files. 8 | --- 9 | 10 | # Frontmatter Merging 11 | 12 | You can provide frontmatter instructions from both your main entry and external markdown pages. If there are duplicate keys in them, the ones from the **main entry have the higher priority**. For example: 13 | 14 | ::: code-group 15 | 16 | ```md [./slides.md] 17 | --- 18 | src: ./cover.md 19 | background: https://sli.dev/bar.png // [!code highlight] 20 | class: text-center 21 | --- 22 | ``` 23 | 24 | ```md [./cover.md] 25 | --- 26 | layout: cover 27 | background: https://sli.dev/foo.png // [!code highlight] 28 | --- 29 | 30 | # Cover 31 | 32 | Cover Page 33 | ``` 34 | 35 | ::: 36 | 37 | They will end up being equivalent to the following page: 38 | 39 | ```md 40 | --- 41 | layout: cover 42 | background: https://sli.dev/bar.png // [!code highlight] 43 | class: text-center 44 | --- 45 | 46 | # Cover 47 | 48 | Cover Page 49 | ``` 50 | -------------------------------------------------------------------------------- /docs/features/mdc.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Nuxt's MDC Syntax: https://content.nuxt.com/docs/files/markdown#mdc-syntax 4 | - markdown-it-mdc: https://github.com/antfu/markdown-it-mdc 5 | since: v0.43.0 6 | tags: [syntax, styling] 7 | description: | 8 | A powerful syntax to enhance your markdown content with components and styles. 9 | --- 10 | 11 | # MDC Syntax 12 | 13 | Slidev supports optional [MDC (Markdown Components) Syntax](https://content.nuxt.com/docs/files/markdown#mdc-syntax) powered by [`markdown-it-mdc`](https://github.com/antfu/markdown-it-mdc). 14 | 15 | You can enable it by adding `mdc: true` to the frontmatter of your markdown file. 16 | 17 | ```mdc 18 | --- 19 | mdc: true 20 | --- 21 | 22 | This is a [red text]{style="color:red"} :inline-component{prop="value"} 23 | 24 | ![](/image.png){width=500px lazy} 25 | 26 | ::block-component{prop="value"} 27 | The **default** slot 28 | :: 29 | ``` 30 | 31 | Learn more about [MDC Syntax](https://content.nuxt.com/docs/files/markdown#mdc-syntax). 32 | -------------------------------------------------------------------------------- /docs/features/mermaid.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Mermaid: https://mermaid.js.org/ 4 | - Mermaid Live Editor: https://mermaid.live/ 5 | - Demo Slide: https://sli.dev/demo/starter/12 6 | - features/plantuml 7 | tags: [diagram] 8 | description: | 9 | Create diagrams/graphs from textual descriptions, powered by Mermaid. 10 | --- 11 | 12 | # Mermaid Diagrams 13 | 14 | You can also create diagrams/graphs from textual descriptions in your Markdown, powered by [Mermaid](https://mermaid.js.org/). 15 | 16 | Code blocks marked as `mermaid` will be converted to diagrams, for example: 17 | 18 | ````md 19 | ```mermaid 20 | sequenceDiagram 21 | Alice->John: Hello John, how are you? 22 | Note over Alice,John: A typical interaction 23 | ``` 24 | ```` 25 | 26 | You can further pass an options object to it to specify the scaling and theming. The syntax of the object is a JavaScript object literal, you will need to add quotes (`'`) for strings and use comma (`,`) between keys. 27 | 28 | ````md 29 | ```mermaid {theme: 'neutral', scale: 0.8} 30 | graph TD 31 | B[Text] --> C{Decision} 32 | C -->|One| D[Result 1] 33 | C -->|Two| E[Result 2] 34 | ``` 35 | ```` 36 | 37 | Visit the [Mermaid Website](https://mermaid.js.org/) for more information. 38 | -------------------------------------------------------------------------------- /docs/features/monaco-write.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - features/monaco-editor 4 | - features/import-snippet 5 | relates: 6 | - features/import-snippet 7 | - Custom Code Runners: /custom/config-code-runners 8 | since: v0.49.5 9 | tags: [codeblock, editor] 10 | description: | 11 | A monaco editor that allows you to write code directly in the slides and save the changes back to the file. 12 | --- 13 | 14 | # Writable Monaco Editor 15 | 16 | You can also use the [Import Code Snippets](#import-code-snippets) syntax combined with the `{monaco-write}` directive, to link your Monaco Editor with a file on your filesystem. This will allow you to edit the code directly in the editor and save the changes back to the file. 17 | 18 | ```md 19 | <<< ./some-file.ts {monaco-write} 20 | ``` 21 | 22 | When using this, be sure to back up your files beforehand, as the changes will be saved directly to the file. 23 | -------------------------------------------------------------------------------- /docs/features/plantuml.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Plant UML: https://plantuml.com/ 4 | - Plant UML Live Editor: https://plantuml.com/plantuml 5 | - Example side: https://sli.dev/demo/starter/12 6 | - features/mermaid 7 | tags: [diagram] 8 | description: | 9 | Create diagrams from textual descriptions, powered by PlantUML. 10 | --- 11 | 12 | # PlantUML Diagrams 13 | 14 | You can create PlantUML diagrams easily in your slides, for example: 15 | 16 | ````md 17 | ```plantuml 18 | @startuml 19 | Alice -> Bob : Hello! 20 | @enduml 21 | ``` 22 | ```` 23 | 24 | The source code will be sent to https://www.plantuml.com/plantuml to render the diagram by default. You can also set up your own server by setting the `plantUmlServer` in the [Slidev configuration](../custom/index#headmatter). 25 | 26 | Visit the [PlantUML Website](https://plantuml.com/) for more information. 27 | -------------------------------------------------------------------------------- /docs/features/side-editor.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/ui#navigation-actions 4 | relates: 5 | - features/vscode-extension 6 | tags: [editor] 7 | description: | 8 | Edit your slides source file alongside the presentation. 9 | --- 10 | 11 | # Integrated Editor 12 | 13 | Slidev comes with an integrated editor that will instantly reload and save the changes to your file. 14 | 15 | Click the button on the navigation panel to open it. 16 | 17 | ![](/screenshots/integrated-editor.png) 18 | -------------------------------------------------------------------------------- /docs/features/slide-hook.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/global-context 4 | tags: [client-api] 5 | description: | 6 | Hooks to manage the slide lifecycle. 7 | --- 8 | 9 | # Slide Hooks 10 | 11 | Slidev provides a set of hooks to help you manage the slide lifecycle: 12 | 13 | ```ts twoslash 14 | import { onSlideEnter, onSlideLeave, useIsSlideActive } from '@slidev/client' 15 | 16 | const isActive = useIsSlideActive() 17 | 18 | onSlideEnter(() => { 19 | /* Called whenever the slide becomes active */ 20 | }) 21 | 22 | onSlideLeave(() => { 23 | /* Called whenever the slide becomes inactive */ 24 | }) 25 | ``` 26 | 27 | You can also use to access other useful context information. 28 | 29 | ::: warning 30 | 31 | In the slide component, `onMounted` and `onUnmounted` hooks are not available, because the component instance is preserved even when the slide is not active. Use `onSlideEnter` and `onSlideLeave` instead. 32 | 33 | ::: 34 | -------------------------------------------------------------------------------- /docs/features/slide-scope-style.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Vue's Scoped CSS: https://vuejs.org/api/sfc-css-features.html#scoped-css 4 | - UnoCSS directives: https://unocss.dev/transformers/directives 5 | tags: [styling, syntax] 6 | description: | 7 | Define styles for only the current slide. 8 | --- 9 | 10 | # Slide Scope Styles 11 | 12 | You can use the ` 22 | 23 | --- 24 | 25 | # Other slides are not affected 26 | ``` 27 | 28 | The ` 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/features/transform-component.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - guide/faq#adjust-size 4 | - features/canvas-size 5 | - features/zoom-slide 6 | tags: [layout] 7 | description: | 8 | A component for scaling some elements. 9 | --- 10 | 11 | # The `Transform` Component 12 | 13 | The `Transform` component allows you to scale the size of the elements on your slides: 14 | 15 | ```md 16 | 17 | 18 | 19 | ``` 20 | 21 | This is useful when you want to adjust the size of some elements on your slides without affecting the layout of the entire slide. 22 | 23 | To scale all the slides in your presentation, you can set the slide canvas size: 24 | 25 | 26 | 27 | To scale several slides in your presentation, you can use the `zoom` option: 28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/features/twoslash.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | relates: 5 | - TwoSlash: https://twoslash.netlify.app/ 6 | since: v0.46.0 7 | tags: [codeblock] 8 | description: | 9 | A powerful tool for rendering TypeScript code blocks with type information on hover or inlined. 10 | --- 11 | 12 | # TwoSlash Integration 13 | 14 | [TwoSlash](https://twoslash.netlify.app/) is a powerful tool for rendering TypeScript code blocks with type information on hover or inlined. It's quite useful for preparing slides for JavaScript/TypeScript-related topics. 15 | 16 | To use it, you can add `twoslash` to the code block's language identifier: 17 | 18 | ````md 19 | ```ts twoslash 20 | import { ref } from 'vue' 21 | 22 | const count = ref(0) 23 | // ^? 24 | ``` 25 | ```` 26 | 27 | It will be rendered as: 28 | 29 | ```ts twoslash 30 | import { ref } from 'vue' 31 | 32 | const count = ref(0) 33 | // ^? 34 | ``` 35 | 36 | 37 |
38 | -------------------------------------------------------------------------------- /docs/features/zoom-slide.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - guide/faq#adjust-size 4 | - features/canvas-size 5 | - features/transform-component 6 | tags: [layout] 7 | description: | 8 | Zoom the content of a slide to a specific scale. 9 | --- 10 | 11 | # Zoom Slides 12 | 13 | You may find some slides in your presentation too spacious or too crowded. Slidev provides a `zoom` option for each slide that allows you to scale the content of a slide: 14 | 15 | ```md 16 | --- 17 | zoom: 0.8 18 | --- 19 | 20 | # A Slide with lots of content 21 | 22 | --- 23 | 24 | # Other slides aren't affected 25 | ``` 26 | 27 | To scale all the slides in your presentation, you can set the slide canvas size: 28 | 29 | 30 | 31 | To adjust the size of some elements on your slides, you can use the `Transform` component: 32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/guide/layout.md: -------------------------------------------------------------------------------- 1 | # Slide Layout 2 | 3 | Layouts in Slidev are used to define the structure for each slides. They are Vue components that wrap the content of the slides. 4 | 5 | ## Using Layouts {#use} 6 | 7 | To use a layout, you can specify it in the frontmatter of the slide: 8 | 9 | ```md 10 | --- 11 | layout: quote 12 | --- 13 | 14 | A quote from someone 15 | ``` 16 | 17 | By default, the layout of the first slide is `cover`, and the rest are `default`. 18 | 19 | The layouts are loaded in the following order, and the last one loaded will override the previous ones: 20 | 21 | 1. default layouts. See [Built-in Layouts](../builtin/layouts). 22 | 2. layouts provided by the theme 23 | 3. layouts provided by the addons 24 | 4. custom layouts in the `layouts` directory 25 | 26 | 29 | 30 | ## Writing Layouts {#write} 31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/guide/write-layout.md: -------------------------------------------------------------------------------- 1 | # Writing Layouts 2 | 3 | > Please read first. 4 | 5 | To create a custom layout, simply create a new Vue file in the `layouts` directory: 6 | 7 | ```bash 8 | your-slidev/ 9 | ├── ... 10 | ├── slides.md 11 | └── layouts/ 12 | ├── ... 13 | └── MyLayout.vue 14 | ``` 15 | 16 | Layouts are Vue components, so you can use all the features of Vue in them. 17 | 18 | In the layout component, use `` (the default slot) for the slide content: 19 | 20 | ```vue [default.vue] 21 | 26 | ``` 27 | 28 | You can also have [named slots](https://vuejs.org/guide/components/slots.html) for more complex layouts: 29 | 30 | ```vue [split.vue] 31 | 41 | ``` 42 | 43 | And then use it with . 44 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | markdownStyles: false 4 | --- 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = ".vitepress/dist" 3 | command = "pnpm run build" 4 | 5 | [build.environment] 6 | NODE_VERSION = "20" 7 | PLAYWRIGHT_BROWSERS_PATH = "0" 8 | 9 | [[redirects]] 10 | from = "/new" 11 | to = "https://stackblitz.com/github/slidevjs/new?file=slides.md" 12 | status = 302 13 | force = true 14 | 15 | [[redirects]] 16 | from = "https://slidev.antfu.me/*" 17 | to = "https://sli.dev/:splat" 18 | status = 301 19 | force = true 20 | 21 | [[redirects]] 22 | from = "/demo/composable-vue/*" 23 | to = "https://demo.sli.dev/composable-vue" 24 | status = 301 25 | force = true 26 | 27 | [[redirects]] 28 | from = "/demo/starter/*" 29 | to = "https://demo.sli.dev/starter" 30 | status = 301 31 | force = true 32 | 33 | [[redirects]] 34 | from = "/*" 35 | to = "/index.html" 36 | status = 200 37 | -------------------------------------------------------------------------------- /docs/public/assets/code-groups-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/assets/code-groups-demo.png -------------------------------------------------------------------------------- /docs/public/demo-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/demo-cover.png -------------------------------------------------------------------------------- /docs/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/favicon.png -------------------------------------------------------------------------------- /docs/public/logo-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/logo-circle.png -------------------------------------------------------------------------------- /docs/public/logo-for-vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/logo-for-vscode.png -------------------------------------------------------------------------------- /docs/public/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/logo-square.png -------------------------------------------------------------------------------- /docs/public/logo-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/logo-title.png -------------------------------------------------------------------------------- /docs/public/logo-triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/logo-triangle.png -------------------------------------------------------------------------------- /docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/logo.png -------------------------------------------------------------------------------- /docs/public/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/og-image.png -------------------------------------------------------------------------------- /docs/public/screenshots/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/screenshots/cover.png -------------------------------------------------------------------------------- /docs/public/screenshots/covers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/screenshots/covers.png -------------------------------------------------------------------------------- /docs/public/screenshots/integrated-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/screenshots/integrated-editor.png -------------------------------------------------------------------------------- /docs/public/screenshots/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/screenshots/navbar.png -------------------------------------------------------------------------------- /docs/public/screenshots/presenter-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/screenshots/presenter-mode.png -------------------------------------------------------------------------------- /docs/public/screenshots/recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/screenshots/recording.png -------------------------------------------------------------------------------- /docs/public/screenshots/slides-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/screenshots/slides-overview.png -------------------------------------------------------------------------------- /docs/public/showcases/composable-vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/showcases/composable-vue.png -------------------------------------------------------------------------------- /docs/public/theme-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/docs/public/theme-placeholder.png -------------------------------------------------------------------------------- /docs/resources/addon-gallery.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | 8 | 9 | # Addon Gallery 10 | 11 | Browse awesome addons available for Slidev here. 12 | 13 | Read more about to use them, and to create your own addon. 14 | 15 | ## Official Addons 16 | 17 | 18 | 19 | 20 | 21 | ## Community Addons 22 | 23 | Here are the curated addons made by the community. 24 | 25 | 26 | 27 | 28 | 29 | 30 | ## More Addons 31 | 32 | Find all the [addons available on NPM](https://www.npmjs.com/search?q=keywords%3Aslidev-addon). 33 | -------------------------------------------------------------------------------- /docs/resources/covers.md: -------------------------------------------------------------------------------- 1 | # Curated Covers 2 | 3 | We curated a few cover images to demonstrate our starter template. 4 | 5 | ![](/screenshots/covers.png) 6 | 7 | ```yaml 8 | --- 9 | # random image from the curated collection 10 | background: https://cover.sli.dev 11 | --- 12 | ``` 13 | 14 | If you enjoy any of them, check out our [Unsplash collection](https://unsplash.com/collections/94734566/slidev) and find out their authors. 15 | 16 | [cover.sli.dev](https://cover.sli.dev) is hosted from [`slidevjs/slidev-covers`](https://github.com/slidevjs/slidev-covers). 17 | -------------------------------------------------------------------------------- /docs/resources/learning.md: -------------------------------------------------------------------------------- 1 | # Learning Resources 2 | 3 | ## English 4 | 5 | ### Videos 6 | 7 | - [Slidev - one of the best presentation software and it is free!](https://www.youtube.com/watch?v=oSgM6GoSwyY) - by [Federico Tartarini](https://www.youtube.com/@FedericoTartarini) 8 | 9 | ### Articles 10 | 11 | - [Tips To Turn R Markdown Into Slidev Presentation](https://yutani.rbind.io/post/2021-06-05-tips-to-turn-r-markdown-into-slidev-presentation/) by Hiroaki Yutani 12 | 13 | ## 中文 14 | 15 | - [Slidev:一个用Markdown写slides的神器](https://zhuanlan.zhihu.com/p/372729473) by [梦里风林](https://www.zhihu.com/people/meng-li-feng-lin) 16 | - [神器!这款开源项目可以让你使用 Markdown 来做 PPT!](https://zhuanlan.zhihu.com/p/377567327) by [Github掘金计划](https://www.zhihu.com/people/github-stars) 17 | 18 | ## 日本語 19 | 20 | - [開発者のためのスライド作成ツール Slidev がすごい](https://zenn.dev/ryo_kawamata/articles/introduce-slidev) by [ryo_kawamata](https://zenn.dev/ryo_kawamata) 21 | - [Markdownでオシャレなスライドを作るSli.dev](https://qiita.com/e99h2121/items/a115f8865a0dc21bb462) by [Nobuko YAMADA](https://qiita.com/e99h2121) 22 | - [【Slidev 超入門】エンジニアだからこそ作れるつよつよスライドの作り方!](https://zenn.dev/takumaru/articles/3faa75c2f09493) by [takuma-ru](https://zenn.dev/takumaru) 23 | -------------------------------------------------------------------------------- /docs/resources/showcases.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # Showcases 6 | 7 | Talks / Presentations using Slidev. 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/resources/theme-gallery.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | 8 | 9 | # Theme Gallery 10 | 11 | Browse awesome themes available for Slidev here. 12 | 13 | Read more about to use them, and to create your own theme. 14 | 15 | ## Official Themes {#official-themes} 16 | 17 | 18 | 19 | 20 | 21 | ## Community Themes {#community-themes} 22 | 23 | Here are the curated themes made by the community. 24 | 25 | 26 | 27 | 28 | 29 | 30 | ## More Themes {#more-themes} 31 | 32 | Find all the [themes available on NPM](https://www.npmjs.com/search?q=keywords%3Aslidev-theme). 33 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "jsx": "preserve", 5 | "lib": ["DOM", "ESNext"], 6 | "baseUrl": ".", 7 | "module": "ESNext", 8 | "moduleResolution": "bundler", 9 | "resolveJsonModule": true, 10 | "types": [ 11 | "vite/client", 12 | "node" 13 | ], 14 | "strict": true, 15 | "strictNullChecks": true, 16 | "noUnusedLocals": true, 17 | "esModuleInterop": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "skipLibCheck": true 20 | }, 21 | "include": [ 22 | "./*.ts", 23 | "./.vitepress/**/*.ts", 24 | "./.vitepress/**/*.vue" 25 | ], 26 | "exclude": ["**/dist/**", "node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /docs/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, presetAttributify, presetIcons, presetWebFonts, presetWind3, transformerDirectives } from 'unocss' 2 | 3 | export default defineConfig({ 4 | presets: [ 5 | presetWind3(), 6 | presetAttributify(), 7 | presetWebFonts({ 8 | fonts: { 9 | mono: ['IBM Plex Mono', 'monospace'], 10 | }, 11 | }), 12 | presetIcons(), 13 | ], 14 | transformers: [ 15 | transformerDirectives(), 16 | ], 17 | shortcuts: { 18 | 'bg-main': 'bg-white dark:bg-[#111]', 19 | }, 20 | theme: { 21 | colors: { 22 | primary: { 23 | DEFAULT: '#3AB9D4', 24 | deep: '#2082A6', 25 | }, 26 | }, 27 | }, 28 | }) 29 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config' 2 | 3 | export default antfu({ 4 | pnpm: true, 5 | formatters: { 6 | markdown: true, 7 | css: true, 8 | slidev: { 9 | files: [ 10 | '**/slides.md', 11 | '**/template.md', 12 | '**/example.md', 13 | 'test/fixtures/markdown/**/*.md', 14 | 'packages/vscode/syntaxes/slidev.example.md', 15 | ], 16 | }, 17 | }, 18 | }) 19 | .removeRules( 20 | 'vue/no-v-text-v-html-on-component', 21 | 'vue/component-name-in-template-casing', 22 | 'jsonc/sort-array-values', 23 | ) 24 | .override('antfu/pnpm/package-json', { 25 | ignores: [ 26 | 'packages/create-theme/template/package.json', 27 | 'packages/create-app/template/package.json', 28 | ], 29 | }) 30 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "docs/.vitepress/dist" 3 | command = "pnpm run docs:build" 4 | 5 | [build.environment] 6 | NODE_VERSION = "22" 7 | NODE_OPTIONS = "--max-old-space-size=8192" 8 | PLAYWRIGHT_BROWSERS_PATH = "0" 9 | 10 | [[redirects]] 11 | from = "/new" 12 | to = "https://stackblitz.com/github/slidevjs/new?file=slides.md" 13 | status = 302 14 | force = true 15 | 16 | [[redirects]] 17 | from = "/demo/composable-vue/*" 18 | to = "/demo/composable-vue/index.html" 19 | status = 200 20 | 21 | [[redirects]] 22 | from = "/demo/starter/*" 23 | to = "/demo/starter/index.html" 24 | status = 200 25 | 26 | [[redirects]] 27 | from = "/demo/vue-runner/*" 28 | to = "/demo/vue-runner/index.html" 29 | status = 200 30 | 31 | [[redirects]] 32 | from = "https://slidev.antfu.me/*" 33 | to = "https://sli.dev/:splat" 34 | status = 301 35 | force = true 36 | 37 | [[redirects]] 38 | from = "/*" 39 | to = "/index.html" 40 | status = 200 41 | -------------------------------------------------------------------------------- /packages/client/App.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 17 | -------------------------------------------------------------------------------- /packages/client/README.md: -------------------------------------------------------------------------------- 1 | # @slidev/client 2 | 3 | [![NPM version](https://img.shields.io/npm/v/@slidev/client?color=3AB9D4&label=)](https://www.npmjs.com/package/@slidev/client) 4 | 5 | Client code for [Slidev](https://sli.dev). Shipped with [`@slidev/cli`](https://www.npmjs.com/package/@slidev/cli). 6 | 7 | ## License 8 | 9 | MIT License © 2021 [Anthony Fu](https://github.com/antfu) 10 | -------------------------------------------------------------------------------- /packages/client/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/packages/client/assets/favicon.png -------------------------------------------------------------------------------- /packages/client/assets/logo-title-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/packages/client/assets/logo-title-horizontal.png -------------------------------------------------------------------------------- /packages/client/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/slidev/4645273d037f1265f9c1af525626ebe9b3ad5610/packages/client/assets/logo.png -------------------------------------------------------------------------------- /packages/client/builtin/LightOrDark.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /packages/client/builtin/Link.vue: -------------------------------------------------------------------------------- 1 | 10 | 20 | 21 | 29 | -------------------------------------------------------------------------------- /packages/client/builtin/PlantUml.vue: -------------------------------------------------------------------------------- 1 | 13 | 27 | 28 | 31 | -------------------------------------------------------------------------------- /packages/client/builtin/PoweredBySlidev.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /packages/client/builtin/SlideCurrentNo.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/client/builtin/SlidesTotal.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /packages/client/builtin/Transform.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 30 | 31 | 36 | -------------------------------------------------------------------------------- /packages/client/builtin/VAfter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * click animations component 3 | * 4 | * Learn more: https://sli.dev/guide/animations.html#click-animation 5 | */ 6 | 7 | import type { Directive, VNode } from 'vue' 8 | import { toArray } from '@antfu/utils' 9 | import { defineComponent, h, resolveDirective, withDirectives } from 'vue' 10 | 11 | export default defineComponent({ 12 | render() { 13 | const after = resolveDirective('after')! 14 | 15 | function applyDirective(node: VNode, directive: Directive) { 16 | return withDirectives(node, [[directive]]) 17 | } 18 | 19 | let defaults = this.$slots.default?.() 20 | 21 | if (!defaults) 22 | return 23 | 24 | defaults = toArray(defaults) 25 | 26 | return defaults.map(i => applyDirective(h(i), after)) 27 | }, 28 | }) 29 | -------------------------------------------------------------------------------- /packages/client/builtin/VClick.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * click animations component 3 | * 4 | * Learn more: https://sli.dev/guide/animations.html#click-animation 5 | */ 6 | 7 | import type { PropType, VNode } from 'vue' 8 | import { defineComponent, h, Text } from 'vue' 9 | import { CLICKS_MAX } from '../constants' 10 | import VClicks from './VClicks' 11 | 12 | export default defineComponent({ 13 | props: { 14 | at: { 15 | type: [Number, String], 16 | default: '+1', 17 | }, 18 | hide: { 19 | type: Boolean, 20 | default: false, 21 | }, 22 | fade: { 23 | type: Boolean, 24 | default: false, 25 | }, 26 | wrapText: { 27 | type: Function as PropType<(text: VNode) => VNode>, 28 | default: (text: VNode) => h('span', text), 29 | }, 30 | }, 31 | render() { 32 | return h( 33 | VClicks, 34 | { 35 | every: CLICKS_MAX, 36 | at: this.at, 37 | hide: this.hide, 38 | fade: this.fade, 39 | handleSpecialElements: false, 40 | }, 41 | { 42 | default: () => 43 | this.$slots.default?.().map(v => 44 | v.type === Text 45 | ? this.wrapText(v) 46 | : v, 47 | ), 48 | }, 49 | ) 50 | }, 51 | }) 52 | -------------------------------------------------------------------------------- /packages/client/builtin/VClickGap.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 35 | -------------------------------------------------------------------------------- /packages/client/builtin/VDrag.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /packages/client/builtin/VDragArrow.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 37 | -------------------------------------------------------------------------------- /packages/client/builtin/Youtube.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | 17 |