├── .github └── ISSUE_TEMPLATE │ └── config.yml ├── .gitignore ├── .npmrc ├── .vitepress ├── config.js ├── scripts │ └── prepare.js ├── showcases.ts ├── theme │ ├── Layout.vue │ ├── NotFound.vue │ ├── components │ │ ├── AlgoliaSearchBox.vue │ │ ├── BooleanDisplay.vue │ │ ├── DarkModeSwitch.vue │ │ ├── DemoContainer.vue │ │ ├── EditLink.vue │ │ ├── Environment.vue │ │ ├── Home.vue │ │ ├── HomeFeatures.vue │ │ ├── HomeFooter.vue │ │ ├── HomeHero.vue │ │ ├── LastUpdated.vue │ │ ├── NavBar.vue │ │ ├── NavBarTitle.vue │ │ ├── NavDropdownLink.vue │ │ ├── NavDropdownLinkItem.vue │ │ ├── NavLink.vue │ │ ├── NavLinks.vue │ │ ├── NextAndPrevLinks.vue │ │ ├── Note.vue │ │ ├── Page.vue │ │ ├── PageFooter.vue │ │ ├── ShowCaseInfo.vue │ │ ├── ShowCases.vue │ │ ├── SideBar.vue │ │ ├── SideBarLink.ts │ │ ├── SideBarLinks.vue │ │ ├── ThemeGallery.vue │ │ ├── ThemeInfo.vue │ │ ├── ToggleSideBarButton.vue │ │ ├── Tweet.vue │ │ ├── WorkingInProgress.vue │ │ ├── demo │ │ │ ├── Demo.vue │ │ │ ├── DemoEditor.vue │ │ │ └── DemoSlide.vue │ │ └── icons │ │ │ ├── ArrowLeft.vue │ │ │ ├── ArrowRight.vue │ │ │ ├── Moon.vue │ │ │ ├── OutboundLink.vue │ │ │ ├── README.md │ │ │ └── Sun.vue │ ├── composables │ │ ├── activeSidebarLink.ts │ │ ├── dark.ts │ │ ├── editLink.ts │ │ ├── nav.ts │ │ ├── navLink.ts │ │ ├── nextAndPrevLinks.ts │ │ ├── repo.ts │ │ ├── sideBar.ts │ │ ├── url.ts │ │ └── versions.ts │ ├── config.ts │ ├── index.ts │ ├── styles │ │ ├── code.css │ │ ├── custom-blocks.css │ │ ├── layout.css │ │ ├── sidebar-links.css │ │ └── vars.css │ ├── support │ │ └── sideBar.ts │ └── utils.ts └── themes.ts ├── README.md ├── TRANSLATIONS.md ├── builtin ├── components.md └── layouts.md ├── custom ├── config-katex.md ├── config-mermaid.md ├── config-monaco.md ├── config-shortcuts.md ├── config-vite.md ├── config-vue.md ├── config-windicss.md ├── directory-structure.md ├── fonts.md ├── global-layers.md ├── highlighters.md ├── index.md └── vue-context.md ├── guide ├── animations.md ├── drawing.md ├── editors.md ├── exporting.md ├── faq.md ├── hosting.md ├── index.md ├── install.md ├── navigation.md ├── presenter-mode.md ├── recording.md ├── syntax.md └── why.md ├── index.md ├── netlify.toml ├── package.json ├── pnpm-lock.yaml ├── public ├── assets │ └── arrow-bottom-left.svg ├── 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 ├── covers.md └── learning.md ├── showcases.md ├── themes ├── gallery.md ├── use.md └── write-a-theme.md ├── tsconfig.json ├── vite.config.ts └── windi.config.ts /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Main Repository 3 | url: https://github.com/slidevjs/slidev/ 4 | about: This translation is out of date, This translation is outdated, please do not file an issue here. 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vitepress/@slidev 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | -------------------------------------------------------------------------------- /.vitepress/config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | const Guide = [ 4 | { 5 | text: 'なぜSlidev?', 6 | link: '/guide/why', 7 | }, 8 | { 9 | text: 'はじめに', 10 | link: '/guide/', 11 | }, 12 | { 13 | text: 'インストール', 14 | link: '/guide/install', 15 | }, 16 | { 17 | text: 'Markdownシンタックス', 18 | link: '/guide/syntax', 19 | }, 20 | { 21 | text: 'ナビゲーション', 22 | link: '/guide/navigation', 23 | }, 24 | { 25 | text: 'アニメーション', 26 | link: '/guide/animations', 27 | }, 28 | { 29 | text: 'エクスポート', 30 | link: '/guide/exporting', 31 | }, 32 | { 33 | text: '静的ホスティング', 34 | link: '/guide/hosting', 35 | }, 36 | { 37 | text: 'レコーディング', 38 | link: '/guide/recording', 39 | }, 40 | { 41 | text: 'プレゼンターモード', 42 | link: '/guide/presenter-mode', 43 | }, 44 | { 45 | text: '描画と注釈', 46 | link: '/guide/drawing', 47 | }, 48 | { 49 | text: 'エディタサポート', 50 | link: '/guide/editors', 51 | }, 52 | { 53 | text: 'FAQ', 54 | link: '/guide/faq', 55 | }, 56 | ] 57 | 58 | const Theme = [ 59 | { 60 | text: 'テーマを使用する', 61 | link: '/themes/use', 62 | }, 63 | { 64 | text: 'テーマギャラリー', 65 | link: '/themes/gallery', 66 | }, 67 | { 68 | text: 'テーマを作成する', 69 | link: '/themes/write-a-theme', 70 | }, 71 | ] 72 | 73 | const Translations = [ 74 | { 75 | text: '日本語', 76 | }, 77 | { 78 | text: 'English', 79 | link: 'https://sli.dev{{pathname}}', 80 | }, 81 | { 82 | text: '简体中文', 83 | link: 'https://cn.sli.dev{{pathname}}', 84 | }, 85 | { 86 | text: 'Français', 87 | link: 'https://fr.sli.dev{{pathname}}', 88 | }, 89 | { 90 | text: 'Español', 91 | link: 'https://es.sli.dev{{pathname}}', 92 | }, 93 | { 94 | text: 'Русский', 95 | link: 'https://ru.sli.dev{{pathname}}', 96 | }, 97 | { 98 | text: 'Việt Nam', 99 | link: 'https://vn.sli.dev{{pathname}}', 100 | }, 101 | { 102 | text: 'Deutsch', 103 | link: 'https://de.sli.dev{{pathname}}', 104 | }, 105 | { 106 | text: 'Português (BR)', 107 | link: 'https://br.sli.dev{{pathname}}', 108 | }, 109 | { 110 | text: 'Ελληνικά', 111 | link: 'https://el.sli.dev{{pathname}}', 112 | }, 113 | { 114 | text: '日本語', 115 | link: 'https://ja.sli.dev{{pathname}}', 116 | }, 117 | ] 118 | 119 | const Customizations = [ 120 | { 121 | text: 'カスタマイズ', 122 | link: '/custom/', 123 | }, 124 | { 125 | text: 'ディレクトリ構造', 126 | link: '/custom/directory-structure', 127 | }, 128 | { 129 | text: 'フォント', 130 | link: '/custom/fonts', 131 | }, 132 | { 133 | text: 'シンタックスハイライト', 134 | link: '/custom/highlighters', 135 | }, 136 | { 137 | text: 'Vueの設定', 138 | link: '/custom/config-vue', 139 | }, 140 | { 141 | text: 'Viteの設定', 142 | link: '/custom/config-vite', 143 | }, 144 | { 145 | text: 'Windi CSSの設定', 146 | link: '/custom/config-windicss', 147 | }, 148 | { 149 | text: 'Monacoの設定', 150 | link: '/custom/config-monaco', 151 | }, 152 | { 153 | text: 'KaTeXの設定', 154 | link: '/custom/config-katex', 155 | }, 156 | { 157 | text: 'Mermaidの設定', 158 | link: '/custom/config-mermaid', 159 | }, 160 | { 161 | text: 'ショートカットの設定', 162 | link: '/custom/config-shortcuts', 163 | }, 164 | { 165 | text: 'Vueグローバルコンテキスト', 166 | link: '/custom/vue-context', 167 | }, 168 | { 169 | text: 'グローバルレイヤー', 170 | link: '/custom/global-layers', 171 | } 172 | ] 173 | 174 | const Resources = [ 175 | { 176 | text: 'ショーケース', 177 | link: '/showcases', 178 | }, 179 | { 180 | text: '学習リソース', 181 | link: '/resources/learning', 182 | }, 183 | { 184 | text: 'キュレーションカバー', 185 | link: '/resources/covers', 186 | }, 187 | ] 188 | 189 | const slidebars = [ 190 | { 191 | text: 'ガイド', 192 | children: Guide, 193 | }, 194 | { 195 | text: 'テーマ', 196 | children: Theme, 197 | }, 198 | { 199 | text: 'カスタマイズ', 200 | children: Customizations, 201 | }, 202 | { 203 | text: 'ビルトイン', 204 | children: [ 205 | { 206 | text: 'コンポーネント', 207 | link: '/builtin/components', 208 | }, 209 | { 210 | text: 'レイアウト', 211 | link: '/builtin/layouts', 212 | }, 213 | ], 214 | }, 215 | ] 216 | 217 | /** 218 | * @type {import('vitepress').UserConfig} 219 | */ 220 | module.exports = { 221 | title: 'Slidev', 222 | description: '開発者のためのプレゼンテーションスライド', 223 | head: [ 224 | ['link', { rel: 'icon', type: 'image/png', href: '/favicon.png' }], 225 | ['meta', { name: 'author', content: 'Anthony Fu' }], 226 | ['meta', { property: 'og:title', content: 'Slidev' }], 227 | ['meta', { property: 'og:image', content: 'https://sli.dev/og-image.png' }], 228 | ['meta', { property: 'og:description', content: 'Presentation slides for developers' }], 229 | ['meta', { name: 'twitter:card', content: 'summary_large_image' }], 230 | ['meta', { name: 'twitter:creator', content: '@slidevjs' }], 231 | ['meta', { name: 'twitter:image', content: 'https://sli.dev/og-image.png' }], 232 | ['link', { rel: 'dns-prefetch', href: 'https://fonts.gstatic.com' }], 233 | ['link', { rel: 'preconnect', crossorigin: 'anonymous', href: 'https://fonts.gstatic.com' }], 234 | ['link', { href: 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@200;400;500&family=Inter:wght@200;400;500;600', rel: 'stylesheet' }], 235 | ], 236 | themeConfig: { 237 | repo: 'slidevjs/docs-ja', 238 | logo: '/logo.svg', 239 | docsBranch: 'main', 240 | editLinks: true, 241 | editLinkText: 'このページの編集を提案する', 242 | 243 | algolia: { 244 | apiKey: '1a5c5a504139c58f428974c78c55291d', 245 | indexName: 'slidev', 246 | searchParameters: { 247 | // for translations maintainers: change the filter to your locale code (subdomain name) 248 | facetFilters: ['language:ja'] 249 | } 250 | }, 251 | 252 | nav: [ 253 | { 254 | text: 'ガイド', 255 | items: Guide, 256 | }, 257 | { 258 | text: 'テーマ', 259 | items: Theme, 260 | }, 261 | { 262 | text: 'カスタマイズ', 263 | items: Customizations, 264 | }, 265 | { 266 | text: 'リソース', 267 | items: Resources, 268 | }, 269 | { 270 | text: '日本語', 271 | items: Translations, 272 | }, 273 | ], 274 | 275 | sidebar: { 276 | '/guide/': slidebars, 277 | '/themes/': slidebars, 278 | '/custom/': slidebars, 279 | '/builtin/': slidebars, 280 | '/resources/': slidebars, 281 | '/': slidebars, 282 | }, 283 | }, 284 | } 285 | -------------------------------------------------------------------------------- /.vitepress/scripts/prepare.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra') 2 | 3 | async function main(){ 4 | await fs.remove('.vitepress/@slidev') 5 | await fs.copy('node_modules/@slidev', '.vitepress/@slidev', { dereference: true }) 6 | } 7 | 8 | main() 9 | -------------------------------------------------------------------------------- /.vitepress/showcases.ts: -------------------------------------------------------------------------------- 1 | export interface ShowCaseInfo { 2 | title: string 3 | cover: string 4 | slidesLink?: string 5 | sourceLink?: string 6 | videoLink?: string 7 | at?: string 8 | datetime: string 9 | author: { 10 | name: string 11 | link?: string 12 | } 13 | } 14 | 15 | export const showcases: ShowCaseInfo[] = [ 16 | { 17 | title: 'Composable Vue', 18 | cover: `${import.meta.env.BASE_URL}showcases/composable-vue.png`, 19 | author: { 20 | name: 'Anthony Fu', 21 | link: 'https://github.com/antfu', 22 | }, 23 | slidesLink: 'https://sli.dev/demo/composable-vue', 24 | sourceLink: 'https://github.com/antfu/talks/tree/master/2021-04-29', 25 | at: 'VueDay 2021', 26 | datetime: '2021-04-29', 27 | }, 28 | { 29 | title: 'Developer Seonglae', 30 | cover: 'https://seonglae-slides.vercel.app/og.png', 31 | author: { 32 | name: 'Seonglae Cho', 33 | link: 'https://github.com/seonglae', 34 | }, 35 | slidesLink: 'https://seonglae-slides.vercel.app', 36 | sourceLink: 'https://github.com/seonglae/seonglae-slides', 37 | at: 'Seongland', 38 | datetime: '2021-05-10', 39 | }, 40 | { 41 | title: 'Vue 3 > Vue 2 + 1', 42 | cover: 'https://user-images.githubusercontent.com/11247099/122246420-1df97b80-cef9-11eb-9c57-7751c6999deb.png', 43 | author: { 44 | name: 'Thorsten Lünborg', 45 | link: 'https://github.com/LinusBorg', 46 | }, 47 | slidesLink: 'http://vueday-2021.linusb.org', 48 | sourceLink: 'https://github.com/LinusBorg/vueday-enterjs-vue3', 49 | at: 'Enter.js Vue Day', 50 | datetime: '2021-06-15', 51 | }, 52 | { 53 | title: 'Simply Publish Your Package to npm', 54 | author: { 55 | name: 'Lucky Dewa Satria', 56 | link: 'https://github.com/lucky401', 57 | }, 58 | at: 'Weekly sharing', 59 | slidesLink: 'https://masukin.link/talks/simply-publish-your-package-to-npm', 60 | cover: 'https://masukin.link/talks-cover-npm.png', 61 | datetime: '2021-06-12', 62 | }, 63 | { 64 | title: 'Create Icon Package With Vue and Rollup', 65 | author: { 66 | name: 'Lucky Dewa Satria', 67 | link: 'https://github.com/lucky401', 68 | }, 69 | at: 'Weekly Sharing', 70 | slidesLink: 'https://masukin.link/talks/create-icon-package-with-vue-and-rollup', 71 | sourceLink: 'https://github.com/lucky401/Create-Icon-Package-With-Vue-and-Rollup', 72 | cover: 'https://masukin.link/talks-cover-create-icon-package-with-vue-and-rollup.png', 73 | datetime: '2021-06-19', 74 | }, 75 | { 76 | title: 'BeAPT', 77 | author: { 78 | name: 'Daniel Sousa @TutoDS', 79 | link: 'https://github.com/tutods', 80 | }, 81 | at: 'Presentation of my college final project', 82 | slidesLink: 'https://beapt-presentation.netlify.app', 83 | sourceLink: 'https://github.com/TutoDS/lei-project/tree/master/presentation', 84 | cover: 'https://raw.githubusercontent.com/TutoDS/lei-project/master/presentation/cover.png', 85 | datetime: '2021-07-20', 86 | }, 87 | { 88 | title: 'Prisma as my ORM for PostgreSQL', 89 | cover: 'https://raw.githubusercontent.com/cedric25/prisma-talk/main/cover-for-slidev.png', 90 | author: { 91 | name: 'Cedric Nicoloso', 92 | link: 'https://github.com/cedric25', 93 | }, 94 | slidesLink: 'https://prisma-talk.netlify.app/', 95 | sourceLink: 'https://github.com/cedric25/prisma-talk', 96 | at: 'LyonJS Meetup', 97 | datetime: '2021-07-21', 98 | }, 99 | { 100 | title: 'Introduction to SVG', 101 | cover: 'https://raw.githubusercontent.com/lyqht/intro-to-svg-slides/main/intro-to-svg-slides-cover.png', 102 | author: { 103 | name: 'Estee Tey', 104 | link: 'https://github.com/lyqht', 105 | }, 106 | slidesLink: 'https://lyqht.github.io/intro-to-svg-slides/', 107 | sourceLink: 'https://github.com/lyqht/intro-to-svg-slides', 108 | at: 'Thoughtworks Internal Lunch & Learn', 109 | datetime: '2021-11-12', 110 | }, 111 | // Add yours here! 112 | { 113 | title: 'Yours?', 114 | author: { 115 | name: '', 116 | }, 117 | at: 'Submit your talk/presentation to be list here!', 118 | slidesLink: 'https://github.com/slidevjs/docs/edit/main/.vitepress/showcases.ts', 119 | cover: `${import.meta.env.BASE_URL}theme-placeholder.png`, 120 | datetime: '2021-04-29', 121 | }, 122 | ] 123 | -------------------------------------------------------------------------------- /.vitepress/theme/Layout.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 145 | 146 | 169 | -------------------------------------------------------------------------------- /.vitepress/theme/NotFound.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | -------------------------------------------------------------------------------- /.vitepress/theme/components/AlgoliaSearchBox.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 130 | 131 | 174 | -------------------------------------------------------------------------------- /.vitepress/theme/components/BooleanDisplay.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 28 | -------------------------------------------------------------------------------- /.vitepress/theme/components/DarkModeSwitch.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /.vitepress/theme/components/DemoContainer.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 19 | -------------------------------------------------------------------------------- /.vitepress/theme/components/EditLink.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | 16 | 40 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Environment.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 24 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Home.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 24 | -------------------------------------------------------------------------------- /.vitepress/theme/components/HomeFeatures.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 34 | 35 | 138 | -------------------------------------------------------------------------------- /.vitepress/theme/components/HomeFooter.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 41 | -------------------------------------------------------------------------------- /.vitepress/theme/components/HomeHero.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 72 | 73 | 175 | -------------------------------------------------------------------------------- /.vitepress/theme/components/LastUpdated.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 43 | 44 | 70 | -------------------------------------------------------------------------------- /.vitepress/theme/components/NavBar.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 56 | 57 | 112 | -------------------------------------------------------------------------------- /.vitepress/theme/components/NavBarTitle.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 44 | -------------------------------------------------------------------------------- /.vitepress/theme/components/NavDropdownLink.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 36 | 37 | 132 | -------------------------------------------------------------------------------- /.vitepress/theme/components/NavDropdownLinkItem.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 25 | 26 | 77 | -------------------------------------------------------------------------------- /.vitepress/theme/components/NavLink.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 23 | 24 | 62 | -------------------------------------------------------------------------------- /.vitepress/theme/components/NavLinks.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 29 | 30 | 49 | -------------------------------------------------------------------------------- /.vitepress/theme/components/NextAndPrevLinks.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 27 | 28 | 88 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Note.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Page.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 23 | 24 | 49 | -------------------------------------------------------------------------------- /.vitepress/theme/components/PageFooter.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 43 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ShowCaseInfo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 68 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ShowCases.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /.vitepress/theme/components/SideBar.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 22 | 23 | 58 | -------------------------------------------------------------------------------- /.vitepress/theme/components/SideBarLink.ts: -------------------------------------------------------------------------------- 1 | import { FunctionalComponent, h, VNode } from 'vue' 2 | import { useRoute, useSiteData } from 'vitepress' 3 | import { DefaultTheme } from '../config' 4 | import { joinUrl, isActive } from '../utils' 5 | 6 | export interface Header { 7 | level: number 8 | title: string 9 | slug: string 10 | } 11 | 12 | interface HeaderWithChildren extends Header { 13 | children?: Header[] 14 | } 15 | 16 | export const SideBarLink: FunctionalComponent<{ 17 | item: DefaultTheme.SideBarItem 18 | }> = (props) => { 19 | const route = useRoute() 20 | const site = useSiteData() 21 | 22 | const headers = route.data.headers 23 | const text = props.item.text 24 | const link = resolveLink(site.value.base, props.item.link) 25 | const children = (props.item as DefaultTheme.SideBarGroup).children 26 | const active = isActive(route, props.item.link) 27 | const childItems = createChildren(active, children, headers) 28 | 29 | return h('li', { class: 'sidebar-link' }, [ 30 | h( 31 | link ? 'a' : 'p', 32 | { 33 | class: { 'sidebar-link-item': true, active }, 34 | href: link, 35 | }, 36 | text, 37 | ), 38 | childItems, 39 | ]) 40 | } 41 | 42 | function resolveLink(base: string, path?: string): string | undefined { 43 | if (path === undefined) 44 | return path 45 | 46 | // keep relative hash to the same page 47 | if (path.startsWith('#')) 48 | return path 49 | 50 | return joinUrl(base, path) 51 | } 52 | 53 | function createChildren( 54 | active: boolean, 55 | children?: DefaultTheme.SideBarItem[], 56 | headers?: Header[], 57 | ): VNode | null { 58 | if (children && children.length > 0) { 59 | return h( 60 | 'ul', 61 | { class: 'sidebar-links' }, 62 | children.map((c) => { 63 | return h(SideBarLink, { item: c }) 64 | }), 65 | ) 66 | } 67 | 68 | return active && headers 69 | ? createChildren(false, resolveHeaders(headers)) 70 | : null 71 | } 72 | 73 | function resolveHeaders(headers: Header[]): DefaultTheme.SideBarItem[] { 74 | return mapHeaders(groupHeaders(headers)) 75 | } 76 | 77 | function groupHeaders(headers: Header[]): HeaderWithChildren[] { 78 | headers = headers.map(h => Object.assign({}, h)) 79 | let lastH2: HeaderWithChildren 80 | headers.forEach((h) => { 81 | if (h.level === 2) 82 | lastH2 = h 83 | 84 | else if (lastH2) 85 | (lastH2.children || (lastH2.children = [])).push(h) 86 | }) 87 | return headers.filter(h => h.level === 2) 88 | } 89 | 90 | function mapHeaders(headers: HeaderWithChildren[]): DefaultTheme.SideBarItem[] { 91 | return headers.map(header => ({ 92 | text: header.title, 93 | link: `#${header.slug}`, 94 | children: header.children ? mapHeaders(header.children) : undefined, 95 | })) 96 | } 97 | -------------------------------------------------------------------------------- /.vitepress/theme/components/SideBarLinks.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ThemeGallery.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ThemeInfo.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 77 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ToggleSideBarButton.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 25 | 47 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Tweet.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 57 | 58 | 69 | -------------------------------------------------------------------------------- /.vitepress/theme/components/WorkingInProgress.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 36 | -------------------------------------------------------------------------------- /.vitepress/theme/components/demo/Demo.vue: -------------------------------------------------------------------------------- 1 | 111 | 112 | 155 | 156 | 164 | -------------------------------------------------------------------------------- /.vitepress/theme/components/demo/DemoEditor.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 31 | -------------------------------------------------------------------------------- /.vitepress/theme/components/demo/DemoSlide.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | -------------------------------------------------------------------------------- /.vitepress/theme/components/icons/ArrowLeft.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /.vitepress/theme/components/icons/ArrowRight.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /.vitepress/theme/components/icons/Moon.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /.vitepress/theme/components/icons/OutboundLink.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 32 | -------------------------------------------------------------------------------- /.vitepress/theme/components/icons/README.md: -------------------------------------------------------------------------------- 1 | Download from https://icones.js.org/collection/carbon 2 | -------------------------------------------------------------------------------- /.vitepress/theme/components/icons/Sun.vue: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/activeSidebarLink.ts: -------------------------------------------------------------------------------- 1 | import { onMounted, onUnmounted, onUpdated } from 'vue-demi' 2 | 3 | export function useActiveSidebarLinks() { 4 | let rootActiveLink: HTMLAnchorElement | null = null 5 | let activeLink: HTMLAnchorElement | null = null 6 | 7 | const onScroll = throttleAndDebounce(setActiveLink, 300) 8 | 9 | function setActiveLink(): void { 10 | const sidebarLinks = getSidebarLinks() 11 | const anchors = getAnchors(sidebarLinks) 12 | 13 | for (let i = 0; i < anchors.length; i++) { 14 | const anchor = anchors[i] 15 | const nextAnchor = anchors[i + 1] 16 | 17 | const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor) 18 | 19 | if (isActive) { 20 | history.replaceState(null, document.title, hash || ' ') 21 | activateLink(hash) 22 | return 23 | } 24 | } 25 | } 26 | 27 | function activateLink(hash: string | null): void { 28 | deactiveLink(activeLink) 29 | deactiveLink(rootActiveLink) 30 | 31 | activeLink = document.querySelector(`.sidebar a[href="${hash}"]`) 32 | 33 | if (!activeLink) 34 | return 35 | 36 | activeLink.classList.add('active') 37 | 38 | // also add active class to parent h2 anchors 39 | const rootLi = activeLink.closest('.sidebar-links > ul > li') 40 | 41 | if (rootLi && rootLi !== activeLink.parentElement) { 42 | rootActiveLink = rootLi.querySelector('a') 43 | rootActiveLink && rootActiveLink.classList.add('active') 44 | } 45 | else { 46 | rootActiveLink = null 47 | } 48 | } 49 | 50 | function deactiveLink(link: HTMLAnchorElement | null): void { 51 | link && link.classList.remove('active') 52 | } 53 | 54 | onMounted(() => { 55 | setActiveLink() 56 | window.addEventListener('scroll', onScroll) 57 | }) 58 | 59 | onUpdated(() => { 60 | // sidebar update means a route change 61 | activateLink(decodeURIComponent(location.hash)) 62 | }) 63 | 64 | onUnmounted(() => { 65 | window.removeEventListener('scroll', onScroll) 66 | }) 67 | } 68 | 69 | function getSidebarLinks(): HTMLAnchorElement[] { 70 | return [].slice.call( 71 | document.querySelectorAll('.sidebar a.sidebar-link-item'), 72 | ) 73 | } 74 | 75 | function getAnchors(sidebarLinks: HTMLAnchorElement[]): HTMLAnchorElement[] { 76 | return [].slice 77 | .call(document.querySelectorAll('.header-anchor')) 78 | .filter((anchor: HTMLAnchorElement) => 79 | sidebarLinks.some(sidebarLink => sidebarLink.hash === anchor.hash), 80 | ) as HTMLAnchorElement[] 81 | } 82 | 83 | function getPageOffset(): number { 84 | return (document.querySelector('.nav-bar') as HTMLElement).offsetHeight 85 | } 86 | 87 | function getAnchorTop(anchor: HTMLAnchorElement): number { 88 | const pageOffset = getPageOffset() 89 | 90 | return anchor.parentElement!.offsetTop - pageOffset - 15 91 | } 92 | 93 | function isAnchorActive( 94 | index: number, 95 | anchor: HTMLAnchorElement, 96 | nextAnchor: HTMLAnchorElement, 97 | ): [boolean, string | null] { 98 | const scrollTop = window.scrollY 99 | 100 | if (index === 0 && scrollTop === 0) 101 | return [true, null] 102 | 103 | if (scrollTop < getAnchorTop(anchor)) 104 | return [false, null] 105 | 106 | if (!nextAnchor || scrollTop < getAnchorTop(nextAnchor)) 107 | return [true, decodeURIComponent(anchor.hash)] 108 | 109 | return [false, null] 110 | } 111 | 112 | function throttleAndDebounce(fn: () => void, delay: number): () => void { 113 | let timeout: NodeJS.Timeout 114 | let called = false 115 | 116 | return () => { 117 | if (timeout) 118 | clearTimeout(timeout) 119 | 120 | if (!called) { 121 | fn() 122 | called = true 123 | setTimeout(() => { 124 | called = false 125 | }, delay) 126 | } 127 | else { 128 | timeout = setTimeout(fn, delay) 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/dark.ts: -------------------------------------------------------------------------------- 1 | import { useDark } from '@vueuse/core' 2 | 3 | export const isDark = useDark() 4 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/editLink.ts: -------------------------------------------------------------------------------- 1 | import { computed } from 'vue-demi' 2 | import { useSiteDataByRoute, usePageData } from 'vitepress' 3 | import { endingSlashRE, isNullish, isExternal } from '../utils' 4 | 5 | const bitbucketRE = /bitbucket.org/ 6 | 7 | export function useEditLink() { 8 | const site = useSiteDataByRoute() 9 | const page = usePageData() 10 | 11 | const url = computed(() => { 12 | const showEditLink = isNullish(page.value.frontmatter.editLink) 13 | ? site.value.themeConfig.editLinks 14 | : page.value.frontmatter.editLink 15 | 16 | const { 17 | repo, 18 | docsDir = '', 19 | docsBranch = 'main', 20 | docsRepo = repo, 21 | } = site.value.themeConfig 22 | 23 | const { relativePath } = page.value 24 | 25 | if (!showEditLink || !relativePath || !repo) 26 | return null 27 | 28 | return createUrl(repo, docsRepo, docsDir, docsBranch, relativePath) 29 | }) 30 | 31 | const text = computed(() => { 32 | return site.value.themeConfig.editLinkText || 'Edit this page' 33 | }) 34 | 35 | return { 36 | url, 37 | text, 38 | } 39 | } 40 | 41 | function createUrl( 42 | repo: string, 43 | docsRepo: string, 44 | docsDir: string, 45 | docsBranch: string, 46 | path: string, 47 | ): string { 48 | return bitbucketRE.test(repo) 49 | ? createBitbucketUrl(repo, docsRepo, docsDir, docsBranch, path) 50 | : createGitHubUrl(repo, docsRepo, docsDir, docsBranch, path) 51 | } 52 | 53 | function createGitHubUrl( 54 | repo: string, 55 | docsRepo: string, 56 | docsDir: string, 57 | docsBranch: string, 58 | path: string, 59 | ): string { 60 | const base = isExternal(docsRepo) 61 | ? docsRepo 62 | : `https://github.com/${docsRepo}` 63 | 64 | return ( 65 | `${base.replace(endingSlashRE, '') 66 | }/edit` 67 | + `/${docsBranch}/${ 68 | docsDir ? `${docsDir.replace(endingSlashRE, '')}/` : '' 69 | }${path}` 70 | ) 71 | } 72 | 73 | function createBitbucketUrl( 74 | repo: string, 75 | docsRepo: string, 76 | docsDir: string, 77 | docsBranch: string, 78 | path: string, 79 | ): string { 80 | const base = isExternal(docsRepo) ? docsRepo : repo 81 | 82 | return ( 83 | `${base.replace(endingSlashRE, '') 84 | }/src` 85 | + `/${docsBranch}/${ 86 | docsDir ? `${docsDir.replace(endingSlashRE, '')}/` : '' 87 | }${path 88 | }?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default` 89 | ) 90 | } 91 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/nav.ts: -------------------------------------------------------------------------------- 1 | import { computed } from 'vue-demi' 2 | import { useRoute, useSiteData, inBrowser } from 'vitepress' 3 | import type { DefaultTheme } from '../config' 4 | 5 | export function useLocaleLinks() { 6 | const route = useRoute() 7 | const site = useSiteData() 8 | 9 | return computed(() => { 10 | const theme = site.value.themeConfig as DefaultTheme.Config 11 | const locales = theme.locales 12 | 13 | if (!locales) 14 | return null 15 | 16 | const localeKeys = Object.keys(locales) 17 | 18 | if (localeKeys.length <= 1) 19 | return null 20 | 21 | // handle site base 22 | const siteBase = inBrowser ? site.value.base : '/' 23 | 24 | const siteBaseWithoutSuffix = siteBase.endsWith('/') 25 | ? siteBase.slice(0, -1) 26 | : siteBase 27 | 28 | // remove site base in browser env 29 | const routerPath = route.path.slice(siteBaseWithoutSuffix.length) 30 | 31 | const currentLangBase = localeKeys.find((key) => { 32 | return key === '/' ? false : routerPath.startsWith(key) 33 | }) 34 | 35 | const currentContentPath = currentLangBase 36 | ? routerPath.substring(currentLangBase.length - 1) 37 | : routerPath 38 | 39 | const candidates = localeKeys.map((v) => { 40 | const localePath = v.endsWith('/') ? v.slice(0, -1) : v 41 | 42 | return { 43 | text: locales[v].label, 44 | link: `${localePath}${currentContentPath}`, 45 | } 46 | }) 47 | 48 | const currentLangKey = currentLangBase || '/' 49 | 50 | const selectText = locales[currentLangKey].selectText 51 | ? locales[currentLangKey].selectText 52 | : 'Languages' 53 | 54 | return { 55 | text: selectText, 56 | items: candidates, 57 | } as DefaultTheme.NavItemWithChildren 58 | }) 59 | } 60 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/navLink.ts: -------------------------------------------------------------------------------- 1 | import { computed, Ref } from 'vue-demi' 2 | import { useRoute } from 'vitepress' 3 | import type { DefaultTheme } from '../config' 4 | import { isExternal as isExternalCheck } from '../utils' 5 | import { useUrl } from '../composables/url' 6 | 7 | export function useNavLink(item: Ref) { 8 | const route = useRoute() 9 | const { withBase } = useUrl() 10 | 11 | const isExternal = isExternalCheck(item.value.link) 12 | 13 | const props = computed(() => { 14 | const link = interpret(item.value.link) 15 | const routePath = normalizePath(`/${route.data.relativePath}`) 16 | 17 | let active = false 18 | if (item.value.activeMatch) { 19 | active = new RegExp(item.value.activeMatch).test(routePath) 20 | } 21 | else { 22 | const itemPath = normalizePath(withBase(link)) 23 | active 24 | = itemPath === '/' 25 | ? itemPath === routePath 26 | : routePath.startsWith(itemPath) 27 | } 28 | 29 | return { 30 | 'class': { 31 | active, 32 | isExternal, 33 | }, 34 | 'href': isExternal ? link : withBase(link), 35 | 'target': item.value.target || isExternal ? '_blank' : null, 36 | 'rel': item.value.rel || isExternal ? 'noopener noreferrer' : null, 37 | 'aria-label': item.value.ariaLabel, 38 | } 39 | }) 40 | 41 | return { 42 | props, 43 | isExternal, 44 | } 45 | } 46 | 47 | function interpret(path = '') { 48 | return path 49 | .replace(/{{pathname}}/, typeof window === 'undefined' ? '/' : location.pathname) 50 | } 51 | 52 | function normalizePath(path: string): string { 53 | return path 54 | .replace(/#.*$/, '') 55 | .replace(/\?.*$/, '') 56 | .replace(/\.(html|md)$/, '') 57 | .replace(/\/index$/, '/') 58 | } 59 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/nextAndPrevLinks.ts: -------------------------------------------------------------------------------- 1 | import { computed } from 'vue-demi' 2 | import { useSiteDataByRoute, usePageData } from 'vitepress' 3 | import { isArray, ensureStartingSlash } from '../utils' 4 | import { getSideBarConfig, getFlatSideBarLinks } from '../support/sideBar' 5 | 6 | export function useNextAndPrevLinks() { 7 | const site = useSiteDataByRoute() 8 | const page = usePageData() 9 | 10 | const path = computed(() => { 11 | return ensureStartingSlash(page.value.relativePath) 12 | }) 13 | 14 | const candidates = computed(() => { 15 | const config = getSideBarConfig(site.value.themeConfig.sidebar, path.value) 16 | 17 | return isArray(config) ? getFlatSideBarLinks(config) : [] 18 | }) 19 | 20 | const index = computed(() => { 21 | return candidates.value.findIndex((item) => { 22 | return item.link === path.value 23 | }) 24 | }) 25 | 26 | const next = computed(() => { 27 | if ( 28 | site.value.themeConfig.nextLinks !== false 29 | && index.value > -1 30 | && index.value < candidates.value.length - 1 31 | ) 32 | return candidates.value[index.value + 1] 33 | }) 34 | 35 | const prev = computed(() => { 36 | if (site.value.themeConfig.prevLinks !== false && index.value > 0) 37 | return candidates.value[index.value - 1] 38 | }) 39 | 40 | const hasLinks = computed(() => !!next.value || !!prev.value) 41 | 42 | return { 43 | next, 44 | prev, 45 | hasLinks, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/repo.ts: -------------------------------------------------------------------------------- 1 | import { computed } from 'vue-demi' 2 | import { useSiteDataByRoute } from 'vitepress' 3 | import type { DefaultTheme } from '../config' 4 | 5 | export const platforms = ['GitHub', 'GitLab', 'Bitbucket'].map((platform) => { 6 | return [platform, new RegExp(platform, 'i')] as const 7 | }) 8 | 9 | export function useRepo() { 10 | const site = useSiteDataByRoute() 11 | 12 | return computed(() => { 13 | const theme = site.value.themeConfig as DefaultTheme.Config 14 | const name = theme.docsRepo || theme.repo 15 | 16 | if (!name) 17 | return null 18 | 19 | const link = getRepoUrl(name) 20 | const text = getRepoText(link, theme.repoLabel) 21 | 22 | return { text, link } 23 | }) 24 | } 25 | 26 | function getRepoUrl(repo: string): string { 27 | // if the full url is not provided, default to GitHub repo 28 | return /^https?:/.test(repo) ? repo : `https://github.com/${repo}` 29 | } 30 | 31 | function getRepoText(url: string, text?: string): string { 32 | if (text) 33 | return text 34 | 35 | // if no label is provided, deduce it from the repo url 36 | const hosts = url.match(/^https?:\/\/[^/]+/) 37 | 38 | if (!hosts) 39 | return 'Source' 40 | 41 | const platform = platforms.find(([, re]) => re.test(hosts[0])) 42 | 43 | if (platform && platform[0]) 44 | return platform[0] 45 | 46 | return 'Source' 47 | } 48 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/sideBar.ts: -------------------------------------------------------------------------------- 1 | import { computed } from 'vue-demi' 2 | import { useRoute, useSiteDataByRoute } from 'vitepress' 3 | // import { Header } from '/@types/shared' 4 | import { useActiveSidebarLinks } from '../composables/activeSidebarLink' 5 | import { getSideBarConfig } from '../support/sideBar' 6 | import { DefaultTheme } from '../config' 7 | 8 | export function useSideBar() { 9 | const route = useRoute() 10 | const site = useSiteDataByRoute() 11 | 12 | useActiveSidebarLinks() 13 | 14 | return computed(() => { 15 | // at first, we'll check if we can find the sidebar setting in frontmatter. 16 | const headers = route.data.headers 17 | const frontSidebar = route.data.frontmatter.sidebar 18 | const sidebarDepth = route.data.frontmatter.sidebarDepth 19 | 20 | // if it's `false`, we'll just return an empty array here. 21 | if (frontSidebar === false) 22 | return [] 23 | 24 | // if it's `atuo`, render headers of the current page 25 | if (frontSidebar === 'auto') 26 | return resolveAutoSidebar(headers, sidebarDepth) 27 | 28 | // now, there's no sidebar setting at frontmatter; let's see the configs 29 | const themeSidebar = getSideBarConfig( 30 | site.value.themeConfig.sidebar, 31 | route.path, 32 | ) 33 | 34 | if (themeSidebar === false) 35 | return [] 36 | 37 | if (themeSidebar === 'auto') 38 | return resolveAutoSidebar(headers, sidebarDepth) 39 | 40 | return themeSidebar 41 | }) 42 | } 43 | 44 | function resolveAutoSidebar( 45 | headers: any[], 46 | depth: number, 47 | ): DefaultTheme.SideBarItem[] { 48 | const ret: DefaultTheme.SideBarItem[] = [] 49 | 50 | if (headers === undefined) 51 | return [] 52 | 53 | let lastH2: DefaultTheme.SideBarItem | undefined 54 | headers.forEach(({ level, title, slug }) => { 55 | if (level - 1 > depth) 56 | return 57 | 58 | const item: DefaultTheme.SideBarItem = { 59 | text: title, 60 | link: `#${slug}`, 61 | } 62 | if (level === 2) { 63 | lastH2 = item 64 | ret.push(item) 65 | } 66 | else if (lastH2) { 67 | ((lastH2 as any).children || ((lastH2 as any).children = [])).push(item) 68 | } 69 | }) 70 | 71 | return ret 72 | } 73 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/url.ts: -------------------------------------------------------------------------------- 1 | import { useSiteData, joinPath } from 'vitepress' 2 | 3 | export function useUrl() { 4 | const site = useSiteData() 5 | 6 | function withBase(path: string): string { 7 | if (!path) 8 | return '' 9 | return joinPath(site.value.base, path) 10 | } 11 | 12 | return { 13 | withBase, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.vitepress/theme/composables/versions.ts: -------------------------------------------------------------------------------- 1 | export * from '../../../../meta/packages' 2 | -------------------------------------------------------------------------------- /.vitepress/theme/config.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define */ 2 | /* eslint-disable @typescript-eslint/no-namespace */ 3 | 4 | export namespace DefaultTheme { 5 | export interface Config { 6 | logo?: string 7 | nav?: NavItem[] | false 8 | sidebar?: SideBarConfig | MultiSideBarConfig 9 | 10 | /** 11 | * GitHub repository following the format /. 12 | * 13 | * @example `"vuejs/vue-next"` 14 | */ 15 | repo?: string 16 | 17 | /** 18 | * Customize the header label. Defaults to GitHub/Gitlab/Bitbucket 19 | * depending on the provided repo. 20 | * 21 | * @exampe `"Contribute!"` 22 | */ 23 | repoLabel?: string 24 | 25 | /** 26 | * If your docs are in a different repository from your main project. 27 | * 28 | * @example `"vuejs/docs-next"` 29 | */ 30 | docsRepo?: string 31 | 32 | /** 33 | * If your docs are not at the root of the repo. 34 | * 35 | * @example `"docs"` 36 | */ 37 | docsDir?: string 38 | 39 | /** 40 | * If your docs are in a different branch. Defaults to `main`. 41 | * 42 | * @example `"next"` 43 | */ 44 | docsBranch?: string 45 | 46 | /** 47 | * Enable links to edit pages at the bottom of the page. 48 | */ 49 | editLinks?: boolean 50 | 51 | /** 52 | * Custom text for edit link. Defaults to "Edit this page". 53 | */ 54 | editLinkText?: string 55 | 56 | /** 57 | * Show last updated time at the bottom of the page. Defaults to `false`. 58 | * If given a string, it will be displayed as a prefix (default value: 59 | * "Last Updated"). 60 | */ 61 | lastUpdated?: string | boolean 62 | 63 | prevLinks?: boolean 64 | nextLinks?: boolean 65 | 66 | locales?: Record> 67 | } 68 | 69 | // navbar -------------------------------------------------------------------- 70 | 71 | export type NavItem = NavItemWithLink | NavItemWithChildren 72 | 73 | export interface NavItemBase { 74 | text: string 75 | target?: string 76 | rel?: string 77 | ariaLabel?: string 78 | activeMatch?: string 79 | } 80 | 81 | export interface NavItemWithLink extends NavItemBase { 82 | link: string 83 | } 84 | 85 | export interface NavItemWithChildren extends NavItemBase { 86 | items: NavItemWithLink[] 87 | } 88 | 89 | // sidebar ------------------------------------------------------------------- 90 | 91 | export type SideBarConfig = SideBarItem[] | 'auto' | false 92 | 93 | export interface MultiSideBarConfig { 94 | [path: string]: SideBarConfig 95 | } 96 | 97 | export type SideBarItem = SideBarLink | SideBarGroup 98 | 99 | export interface SideBarLink { 100 | text: string 101 | link: string 102 | } 103 | 104 | export interface SideBarGroup { 105 | text: string 106 | link?: string 107 | 108 | /** 109 | * @default false 110 | */ 111 | collapsable?: boolean 112 | 113 | children: SideBarItem[] 114 | } 115 | 116 | // locales ------------------------------------------------------------------- 117 | 118 | export interface LocaleConfig { 119 | /** 120 | * Text for the language dropdown. 121 | */ 122 | selectText?: string 123 | 124 | /** 125 | * Label for this locale in the language dropdown. 126 | */ 127 | label?: string 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import Layout from './Layout.vue' 2 | import NotFound from './NotFound.vue' 3 | 4 | import 'windi-base.css' 5 | import 'windi-components.css' 6 | import './styles/vars.css' 7 | import './styles/layout.css' 8 | import './styles/code.css' 9 | import './styles/custom-blocks.css' 10 | import './styles/sidebar-links.css' 11 | import 'windi-utilities.css' 12 | 13 | const theme = { 14 | Layout, 15 | NotFound, 16 | } 17 | 18 | export default theme 19 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/code.css: -------------------------------------------------------------------------------- 1 | /* https://github.com/antfu/prism-theme-vars */ 2 | @import 'prism-theme-vars/base.css'; 3 | @import 'prism-theme-vars/marker.css'; 4 | 5 | :root { 6 | --prism-font-family: var(--font-family-mono); 7 | --prism-font-size: 0.85rem; 8 | --prism-marker-opacity: 0; 9 | } 10 | 11 | html:not(.dark) { 12 | --prism-foreground: #393a34; 13 | --prism-background: #fafafa; 14 | --prism-inline-background: #f5f5f5; 15 | --prism-comment: #a0ada0; 16 | --prism-string: #b56959; 17 | --prism-literal: #2f8a89; 18 | --prism-number: #296aa3; 19 | --prism-keyword: #1c6b48; 20 | --prism-function: #6c7834; 21 | --prism-boolean: #296aa3; 22 | --prism-constant: #a65e2b; 23 | --prism-deleted: #a14f55; 24 | --prism-class: #2993a3; 25 | --prism-builtin: #ab5959; 26 | --prism-property: #b58451; 27 | --prism-namespace: #b05a78; 28 | --prism-punctuation: #8e8f8b; 29 | --prism-decorator: #bd8f8f; 30 | --prism-regex: #ab5e3f; 31 | --prism-json-property: #698c96; 32 | } 33 | 34 | html.dark { 35 | --prism-scheme: dark; 36 | --prism-foreground: #d4cfbf; 37 | --prism-background: #181818; 38 | --prism-comment: #758575; 39 | --prism-string: #d48372; 40 | --prism-literal: #429988; 41 | --prism-keyword: #4d9375; 42 | --prism-boolean: #6394bf; 43 | --prism-number: #6394bf; 44 | --prism-variable: #c2b36e; 45 | --prism-function: #a1b567; 46 | --prism-deleted: #bc6066; 47 | --prism-class: #54b1bf; 48 | --prism-builtin: #e0a569; 49 | --prism-property: #dd8e6e; 50 | --prism-namespace: #db889a; 51 | --prism-punctuation: #858585; 52 | --prism-decorator: #bd8f8f; 53 | --prism-regex: #ab5e3f; 54 | --prism-json-property: #6b8b9e; 55 | --prism-line-number: #888888; 56 | --prism-line-number-gutter: #eeeeee; 57 | --prism-line-highlight-background: #444444; 58 | --prism-selection-background: #444444; 59 | --prism-inline-background: theme('colors.dark.300'); 60 | } 61 | 62 | 63 | .token.title { 64 | color: var(--prism-keyword); 65 | } 66 | 67 | /* Overrides */ 68 | 69 | pre, code { 70 | @apply font-mono; 71 | } 72 | 73 | :not(pre) > code { 74 | background: var(--prism-inline-background); 75 | padding: 1px 6px; 76 | border-radius: 3px; 77 | } 78 | 79 | a > code { 80 | color: var(--c-brand-dark); 81 | } 82 | 83 | div[class*='language-'] { 84 | position: relative; 85 | } 86 | 87 | div[class*='language-'] pre { 88 | margin: 0; 89 | z-index: 1; 90 | } 91 | 92 | div[class*='language-'] code { 93 | font-size: var(--prism-font-size); 94 | font-family: var(--prism-font-family); 95 | } 96 | 97 | .token.important { 98 | font-weight: normal; 99 | } 100 | 101 | /* Line highlighting */ 102 | 103 | .highlight-lines { 104 | position: absolute; 105 | top: 0; 106 | bottom: 0; 107 | left: 0; 108 | padding: var(--prism-block-padding-y) 0; 109 | width: 100%; 110 | line-height: var(--prism-line-height); 111 | font-family: var(--prism-font-family); 112 | font-size: var(--prism-font-size); 113 | user-select: none; 114 | overflow: hidden; 115 | z-index: -1; 116 | } 117 | 118 | .highlight-lines .highlighted { 119 | background-color: var(--prism-line-highlight-background); 120 | } 121 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/custom-blocks.css: -------------------------------------------------------------------------------- 1 | .custom-block.tip, 2 | .custom-block.warning, 3 | .custom-block.danger { 4 | margin: 2rem 0 1rem 0; 5 | border-left: .5rem solid; 6 | padding: .1rem 1.5rem; 7 | overflow-x: auto; 8 | } 9 | 10 | .custom-block.tip { 11 | background-color: var(--c-bg-secondary); 12 | border-color: #42b983; 13 | } 14 | 15 | .custom-block.warning { 16 | border-color: #e7c000; 17 | background-color: rgba(255, 229, 100, .3); 18 | } 19 | 20 | .custom-block.warning .custom-block-title { 21 | color: #b29400; 22 | } 23 | 24 | .custom-block.warning a { 25 | color: var(--c-text); 26 | } 27 | 28 | .custom-block.danger { 29 | border-color: #c00; 30 | background-color: #ffe6e6; 31 | } 32 | 33 | .custom-block.danger .custom-block-title { 34 | color: #900; 35 | } 36 | 37 | .custom-block.danger a { 38 | color: var(--c-text); 39 | } 40 | 41 | .custom-block.details { 42 | position: relative; 43 | display: block; 44 | border-radius: 2px; 45 | margin: 1.6em 0; 46 | padding: 1.6em; 47 | background-color: #eee; 48 | } 49 | 50 | .custom-block.details h4 { 51 | margin-top: 0; 52 | } 53 | 54 | .custom-block.details figure:last-child, 55 | .custom-block.details p:last-child { 56 | margin-bottom: 0; 57 | padding-bottom: 0; 58 | } 59 | 60 | .custom-block.details summary { 61 | outline: none; 62 | cursor: pointer; 63 | } 64 | 65 | .custom-block-title { 66 | display: none; 67 | } 68 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/layout.css: -------------------------------------------------------------------------------- 1 | *, 2 | ::before, 3 | ::after { 4 | box-sizing: border-box; 5 | border-width: 0; 6 | border-style: solid; 7 | border-color: #e5e7eb; 8 | } 9 | /* 10 | * { 11 | scrollbar-color: var(--c-divider-light) var(--c-bg); 12 | } 13 | ::-webkit-scrollbar { 14 | width: var(--scrollbar-width); 15 | } 16 | ::-webkit-scrollbar:horizontal { 17 | height: var(--scrollbar-width); 18 | } 19 | ::-webkit-scrollbar-track { 20 | background: var(--c-bg); 21 | border-radius: 10px; 22 | } 23 | ::-webkit-scrollbar-thumb { 24 | background: transparent; 25 | border-radius: 10px; 26 | background-clip: padding-box; 27 | } 28 | ::-webkit-scrollbar-thumb:hover { 29 | background: var(--c-divider-dark); 30 | } 31 | *:hover::-webkit-scrollbar-thumb { 32 | background: var(--c-divider-light); 33 | } */ 34 | 35 | html { 36 | line-height: 1.4; 37 | font-size: 16px; 38 | -webkit-text-size-adjust: 100%; 39 | } 40 | 41 | body { 42 | margin: 0; 43 | width: 100%; 44 | min-width: 320px; 45 | min-height: 100vh; 46 | line-height: 1.4; 47 | font-family: var(--font-family-base); 48 | font-size: 16px; 49 | font-weight: 400; 50 | color: var(--c-text); 51 | background-color: var(--c-bg); 52 | direction: ltr; 53 | font-synthesis: none; 54 | text-rendering: optimizeLegibility; 55 | -webkit-font-smoothing: antialiased; 56 | -moz-osx-font-smoothing: grayscale; 57 | overflow-x: hidden; 58 | } 59 | 60 | main { 61 | display: block; 62 | } 63 | 64 | h1, 65 | h2, 66 | h3, 67 | h4, 68 | h5, 69 | h6 { 70 | margin: 0; 71 | line-height: 1.25; 72 | } 73 | 74 | h1, 75 | h2, 76 | h3, 77 | h4, 78 | h5, 79 | h6, 80 | strong, 81 | b { 82 | font-weight: 600; 83 | } 84 | 85 | h1:hover .header-anchor, 86 | h1:focus .header-anchor, 87 | h2:hover .header-anchor, 88 | h2:focus .header-anchor, 89 | h3:hover .header-anchor, 90 | h3:focus .header-anchor, 91 | h4:hover .header-anchor, 92 | h4:focus .header-anchor, 93 | h5:hover .header-anchor, 94 | h5:focus .header-anchor, 95 | h6:hover .header-anchor, 96 | h6:focus .header-anchor { 97 | opacity: 1; 98 | } 99 | 100 | h1 { 101 | margin-top: 1.5rem; 102 | font-size: 1.9rem; 103 | } 104 | 105 | @media screen and (min-width: 420px) { 106 | h1 { 107 | font-size: 2.2rem; 108 | } 109 | } 110 | 111 | h2 { 112 | margin-top: 2.25rem; 113 | margin-bottom: 1.25rem; 114 | border-bottom: 1px solid var(--c-divider); 115 | padding-bottom: 0.3rem; 116 | line-height: 1.25; 117 | font-size: 1.65rem; 118 | /* overflow-x: auto; */ 119 | } 120 | 121 | h2 + h3 { 122 | margin-top: 1.5rem; 123 | } 124 | 125 | h3 { 126 | margin-top: 2rem; 127 | font-size: 1.35rem; 128 | } 129 | 130 | h4 { 131 | font-size: 1.15rem; 132 | } 133 | 134 | p, 135 | ol, 136 | ul { 137 | margin: 1rem 0; 138 | line-height: 1.7; 139 | } 140 | 141 | a, 142 | area, 143 | button, 144 | [role="button"], 145 | input, 146 | label, 147 | select, 148 | summary, 149 | textarea { 150 | touch-action: manipulation; 151 | } 152 | 153 | a { 154 | text-decoration: none; 155 | color: var(--c-brand); 156 | } 157 | 158 | a:hover { 159 | text-decoration: underline; 160 | } 161 | 162 | a.header-anchor { 163 | float: left; 164 | margin-top: 0.125em; 165 | margin-left: -0.87em; 166 | padding-right: 0.23em; 167 | font-size: 0.85em; 168 | opacity: 0; 169 | } 170 | 171 | a.header-anchor:hover, 172 | a.header-anchor:focus { 173 | text-decoration: none; 174 | } 175 | 176 | figure { 177 | margin: 0; 178 | } 179 | 180 | img { 181 | max-width: 100%; 182 | } 183 | 184 | ul, 185 | ol { 186 | padding-left: 1.25em; 187 | } 188 | 189 | li > ul, 190 | li > ol { 191 | margin: 0; 192 | } 193 | 194 | table { 195 | @apply w-full; 196 | } 197 | 198 | tr { 199 | @apply border-b border-gray-400 border-opacity-20; 200 | } 201 | 202 | th { 203 | @apply text-left font-600; 204 | } 205 | 206 | td, th { 207 | @apply p-1 py-2; 208 | } 209 | 210 | blockquote { 211 | margin: 1rem 0; 212 | border-left: 0.2rem solid #8885; 213 | padding: 0.25rem 0 0.25rem 1rem; 214 | font-size: 1rem; 215 | color: var(--c-text); 216 | @apply bg-gray-400 bg-opacity-10; 217 | } 218 | 219 | kbd { 220 | @apply border border-gray-400 border-b-2 border-opacity-20 rounded; 221 | @apply bg-gray-400 bg-opacity-5 py-0.5 px-2 text-sm text-center font-mono; 222 | } 223 | 224 | blockquote > p { 225 | margin: 0; 226 | } 227 | 228 | form { 229 | margin: 0; 230 | } 231 | 232 | .theme.sidebar-open .sidebar-mask { 233 | display: block; 234 | } 235 | 236 | .theme.no-navbar > h1, 237 | .theme.no-navbar > h2, 238 | .theme.no-navbar > h3, 239 | .theme.no-navbar > h4, 240 | .theme.no-navbar > h5, 241 | .theme.no-navbar > h6 { 242 | margin-top: 1.5rem; 243 | padding-top: 0; 244 | } 245 | 246 | .theme.no-navbar aside { 247 | top: 0; 248 | } 249 | 250 | @media screen and (min-width: 720px) { 251 | .theme.no-sidebar aside { 252 | display: none; 253 | } 254 | 255 | .theme.no-sidebar main { 256 | margin-left: 0; 257 | } 258 | } 259 | 260 | .sidebar-mask { 261 | position: fixed; 262 | z-index: 2; 263 | display: none; 264 | width: 100vw; 265 | height: 100vh; 266 | } 267 | 268 | .nav-btn { 269 | display: flex; 270 | font-size: 1.05rem; 271 | border: 0; 272 | outline: none; 273 | background: none; 274 | color: var(--c-text); 275 | opacity: 0.8; 276 | cursor: pointer; 277 | } 278 | .nav-btn:hover { 279 | opacity: 1; 280 | } 281 | .nav-btn svg { 282 | margin: auto; 283 | } 284 | .external-link { 285 | font-size: 0.95rem; 286 | opacity: 0.7; 287 | } 288 | 289 | .icon-btn { 290 | @apply inline-block cursor-pointer select-none !outline-none; 291 | @apply opacity-75 transition duration-200 ease-in-out align-middle rounded p-2; 292 | @apply hover:(opacity-100 bg-gray-400 bg-opacity-10); 293 | } 294 | 295 | .icon-btn.disabled { 296 | @apply opacity-25 pointer-events-none; 297 | } 298 | 299 | .inline-icon-btn { 300 | @apply text-primary-deep; 301 | @apply inline-block rounded p-0.5 text-2xl align-middle; 302 | @apply border border-primary border-opacity-20 border-solid; 303 | } 304 | 305 | p > img { 306 | @apply rounded-2xl 307 | } 308 | 309 | li > svg { 310 | vertical-align: middle; 311 | transform: translateY(-10%); 312 | } 313 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/sidebar-links.css: -------------------------------------------------------------------------------- 1 | .sidebar-links { 2 | margin: 0; 3 | padding: 0; 4 | list-style: none; 5 | } 6 | 7 | .sidebar-link-item { 8 | display: block; 9 | margin: 0; 10 | border-left: .25rem solid transparent; 11 | color: var(--c-text); 12 | } 13 | 14 | a.sidebar-link-item:hover { 15 | text-decoration: none; 16 | color: var(--c-brand); 17 | } 18 | 19 | a.sidebar-link-item.active { 20 | color: var(--c-brand); 21 | } 22 | 23 | .sidebar > .sidebar-links { 24 | padding: .75rem 0 5rem; 25 | } 26 | 27 | @media (min-width: 720px) { 28 | .sidebar > .sidebar-links { 29 | padding: 1.5rem 0; 30 | } 31 | } 32 | 33 | .sidebar > .sidebar-links > .sidebar-link + .sidebar-link { 34 | padding-top: .5rem; 35 | } 36 | 37 | @media (min-width: 720px) { 38 | .sidebar > .sidebar-links > .sidebar-link + .sidebar-link { 39 | padding-top: 1.25rem; 40 | } 41 | } 42 | 43 | .sidebar > .sidebar-links > .sidebar-link > .sidebar-link-item { 44 | padding: .35rem 1.5rem .35rem 1.25rem; 45 | font-size: 1.1rem; 46 | font-weight: 700; 47 | } 48 | 49 | .sidebar > .sidebar-links > .sidebar-link > a.sidebar-link-item.active { 50 | border-left-color: var(--c-brand); 51 | font-weight: 600; 52 | } 53 | 54 | .sidebar > .sidebar-links > .sidebar-link > .sidebar-links > .sidebar-link > .sidebar-link-item { 55 | display: block; 56 | padding: .35rem 1.5rem .35rem 2rem; 57 | line-height: 1.4; 58 | font-size: 1rem; 59 | font-weight: 400; 60 | } 61 | 62 | .sidebar > .sidebar-links > .sidebar-link > .sidebar-links > .sidebar-link > a.sidebar-link-item.active { 63 | border-left-color: var(--c-brand); 64 | font-weight: 600; 65 | } 66 | 67 | .sidebar > 68 | .sidebar-links > 69 | .sidebar-link > 70 | .sidebar-links > 71 | .sidebar-link > 72 | .sidebar-links > 73 | .sidebar-link > 74 | .sidebar-link-item { 75 | display: block; 76 | padding: .3rem 1.5rem .3rem 3rem; 77 | line-height: 1.4; 78 | font-size: .9rem; 79 | font-weight: 400; 80 | } 81 | 82 | .sidebar > 83 | .sidebar-links > 84 | .sidebar-link > 85 | .sidebar-links > 86 | .sidebar-link > 87 | .sidebar-links > 88 | .sidebar-link > 89 | .sidebar-links > 90 | .sidebar-link > 91 | .sidebar-link-item { 92 | display: block; 93 | padding: .3rem 1.5rem .3rem 4rem; 94 | line-height: 1.4; 95 | font-size: .9rem; 96 | font-weight: 400; 97 | } 98 | /* 99 | a.sidebar-link-item { 100 | font-family: monospace; 101 | letter-spacing: -0.5px; 102 | } */ 103 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/vars.css: -------------------------------------------------------------------------------- 1 | /** Base Styles */ 2 | :root { 3 | 4 | /** 5 | * Colors 6 | * --------------------------------------------------------------------- */ 7 | --c-bg: #fff; 8 | --c-bg-semi: rgba(255,255,255,0.8); 9 | --c-bg-secondary: #f3f5f7; 10 | 11 | --c-white: #ffffff; 12 | --c-black: #000000; 13 | 14 | --c-divider-light: rgba(60, 60, 67, .12); 15 | --c-divider-dark: rgba(84, 84, 88, .48); 16 | 17 | --c-text-light-1: #2c3e50; 18 | --c-text-light-2: #476582; 19 | --c-text-light-3: #90a4b7; 20 | 21 | --c-brand: #3AB9D4; 22 | --c-brand-active: #3AB9D4; 23 | --c-brand-dark: #3AB9D4; 24 | --c-brand-light: #3AB9D4; 25 | 26 | --c-disabled-bg: #e5e5e5; 27 | --c-disabled-fg: #666; 28 | 29 | --code-bg-color: #f8f8f8; 30 | --code-inline-bg-color: rgba(27, 31, 35, .04); 31 | --code-highlight: rgba(0, 0, 0, .04); 32 | 33 | /** 34 | * Typography 35 | * --------------------------------------------------------------------- */ 36 | 37 | --font-family-base: 'Inter', apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 38 | --font-family-mono: 'IBM Plex Mono', source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; 39 | 40 | /** 41 | * Z Indexes 42 | * 43 | * Algolia SearchBox has a z-index of 200, so make sure not to go above 44 | * that value. 45 | * --------------------------------------------------------------------- */ 46 | 47 | --z-index-navbar: 10; 48 | --z-index-sidebar: 6; 49 | 50 | /** 51 | * Shadows 52 | * --------------------------------------------------------------------- */ 53 | 54 | --shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06); 55 | --shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07); 56 | --shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08); 57 | --shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12); 58 | --shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16); 59 | 60 | /** 61 | * Sizes 62 | * --------------------------------------------------------------------- */ 63 | 64 | --header-height: 3.6rem; 65 | --sidebar-width: 17.5rem; 66 | --scrollbar-width: 0; 67 | } 68 | 69 | html.dark { 70 | --c-bg: #111; 71 | --c-bg-semi: rgba(17,17,17,0.8); 72 | --c-bg-secondary: #222; 73 | --c-text: #f5f7fa; 74 | --c-text-light: #f9f9f9; 75 | --c-text-lighter: #ffffff; 76 | 77 | --c-divider-light: rgba(200, 200, 200, .12); 78 | --c-divider-dark: rgba(200, 200, 200, .48); 79 | --code-bg-color: #191919; 80 | --code-inline-bg-color: rgba(255, 255, 255, .04); 81 | --code-highlight: rgba(0, 0, 0, .66); 82 | 83 | --c-disabled-bg: #333; 84 | --c-disabled-fg: #aaa; 85 | } 86 | 87 | /** Fallback Styles */ 88 | :root { 89 | --c-divider: var(--c-divider-light); 90 | 91 | --c-text: var(--c-text-light-1); 92 | --c-text-light: var(--c-text-light-2); 93 | --c-text-lighter: var(--c-text-light-3); 94 | 95 | --c-bg: var(--c-white); 96 | 97 | --code-line-height: 24px; 98 | --code-font-family: var(--font-family-mono); 99 | --code-font-size: 14px; 100 | } 101 | 102 | .no-sidebar { 103 | --sidebar-width: 0; 104 | } 105 | -------------------------------------------------------------------------------- /.vitepress/theme/support/sideBar.ts: -------------------------------------------------------------------------------- 1 | import type { DefaultTheme } from '../config' 2 | import { 3 | isArray, 4 | ensureSlash, 5 | ensureStartingSlash, 6 | removeExtention, 7 | } from '../utils' 8 | 9 | export function isSideBarConfig( 10 | sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig, 11 | ): sidebar is DefaultTheme.SideBarConfig { 12 | return sidebar === false || sidebar === 'auto' || isArray(sidebar) 13 | } 14 | 15 | export function isSideBarGroup( 16 | item: DefaultTheme.SideBarItem, 17 | ): item is DefaultTheme.SideBarGroup { 18 | return (item as DefaultTheme.SideBarGroup).children !== undefined 19 | } 20 | 21 | /** 22 | * Get the `SideBarConfig` from sidebar option. This method will ensure to get 23 | * correct sidebar config from `MultiSideBarConfig` with various path 24 | * combinations such as matching `guide/` and `/guide/`. If no matching config 25 | * was found, it will return `auto` as a fallback. 26 | */ 27 | export function getSideBarConfig( 28 | sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig, 29 | path: string, 30 | ): DefaultTheme.SideBarConfig { 31 | if (isSideBarConfig(sidebar)) 32 | return sidebar 33 | 34 | // get the very first segment of the path to compare with nulti sidebar keys 35 | // and make sure it's surrounded by slash 36 | path = removeExtention(path) 37 | path = ensureStartingSlash(path).split('/')[1] || '/' 38 | path = ensureSlash(path) 39 | 40 | for (const dir of Object.keys(sidebar)) { 41 | // make sure the multi sidebar key is surrounded by slash too 42 | if (path === ensureSlash(dir)) 43 | return sidebar[dir] 44 | } 45 | 46 | return 'auto' 47 | } 48 | 49 | /** 50 | * Get flat sidebar links from the sidebar items. This method is useful for 51 | * creating the "next and prev link" feature. It will ignore any items that 52 | * don't have `link` property and removes `.md` or `.html` extension if a 53 | * link contains it. 54 | */ 55 | export function getFlatSideBarLinks( 56 | sidebar: DefaultTheme.SideBarItem[], 57 | ): DefaultTheme.SideBarLink[] { 58 | return sidebar.reduce((links, item) => { 59 | if (item.link) 60 | links.push({ text: item.text, link: removeExtention(item.link) }) 61 | 62 | if (isSideBarGroup(item)) 63 | links = [...links, ...getFlatSideBarLinks(item.children)] 64 | 65 | return links 66 | }, []) 67 | } 68 | -------------------------------------------------------------------------------- /.vitepress/theme/utils.ts: -------------------------------------------------------------------------------- 1 | export const hashRE = /#.*$/ 2 | export const extRE = /(index)?\.(md|html)$/ 3 | export const endingSlashRE = /\/$/ 4 | export const outboundRE = /^[a-z]+:/i 5 | 6 | export function isNullish(value: any): value is null | undefined { 7 | return value === null || value === undefined 8 | } 9 | 10 | export function isArray(value: any): value is any[] { 11 | return Array.isArray(value) 12 | } 13 | 14 | export function isExternal(path: string): boolean { 15 | return outboundRE.test(path) 16 | } 17 | 18 | export function isActive(route: any, path?: string): boolean { 19 | if (path === undefined) 20 | return false 21 | 22 | const routePath = normalize(route.path) 23 | const pagePath = normalize(path) 24 | 25 | return routePath === pagePath 26 | } 27 | 28 | export function normalize(path: string): string { 29 | return decodeURI(path).replace(hashRE, '').replace(extRE, '') 30 | } 31 | 32 | export function joinUrl(base: string, path: string): string { 33 | const baseEndsWithSlash = base.endsWith('/') 34 | const pathStartsWithSlash = path.startsWith('/') 35 | 36 | if (baseEndsWithSlash && pathStartsWithSlash) 37 | return base.slice(0, -1) + path 38 | 39 | if (!baseEndsWithSlash && !pathStartsWithSlash) 40 | return `${base}/${path}` 41 | 42 | return base + path 43 | } 44 | 45 | /** 46 | * get the path without filename (the last segment). for example, if the given 47 | * path is `/guide/getting-started.html`, this method will return `/guide/`. 48 | * Always with a trailing slash. 49 | */ 50 | export function getPathDirName(path: string): string { 51 | const segments = path.split('/') 52 | 53 | if (segments[segments.length - 1]) 54 | segments.pop() 55 | 56 | return ensureEndingSlash(segments.join('/')) 57 | } 58 | 59 | export function ensureSlash(path: string): string { 60 | return ensureEndingSlash(ensureStartingSlash(path)) 61 | } 62 | 63 | export function ensureStartingSlash(path: string): string { 64 | return /^\//.test(path) ? path : `/${path}` 65 | } 66 | 67 | export function ensureEndingSlash(path: string): string { 68 | return /(\.html|\/)$/.test(path) ? path : `${path}/` 69 | } 70 | 71 | /** 72 | * Remove `.md` or `.html` extention from the given path. It also converts 73 | * `index` to slush. 74 | */ 75 | export function removeExtention(path: string): string { 76 | return path.replace(/(index)?(\.(md|html))?$/, '') || '/' 77 | } 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [sli.dev](https://sli.dev) 2 | 3 | > [!WARNING] 4 | > 5 | > This translation is out-dated and not maintained. Please refer to the [English documentation](https://sli.dev) instead. 6 | 7 | [Slidev](https://github.com/slidevjs/slidev)の日本語ドキュメントです 8 | 9 | ## All Translations 10 | 11 | > [!WARNING] 12 | > 13 | > Translations with strikethroughs are no longer maintained. The content is outdated and not encouraged to refer. 14 | 15 | | | Repo | Site | Maintainers | 16 | | ------------------------- | ---------------------------------------------- | -------------------------------: | --------------------------------------------------------------------- | 17 | | English | [docs](https://github.com/slidevjs/docs) | [sli.dev](https://sli.dev) | [@antfu](https://github.com/antfu) | 18 | | 简体中文 | [docs-cn](https://github.com/slidevjs/docs-cn) | [cn.sli.dev](https://cn.sli.dev) | [@QC-L](https://github.com/QC-L) [@Ivocin](https://github.com/Ivocin) | 19 | | Français | [docs-fr](https://github.com/slidevjs/docs-fr) | [fr.sli.dev](https://fr.sli.dev) | [@ArthurDanjou](https://github.com/ArthurDanjou) | 20 | | Español | [docs-es](https://github.com/slidevjs/docs-es) | [es.sli.dev](https://es.sli.dev) | [@owlnai](https://github.com/owlnai) | 21 | | Русский | [docs-ru](https://github.com/slidevjs/docs-ru) | [ru.sli.dev](https://ru.sli.dev) | [@xesjkeee](https://github.com/xesjkeee) | 22 | | Việt Nam | [docs-vn](https://github.com/slidevjs/docs-vn) | [vn.sli.dev](https://vn.sli.dev) | [@bongudth](https://github.com/bongudth) | 23 | | Deutsch | [docs-de](https://github.com/slidevjs/docs-de) | [de.sli.dev](https://de.sli.dev) | [@fabiankachlock](https://github.com/fabiankachlock) | 24 | | Português (BR) | [docs-br](https://github.com/slidevjs/docs-br) | [br.sli.dev](https://br.sli.dev) | [@luisfelipesdn12](https://github.com/luisfelipesdn12) | 25 | | Ελληνικά | [docs-el](https://github.com/slidevjs/docs-el) | [el.sli.dev](https://el.sli.dev) | [@GeopJr](https://github.com/GeopJr) | 26 | | 日本語 | [docs-ja](https://github.com/slidevjs/docs-el) | [ja.sli.dev](https://ja.sli.dev) | [@IkumaTadokoro](https://github.com/IkumaTadokoro) | 27 | 28 | ## ローカルでサーバーを立ち上げる 29 | 30 | ``` 31 | npm i -g pnpm 32 | 33 | pnpm i 34 | pnpm run dev 35 | ``` 36 | 37 | コマンドを実行したら `http://localhost:3000` にアクセスしてください。 38 | 39 | または [Vite extension for VS Code](https://marketplace.visualstudio.com/items?itemName=antfu.vite) 40 | をインストールすると、サイドバイサイドで編集できます。 41 | 42 | ## 翻訳に貢献する 43 | 44 | [TRANSLATIONS.md](/TRANSLATIONS.md) をご一読ください 45 | -------------------------------------------------------------------------------- /TRANSLATIONS.md: -------------------------------------------------------------------------------- 1 | # Help on Translating 2 | 3 | 4 | 5 | First of all, thank you for being interested in contributing to translations! 6 | 7 | You can find the repositories for each existing translation in [README.md](./README.md). To help improve them, simply sending a Pull Request to their repo. 8 | 9 | If the language you want to contribute isn't on the list, join [our Discord server](https://chat.sli.dev), and find the `#translations` channel to see if someone is already working on the language you want, consider joining them and translate together. If not, you can start a new translation project with the following steps. 10 | 11 | In case it's already been translated but you're wondering how to maintain it, skip to the end. 12 | ## Some tips before you get started 13 | - It is recommended that you use your IDE of choice (e.g VSCode) paired with a development server running, so you can see your translation changes in real-time. 14 | - You can mark these checkmarks as the translation progresses or use your own workflow. The translations don't need to be made in any particular order. 15 | - Translations don't need to be literal, but they should convey the same message. In case you're not sure how to translate something, you can either leave it as it is or use online tools like WordReference or Linguee to aid you. 16 | - Most translations will simply consist in editing Markdown files. Certain areas are buried under Vue components, which will be listed below. You can also use your IDE to find the string to translate. 17 | 18 | ## Getting started 19 | 20 | - [ ] Fork the main docs repo: [slidevjs/docs](https://github.com/slidevjs/docs) 21 | - [ ] Translate README.md, you can take one of the already translated repositories as an example. 22 | - [ ] Share your repo's link to the `#translations` channel telling people you are working on it and find collaborators. 23 | 24 | ## Translating Markdown files 25 | 26 | - [ ] `showcases.md` - A gallery showcase of Slidev presentations. 27 | - [ ] `index.md` - Mainpage content, note that some of it is buried under Vue components listed further below. 28 | 29 | ### .vitepress/ 30 | 31 | - [ ] `config.js` - Sitemap 32 | - [ ] `/theme/components/WorkingInProgress.vue` - WIP notice shown in mainpage 33 | - [ ] `/theme/components/demo/Demo.vue` - Animated demo shown in mainpage 34 | - [ ] `/theme/components/Environment.vue` - Describes the environment of a setting. 35 | 36 | ### builtin/ 37 | 38 | - [ ] `components.md` - Use [Vue components](https://v3.vuejs.org/guide/component-basics.html) inside Slidev 39 | - [ ] `layouts.md` - Use Vue layouts inside Slidev 40 | 41 | ### custom/ 42 | 43 | - [ ] `config-katex.md` - Configuring Katex 44 | - [ ] `config-mermaid.md` - Configuring Mermaid 45 | - [ ] `config-monaco.md` - Configuring Monaco 46 | - [ ] `config-shortcuts.md` - Configuring Shortcuts 47 | - [ ] `config-vite.md` - Configuring Vite 48 | - [ ] `config-vue.md` - Configuring Vue 49 | - [ ] `config-windicss.md`- Configuring Windicss 50 | - [ ] `directory-structure.md` - Configuring the directory structure 51 | - [ ] `fonts.md` - Configuring fonts 52 | - [ ] `global-layers.md` - Configuring the global layers 53 | - [ ] `highlighters.md` - Configuring code highlighters 54 | - [ ] `index.md`- Customizations index page 55 | - [ ] `vue-context.md` - The Vue global context 56 | 57 | ### guide/ 58 | 59 | - [ ] `animations.md` - Animations and transitions 60 | - [ ] `editors.md` - Editor integrations 61 | - [ ] `exporting.md`- Exporting your slides 62 | - [ ] `faq.md` - Frequent Answered Questions 63 | - [ ] `index.md` - Getting started with Slidev 64 | - [ ] `navigation.md` - Navigation across slides 65 | - [ ] `presenter-mode.md`- Toggling presenter mode 66 | - [ ] `recording.md`- Recording your presentation 67 | - [ ] `syntax.md` - Markdown syntax 68 | - [ ] `why.md` - _Why Slidev?_ 69 | 70 | ### resources/ 71 | 72 | - [ ] `covers.md` - Curated covers for Slidev 73 | 74 | ### themes/ 75 | 76 | - [ ] `gallery.md` - Theme gallery 77 | - [ ] `use.md` - How to use Slidev themes 78 | - [ ] `write-a-theme.md` - Write your own theme 79 | 80 | ## Publishing your translations 81 | 82 | - [ ] When you finish the translation (at least 90%), `@antfu` in the Discord and we will invite you to the org and make the translation official. 83 | - [ ] Once the transferring is done, we will set up the subdomain, auto-deployment, and a daily sync-up bot to keep the translation up-to-date with the latest English docs. 84 | - [ ] The site is live, and we will send a shout-out tweet on [our Twitter account](https://twitter.com/Slidevjs). 85 | 86 | ## Maintaining the translations up-to-date 87 | 88 | - `docschina-bot` will periodically submit merge requests from the `slidev/docs` repository. Switch to the branch created in the pull request, make any changes necessary and merge it. [example](https://github.com/slidevjs/docs-fr/pull/13). 89 | - Sometimes it will occur that a merge request is made and you haven't merged the previous one. The latest PR always checks your main branch against the English one; so you can just close the previous PR(s), move your work to the latest one and merge it. 90 | 91 | 92 | [Working-in-progress translation list](https://discord.com/channels/851817370623410197/851822360955977760/852614294017146900) 93 | 94 | Thanks again! 95 | -------------------------------------------------------------------------------- /builtin/components.md: -------------------------------------------------------------------------------- 1 | # コンポーネント 2 | 3 | ## ビルトインコンポーネント 4 | 5 | > このセクションのドキュメントはまだ作成中です。完成するまでは[ソースコード](https://github.com/slidevjs/slidev/blob/main/packages/client/builtin)を直接参照してください。 6 | 7 | ### `TOC` 8 | 9 | 目次を挿入します。 10 | 11 | タイトルとタイトルレベルは、各スライドの最初のタイトル要素から自動的に取得されます。 12 | 13 | フロントマターの構文を使用することで、スライドに対するこの自動取得の動作をオーバーライドすることができます: 14 | ```yml 15 | --- 16 | title: Amazing slide title 17 | level: 2 18 | --- 19 | ``` 20 | 21 | またスライドが目次に全く表示されないようにしたい場合には、次のようにします: 22 | ```yml 23 | --- 24 | hideInToc: true 25 | --- 26 | ``` 27 | 28 | #### 使い方 29 | ~~~md 30 | 31 | ~~~ 32 | 33 | パラメータ: 34 | 35 | * `columns` (`string | number`, デフォルト: `1`): 表示する列数 36 | * `maxDepth` (`string | number`, デフォルト: `Infinity`): 表示する目次の階層の最大値 37 | * `minDepth` (`string | number`, デフォルト: `1`): 表示する目次の階層の最小値 38 | * `mode` (`'all' | 'onlyCurrentTree'| 'onlySiblings'`, デフォルト: `'all'`): 39 | * `'all'`: すべての項目を表示する 40 | * `'onlyCurrentTree'`: 現在のページが含まれるツリーのアイテムのみを表示する(アクティブな要素、アクティブな要素の親と子) 41 | * `'onlySiblings'`: 現在のページが含まれるツリーと直接の兄弟関係にある要素のみを表示する 42 | 43 | ## カスタムコンポーネント 44 | 45 | プロジェクトルートに`components/`ディレクトリを作成し、カスタムVueコンポーネントを配置するだけで、Markdownファイル内で同じ名前を使用してコンポーネントを使用することができます! 46 | 47 | 詳細は[コンポーネント](/custom/directory-structure#コンポーネント)を参照してください。 48 | 49 | ## テーマが提供するコンポーネント 50 | 51 | テーマはコンポーネントを提供することもできます。提供されているものについては、それぞれのテーマのドキュメントを参照してください。 52 | 53 | 詳細は[ディレクトリ構造](/custom/directory-structure)のセクションを参照してください。 54 | -------------------------------------------------------------------------------- /builtin/layouts.md: -------------------------------------------------------------------------------- 1 | # レイアウト 2 | 3 | ## ビルトインレイアウト 4 | 5 | > テーマはレイアウトの動作を上書きすることがあるため、使い方やパラメータ、サンプルを正しく知るには、各テーマのドキュメントを参照するのがよいでしょう。 6 | 7 | 8 | ### `center` 9 | 10 | コンテンツを画面中央に表示します。 11 | 12 | ### `cover` 13 | 14 | プレゼンテーションの表紙を表示するために使用します。プレゼンテーションのタイトルや、コンテキストを含めることができます。 15 | 16 | ### `default` 17 | 18 | 最も基本的なレイアウトで、あらゆる種類のコンテンツを表示することができます。 19 | 20 | ### `end` 21 | 22 | プレゼンテーションの最後のページです。 23 | 24 | ### `fact` 25 | 26 | 事実やデータを画面上で大きく目立たせて見せるために使用します。 27 | 28 | ### `full` 29 | 30 | 画面のすべてのスペースを使って、コンテンツを表示します。 31 | 32 | ### `image-left` 33 | 34 | 画面の左側に画像を表示し、右側にコンテンツを配置します。 35 | 36 | #### 使い方 37 | 38 | ```yaml 39 | --- 40 | layout: image-left 41 | 42 | # the image source 43 | image: ./path/to/the/image 44 | 45 | # a custom class name to the content 46 | class: my-cool-content-on-the-right 47 | --- 48 | ``` 49 | 50 | ### `image-right` 51 | 52 | 画面右側に画像を表示し、左側にコンテンツを配置します。 53 | 54 | #### 使い方 55 | 56 | ```yaml 57 | --- 58 | layout: image-right 59 | 60 | # the image source 61 | image: ./path/to/the/image 62 | 63 | # a custom class name to the content 64 | class: my-cool-content-on-the-left 65 | --- 66 | ``` 67 | 68 | ### `image` 69 | 70 | 画像をページのメインコンテンツとして表示します。 71 | 72 | #### 使い方 73 | 74 | ```yaml 75 | --- 76 | layout: image 77 | 78 | # the image source 79 | image: ./path/to/the/image 80 | --- 81 | ``` 82 | 83 | 84 | ### `iframe-left` 85 | 86 | 画面の左側にWebページを表示し、右側にコンテンツを配置します。 87 | 88 | #### 使い方 89 | 90 | ```yaml 91 | --- 92 | layout: iframe-left 93 | 94 | # the web page source 95 | url: https://github.com/slidevjs/slidev 96 | 97 | # a custom class name to the content 98 | class: my-cool-content-on-the-right 99 | --- 100 | ``` 101 | 102 | ### `iframe-right` 103 | 104 | 画面の右側にWebページを表示し、左側にコンテンツを配置します。 105 | 106 | #### 使い方 107 | 108 | ```yaml 109 | --- 110 | layout: iframe-right 111 | 112 | # the web page source 113 | url: https://github.com/slidevjs/slidev 114 | 115 | # a custom class name to the content 116 | class: my-cool-content-on-the-left 117 | --- 118 | ``` 119 | 120 | ### `iframe` 121 | 122 | Webページをメインコンテンツとして表示します。 123 | 124 | #### 使い方 125 | 126 | ```yaml 127 | --- 128 | layout: iframe 129 | 130 | # the web page source 131 | url: https://github.com/slidevjs/slidev 132 | --- 133 | ``` 134 | 135 | 136 | ### `intro` 137 | 138 | プレゼンテーションの始まりに使用します。一般的にはプレゼンテーションのタイトル、簡潔な説明、著者などです。 139 | 140 | ### `none` 141 | 142 | スタイルなしのレイアウトです。 143 | 144 | ### `quote` 145 | 146 | 引用文を目立つように表示します。 147 | 148 | ### `section` 149 | 150 | 新しいプレゼンテーションのセクションの開始を示すために使用します。 151 | 152 | ### `statement` 153 | 154 | 断言/宣言をメインページのコンテンツとして表示します。 155 | 156 | ### `two-cols` 157 | 158 | ページのコンテンツを2列に分割します。 159 | 160 | #### 使い方 161 | 162 | 163 | ```md 164 | --- 165 | layout: two-cols 166 | --- 167 | 168 | # Left 169 | 170 | これは左側に表示されます。 171 | 172 | ::right:: 173 | 174 | # Right 175 | 176 | これは右側に表示されます。 177 | ``` 178 | 179 | ## カスタムレイアウト 180 | 181 | プロジェクトルートの配下に`layouts/`というディレクトリを作成し、そこにカスタムしたVueのレイアウトコンポーネントを配置します。 182 | 183 | 詳細は[レイアウト](/custom/directory-structure#レイアウト)のセクションを参照してください。 184 | 185 | ## テーマが提供するレイアウト 186 | 187 | テーマはレイアウトを提供したり、既存のレイアウトを上書きすることができます。テーマが提供するレイアウトについては、各テーマのドキュメントを参照してください。 188 | -------------------------------------------------------------------------------- /custom/config-katex.md: -------------------------------------------------------------------------------- 1 | # KaTeXの設定 2 | 3 | 4 | 5 | 以下の内容で`./setup/katex.ts`を作成します: 6 | 7 | ```ts 8 | import { defineKatexSetup } from '@slidev/types' 9 | 10 | export default defineKatexSetup(() => { 11 | return { 12 | /* ... */ 13 | } 14 | }) 15 | ``` 16 | 17 | この設定により、[KaTex Options](https://katex.org/docs/options.html)のカスタム設定を使用することができます。詳細については、型の定義とドキュメントを参照してください。 18 | -------------------------------------------------------------------------------- /custom/config-mermaid.md: -------------------------------------------------------------------------------- 1 | # Mermaidの設定 2 | 3 | 4 | 5 | 以下の内容で`./setup/mermaid.ts`を作成します: 6 | 7 | ```ts 8 | import { defineMermaidSetup } from '@slidev/types' 9 | 10 | export default defineMermaidSetup(() => { 11 | return { 12 | theme: 'forest', 13 | } 14 | }) 15 | ``` 16 | 17 | セットアップにより、[Mermaid](https://mermaid-js.github.io/)のカスタムデフォルト設定を使用することができます。詳細については、型の定義とドキュメントを参照してください。 18 | -------------------------------------------------------------------------------- /custom/config-monaco.md: -------------------------------------------------------------------------------- 1 | # Monacoの設定 2 | 3 | 4 | 5 | 以下の内容で`./setup/monaco.ts`を作成します。 6 | 7 | ```ts 8 | import { defineMonacoSetup } from '@slidev/types' 9 | 10 | export default defineMonacoSetup(async (monaco) => { 11 | // 設定するためには`monaco`を使用します 12 | }) 13 | ``` 14 | 15 | 詳細は[configuring Monaco](https://github.com/Microsoft/monaco-editor)を参照してください。 16 | 17 | ## 使い方 18 | 19 | スライドでMonacoを使用するには、コードスニペットに`{monaco}`を追加するだけです: 20 | 21 | ~~~js 22 | //```js 23 | const count = ref(1) 24 | const plusOne = computed(() => count.value + 1) 25 | 26 | console.log(plusOne.value) // 2 27 | 28 | plusOne.value++ // error 29 | //``` 30 | ~~~ 31 | 32 | これを以下のように変更します 33 | 34 | ~~~js 35 | //```js {monaco} 36 | const count = ref(1) 37 | const plusOne = computed(() => count.value + 1) 38 | 39 | console.log(plusOne.value) // 2 40 | 41 | plusOne.value++ // error 42 | //``` 43 | ~~~ 44 | 45 | ## エクスポート 46 | 47 | デフォルトでは、Monacoは`開発者`モードのみで動作します。エクスポートされたSPAでMonacoを使用したい場合は、フロントマターで設定してください: 48 | 49 | ```yaml 50 | --- 51 | monaco: true # デフォルト "dev" 52 | --- 53 | ``` 54 | 55 | ## 型の自動インストール 56 | 57 | MonacoでTypeScriptを使用する場合、依存関係のある型は自動的にクライアントサイドにインストールされます。 58 | 59 | ~~~ts 60 | //```ts {monaco} 61 | import { ref } from 'vue' 62 | import { useMouse } from '@vueuse/core' 63 | 64 | const counter = ref(0) 65 | //``` 66 | ~~~ 67 | 68 | 上記の例では、`vue`と`@vueuse/core`はdependencies / devDependenciesとしてローカルにインストールされています。あとはSlidevが自動的にエディタに対応した型を作成します。 69 | 70 | ## テーマの設定 71 | 72 | テーマはライトテーマ/ダークテーマをベースにSlidevで制御されています。テーマをカスタマイズしたい場合は、テーマのIDをsetup関数に指定します: 73 | 74 | ```ts 75 | // ./setup/monaco.ts 76 | import { defineMonacoSetup } from '@slidev/types' 77 | 78 | export default defineMonacoSetup(() => { 79 | return { 80 | theme: { 81 | dark: 'vs-dark', 82 | light: 'vs', 83 | }, 84 | } 85 | }) 86 | ``` 87 | 88 | カスタムテーマを使用する場合には次のようにします: 89 | 90 | ```ts 91 | import { defineMonacoSetup } from '@slidev/types' 92 | 93 | // change to your themes 94 | import dark from 'theme-vitesse/themes/vitesse-dark.json' 95 | import light from 'theme-vitesse/themes/vitesse-light.json' 96 | 97 | export default defineMonacoSetup((monaco) => { 98 | monaco.editor.defineTheme('vitesse-light', light as any) 99 | monaco.editor.defineTheme('vitesse-dark', dark as any) 100 | 101 | return { 102 | theme: { 103 | light: 'vitesse-light', 104 | dark: 'vitesse-dark', 105 | }, 106 | } 107 | }) 108 | ``` 109 | 110 | > Slidev用のテーマを作成する場合は、setup関数内で動的`import()`を使用すると、より良いtree-shakingとcode-splittingの結果を得ることができます。 111 | -------------------------------------------------------------------------------- /custom/config-shortcuts.md: -------------------------------------------------------------------------------- 1 | # ショートカットの設定 2 | 3 | > v0.20から使用可能です 4 | 5 | 6 | 7 | 以下の内容で`./setup/shortcuts.ts`を作成します: 8 | 9 | ```ts 10 | import { defineShortcutsSetup, NavOperations } from '@slidev/types' 11 | 12 | export default defineShortcutsSetup((nav: NavOperations) => { 13 | return [ 14 | { 15 | key: 'enter', 16 | fn: () => nav.next(), 17 | autoRepeat: true, 18 | }, 19 | { 20 | key: 'backspace', 21 | fn: () => nav.prev(), 22 | autoRepeat: true, 23 | }, 24 | ] 25 | }) 26 | ``` 27 | 28 | セットアップによって、[ナビゲーション](/guide/navigation#navigation-bar)で言及されているショートカットに対して、カスタム設定を使用することができます。上記の設定により、次のアニメーションやスライドへの移動はenterに、前のアニメーションやスライドへの移動はbackspaceに割り当てられます。 29 | 30 | 設定用の関数は、いくつかのナビゲーションメソッドを持つオブジェクトを受け取り、いくつかのショートカット設定を含む配列を返します。詳細については型定義を参照してください。 31 | 32 | キーが押されたときのイベントについての詳細は、[useMagicKeys | VueUse](https://vueuse.org/core/useMagicKeys/)を参照してください。 33 | -------------------------------------------------------------------------------- /custom/config-vite.md: -------------------------------------------------------------------------------- 1 | # Viteの設定 2 | 3 | 4 | 5 | Slidevは[Vite](http://vitejs.dev/)を搭載しています。つまり、Viteの素晴らしいプラグインシステムを利用して、スライドをさらにカスタマイズすることができます。 6 | 7 | `vite.config.ts`があれば、それが採用されます。 8 | 9 | Slidevには以下のプラグインがあらかじめ設定されています: 10 | 11 | - [@vitejs/plugin-vue](https://github.com/vitejs/vite/tree/main/packages/plugin-vue) 12 | - [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components) 13 | - [unplugin-icons](https://github.com/antfu/unplugin-icons) 14 | - [vite-plugin-md](https://github.com/antfu/vite-plugin-md) 15 | - [vite-plugin-windicss](https://github.com/windicss/vite-plugin-windicss) 16 | - [vite-plugin-remote-assets](https://github.com/antfu/vite-plugin-remote-assets) 17 | 18 | 詳細は[pre-configurations here](https://github.com/slidevjs/slidev/blob/main/packages/slidev/node/plugins/preset.ts)を参照してください。 19 | 20 | ## 内部プラグインの設定 21 | 22 | > v0.21から使用可能です 23 | 24 | 上記のビルトインプラグインのリストを設定するために、以下の内容で`vite.config.ts`を作成します。Slidevはこれらのプラグインに対して、いくつかあらかじめ設定されたオプションを保持していることに注意してください。この使い方はそれらの設定を上書きし、アプリケーションが潜在的に壊れる原因になる可能性があります。これは**高度な機能**として扱い、何を行っているのかを確認してから次に進んでください。 25 | 26 | ```ts 27 | import { defineConfig } from 'vite' 28 | 29 | export default defineConfig({ 30 | slidev: { 31 | vue: { 32 | /* vue options */ 33 | }, 34 | markdown: { 35 | /* markdown-it options */ 36 | markdownItSetup(md) { 37 | /* custom markdown-it plugins */ 38 | md.use(/* ... */) 39 | }, 40 | }, 41 | /* options for other plugins */ 42 | }, 43 | }) 44 | ``` 45 | 46 | その他のオプションについては[type declarations](https://github.com/slidevjs/slidev/blob/main/packages/slidev/node/options.ts#L50)を参照してください。 47 | -------------------------------------------------------------------------------- /custom/config-vue.md: -------------------------------------------------------------------------------- 1 | # Vueの設定 2 | 3 | 4 | 5 | Slidevはクライアントサイドでアプリケーションをレンダリングするために[Vue 3](https://v3.ja.vuejs.org/)を使用しています。カスタムプラグインや設定を追加することで、アプリケーションを拡張することができます。 6 | 7 | 以下の内容で`./setup/main.ts`を作成します: 8 | 9 | ```ts 10 | import { defineAppSetup } from '@slidev/types' 11 | 12 | export default defineAppSetup(({ app, router }) => { 13 | // Vue App 14 | app.use(YourPlugin) 15 | }) 16 | ``` 17 | 18 | これはSlidevアプリのメインエントランスとしても使用することができ、アプリ起動前にいくつかの初期化を行うことができます。 19 | 20 | 詳細: [アプリケーションAPI](https://v3.ja.vuejs.org/api/application-api.html#component) 21 | -------------------------------------------------------------------------------- /custom/config-windicss.md: -------------------------------------------------------------------------------- 1 | # Windi CSSの設定 2 | 3 | 4 | 5 | Markdownは当然ですが、埋め込まれたHTMLマークアップをサポートしています。したがって、好きなようにコンテンツをスタイルすることができます。いくつかの利便性を提供するために、[Windi CSS](https://github.com/windicss/windicss)を内蔵し、クラスユーティリティを使用して、直接マークアップにスタイルを設定することができます。 6 | 7 | 例: 8 | 9 | ```html 10 |
11 | 12 | ### Name 13 | 14 | - Item 1 15 | - Item 2 16 | 17 |
18 | ``` 19 | 20 | [Windi CSS v3.0](https://windicss.org/posts/v30.html)の[Attributify Mode](https://windicss.org/posts/v30.html#attributify-mode)はデフォルトで有効になっています。 21 | 22 | ## 設定 23 | 24 | Windi CSSを設定するために、以下の内容で`setup/windicss.ts`を作成し、ビルトインの設定を拡張します。 25 | 26 | ```ts 27 | // setup/windicss.ts 28 | 29 | import { defineWindiSetup } from '@slidev/types' 30 | 31 | // ビルトインのWindi CSSの設定を拡張する 32 | export default defineWindiSetup(() => ({ 33 | shortcuts: { 34 | // デフォルトの背景をカスタマイズします 35 | 'bg-main': 'bg-white text-[#181818] dark:(bg-[#121212] text-[#ddd])', 36 | }, 37 | theme: { 38 | extend: { 39 | // フォントはここで置き換えることができますが、`index.html`のWebフォントのリンクの更新を忘れないようにしてください 40 | fontFamily: { 41 | sans: 'ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"', 42 | mono: '"Fira Code", monospace', 43 | }, 44 | }, 45 | }, 46 | })) 47 | ``` 48 | 49 | 詳細は[Windi CSS configurations](https://windicss.org/guide/configuration.html)を参照してください。 50 | -------------------------------------------------------------------------------- /custom/directory-structure.md: -------------------------------------------------------------------------------- 1 | # ディレクトリ構造 2 | 3 | Slidevは設定面を最小化し、機能拡張を柔軟かつ直感的に行うために、いくつかのディレクトリ構造の規約を採用しています。 4 | 5 | 基本的な構造は以下の通りです: 6 | 7 | ```bash 8 | your-slidev/ 9 | ├── components/ # カスタムコンポーネント 10 | ├── layouts/ # カスタムレイアウト 11 | ├── public/ # 静的アセット 12 | ├── setup/ # カスタムセットアップ/フック 13 | ├── styles/ # カスタムスタイル 14 | ├── index.html # index.htmlへのインジェクション 15 | ├── slides.md # メインスライド 16 | └── vite.config.ts # 拡張されたviteの設定 17 | ``` 18 | 19 | すべてオプションです。 20 | 21 | ## コンポーネント 22 | 23 | 規約: `./components/*.{vue,js,ts,jsx,tsx,md}` 24 | 25 | このディレクトリ内のコンポーネントは、ファイル名と同じコンポーネント名で、スライドのMarkdownで直接使用することができます。 26 | 27 | 例: 28 | 29 | ```bash 30 | your-slidev/ 31 | ├── ... 32 | └── components/ 33 | ├── MyComponent.vue 34 | └── HelloWorld.ts 35 | ``` 36 | 37 | ```md 38 | 39 | 40 | # My Slide 41 | 42 | 43 | 44 | 45 | 46 | 47 | Slot 48 | 49 | ``` 50 | 51 | この機能は[`vite-plugin-components`](https://github.com/antfu/vite-plugin-components)によって提供されています。詳細はこちらを参照してください。 52 | 53 | またSlidevはいくつかの[ビルトインコンポーネント](/builtin/components)を提供していますので、それを利用することもできます。 54 | 55 | ## レイアウト 56 | 57 | 規約: `./layouts/*.{vue,js,ts,jsx,tsx}` 58 | 59 | ``` 60 | your-slidev/ 61 | ├── ... 62 | └── layouts/ 63 | ├── cover.vue 64 | └── my-cool-theme.vue 65 | ``` 66 | 67 | レイアウトには任意のファイル名を使用することができます。そしてファイル名を使用して、YAMLヘッダでレイアウトを参照します。 68 | 69 | ```yaml 70 | --- 71 | layout: my-cool-theme 72 | --- 73 | ``` 74 | 75 | 作成したレイアウトがビルトインのレイアウトやテーマと同じ名前の場合、カスタムレイアウトがビルトイン/テーマレイアウトより優先されます。優先順位は`ローカル > テーマ > ビルトイン`の順です。 76 | 77 | レイアウトコンポーネントでは、スライドのコンテンツに対して``を使用します。例: 78 | 79 | ```html 80 | 81 | 86 | ``` 87 | 88 | ## 静的アセット 89 | 90 | 規約: `./public/*` 91 | 92 | このディレクトリに配置されているアセットは、開発中はルートパス`/`で提供され、そのままdistディレクトリのルートにコピーされます。詳細は[Vite's `public` directory](https://vitejs.dev/guide/assets.html#the-public-directory)を参照してください。 93 | 94 | ## スタイル 95 | 96 | 規約: `./style.css` | `./styles/index.{css,js,ts}` 97 | 98 | この規約に従って配置されたファイルは、Appのルートに挿入されます。複数のCSSをインポートする必要がある場合は、以下のような構造を作成し、インポートの順序を自分で管理することができます。 99 | 100 | ```bash 101 | your-slidev/ 102 | ├── ... 103 | └── styles/ 104 | ├── index.ts 105 | ├── base.css 106 | ├── code.css 107 | └── layouts.css 108 | ``` 109 | 110 | ```ts 111 | // styles/index.ts 112 | 113 | import './base.css' 114 | import './code.css' 115 | import './layouts.css' 116 | ``` 117 | 118 | スタイルは[Windi CSS](http://windicss.org/)と[PostCSS](https://postcss.org/)で処理されるため、CSSのネストや[at-directives](https://windicss.org/features/directives.html)をそのまま使用することができます。例: 119 | 120 | ```less 121 | .slidev-layout { 122 | @apply px-14 py-10 text-[1.1rem]; 123 | 124 | h1, h2, h3, h4, p, div { 125 | @apply select-none; 126 | } 127 | 128 | pre, code { 129 | @apply select-text; 130 | } 131 | 132 | a { 133 | color: theme('colors.primary'); 134 | } 135 | } 136 | ``` 137 | 138 | [シンタックスについて詳しく学ぶ](https://windicss.org/features/directives.html) 139 | 140 | ## `index.html` 141 | 142 | 規約: `index.html` 143 | 144 | `index.html`はメインの`index.html`にmeteタグやscriptを挿入する機能を提供します。 145 | 146 | 例えば、次のようなカスタム`index.html`の場合: 147 | 148 | ```html 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | ``` 159 | 160 | 最終的にホストされる`index.html`は次のようになります。 161 | 162 | ```html 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 |
175 | 176 | 177 | 178 | 179 | 180 | ``` 181 | 182 | ## グローバルレイヤー 183 | 184 | 規約: `global-top.vue` | `global-bottom.vue` 185 | 186 | 詳細: [グローバルレイヤー](/custom/global-layers) 187 | 188 | -------------------------------------------------------------------------------- /custom/fonts.md: -------------------------------------------------------------------------------- 1 | # フォント 2 | 3 | > v0.20から使用可能です 4 | 5 | HTMLやCSSを使ってスライドのフォントやスタイルを自由にカスタマイズすることができますが、Slidevはそれらを楽に扱うための便利な方法も提供しています。 6 | 7 | フロントマターで、以下のように設定します。 8 | 9 | ```yaml 10 | --- 11 | fonts: 12 | # basically the text 13 | sans: 'Robot' 14 | # use with `font-serif` css class from windicss 15 | serif: 'Robot Slab' 16 | # for code blocks, inline code, etc. 17 | mono: 'Fira Code' 18 | --- 19 | ``` 20 | 21 | フォントは **[Google Fonts](https://fonts.google.com/)から自動的にインポート** されます。つまり、Google Fontsで利用可能なフォントを直接利用することができます。 22 | 23 | ## ローカルフォント 24 | 25 | デフォルトでは、Slidevは`fonts`で指定されたすべてのフォントをGoogle Fontsのものとして認識します。ローカルのフォントを使用したい場合は、`fonts.local`を指定して、自動インポートを無効にします。 26 | 27 | ```yaml 28 | --- 29 | fonts: 30 | # CSSにおけるfont-familyの指定のように、`,`を使用することでフォールバックのためのフォントを複数指定できます。 31 | sans: 'Helvetica Neue,Robot' 32 | # 'Helvetica Neue'をローカルフォントとして指定します。 33 | local: 'Helvetica Neue' 34 | --- 35 | ``` 36 | 37 | ## 太さと斜体 38 | 39 | デフォルトでは、Slidevは各フォントに対して、`200`、`400`、`600`の3つの太さをインポートします。次のように指定することができます: 40 | 41 | ```yaml 42 | --- 43 | fonts: 44 | sans: 'Robot' 45 | # デフォルト 46 | weights: '200,400,600' 47 | # デフォルトで`false`になっている斜体フォントをインポートします。 48 | italic: false 49 | --- 50 | ``` 51 | 52 | この設定はすべてのWebフォントに適用されます。各フォントの太さをより細かく制御するには、[HTML](/custom/directory-structure.html#index-html)とCSSで手動でインポートする必要があります。 53 | 54 | ## フォントのフォールバック 55 | 56 | ほとんどのケースでは、"特別なフォント"を指定するだけで、Slidevがフォントフォールバックを追加してくれます。例: 57 | 58 | ```yaml 59 | --- 60 | fonts: 61 | sans: 'Robot' 62 | serif: 'Robot Slab' 63 | mono: 'Fira Code' 64 | --- 65 | ``` 66 | 67 | これは次のようになります 68 | 69 | ```css 70 | .font-sans { 71 | font-family: "Robot",ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; 72 | } 73 | .font-serif { 74 | font-family: "Robot Slab",ui-serif,Georgia,Cambria,"Times New Roman",Times,serif; 75 | } 76 | .font-mono { 77 | font-family: "Fira Code",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; 78 | } 79 | ``` 80 | 81 | フォントフォールバックを無効化するには、次のように設定します。 82 | 83 | ```yaml 84 | --- 85 | fonts: 86 | mono: 'Fira Code, monospace' 87 | fallback: false 88 | --- 89 | ``` 90 | 91 | ## プロバイダー 92 | 93 | - オプション: `google` | `none` 94 | - デフォルト: `google` 95 | 96 | 現時点ではGoogle Fontsのみをサポートしていますが、将来的にはほかのプロバイダーも追加する予定です。`none`を指定すると、自動インポート機能を完全に無効にし、すべてのフォントをローカルに扱えるようになります。 97 | 98 | ```yaml 99 | --- 100 | fonts: 101 | provider: 'none' 102 | --- 103 | ``` 104 | 105 | 106 | -------------------------------------------------------------------------------- /custom/global-layers.md: -------------------------------------------------------------------------------- 1 | # グローバルレイヤー 2 | 3 | > v0.17から使用可能です 4 | 5 | グローバルレイヤーを使用すると、スライド間で**永続的な**カスタムコンポーネントを持つことができます。これはフッター、スライドをまたぐアニメーション、グローバルエフェクトなどに便利です。 6 | 7 | Slidevはこのために2つのレイヤーを提供しています。プロジェクトのルートに`global-top.vue`や`global-bottom.vue`を作成すると、自動的にピックアップされます。 8 | 9 | レイヤーの関係性: 10 | 11 | - グローバルトップ (`global-top.vue`) 12 | - スライド 13 | - グローバルボトム (`global-bottom.vue`) 14 | 15 | ## 例 16 | 17 | ```html 18 | 19 | 22 | ``` 23 | 24 | `Your Name`という文字はすべてのスライドに表示されます。 25 | 26 | 条件付きで有効にするには、[Vueグローバルコンテキスト](/custom/vue-context)を使用して適用します。 27 | 28 | ```html 29 | 30 | 38 | ``` 39 | 40 | ```html 41 | 42 | 50 | ``` 51 | 52 | ```html 53 | 54 | 62 | ``` 63 | -------------------------------------------------------------------------------- /custom/highlighters.md: -------------------------------------------------------------------------------- 1 | # シンタックスハイライト 2 | 3 | Slidevには2種類のシンタックスハイライトが付属しており、好みに合わせて選択できます: 4 | 5 | - [Prism](https://prismjs.com/) 6 | - [Shiki](https://github.com/shikijs/shiki) 7 | 8 | **Prism**は最も人気のあるシンタックスハイライトの1つです。ハイライトはトークンクラスにコードを追加することで行われ、CSSによって色付けされます。[公式テーマ](https://github.com/PrismJS/prism-themes)を確認したり、[`prism-theme-vars`](https://github.com/antfu/prism-theme-vars)を使用して簡単にテーマを作成/カスタマイズすることができます。 9 | 10 | 一方で**Shiki**はTextMateの文法に対応したシンタックスハイライトです。色付きのトークンを生成するため、追加のCSSは必要ありません。充実した文法サポートにより、生成された色はVS Codeで見るのと同じように非常に正確です。またShikiには[多くのビルトインテーマ](https://github.com/shikijs/shiki/blob/master/docs/themes.md)が付属しています。Shikiの欠点は、ハイライトを行うためにTextMateのテーマ(VS Codeのテーマと互換性あり)も必要で、カスタマイズが少し難しくなることです。 11 | 12 | Slidevのテーマは通常PrismとShikiの双方をサポートしていますが、使用するテーマによっては、どちらか一方しかサポートしていない場合があります。 13 | 14 | 選択肢がある場合、基本的にトレードオフです: 15 | 16 | - **Prism**はカスタマイズが容易です。 17 | - **Shiki**はより正確にハイライトできます。 18 | 19 | デフォルトでは、SlidevはPrismを使用します。フロントマターを修正することで、この設定を変更できます: 20 | 21 | ```yaml 22 | --- 23 | highlighter: shiki 24 | --- 25 | ``` 26 | 27 | ## Prismの設定 28 | 29 | Prismを設定する場合には、テーマのCSSをインポートするか、[`prism-theme-vars`](https://github.com/antfu/prism-theme-vars)を使用してテーマを設定することで、ライトモードとダークモードの両方のテーマを設定することができます。詳しくはドキュメントを参照してください。 30 | 31 | ## Shikiの設定 32 | 33 | 34 | 35 | 以下の内容で`./setup/shiki.ts`ファイルを作成します。 36 | 37 | ```ts 38 | /* ./setup/shiki.ts */ 39 | import { defineShikiSetup } from '@slidev/types' 40 | 41 | export default defineShikiSetup(() => { 42 | return { 43 | theme: { 44 | dark: 'min-dark', 45 | light: 'min-light', 46 | }, 47 | } 48 | }) 49 | ``` 50 | 51 | 利用可能なテーマの名前については、[Shikiのドキュメント](https://github.com/shikijs/shiki/blob/master/docs/themes.md#all-themes)を参照してください。 52 | 53 | 自身のテーマを使用したい場合は次のようにします: 54 | 55 | ```ts 56 | /* ./setup/shiki.ts */ 57 | 58 | import { defineShikiSetup } from '@slidev/types' 59 | 60 | export default defineShikiSetup(async({ loadTheme }) => { 61 | return { 62 | theme: { 63 | dark: await loadTheme('path/to/theme.json'), 64 | light: await loadTheme('path/to/theme.json'), 65 | }, 66 | } 67 | }) 68 | ``` 69 | -------------------------------------------------------------------------------- /custom/index.md: -------------------------------------------------------------------------------- 1 | # カスタマイズ 2 | 3 | Slidevは、スタイリングからツールの設定まで、フルカスタマイズが可能です。Slidevの配下にあるツール([Vite](/custom/config-vite)、[Windi CSS](/custom/config-windicss)、 [Monaco](/custom/config-monaco)など)を設定することが可能です。 4 | 5 | ## フロントマターの設定 6 | 7 | 最初のスライドのフロントマターで、Slidevの設定をすることができます。以下に各オプションのデフォルト値を示しています。 8 | 9 | ```yaml 10 | --- 11 | # テーマのIDもしくはパッケージ名 12 | theme: 'default' 13 | # スライドのタイトル 指定されていない場合、最初のヘッダーから自動的に推測されます。 14 | title: '' 15 | # webページのタイトルテンプレート `%s`は各ページのタイトルで置き換えられます。 16 | titleTemplate: '%s - Slidev' 17 | 18 | # SPAビルドにおけるPDFダウンロードを有効化します。カスタムURLを使用することも可能です。 19 | download: true 20 | # シンタックスハイライト 'prism'か'shiki'が選択可能です。 21 | highlighter: 'prism' 22 | # コードブロックに行番号を表示します。 23 | lineNumbers: false 24 | # Monacoエディタを有効化します。デフォルトでは開発環境のみ有効です。 25 | monaco: 'dev' 26 | 27 | # スライドのカラースキーマを変更します。'auto'、'light'または'dark'を指定可能です。 28 | colorSchema: 'auto' 29 | # vue-routerのためのrouterModeを指定します。"history"または"hash"が指定可能です。 30 | routerMode: 'history' 31 | # スライドのアスペクト比を指定します。 32 | aspectRatio: '16/9' 33 | # canvasの実際の横幅を指定します。単位はpxです。 34 | canvasWidth: 980 35 | 36 | # faviconにはローカルファイルのパスか、URLを使用できます。 37 | favicon: 'https://cdn.jsdelivr.net/gh/slidevjs/slidev/assets/favicon.png' 38 | # フォントはGoogle Fontsから自動的にimportされます。 39 | # 詳細: https://sli.dev/custom/fonts 40 | fonts: 41 | sans: 'Roboto' 42 | serif: 'Roboto Slab' 43 | mono: 'Fira Code' 44 | 45 | # デフォルトのフロントマターはすべてのスライドに適用されます。 46 | defaults: 47 | layout: 'default' 48 | # ... 49 | 50 | # スライドの情報をMarkdownで記述することができます。 51 | info: | 52 | ## Slidev 53 | My first [Slidev](http://sli.dev/) presentations! 54 | --- 55 | ``` 56 | 57 | より詳しいオプションは[type definitions](https://github.com/slidevjs/slidev/blob/main/packages/types/src/config.ts)を参照してください。 58 | 59 | ## ディレクトリ構造 60 | 61 | Slidevはディレクトリ構造の規約を利用して、設定を最小化し、機能の拡張を柔軟かつ直感的に行えるようにしています。 62 | 63 | [ディレクトリ構造](/custom/directory-structure)のセクションを参照してください。 64 | 65 | ## ツールを設定する 66 | 67 | - [シンタックスハイライト](/custom/highlighters) 68 | - [Vueの設定](/custom/config-vue) 69 | - [Viteの設定](/custom/config-vite) 70 | - [Windi CSSの設定](/custom/config-windicss) 71 | - [Monacoの設定](/custom/config-monaco) 72 | - [KaTeXの設定](/custom/config-katex) 73 | - [Mermaidの設定](/custom/config-mermaid) 74 | -------------------------------------------------------------------------------- /custom/vue-context.md: -------------------------------------------------------------------------------- 1 | # Vueグローバルコンテキスト 2 | 3 | Slidevは高度な条件やナビゲーションのコントロールのために、[グローバルVueコンテキスト](https://v3.ja.vuejs.org/api/application-config.html#globalproperties) `$slidev`を注入しています。 4 | 5 | ## 使い方 6 | 7 | MarkdownやVueテンプレートのどこでも、["Mustache"タグ](https://v3.ja.vuejs.org/guide/template-syntax.html)を使ってアクセスできます。 8 | 9 | ```md 10 | 11 | 12 | # Page 1 13 | 14 | Current page is: {{ $slidev.nav.currentPage }} 15 | ``` 16 | 17 | ```html 18 | 19 | 20 | 24 | ``` 25 | 26 | ## プロパティ 27 | 28 | ### `$slidev.nav` 29 | 30 | スライドナビゲーションのプロパティとコントロールを保持するリアクティブオブジェクトです。 例: 31 | 32 | ```js 33 | $slidev.nav.next() // go next step 34 | 35 | $slidev.nav.nextSlide() // go next slide (skip v-clicks) 36 | 37 | $slidev.nav.go(10) // go slide #10 38 | ``` 39 | 40 | ```js 41 | $slidev.nav.currentPage // current slide number 42 | 43 | $slidev.nav.currentLayout // current layout id 44 | 45 | $slidev.nav.clicks // current clicks count 46 | ``` 47 | 48 | 利用できるプロパティの詳細については、[nav.ts](https://github.com/slidevjs/slidev/blob/main/packages/client/logic/nav.ts)のエクスポートを参照してください。 49 | 50 | ### `$slidev.configs` 51 | 52 | `slides.md`の[フロントマターの設定](/custom/#フロントマターの設定)をパースしたものを保持するリアクティブオブジェクトです。 例: 53 | 54 | ```yaml 55 | --- 56 | title: My First Slidev! 57 | --- 58 | ``` 59 | 60 | ``` 61 | {{ $slidev.configs.title }} // 'My First Slidev!' 62 | ``` 63 | 64 | ### `$slidev.themeConfigs` 65 | 66 | テーマの設定をパースしたものを保持するリアクティブオブジェクトです。 67 | 68 | ```yaml 69 | --- 70 | title: My First Slidev! 71 | themeConfig: 72 | primary: #213435 73 | --- 74 | ``` 75 | 76 | ``` 77 | {{ $slidev.themeConfigs.primary }} // '#213435' 78 | ``` 79 | -------------------------------------------------------------------------------- /guide/animations.md: -------------------------------------------------------------------------------- 1 | # アニメーション 2 | 3 | ## クリックアニメーション 4 | 5 | ### `v-click` 6 | 7 | 要素に対して"クリックアニメーション"を適用するには、`v-click`ディレクティブか``コンポーネントを使用することができます。 8 | 9 | ```md 10 | # Hello 11 | 12 | 13 | 14 | 15 | Hello World 16 | 17 | 18 | 19 | 20 |
21 | 22 | Hey! 23 | 24 |
25 | ``` 26 | 27 | ### `v-after` 28 | 29 | `v-after`は`v-click`に似ていますが、直前の`v-click`がトリガーされたときに要素を可視化します。 30 | 31 | ```md 32 |
Hello
33 |
World
34 | ``` 35 | 36 | "次へ"ボタンを押した時に、`Hello`と`World`の両方が一緒に表示されます。 37 | 38 | ### `v-click-hide` 39 | 40 | `v-click`と同じですが、要素を表示するのではなく、クリックした後に要素を非表示にします。 41 | 42 | ```md 43 |
Hello
44 | ``` 45 | 46 | ### `v-clicks` 47 | 48 | `v-clicks`はコンポーネントとしてのみ提供されています。これは`v-click`ディレクティブをそのすべての子要素に適用するためのショートハンドです。特にリストを扱う場合に便利です。 49 | 50 | ```md 51 | 52 | 53 | - Item 1 54 | - Item 2 55 | - Item 3 56 | - Item 4 57 | 58 | 59 | ``` 60 | 61 | "次へ"をクリックするたびに、項目が表示されるようになります。 62 | 63 | ### カスタムクリックカウント 64 | 65 | デフォルトでは、Slidevは次のスライドに進む前に必要なステップ数をカウントします。`clicks`というフロントマターオプションを記述することで、この設定をオーバーライドできます。 66 | 67 | ```yaml 68 | --- 69 | # このスライドでは、次のスライドに進むまでに10回クリックする 70 | clicks: 10 71 | --- 72 | ``` 73 | 74 | ### 並び替え 75 | 76 | ディレクティブにクリックインデックスを渡すことで、公開する順番をカスタマイズすることができます。 77 | 78 | ```md 79 |
1
80 |
2
81 |
3
82 | ``` 83 | 84 | ```md 85 | 86 |
1
87 |
2
88 |
3
89 | ``` 90 | 91 | ```md 92 | --- 93 | clicks: 3 94 | --- 95 | 96 | 97 | 98 |
Hi
99 |
100 | ``` 101 | 102 | ### 要素のトランジション 103 | 104 | 要素に`v-click`ディレクティブを適用すると、`slidev-vclick-target`というクラス名が付与されます。要素が非表示になった場合、クラス名`slidev-vclick-hidden`が付与されます。例: 105 | 106 | ```html 107 |
テキスト
108 | ``` 109 | 110 | クリックすると、以下のようになります 111 | 112 | ```html 113 |
テキスト
114 | ``` 115 | 116 | デフォルトでは、これらのクラスにはわずかな透明度のトランジションが適用されます。 117 | 118 | ```css 119 | // デフォルト 120 | 121 | .slidev-vclick-target { 122 | transition: opacity 100ms ease; 123 | } 124 | 125 | .slidev-vclick-hidden { 126 | opacity: 0; 127 | pointer-events: none; 128 | } 129 | ``` 130 | 131 | トランジション効果をカスタマイズするために、カスタムスタイルシートでそれらをオーバーライドすることができます。 132 | 133 | 例えば、スケールアップのトランジションは次のようにして実現することができます: 134 | 135 | ```css 136 | // styles.css 137 | 138 | .slidev-vclick-target { 139 | transition: all 500ms ease; 140 | } 141 | 142 | .slidev-vclick-hidden { 143 | transform: scale(0); 144 | } 145 | ``` 146 | 147 | 特定のスライドもしくはレイアウトにのみアニメーションを適用する場合 148 | 149 | ```scss 150 | .slidev-page-7, 151 | .slidev-layout.my-custom-layout { 152 | .slidev-vclick-target { 153 | transition: all 500ms ease; 154 | } 155 | 156 | .slidev-vclick-hidden { 157 | transform: scale(0); 158 | } 159 | } 160 | ``` 161 | 162 | 詳細は[スタイルのカスタマイズ](/custom/directory-structure#スタイル)を参照してください。 163 | 164 | ## モーション 165 | 166 | Slidevは[@vueuse/motion](https://motion.vueuse.org/)を内蔵しています。任意の要素にモーションを適用するために`v-motion`ディレクティブを使用することができます。例: 167 | 168 | ```html 169 |
173 | Slidev 174 |
175 | ``` 176 | 177 | `Slidev`というテキストは初期化時に`-80px`から元の位置へ移動します。 178 | 179 | > 注: Slidevはパフォーマンスのために次のスライドをプリロードします、つまり、ページに遷移する前にアニメーションが始まる可能性があります。正しく動作させるために、特定のスライドに対してプリロードを無効にすることができます。 180 | > 181 | > ```md 182 | > --- 183 | > preload: false 184 | > --- 185 | > ``` 186 | > 187 | > もしくは要素のライフサイクルを`v-if`で制御することで、きめ細やかな制御を行うこともできます。 188 | > 189 | > ```html 190 | >
v-if="$slidev.nav.currentPage === 7" 192 | > v-motion 193 | > :initial="{ x: -80 }" 194 | > :enter="{ x: 0 }"> 195 | > Slidev 196 | >
197 | > ``` 198 | 199 | 詳細: [デモ](https://sli.dev/demo/starter/7) | [@vueuse/motion](https://motion.vueuse.org/) | [v-motion](https://motion.vueuse.org/directive-usage.html) | [Presets](https://motion.vueuse.org/presets.html) 200 | 201 | ## ページのトランジション 202 | 203 | > 現在のバージョンでは、スライドのビルトインサポートはまだ提供されていません。次のメジャーバージョンでサポートする予定です。それまでは、カスタムスタイルやライブラリを使ってスライドを作成することができます。 204 | -------------------------------------------------------------------------------- /guide/drawing.md: -------------------------------------------------------------------------------- 1 | # 描画と注釈 2 | 3 | > v0.23から使用可能です 4 | 5 | 描画や注釈を行うための[drauu](https://github.com/antfu/drauu)を内蔵しており、プレゼンテーションをさらに充実させることができます。 6 | 7 | ツールバーのアイコンをクリックして、描画を開始します。 [プレゼンターモード](/guide/presenter-mode)でも使用可能です。作成した描画や注釈は、全インスタンスでリアルタイムに**同期**されます。 8 | 9 | 10 | 11 | ## スタイライスペンとともに使用する 12 | 13 | タブレットでスタイラスペンを使用する場合(例えば、iPadとApple Pencil)、Slidevは入力をスマートに検出することができます。描画モードをオンにすることなく、指やマウスでナビゲーションをコントロールしながら、ペンで直接スライドに描画することができます。 14 | 15 | ## 描画を保存する 16 | 17 | 以下のフロントマターの設定により、描画した内容はSVGとして`.slidev/drawings`ディレクトリ配下に保存され、エクスポートしたPDFやホスティングしたサイト内に表示させることができます。 18 | 19 | ```md 20 | --- 21 | drawings: 22 | persist: true 23 | --- 24 | ``` 25 | 26 | ## 描画を非表示にする 27 | 28 | 全体に対して: 29 | 30 | ```md 31 | --- 32 | drawings: 33 | enabled: false 34 | --- 35 | ``` 36 | 37 | 開発環境でのみ: 38 | 39 | ```md 40 | --- 41 | drawings: 42 | enabled: dev 43 | --- 44 | ``` 45 | 46 | プレゼンテーションモードでのみ: 47 | 48 | ```md 49 | --- 50 | drawings: 51 | presenterOnly: true 52 | --- 53 | ``` 54 | 55 | ## 描画を同期させる 56 | 57 | デフォルトでは、Slidevはすべてのインスタンスで描画を同期します。もし他の誰かとスライドを共有している場合は、同期を無効にした方がいいかもしれません: 58 | 59 | ```md 60 | --- 61 | drawings: 62 | syncAll: false 63 | --- 64 | ``` 65 | 66 | この設定により、プレゼンターのインスタンスからの描画のみ、他のインスタンスと同期することができるようになります。 67 | 68 | 69 | -------------------------------------------------------------------------------- /guide/editors.md: -------------------------------------------------------------------------------- 1 | # エディタサポート 2 | 3 | Slidevはソースの入力にMarkdownを使用しているので、あなたが好きなエディタで書くことができます。 4 | 5 | スライドを高度に管理したい場合、以下のエディタインテグレーションを使用することができます。 6 | 7 | ## 統合エディタ 8 | 9 | Slidevには[CodeMirror](https://codemirror.net/)というエディタが統合されており、ファイルの変更を即座に再読み込みして保存してくれます。 10 | 11 | 起動するためにはボタンを押してください。 12 | 13 | ![](/screenshots/integrated-editor.png) 14 | 15 | ## VS Code拡張機能 16 | 17 |

18 | 19 | Slidev 20 | 21 |
22 | 23 | Visual Studio Marketplace Version 24 | 25 |   26 | 27 | Visual Studio Marketplace Downloads 28 | 29 |

30 | 31 | VS Code拡張機能はスライドをよりよく整理し、その概要を素早く把握するための機能を提供します。 32 | 33 | ### 機能 34 | 35 | - スライドをサイドパネルで確認 36 | - 次へ / 戻るボタン 37 | - スライドの順序入れ替え 38 | - スライドブロックのための折り畳み機能 39 | - MarkdownをHTMLに変換 40 | 41 | ![](https://user-images.githubusercontent.com/11247099/116809994-cc2caa00-ab73-11eb-879f-60585747c3c9.png) 42 | 43 | 44 | -------------------------------------------------------------------------------- /guide/exporting.md: -------------------------------------------------------------------------------- 1 | # エクスポート 2 | 3 | ## PDF 4 | 5 | > PDFもしくはPNGへのエクスポートはレンダリングのために[Playwright](https://playwright.dev)に依存しています。したがって、この機能を使用するためには[`playwright-chromium`](https://playwright.dev/docs/installation#download-single-browser-binary)をインストールする必要があります。 6 | > CI環境でエクスポートを行う場合は、[the playwright CI guide](https://playwright.dev/docs/ci)が参考になります。 7 | 8 | `playwright-chromium`のインストール 9 | 10 | ```bash 11 | $ npm i -D playwright-chromium 12 | ``` 13 | 14 | 次のコマンドを使用してスライドをPDFにエクスポートします。 15 | 16 | ```bash 17 | $ slidev export 18 | ``` 19 | 20 | しばらくすると、スライドが`./slides-exports.pdf`に出力されます。 21 | 22 | ### クリックステップをエクスポートする 23 | 24 | > v0.21から使用可能です 25 | 26 | デフォルトでは、Slidevはクリックアニメーションを無効にして、スライド単位で1ページをエクスポートします。複数のステップがあるスライドを複数のページにエクスポートしたい場合は、`--with-clicks`オプションを指定します。 27 | 28 | ```bash 29 | $ slidev export --with-clicks 30 | ``` 31 | 32 | ## PNGs 33 | 34 | `--format png`オプションを指定した場合、Slidevは各スライドをPDFの代わりにPNG画像として出力します。 35 | 36 | ```bash 37 | $ slidev export --format png 38 | ``` 39 | 40 | ## シングルページアプリケーション (SPA) 41 | 42 | [静的ホスティング](/guide/hosting)を参照してください。 43 | -------------------------------------------------------------------------------- /guide/faq.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | ## グリッド 4 | 5 | SlidevはWebをベースにしているので、グリッドレイアウトを自由に適用することができます。[CSS Grids](https://css-tricks.com/snippets/css/complete-guide-grid/)、[flexboxes](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)、あるいは[Masonry](https://css-tricks.com/native-css-masonry-layout-in-css-grid/)で制御することができます。 6 | 7 | また[Windi CSS](https://windicss.org/)が内蔵されているので、参考までにそれを使った簡単な方法を紹介します: 8 | 9 | ```html 10 |
11 |
12 | 13 | 最初のカラム 14 | 15 |
16 |
17 | 18 | 2番目のカラム 19 | 20 |
21 |
22 | ``` 23 | 24 | さらに、各カラムのサイズをカスタマイズすることも可能です。: 25 | 26 | ```html 27 |
28 |
29 | 30 | 最初のカラム (200px) 31 | 32 |
33 |
34 | 35 | 2番目のカラム (自動調整) 36 | 37 |
38 |
39 | 40 | 3番目のカラム (親のコンテナに対して10%) 41 | 42 |
43 |
44 | ``` 45 | 46 | 詳細は[Windi CSS Grids](https://windicss.org/utilities/grid.html)を参照してください。 47 | 48 | ## ポジショニング 49 | 50 | スライドは固定サイズ(デフォルトは`980x552px`)で定義され、ユーザーのスクリーンに合わせて拡大・縮小されます。画面に合わせて拡大・縮小されるため、absolute positionを使用しても安全です。 51 | 52 | 例: 53 | 54 | ```html 55 |
56 | これは左下寄せのフッターです 57 |
58 | ``` 59 | 60 | キャンバスの実際の大きさを変更するには、最初のフロントマターで`canvasWidth`オプションを指定します。 61 | 62 | ```yaml 63 | --- 64 | canvasWidth: 800 65 | --- 66 | ``` 67 | 68 | ## フォントサイズ 69 | 70 | スライドのフォントサイズが小さすぎると感じる場合、いくつかの方法で調整することができます: 71 | 72 | ### ローカルスタイルをオーバーライドする 73 | 74 | インライン` 84 | 85 | --- 86 | 87 | # Page 2 88 | 89 | ここには適用されません 90 | ``` 91 | 92 | 詳細: [埋め込みスタイル](/guide/syntax.html#埋め込みスタイル) 93 | 94 | ### グローバルスタイルをオーバーライドする 95 | 96 | カスタムグローバルスタイルを定義するには、次のように`./style.css`を作成します。 97 | 98 | ```css 99 | /* style.css */ 100 | 101 | h1 { 102 | font-size: 10em !important; 103 | } 104 | ``` 105 | 106 | 詳細: [グローバルスタイル](/custom/directory-structure.html#スタイル) 107 | 108 | ### キャンバスの拡大・縮小 109 | 110 | キャンバスの実寸を変更すると、すべてのコンテンツ(テキスト、画像、コンポーネントなど)とスライドが拡大・縮小されます。 111 | 112 | ```yaml 113 | --- 114 | # default: 980 115 | # キャンバスが小さくなれば、視覚的なサイズは大きくなります。 116 | canvasWidth: 800 117 | --- 118 | ``` 119 | 120 | ### Transformの使用 121 | 122 | CSSのtransformプロパティの薄いラッパーである、ビルトインコンポーネント``を提供しています。 123 | 124 | ```md 125 | 126 | 127 | - Item 1 128 | - Item 2 129 | 130 | 131 | ``` 132 | -------------------------------------------------------------------------------- /guide/hosting.md: -------------------------------------------------------------------------------- 1 | # 静的ホスティング 2 | 3 | ## シングルページアプリケーション(SPA)を構築する 4 | 5 | スライドをセルフホスティング可能なSPAとして構築することができます: 6 | 7 | ```bash 8 | $ slidev build 9 | ``` 10 | 11 | 生成されたアプリケーションは`dist/`の配下に配置され、[GitHub Pages](https://pages.github.com/)、[Netlify](https://netlify.app/)、[Vercel](https://vercel.com/)など、好きな場所にホストすることができます。これでリンク1つで世界中の人とスライドを共有することできます。 12 | 13 | ### ベースパス 14 | 15 | サブルート下にスライドをデプロイするには、`--base`オプションを指定する必要があります。例: 16 | 17 | ```bash 18 | $ slidev build --base /talks/my-cool-talk/ 19 | ``` 20 | 21 | 詳細は[Viteのドキュメント](https://vitejs.dev/guide/build.html#public-base-path)を参照してください。 22 | 23 | ### ダウンロード可能なPDFを提供する 24 | 25 | 以下の設定により、SPAの閲覧者向けにダウンロード可能なPDFを提供することができます: 26 | 27 | ```md 28 | --- 29 | download: true 30 | --- 31 | ``` 32 | 33 | Slidevはビルドと一緒にPDFファイルを生成し、SPAにダウンロードボタンが表示されます。 34 | 35 | またPDFに対してカスタムURLを指定することもできます。その場合、レンダリング処理はスキップされます。 36 | 37 | ```md 38 | --- 39 | download: 'https://myside.com/my-talk.pdf' 40 | --- 41 | ``` 42 | 43 | ## サンプル 44 | 45 | 以下はSPAとしてエクスポートされた例です: 46 | 47 | - [Starter Template](https://sli.dev/demo/starter) 48 | - [Composable Vue](https://talks.antfu.me/2021/composable-vue) by [Anthony Fu](https://github.com/antfu) 49 | 50 | 詳しくは[ショーケース](/showcases)を参照してください。 51 | 52 | ## ホスティング 53 | 54 | `npm init slidev@lastest`を使って、サービスをそのままホスティングするために必要な設定ファイルが含まれたプロジェクトの雛形を生成することを推奨します。 55 | 56 | ### Netlify 57 | 58 | - [Netlify](https://netlify.com/) 59 | 60 | プロジェクトルートに以下の内容で`netlify.toml`を作成します。 61 | 62 | ```ts 63 | [build.environment] 64 | NODE_VERSION = "14" 65 | 66 | [build] 67 | publish = "dist" 68 | command = "npm run build" 69 | 70 | [[redirects]] 71 | from = "/*" 72 | to = "/index.html" 73 | status = 200 74 | ``` 75 | 76 | Netlifyのダッシュボードを開き、リポジトリを指定して新しいサイトを作成してください。 77 | 78 | ### Vercel 79 | 80 | - [Vercel](https://vercel.com/) 81 | 82 | プロジェクトルートに以下の内容で`vercel.json`を作成します。 83 | 84 | ```json 85 | { 86 | "rewrites": [ 87 | { "source": "/(.*)", "destination": "/index.html" } 88 | ] 89 | } 90 | ``` 91 | 92 | Vercelのダッシュボードを開き、リポジトリを指定して新しいサイトを作成してください。 93 | 94 | ## GitHub Pages 95 | 96 | - [GitHub Pages](https://pages.github.com/) 97 | 98 | GitHub Actionsを使用してGitHub Pagesにスライドをデプロイするために、以下の内容で`.github/workflows/deploy.yml`を作成してください。 99 | 100 | ```yaml 101 | name: Deploy pages 102 | on: push 103 | jobs: 104 | deploy: 105 | runs-on: ubuntu-latest 106 | steps: 107 | - uses: actions/checkout@v2 108 | - uses: actions/setup-node@v2 109 | with: 110 | node-version: '14' 111 | - name: Install dependencies 112 | run: npm install 113 | - name: Build 114 | run: npm run build 115 | - name: Deploy pages 116 | uses: crazy-max/ghaction-github-pages@v2 117 | with: 118 | build_dir: dist 119 | env: 120 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 121 | ``` 122 | -------------------------------------------------------------------------------- /guide/index.md: -------------------------------------------------------------------------------- 1 | # はじめに 2 | 3 | ## 概要 4 | 5 | Slidev (slide + dev, `/slʌɪdɪv/`) はWebベースのスライド作成およびプレゼンテーションツールです。開発者がMarkdownでコンテンツを書くことに集中しつつ、HTMLとVueコンポーネントを用いて、プレゼンテーションにインタラクティブなデモを埋め込んだピクセルパーフェクトなレイアウトとデザインを提供できるようにも設計されています。 6 | 7 | 機能豊富なマークダウンファイルを使用して、ライブコーディング、PDFエクスポート、プレゼンテーションのレコーディングのような、多くのビルトインインテグレーションとともに、瞬時に再読み込みが可能な美しいスライドを生成します。webで動くので、Slidevを使ってどんなことでもできます - 可能性は無限大です。 8 | 9 | プロジェクトの論理的根拠については [なぜSlidev?](/guide/why) のセクションで詳しく説明しています。 10 | 11 | ### 機能 12 | 13 | - 📝 [**Markdownベース**](/guide/syntax.html) - お気に入りのエディタとワークフローを使用 14 | - 🧑‍💻 [**デベロッパーフレンドリー**](/guide/syntax.html#コードブロック) - ビルトインのシンタックスハイライト、ライブコーディングなど 15 | - 🎨 [**豊富なテーマ**](/themes/gallery.html) - テーマはnpmパッケージで共有・利用が可能 16 | - 🌈 [**スタイリッシュ**](/guide/syntax.html#埋め込みスタイル) - [Windi CSS](https://windicss.org/) オンデマンドユーティリティ、 使いやすい埋め込まれたスタイルシート 17 | - 🤹 [**インタラクティブ**](/custom/directory-structure.html#コンポーネント) - Vueコンポーネントをシームレスに埋め込み 18 | - 🎙 [**プレゼンターモード**](/guide/presenter-mode.html) - 別のウィンドウ、スマートフォンでさえもスライドを操作 19 | - 🎨 [**描画**](/guide/drawing.html) - スライドに描画し、注釈をつける 20 | - 🧮 [**LaTeX**](/guide/syntax.html#latex) - LaTeX数式のビルトインサポート 21 | - 📰 [**図形**](/guide/syntax.html#図形) - 説明と合わせて図形を作成 22 | - 🌟 [**アイコン**](/guide/syntax.html#アイコン) - どんなアイコンセットからでも、直接アイコンにアクセス 23 | - 💻 [**エディタ**](/guide/editors.html) - 統合されたエディタと[VS Code拡張機能](https://github.com/slidevjs/slidev-vscode) 24 | - 🎥 [**レコーディング**](/guide/recording.html) - ビルトインのレコーディングとカメラビュー 25 | - 📤 [**ポータブル**](/guide/exporting.html) - PDF、PNG、またはホスト可能なSPAにエクスポート 26 | - ⚡️ [**高速**](https://vitejs.dev) - [Vite](https://vitejs.dev) によって提供されたインスタントリロード 27 | - 🛠 [**自由に開発可能**](/custom/config-vite.html) - Viteプラグイン、Vue components、どんなnpmパッケージも使用可能 28 | 29 | ### 技術スタック 30 | 31 | これらのツールや技術を組み合わせることで、Slidevは実現されています。 32 | 33 | - [Vite](https://vitejs.dev) - 非常に高速なフロントエンドツール 34 | - [Vue 3](https://v3.ja.vuejs.org/)をベースにした[Markdown](https://daringfireball.net/projects/markdown/syntax) - 必要に応じてHTMLとVueコンポーネントを使いつつ、コンテンツに集中できます 35 | - [Windi CSS](https://github.com/windicss/windicss) - オンデマンドなユーティリティファーストのCSSフレームワーク、 スライドを自在にスタイリング 36 | - [Prism](https://github.com/PrismJS/prism)、[Shiki](https://github.com/shikijs/shiki)、[Monaco Editor](https://github.com/Microsoft/monaco-editor) - ファーストクラスのコードスニペットサポートとライブコーディング機能 37 | - [RecordRTC](https://recordrtc.org) - ビルトインのレコーディングとカメラビュー 38 | - [VueUse](https://vueuse.org)ファミリー - [`@vueuse/core`](https://github.com/vueuse/vueuse)、[`@vueuse/head`](https://github.com/vueuse/head)、[`@vueuse/motion`](https://github.com/vueuse/motion)など 39 | - [Iconify](https://iconify.design/) - アイコンセットコレクション 40 | - [Drauu](https://github.com/antfu/drauu) - 描画と注釈のサポート 41 | - [KaTeX](https://katex.org/) - LaTeX数式のレンダリング 42 | - [Mermaid](https://mermaid-js.github.io/mermaid) - テキストによる図解 43 | 44 | ### はじめてのプレゼンテーションを作成する 45 | 46 |
47 | 48 | #### オンラインで試す 49 | 50 | [sli.dev/new](https://sli.dev/new) 51 | 52 | [![](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://sli.dev/new) 53 | 54 | #### ローカルで作成する 55 | 56 | NPMで作成: 57 | 58 | ```bash 59 | $ npm init slidev 60 | ``` 61 | 62 | Yarnで作成: 63 | 64 | ```bash 65 | $ yarn create slidev 66 | ``` 67 | 68 | プロンプトに従って、今すぐスライドを作り始めましょう! Markdownシンタックスの詳細は、 [シンタックスガイド](/guide/syntax)を参照してください。 69 | 70 | ### コマンドラインインターフェース 71 | 72 | Slidevがインストールされたプロジェクトでは、 npmスクリプトで `slidev`コマンドを使用することができます。 73 | 74 | ```json 75 | { 76 | "scripts": { 77 | "dev": "slidev", // start dev server 78 | "build": "slidev build", // build for production SPA 79 | "export": "slidev export" // export slides to pdf 80 | } 81 | } 82 | ``` 83 | 84 | あるいは [`npx`](https://www.npmjs.com/package/npx) で使用することができます。 85 | 86 | ```bash 87 | $ npx slidev 88 | ``` 89 | 90 | その他のオプションについては、 `slidev --help` を実行してください。 91 | 92 | ### Markdownシンタックス 93 | 94 | Slidevはプロジェクトルートの配下にある `slides.md` を読み取り、スライドに変換します。 変更を加えると、 スライドのコンテンツに即時に反映されます。 例: 95 | 96 | ~~~md 97 | # Slidev 98 | 99 | Hello World 100 | 101 | --- 102 | 103 | # Page 2 104 | 105 | Directly use code blocks for highlighting 106 | 107 | //```ts 108 | console.log('Hello, World!') 109 | //``` 110 | 111 | --- 112 | 113 | # Page 3 114 | ~~~ 115 | 116 | SlidevのMarkdownシンタックスについては [シンタックスガイド](/guide/syntax) を参照してください。 117 | -------------------------------------------------------------------------------- /guide/install.md: -------------------------------------------------------------------------------- 1 | # インストール 2 | 3 | ## スターターテンプレート 4 | 5 | > Slidevは[**Node.js >=14.0**](https://nodejs.org/)で動作します 6 | 7 | まずは公式スターターテンプレートを利用してみてください。 8 | 9 | NPMで使用する: 10 | 11 | ```bash 12 | $ npm init slidev@latest 13 | ``` 14 | 15 | Yarnで使用する: 16 | 17 | ```bash 18 | $ yarn create slidev 19 | ``` 20 | 21 | 表示されるプロンプトに従って操作をすると、スライドショーが http://localhost:3030/ で自動的に立ち上がります。 22 | 23 | スターターテンプレートには基本的な設定やSlidevの使い方を説明した簡単なデモも収録されています。 24 | 25 | ## マニュアルインストール 26 | 27 | Slidevを手動でインストールしたい、または既存のプロジェクトに統合したい場合は、次のようにします: 28 | 29 | ```bash 30 | $ npm install @slidev/cli @slidev/theme-default 31 | ``` 32 | ```bash 33 | $ touch slides.md 34 | ``` 35 | ```bash 36 | $ npx slidev 37 | ``` 38 | 39 | > [pnpm](https://pnpm.io)を使用している場合、Slidevを正しく動作させるために[shamefully-hoist](https://pnpm.io/npmrc#shamefully-hoist)オプションを有効にする必要があることに注意してください。 40 | > 41 | > ```bash 42 | > echo 'shamefully-hoist=true' >> .npmrc 43 | > ``` 44 | 45 | ## グローバルインストール 46 | 47 | > v0.14から使用可能です 48 | 49 | 以下のコマンドで、Slidevをグローバルにインストール可能です。 50 | 51 | ```bash 52 | $ npm i -g @slidev/cli 53 | ``` 54 | 55 | 毎回プロジェクトを作成することなく、どこでも`slidev`コマンドを使用できるようになります。 56 | 57 | ```bash 58 | $ slidev 59 | ``` 60 | 61 | このコマンドはローカルの`@slidev/cli`が`node_modules`にあれば、それを実行します。 62 | 63 | ## Docker上にインストールする 64 | 65 | コンテナでプレゼンテーションを迅速に実行する必要がある場合、あらかじめ組み込まれている[docker](https://hub.docker.com/r/stig124/slidev)イメージ(メンテナー:[stig124](https://github.com/Stig124))を使うか、あるいは自分でビルドします。 66 | 67 | 詳しくは[slidevjs/container repo](https://github.com/slidevjs/container)を参照してください。 68 | -------------------------------------------------------------------------------- /guide/navigation.md: -------------------------------------------------------------------------------- 1 | # ナビゲーション 2 | 3 | ## ナビゲーションバー 4 | 5 | Slidevのページの左下にマウスを移動すると、ナビゲーションバーが表示されます。 6 | 7 | ![](/screenshots/navbar.png) 8 | 9 | | ショートカット | ボタン | 説明 | 10 | | --- | --- | --- | 11 | | f | | フルスクリーンに切り替え | 12 | | right / space | | 次のアニメーションもしくはスライドへ | 13 | | left | | 前のアニメーションもしくはスライドへ | 14 | | up | - | 前のスライドへ | 15 | | down | - | 次のスライドへ | 16 | | o | | [スライドオーバービュー](#スライドオーバービュー)に切り替え | 17 | | d | | ダークモードに切り替え | 18 | | - | | [カメラビュー](/guide/recording#カメラビュー)に切り替え | 19 | | - | | [レコーディング](/guide/recording#レコーディング-1) | 20 | | - | | [プレゼンターモード](/guide/presenter-mode) | 21 | | - | | [統合エディタ](/guide/editors#統合エディタ)に切り替え | 22 | | - | | スライドをダウンロード ([SPAビルド](/guide/exporting#シングルページアプリケーション-spa)でだけ表示されます) | 23 | | - | | スライドの情報を表示 | 24 | | - | | 設定メニューを表示 | 25 | | g | - | goto...を表示 | 26 | 27 |
28 | 29 | ## スライドオーバービュー 30 | 31 | oを押すか、ナビゲーションバーのボタンをクリックすることで、スライドを俯瞰することができ、スライド間を簡単にジャンプできます。 32 | 33 | ![](/screenshots/slides-overview.png) 34 | -------------------------------------------------------------------------------- /guide/presenter-mode.md: -------------------------------------------------------------------------------- 1 | # プレゼンターモード 2 | 3 | ナビゲーションパネルのボタンをクリックするか、 http://localhost:3030/presenter に手動でアクセスすることで、プレゼンターモードに入ります。プレゼンターモードに入ると、他のページインスタンスも自動的にプレゼンターと同期するようになります。 4 | 5 | ![](/screenshots/presenter-mode.png) 6 | -------------------------------------------------------------------------------- /guide/recording.md: -------------------------------------------------------------------------------- 1 | # レコーディング 2 | 3 | Slidevにはレコーディング機能とカメラビューが内蔵されています。これらを使って一箇所で簡単にプレゼンテーションをレコーディングすることができます。 4 | 5 | ## カメラビュー 6 | 7 | カメラビューをプレゼンテーションで有効にするには、ナビゲーションパネルのボタンをクリックしてください。ドラッグで移動、右下のハンドラでサイズ変更も可能です。サイズと位置は`localStorage`に保存され、リフレッシュされても維持されるため、心配する必要はありません。 8 | 9 | 10 | 11 | ## レコーディング 12 | 13 | ナビゲーションパネルのボタンをクリックすると、ダイアログが表示されます。ここでは、スライドにカメラを埋め込んで録画するか、2つの動画ファイルに分離して録画するかを選択することができます。 14 | 15 | この機能は[RecordRTC](https://github.com/muaz-khan/RecordRTC)によって提供され、[WebRTC API](https://webrtc.org/)を使用しています。 16 | 17 | ![](/screenshots/recording.png) 18 | -------------------------------------------------------------------------------- /guide/syntax.md: -------------------------------------------------------------------------------- 1 | # Markdownシンタックス 2 | 3 | スライドは **1つのマークダウンファイル** (デフォルト: `./slides.md`) の中に記述されます。 4 | 5 | [Markdownの機能](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)は通常通り使用することができ、インラインHTMLとVueコンポーネントが追加でサポートされています。[Windi CSS](https://windicss.org)を使ったスタイリングもサポートされています。スライドを区切るには改行で囲まれた`---`を使用してください。 6 | 7 | ~~~md 8 | # Slidev 9 | 10 | Hello, World! 11 | 12 | --- 13 | 14 | # Page 2 15 | 16 | コードブロックを直接使用してハイライト表示する 17 | 18 | //```ts 19 | console.log('Hello, World!') 20 | //``` 21 | 22 | --- 23 | 24 | # Page 3 25 | 26 | Windi CSSとVueコンポーネントを直接使用して、スライドをスタイリングし、リッチにすることができます。 27 | 28 |
29 | 30 |
31 | ~~~ 32 | 33 | ## フロントマター & レイアウト 34 | 35 | スライドのセパレータを[フロントマターブロック](https://jekyllrb.com/docs/front-matter/)に変換して、各スライドのレイアウトやその他のメタデータを指定します。各フロントマターはトリプルダッシュで始まり、トリプルダッシュで終わります。その間にあるテキストは[YAML](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started/)形式のデータオブジェクトになります。例: 36 | 37 | ~~~md 38 | --- 39 | layout: cover 40 | --- 41 | 42 | # Slidev 43 | 44 | これはカバーページです。 45 | 46 | --- 47 | layout: center 48 | background: './images/background-1.png' 49 | class: 'text-white' 50 | ---​ 51 | 52 | # Page 2 53 | 54 | これはレイアウト`center`とバックグラウンドイメージが指定されたページです。 55 | 56 | --- 57 | 58 | # Page 3 59 | 60 | これはいかなる追加のメタデータもない、デフォルトのページです。 61 | ~~~ 62 | 63 | 詳細は[カスタマイズ](/custom/)を参照してください。 64 | 65 | ## コードブロック 66 | 67 | Slidevを開発した大きな理由の1つは、自分のコードをスライド上で正しく見せる必要があるためです。SlidevではMarkdownフレーバーなコードブロックを使って、意図した通りにコードをハイライトすることができます。 68 | 69 | ~~~ts 70 | //```ts 71 | console.log('Hello, World!') 72 | //``` 73 | ~~~ 74 | 75 | Slidevはシンタックスハイライターとして[Prism](http://prismjs.com)と[Shiki](https://github.com/shikijs/shiki)をサポートしています。詳細は[シンタックスハイライト](/custom/highlighters)を参照してください。 76 | 77 | ### 行のハイライト 78 | 79 | 特定の行をハイライトするためには、ブラケット`{}`の中に単純に行番号を追加するだけです。行番号のカウントは1から始まります。 80 | 81 | ~~~ts 82 | //```ts {2,3} 83 | function add( 84 | a: Ref | number, 85 | b: Ref | number 86 | ) { 87 | return computed(() => unref(a) + unref(b)) 88 | } 89 | //``` 90 | ~~~ 91 | 92 | ハイライトする行を複数ステップに分けて変更するには、`|`を使用して行番号を分割してください。例: 93 | 94 | ~~~ts 95 | //```ts {2-3|5|all} 96 | function add( 97 | a: Ref | number, 98 | b: Ref | number 99 | ) { 100 | return computed(() => unref(a) + unref(b)) 101 | } 102 | //``` 103 | ~~~ 104 | 105 | このサンプルでは、はじめに`a: Ref | number`と`b: Ref | number`を、次にクリックがされた後に`return computed(() => unref(a) + unref(b))`を、最後にコードブロック全体をハイライトします。詳細は[アニメーションガイド](/guide/animations)を参照してください。 106 | 107 | ### Monacoエディタ 108 | 109 | プレゼンテーション中になんらかの変更を加えたいときは、言語名の後ろに`{monaco}`を追加するだけで、ブロックが完全なMonacoエディタに切り替わります! 110 | 111 | ~~~ts 112 | //```ts {monaco} 113 | console.log('HelloWorld') 114 | //``` 115 | ~~~ 116 | 117 | 詳細は[Monacoの設定](/custom/config-monaco)を参照してください。 118 | 119 | ## 埋め込みスタイル 120 | 121 | Markdownで直接` 131 | 132 | --- 133 | 134 | # 次のスライドには適用されない 135 | ``` 136 | 137 | Markdown内の` 153 | ``` 154 | 155 | ## 静的アセット 156 | 157 | Markdownで書くのと同じように、リモートまたはローカルのURLを指定して画像を使用することができます。 158 | 159 | リモートのアセットについては、ビルトインの[`vite-plugin-remote-assets`](https://github.com/antfu/vite-plugin-remote-assets)が初回実行時にディスクにキャッシュするため、あとで大きなサイズの画像を読み込み場合でもすぐに読み込むことができます。 160 | 161 | ```md 162 | ![リモートの画像](https://sli.dev/favicon.png) 163 | ``` 164 | 165 | ローカルのアセットについては、[`public`フォルダ](/custom/directory-structure.html#public)に格納し、**頭にスラッシュ**をつけて参照します。 166 | 167 | ```md 168 | ![ローカルの画像](/pic.png) 169 | ``` 170 | 171 | カスタムサイズやスタイルを適用したい場合は、``タグに変換することもできます。 172 | 173 | ```html 174 | 175 | ``` 176 | 177 | ## ノート 178 | 179 | 各スライドにメモを取ることもできます。メモは[プレゼンターモード](/guide/presenter-mode)に表示され、プレゼンテーションの際に参照することができます。 180 | 181 | Markdownでは、各スライドの最後のコメントブロックはノートとして扱われます。 182 | 183 | ~~~md 184 | --- 185 | layout: cover 186 | --- 187 | 188 | # Page 1 189 | 190 | これはカバーページです。 191 | 192 | 193 | 194 | --- 195 | 196 | # Page 2 197 | 198 | 199 | 200 | 2ページ目 201 | 202 | 205 | ~~~ 206 | 207 | ## アイコン 208 | 209 | Slidevを使用すると、Markdownの中でほとんどすべての人気のあるオープンソースのアイコンセットに**直接**アクセスすることができます。[`vite-plugin-icons`](https://github.com/antfu/vite-plugin-icons)と[Iconify](https://iconify.design/)によって提供されています。 210 | 211 | 命名は[Iconify](https://iconify.design/)の`{collection-name}-{icon-name}`の形式に従います。例: 212 | 213 | - `` - from [Material Design Icons](https://github.com/Templarian/MaterialDesign) 214 | - `` - from [Carbon](https://github.com/carbon-design-system/carbon/tree/main/packages/icons) 215 | - `` - from [Unicons Monochrome](https://github.com/Iconscout/unicons) 216 | - `` - from [Twemoji](https://github.com/twitter/twemoji) 217 | - `` - from [SVG Logos](https://github.com/gilbarbara/logos) 218 | - その他にも。.. 219 | 220 | 利用可能なすべてのアイコンは[Icônes](https://icones.js.org/)で閲覧・検索できます。 221 | 222 | ### アイコンのスタイリング 223 | 224 | 他のHTML同様にアイコンをスタイルすることができます。例: 225 | 226 | ```html 227 | 228 | 229 | 230 | ``` 231 | 232 | 233 | 234 | 235 | 236 | ## スロット 237 | 238 | > v0.18から使用可能です 239 | 240 | レイアウトによっては、[名前付きスロット](https://v3.ja.vuejs.org/guide/component-slots.html#%E3%83%95%E3%82%A9%E3%83%BC%E3%83%AB%E3%83%8F%E3%82%99%E3%83%83%E3%82%AF%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84)を使用して、複数のコントリビューションポイントを提供できます。 241 | 242 | 例えば、[`two-cols`レイアウト](https://github.com/slidevjs/slidev/blob/main/packages/client/layouts/two-cols.vue)では、左 (`default`スロット)と右 (`right` スロット)の2つのカラムを並べることができるようになります。 243 | 244 | ```md 245 | --- 246 | layout: two-cols 247 | --- 248 | 249 | 256 | 263 | ``` 264 | 265 |
266 |
267 |

268 |

これは左側に表示されます。

269 |
270 |
271 |

272 |

これは右側に表示されます。

273 |
274 |
275 | 276 | またスロット名のショートハンドシンタックスシュガー`::name::`も用意されています。次の例は前に示した例と全く同じように動作します。 277 | 278 | ```md 279 | --- 280 | layout: two-cols 281 | --- 282 | 283 | # Left 284 | 285 | これは左側に表示されます。 286 | 287 | ::right:: 288 | 289 | # Right 290 | 291 | これは右側に表示されます。 292 | ``` 293 | 294 | またデフォルトのスロットを明示的に指定し、カスタムオーダーで提供することも可能です。 295 | 296 | ```md 297 | --- 298 | layout: two-cols 299 | --- 300 | 301 | ::right:: 302 | 303 | # Right 304 | 305 | これは右側に表示されます。 306 | 307 | ::default:: 308 | 309 | # Left 310 | 311 | これは左側に表示されます。 312 | ``` 313 | 314 | ## 設定 315 | 316 | 必要な設定はすべてMarkdownファイルで定義することができます。 例: 317 | 318 | ```md 319 | --- 320 | theme: seriph 321 | layout: cover 322 | background: 'https://source.unsplash.com/1600x900/?nature,water' 323 | --- 324 | 325 | # Slidev 326 | 327 | これはカバーページです。 328 | ``` 329 | 330 | 詳細は[フロントマターの設定](/custom/#フロントマターの設定)を参照してください。 331 | 332 | ## LaTeX 333 | 334 | Slidevは[KaTeX](https://katex.org/)によってLaTeXをサポートしています。 335 | 336 | 337 | 338 | ### インライン 339 | 340 | インラインで表示する場合は、LaTeXの両側を1つの`$`で囲います。 341 | 342 | ```md 343 | $\sqrt{3x-1}+(1+x)^2$ 344 | ``` 345 | 346 | ### ブロック 347 | 348 | ブロックで表示するには、2つの (`$$`)を使います。このモードではより大きな記号を使用し、結果を中央に配置します。 349 | 350 | ```md 351 | $$ 352 | \begin{array}{c} 353 | 354 | \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & 355 | = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ 356 | 357 | \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ 358 | 359 | \nabla \cdot \vec{\mathbf{B}} & = 0 360 | 361 | \end{array} 362 | $$ 363 | ``` 364 | 365 | 詳細: [デモ](https://sli.dev/demo/starter/8) | [KaTeX](https://katex.org/) | [`markdown-it-katex`](https://github.com/waylonflinn/markdown-it-katex) 366 | 367 | ## 図形 368 | 369 | [Mermaid](https://mermaid-js.github.io/mermaid)を利用して、Markdownのテキスト記述から図 / グラフを作成することも可能です。 370 | 371 | `mermaid`として指定されたコードブロックは図形に変換されます。 例: 372 | 373 | ~~~md 374 | //```mermaid 375 | sequenceDiagram 376 | Alice->John: Hello John, how are you? 377 | Note over Alice,John: A typical interaction 378 | //``` 379 | ~~~ 380 | 381 | さらにオプションオブジェクトを渡すことで、スケーリングやテーマを指定することができます。オブジェクトのシンタックスはJavaScriptのオブジェクトリテラルで、文字列には引用符(`'`)を、キーの間には(`,`)を追加する必要があります。 382 | 383 | ~~~md 384 | //```mermaid {theme: 'neutral', scale: 0.8} 385 | graph TD 386 | B[Text] --> C{Decision} 387 | C -->|One| D[Result 1] 388 | C -->|Two| E[Result 2] 389 | //``` 390 | ~~~ 391 | 392 | 詳細: [デモ](https://sli.dev/demo/starter/9) | [Mermaid](https://mermaid-js.github.io/mermaid) 393 | 394 | ## マルチプルエントリー 395 | 396 | > v0.15から使用可能です 397 | 398 | `slides.md`を複数のファイルに分割して、好きなように整理することができます。 399 | 400 | `slides.md` : 401 | 402 | ```md 403 | # Page 1 404 | 405 | これは通常のページです。 406 | 407 | --- 408 | src: ./subpage2.md 409 | --- 410 | 411 | 412 | インラインコンテンツは無視されます 413 | ``` 414 | 415 | `subpage2.md` : 416 | 417 | ```md 418 | # Page 2 419 | 420 | このページは別のファイルのものです 421 | ``` 422 | 423 | ### フロントマターのマージ 424 | 425 | フロントマターはメインのエントリーと外部のMarkdownページの両方から指定することができます。もし同じキーがある場合は、**メインエントリに記載されている内容がより優先度が高くなります**。例: 426 | 427 | `slides.md` : 428 | 429 | ```md 430 | --- 431 | src: ./cover.md 432 | background: https://sli.dev/bar.png 433 | class: text-center 434 | --- 435 | ``` 436 | 437 | `cover.md` : 438 | 439 | ```md 440 | --- 441 | layout: cover 442 | background: https://sli.dev/foo.png 443 | --- 444 | 445 | # カバー 446 | 447 | カバーページ 448 | ``` 449 | 450 | 以下のページと同じように評価されます: 451 | 452 | ```md 453 | --- 454 | layout: cover 455 | background: https://sli.dev/bar.png 456 | class: text-center 457 | --- 458 | 459 | # カバー 460 | 461 | カバーページ 462 | ``` 463 | 464 | ### ページの再利用 465 | 466 | マルチエントリーにより、ページの再利用が容易になります。例: 467 | 468 | ```yaml 469 | --- 470 | src: ./cover.md 471 | --- 472 | 473 | --- 474 | src: ./intro.md 475 | --- 476 | 477 | --- 478 | src: ./content.md 479 | --- 480 | 481 | --- 482 | # reuse 483 | src: ./content.md 484 | --- 485 | ``` 486 | -------------------------------------------------------------------------------- /guide/why.md: -------------------------------------------------------------------------------- 1 | # なぜSlidev? 2 | 3 | [Microsoft PowerPoint](https://www.microsoft.com/en-us/microsoft-365/powerpoint)や[Apple Keynote](https://www.apple.com/keynote/)など、機能豊富で汎用的なWYSIWYGのスライド作成ツールがたくさんあります。これらは非常に直感的で簡単に学ぶことができる一方で、アニメーションやチャート、その他の多くの機能を使った素晴らしいスライドを作成するのに非常によく機能します。では、なぜわざわざSlidevを作ったのでしょうか? 4 | 5 | Slidevの目的は、開発者が既に慣れ親しんでいるツールや技術を使って、プレゼンテーションをさらに面白く、表現力豊かに、そして魅力的にするための柔軟性と対話性を提供することです。 6 | 7 | WYSIWYGエディタで作業していると、スタイリングオプションに気を取られがちです。Slidevはコンテンツとビジュアルを分離することでそれを改善します。これによって、一度に1つのことに集中できるようになり、同時にコミュニティのテーマを再利用できるようになります。Slidevは他のスライドデッキビルダーに完全に取って代わろうとはしていません。それよりも、開発者コミュニティに応えることに重点をおいています。 8 | 9 | ## Slidev 10 | 11 | ![](/screenshots/cover.png) 12 | 13 | ここでは、いくつかのSlidevのクールな機能を紹介します: 14 | 15 | ## Markdownベース 16 | 17 | Slidevは拡張されたMarkdown形式を使用して、スライドを単一のプレーンテキストファイルに保存し、整理します。これにより、コンテンツの作成に集中することができます。またコンテンツとスタイルが分離されているので、異なるテーマに楽に切り替えることが可能です。 18 | 19 | 詳しくは[Markdownシンタックス](/guide/syntax)を参照してください。 20 | 21 | ## 豊富なテーマ 22 | 23 | Slidevのテーマは、npmパッケージを使用して共有とインストールができます。そして1行設定するだけでテーマを適用することができます。 24 | 25 | [テーマギャラリー](/themes/gallery)や[テーマを作成する](/themes/write-a-theme)をチェックしてみてください。 26 | 27 | ## デベロッパーフレンドリー 28 | 29 | Slidevは開発者のためにコードスニペットのファーストクラスのサポートを提供します。[Prism](https://prismjs.com/)と[Shiki](https://github.com/shikijs/shiki)の両方をサポートし、ピクセルパーフェクトなシンタックスハイライトを実現しつつ、いつでもコードを修正することができます。[Monaco editor](https://microsoft.github.io/monaco-editor/) を内蔵し、オートコンプリート、タイプホバーリング、TypeScriptの型チェックサポートにより、プレゼンテーションでのライブコーディングやデモも可能になります。 30 | 31 | 詳しくは[シンタックスハイライト](/custom/highlighters)と[Monacoの設定](/custom/config-monaco)を参照してください。 32 | 33 | ## 高速 34 | 35 | Slidevは[Vite](https://vitejs.dev/)、[Vue 3](https://v3.ja.vuejs.org/)、そして[Windi CSS](https://windicss.org/)を利用しており、もっとも素晴らしいオーサリング体験を提供しています。あなたが行ったすべての変更は、**即時に**あなたのスライドに反映されます。 36 | 37 | 詳しくは[技術スタック](/guide/#技術スタック)をご覧ください。 38 | 39 | ## インタラクティブ & エクスプレッシブ 40 | 41 | Markdownファイルの中に直接Vueのカスタムコンポーネントを記述することができます。また、プレゼンテーションの中でそれらとやりとりすることで、より面白く、より直感的にアイデアを表現することができます。 42 | 43 | ## レコーディングサポート 44 | 45 | Slidevはビルトインのレコーディング機能とカメラービューを提供します。カメラービューを含めたプレゼンテーションを共有したり、画面とカメラで別々に録画・保存することも可能です。すべてSlidevだけで完結しており、追加のツールは必要ありません。 46 | 47 | 詳しくは[レコーディング](/guide/recording)を参照してください。 48 | 49 | ## ポータブル 50 | 51 | コマンド1つでスライドをPDF、PNG、あるいはホスティング可能なSPAとしてエクスポートでき、どこへでも共有することができます。 52 | 53 | 詳しくは[エクスポート](/guide/exporting)を参照してください。 54 | 55 | ## 自由に開発可能 56 | 57 | Web技術を使用していることにより、WebアプリでできることはSlidevでも実現可能です。例えば、WebGL、APIリクエスト、iframe、あるいはライブシェアリングなどが利用可能です。あなたの想像力次第でなんでもできます! 58 | 59 | ## 試してみる 60 | 61 | 百聞は一件にしかずということで、実際にSlidevを使ってみましょう。 コマンドを実行: 62 | 63 | ```bash 64 | $ npm init slidev 65 | ``` 66 | 67 | またはプレビュー: 68 | 69 |
70 | 71 |
72 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /logo.png 4 | actionText: はじめる 5 | actionLink: /guide/ 6 | 7 | altActionText: もっと詳しく 8 | altActionLink: /guide/why 9 | 10 | footer: MIT Licensed | Copyright © 2021-PRESENT Anthony Fu 11 | --- 12 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build.environment] 2 | NPM_FLAGS = "--prefix=/dev/null" 3 | NODE_VERSION = "20" 4 | PLAYWRIGHT_BROWSERS_PATH = "0" 5 | 6 | [build] 7 | publish = ".vitepress/dist" 8 | command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run build" 9 | 10 | [[redirects]] 11 | from = "/new" 12 | to = "https://stackblitz.com/fork/slidev?file=slides.md" 13 | status = 302 14 | force = true 15 | 16 | [[redirects]] 17 | from = "https://slidev.antfu.me/*" 18 | to = "https://sli.dev/:splat" 19 | status = 301 20 | force = true 21 | 22 | [[redirects]] 23 | from = "/demo/composable-vue/*" 24 | to = "https://demo.sli.dev/composable-vue" 25 | status = 301 26 | force = true 27 | 28 | [[redirects]] 29 | from = "/demo/starter/*" 30 | to = "https://demo.sli.dev/starter" 31 | status = 301 32 | force = true 33 | 34 | [[redirects]] 35 | from = "/*" 36 | to = "/index.html" 37 | status = 200 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "vitepress", 5 | "build": "vitepress build", 6 | "postinstall": "node .vitepress/scripts/prepare.js" 7 | }, 8 | "devDependencies": { 9 | "@iconify/json": "^1.1.380", 10 | "@slidev/client": "^0.13.13", 11 | "@slidev/parser": "^0.13.13", 12 | "@slidev/theme-default": "^0.7.9", 13 | "@slidev/types": "^0.13.13", 14 | "@types/fs-extra": "^9.0.12", 15 | "@types/node": "^15.14.3", 16 | "fs-extra": "^10.0.0", 17 | "typescript": "^4.3.5", 18 | "vite-plugin-components": "^0.10.4", 19 | "vite-plugin-icons": "^0.6.5", 20 | "vite-plugin-windicss": "^0.17.1", 21 | "vitepress": "^0.14.1", 22 | "windicss": "^3.1.5" 23 | }, 24 | "dependencies": { 25 | "@antfu/utils": "^0.1.7", 26 | "@vueuse/core": "^4.11.2", 27 | "typeit": "^7.0.4" 28 | }, 29 | "pnpm": { 30 | "overrides": { 31 | "vue-demi": "0.9.1" 32 | } 33 | }, 34 | "packageManager": "pnpm@9.6.0+sha512.38dc6fba8dba35b39340b9700112c2fe1e12f10b17134715a4aa98ccf7bb035e76fd981cf0bb384dfa98f8d6af5481c2bef2f4266a24bfa20c34eb7147ce0b5e" 35 | } 36 | -------------------------------------------------------------------------------- /public/assets/arrow-bottom-left.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 9 | 10 | 12 | 15 | 16 | 18 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /public/demo-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/demo-cover.png -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/favicon.png -------------------------------------------------------------------------------- /public/logo-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/logo-circle.png -------------------------------------------------------------------------------- /public/logo-for-vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/logo-for-vscode.png -------------------------------------------------------------------------------- /public/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/logo-square.png -------------------------------------------------------------------------------- /public/logo-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/logo-title.png -------------------------------------------------------------------------------- /public/logo-triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/logo-triangle.png -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/logo.png -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /public/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/og-image.png -------------------------------------------------------------------------------- /public/screenshots/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/screenshots/cover.png -------------------------------------------------------------------------------- /public/screenshots/covers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/screenshots/covers.png -------------------------------------------------------------------------------- /public/screenshots/integrated-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/screenshots/integrated-editor.png -------------------------------------------------------------------------------- /public/screenshots/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/screenshots/navbar.png -------------------------------------------------------------------------------- /public/screenshots/presenter-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/screenshots/presenter-mode.png -------------------------------------------------------------------------------- /public/screenshots/recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/screenshots/recording.png -------------------------------------------------------------------------------- /public/screenshots/slides-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/screenshots/slides-overview.png -------------------------------------------------------------------------------- /public/showcases/composable-vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/showcases/composable-vue.png -------------------------------------------------------------------------------- /public/theme-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-ja/f1d28dd3c4ad5291869a218e887387d572df59db/public/theme-placeholder.png -------------------------------------------------------------------------------- /resources/covers.md: -------------------------------------------------------------------------------- 1 | # キュレーションカバー 2 | 3 | スターターテンプレートのデモとして、いくつかのカバー画像をキュレーションしました。 4 | 5 | ![](/screenshots/covers.png) 6 | 7 | ```yaml 8 | --- 9 | # キュレーションコレクションからランダムに画像が表示されます 10 | background: https://source.unsplash.com/collection/94734566/1920x1080 11 | --- 12 | ``` 13 | 14 | もし気に入ったものがあれば、[Unsplash collection](https://unsplash.com/collections/94734566/slidev)をチェックして作者を探してみてください。 15 | -------------------------------------------------------------------------------- /resources/learning.md: -------------------------------------------------------------------------------- 1 | # 学習リソース 2 | 3 | ## 英語 4 | 5 | ### 動画 6 | 7 | 8 | 9 | ### 記事 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 | - [【用 markdown 写 Slide!】神器 Slidev 的安装及 bug 解决](https://blog.csdn.net/weixin_43828250/article/details/116664775) by HaloHoohoo 18 | 19 | ## 日本語 20 | 21 | - [開発者のためのスライド作成ツール Slidev がすごい](https://zenn.dev/ryo_kawamata/articles/introduce-slidev) by [ryo_kawamata](https://zenn.dev/ryo_kawamata) 22 | - [Markdownでオシャレなスライドを作るSli.dev](https://qiita.com/e99h2121/items/a115f8865a0dc21bb462) by [Nobuko YAMADA](https://qiita.com/e99h2121) 23 | -------------------------------------------------------------------------------- /showcases.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: false 3 | --- 4 | 5 | # ショーケース 6 | 7 | Slidevを使ったトーク / プレゼンテーションです。 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /themes/gallery.md: -------------------------------------------------------------------------------- 1 | # テーマギャラリー 2 | 3 | Slidevで利用できる素晴らしいテーマはこちらでご覧いただけます。 4 | 5 | 詳細は[テーマを使用する](/themes/use)または[テーマを作成する](/themes/write-a-theme)を参照してください。テーマをコミュニティで共有しましょう! 6 | 7 | ## 公式テーマ 8 | 9 | 10 | 11 | 12 | 13 | ## コミュニティテーマ 14 | 15 | コミュニティで作成されたキュレーションテーマを紹介します。 16 | 17 | 18 | 19 | 20 | 21 | 22 | ## その他のテーマ 23 | 24 | [NPMで利用可能なテーマ](https://www.npmjs.com/search?q=keywords%3Aslidev-theme)をすべて検索できます。 25 | -------------------------------------------------------------------------------- /themes/use.md: -------------------------------------------------------------------------------- 1 | # テーマを使用する 2 | 3 | Slidevのテーマを変更するのは驚くほど簡単です。フロントマターに`theme:`フィールドを追加するだけです。 4 | 5 | ```yaml 6 | --- 7 | theme: seriph 8 | --- 9 | ``` 10 | 11 | サーバーを起動すると、テーマの自動インストールを促すメッセージが表示されます。 12 | 13 |
14 |
15 | ? The theme "@slidev/theme-seriph" was not found in your project, do you want to install it now? › (Y/n)
16 | 
17 |
18 | 19 | あるいは以下の方法で手動でテーマをインストールします 20 | 21 | ```bash 22 | $ npm install @slidev/theme-seriph 23 | ``` 24 | 25 | 以上、新しいテーマをお楽しみください。各テーマの使い方の詳細については、テーマのREADMEを参照してください。 26 | 27 | あなたのテーマを共有したいですか?[テーマを作成する](/themes/write-a-theme)を参照してください。 28 | 29 | ## テーマの取り出し 30 | 31 | 現在のテーマを完全に制御したい場合は、ローカルファイルシステム上に**取り出し**して好きなように変更することができます。次のコマンドを実行します。 32 | 33 | ```bash 34 | $ slidev theme eject 35 | ``` 36 | 37 | 現在使用しているテーマを`./theme`に出力し、フロントマターを次のように変更します。 38 | 39 | ```yaml 40 | --- 41 | theme: ./theme 42 | --- 43 | ``` 44 | 45 | また、これは既存のテーマをベースにテーマを作成するのに参考になります。その際は、元のテーマと作者について言及することを忘れないでください :) 46 | 47 | ## ローカルテーマ 48 | 49 | 前のセクションでおわかりのように、プロジェクトにローカルテーマを指定することができます。themeフィールドに**相対パス**を指定します。 50 | 51 | ```yaml 52 | --- 53 | theme: ./path/to/theme 54 | --- 55 | ``` 56 | 57 | 詳細は[テーマを作成する](/themes/write-a-theme)を参照してください。 58 | -------------------------------------------------------------------------------- /themes/write-a-theme.md: -------------------------------------------------------------------------------- 1 | # テーマを作成する 2 | 3 | 最初のテーマを作成するために、ジェネレータを作成することを推奨します。 4 | 5 | ```bash 6 | $ npm init slidev-theme 7 | ``` 8 | 9 | 作成されたテーマを修正し、試すことができます。例として [公式テーマ](/themes/gallery)を参照することもできます。 10 | 11 | ## できること 12 | 13 | テーマでは次のことができます: 14 | 15 | - グローバルスタイル 16 | - デフォルトの設定を指定する (フォント、 カラースキーマ、 ハイライト、など) 17 | - カスタムレイアウトを指定する、もしくは既存のレイアウトを上書きする 18 | - カスタムコンポーネントを指定する、もしくは既存のコンポーネントを上書きする 19 | - Windi CSSの設定を拡張する 20 | - MonacoやPrismのようなツールの設定をする 21 | 22 | ## 規約 23 | 24 | テーマはnpmレジストリに公開され、以下の規約に従います。 25 | 26 | - パッケージ名は`slidev-theme-`から始めます。例: `slidev-theme-awesome` 27 | - `package.json`の`keywords`フィールドに、`slidev-theme`と`slidev`を追加します。 28 | 29 | ## セットアップ 30 | 31 | テーマのテスト用プレイグラウンドをセットアップするには、以下のようなフロントマターで`example.md`を作成し、現在のディレクトリをテーマとして使用することをSlidevに伝えます。 32 | 33 | ```md 34 | --- 35 | theme: ./ 36 | --- 37 | ``` 38 | 39 | オプションで、いくつかのスクリプトを`package.json`に追加することもできます。 40 | 41 | ```json 42 | // package.json 43 | { 44 | "scripts": { 45 | "dev": "slidev example.md", 46 | "build": "slidev build example.md", 47 | "export": "slidev export example.md", 48 | "screenshot": "slidev export example.md --format png" 49 | } 50 | } 51 | ``` 52 | 53 | テーマを公開するには`npm publish`を実行すればOKです。ビルドプロセスは必要ありません(つまり、`.vue`と`.ts`ファイルを直接公開することができ、Slidevはスマートなのでそれらを読み込むことができます)。 54 | 55 | テーマのコントリビューションポイントはローカルカスタマイズと同じ規約に従います。[命名規約についてはドキュメント](/custom/)を参照してください。 56 | 57 | ## デフォルトの設定 58 | 59 | > v0.19から使用可能です 60 | 61 | テーマでは`package.json`を介して、デフォルトの[設定](/custom/#フロントマターの設定)を指定できます。 62 | 63 | ```json 64 | // package.json 65 | { 66 | "slidev": { 67 | "default": { 68 | "aspectRatio": "16/9", 69 | "canvasWidth": 980, 70 | "fonts": { 71 | "sans": "Robot", 72 | "mono": "Fira Code" 73 | } 74 | } 75 | } 76 | } 77 | ``` 78 | 79 | フォントは[Google Fonts](https://fonts.google.com/)から自動でインポートされます。 80 | 81 | 詳細は[フォント](/custom/fonts)と[フロントマターの設定](/custom/#フロントマターの設定)を参照してください。 82 | 83 | ## メタデータ 84 | 85 | ### カラースキーマ 86 | 87 | デフォルトでは、Slidevはライトモードとダークモードの両方をサポートするテーマを想定しています。もしデザインされたカラースキーマだけでテーマを表示したいなら、`package.json`で明示的に指定する必要があります。 88 | 89 | ```json 90 | // package.json 91 | { 92 | "name": "slidev-theme-my-cool-theme", 93 | "keywords": [ 94 | "slidev-theme", 95 | "slidev" 96 | ], 97 | "slidev": { 98 | "colorSchema": "light" // or "dark" or "both" 99 | } 100 | } 101 | ``` 102 | 103 | テーマのスタイルを作成する際にダークモードにアクセスするには、ダークモード特有の設定を`dark`クラスで囲みます: 104 | 105 | ```css 106 | /* 全体に適用されるCSS */ 107 | 108 | html:not(.dark) { 109 | /* ライトモードのCSS */ 110 | } 111 | 112 | html.dark { 113 | /* ダークモードのCSS */ 114 | } 115 | ``` 116 | 117 | Slidevはカラースキーマを切り替えるために、ページの`html`要素の`dark`クラスを切り替えます。 118 | 119 | ### シンタックスハイライト 120 | 121 | シンタックスハイライトの色もテーマで指定することができます。[Prism](https://prismjs.com/)と[Shiki](https://github.com/shikijs/shiki)の両方をサポートしています。詳細は[シンタックスハイライトについてのドキュメント](/custom/highlighters)を参照してください。 122 | 123 | どちらかだけをサポートすることもできます。サンプルとして、デフォルトテーマを参照してください [`./styles/code.css`](https://github.com/slidevjs/slidev/blob/main/packages/create-theme/template/styles/code.css) / [`./setup/shiki.ts`](https://github.com/slidevjs/slidev/blob/main/packages/create-theme/template/setup/shiki.ts) 124 | 125 | また`package.json`でサポートしているシンタックスハイライトを指定することを忘れないでください。 126 | 127 | ```json 128 | // package.json 129 | { 130 | "slidev": { 131 | "highlighter": "shiki" // or "prism" or "all" 132 | } 133 | } 134 | ``` 135 | 136 | ### Slidevのバージョン 137 | 138 | テーマが新しく追加されたSlidevの機能に依存している場合は、テーマが正しく動作するのに必要な最小のSlidevのバージョンを指定する必要があります。 139 | 140 | ```json 141 | // package.json 142 | { 143 | "engines": { 144 | "slidev": ">=0.19.3" 145 | } 146 | } 147 | ``` 148 | 149 | ユーザーが指定されたバージョンよりも古いSlidevを使用している場合、例外が発生します。 150 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "baseUrl": ".", 5 | "target": "es2016", 6 | "lib": ["DOM", "ESNext"], 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "noUnusedLocals": true, 11 | "moduleResolution": "node", 12 | "resolveJsonModule": true, 13 | "strictNullChecks": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "types": [ 16 | "vite/client", 17 | "node" 18 | ] 19 | }, 20 | "include": [ 21 | "./*.ts", 22 | "./.vitepress/**/*.ts", 23 | "./.vitepress/**/*.vue", 24 | ], 25 | "exclude": ["**/dist/**", "node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path' 2 | import { UserConfig } from 'vite' 3 | import Icons, { ViteIconsResolver } from 'vite-plugin-icons' 4 | import Components from 'vite-plugin-components' 5 | import WindiCSS from 'vite-plugin-windicss' 6 | 7 | const config: UserConfig = { 8 | resolve: { 9 | alias: { 10 | '@slidev/client': resolve(__dirname, '.vitepress/@slidev/client'), 11 | '@slidev/parser': resolve(__dirname, '.vitepress/@slidev/parser'), 12 | '@slidev/theme-default': resolve(__dirname, '.vitepress/@slidev/theme-default'), 13 | }, 14 | }, 15 | optimizeDeps: { 16 | exclude: [ 17 | 'vue-demi', 18 | '@vueuse/shared', 19 | '@vueuse/core', 20 | ], 21 | }, 22 | server: { 23 | hmr: { 24 | overlay: false, 25 | }, 26 | }, 27 | plugins: [ 28 | Components({ 29 | dirs: [ 30 | '.vitepress/theme/components', 31 | '.vitepress/@slidev/client/builtin', 32 | ], 33 | customLoaderMatcher: id => id.endsWith('.md'), 34 | customComponentResolvers: [ 35 | ViteIconsResolver({ 36 | componentPrefix: '', 37 | }), 38 | ], 39 | }), 40 | Icons(), 41 | WindiCSS({ 42 | preflight: false, 43 | }), 44 | { 45 | name: 'code-block-escape', 46 | enforce: 'post', 47 | transform(code, id) { 48 | if (!id.endsWith('.md')) 49 | return 50 | return code.replace(/\/\/```/mg, '```') 51 | }, 52 | }, 53 | { 54 | name: 'virtual-modules', 55 | resolveId(id){ 56 | return id === '/@slidev/configs' ? id : null 57 | }, 58 | load(id) { 59 | if(id !== '/@slidev/configs') 60 | return 61 | return 'export default {}' 62 | } 63 | }, 64 | ], 65 | } 66 | 67 | export default config 68 | -------------------------------------------------------------------------------- /windi.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite-plugin-windicss' 2 | import aspectRatio from 'windicss/plugin/aspect-ratio' 3 | 4 | export default defineConfig({ 5 | extract: { 6 | include: [ 7 | '**/*.md', 8 | '.vitepress/theme/**/*.{md,vue}', 9 | '.vitepress/@slidev/client/internals/SlideContainer.vue', 10 | '.vitepress/@slidev/client/layouts/*.vue', 11 | '.vitepress/@slidev/theme-default/layouts/*.vue', 12 | ] 13 | }, 14 | attributify: true, 15 | plugins: [ 16 | aspectRatio, 17 | ], 18 | shortcuts: { 19 | 'bg-main': 'bg-white dark:bg-[#111]', 20 | }, 21 | theme: { 22 | extend: { 23 | colors: { 24 | primary: { 25 | DEFAULT: '#3AB9D4', 26 | deep: '#2082A6', 27 | }, 28 | }, 29 | fontFamily: { 30 | mono: '\'IBM Plex Mono\', source-code-pro, Menlo, Monaco, Consolas, \'Courier New\', monospace', 31 | }, 32 | }, 33 | }, 34 | }) 35 | --------------------------------------------------------------------------------