From 3567a199f615b77509b3231cc1202f964f89c582 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Sat, 20 Jul 2024 22:30:22 +0200 Subject: [PATCH] feat(vscode): support schema for frontmatters --- docs/builtin/components.md | 2 +- packages/types/src/builtin-layouts.ts | 22 + packages/types/src/config.ts | 348 +------------ packages/types/src/frontmatter.ts | 441 +++++++++++++++++ packages/types/src/index.ts | 1 + packages/types/src/vite.ts | 2 +- packages/vscode/language-server/index.ts | 8 + packages/vscode/schema/frontmatter.json | 217 ++++++++ packages/vscode/schema/headmatter.json | 600 +++++++++++++++-------- packages/vscode/scripts/schema.ts | 19 +- scripts/gen-layouts.ts | 12 + 11 files changed, 1118 insertions(+), 554 deletions(-) create mode 100644 packages/types/src/builtin-layouts.ts create mode 100644 packages/types/src/frontmatter.ts create mode 100644 packages/vscode/schema/frontmatter.json create mode 100644 scripts/gen-layouts.ts diff --git a/docs/builtin/components.md b/docs/builtin/components.md index bfcc2636b1..9fe7598e5d 100644 --- a/docs/builtin/components.md +++ b/docs/builtin/components.md @@ -297,7 +297,7 @@ See https://sli.dev/guide/animations.html#enter-leave ## `VDrag` -See https://sli.dev/guide/draggable.html + ## `SlidevVideo` diff --git a/packages/types/src/builtin-layouts.ts b/packages/types/src/builtin-layouts.ts new file mode 100644 index 0000000000..f3a33fc9d7 --- /dev/null +++ b/packages/types/src/builtin-layouts.ts @@ -0,0 +1,22 @@ +export type BuiltinLayouts = + | '404' + | 'center' + | 'cover' + | 'default' + | 'end' + | 'error' + | 'fact' + | 'full' + | 'iframe-left' + | 'iframe-right' + | 'iframe' + | 'image-left' + | 'image-right' + | 'image' + | 'intro' + | 'none' + | 'quote' + | 'section' + | 'statement' + | 'two-cols-header' + | 'two-cols' diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index de4dbd4fa1..05f2737c14 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -1,345 +1,15 @@ -import type { TransitionGroupProps } from 'vue' import type { ExportArgs } from './cli' -import type { SlidevThemeConfig } from './types' +import type { HeadmatterConfig } from './frontmatter' -export interface Headmatter { - /** - * Title of the slides - */ - title?: string - /** - * String template to compose title - * - * @example "%s - Slidev" - to suffix " - Slidev" to all pages - * @default '%s - Slidev' - */ - titleTemplate?: string - /** - * Theme to use for the slides - * - * @see https://sli.dev/themes/use.html - * @default 'default' - */ - theme?: string - /** - * List of Slidev addons - * - * @default [] - */ - addons?: string[] - /** - * Download remote assets in local using vite-plugin-remote-assets - * - * @default false - */ - remoteAssets?: boolean | 'dev' | 'build' - /** - * Show a download button in the SPA build, - * could also be a link to custom pdf - * - * @default false - */ - download?: boolean | string - /** - * Show a copy button in code blocks - * - * @default true - */ - codeCopy?: boolean - /** - * Information shows on the built SPA - * Can be a markdown string - * - * @default false - */ - info?: string | boolean - /** - * Prefer highlighter - * - * @see https://sli.dev/custom/config-highlighter.html - * @default shiki - */ - highlighter?: 'shiki' | 'prism' - /** - * Enable Twoslash - * - * @default true - */ - twoslash?: boolean | 'dev' | 'build' - /** - * Show line numbers in code blocks - * - * @default false - */ - lineNumbers?: boolean - /** - * Force slides color schema - * - * @default 'auto' - */ - colorSchema?: 'dark' | 'light' | 'all' | 'auto' - /** - * Router mode for vue-router - * - * @default 'history' - */ - routerMode?: 'hash' | 'history' - /** - * Aspect ratio for slides - * should be like `16/9` or `1:1` - * - * @default '16/9' - */ - aspectRatio?: number - /** - * The actual width for slides canvas. - * unit in px. - * - * @default '980' - */ - canvasWidth?: number - /** - * Controls whether texts in slides are selectable - * - * @default true - */ - selectable?: boolean - /** - * Configure for themes, will inject intro root styles as - * `--slidev-theme-x` for attribute `x` - * - * This allows themes to have customization options in frontmatter - * Refer to themes' document for options avaliable - * - * @default {} - */ - themeConfig?: SlidevThemeConfig - /** - * Configure fonts for the slides and app - * - * @default {} - */ - fonts?: ResolvedFontOptions - /** - * Configure the icon for app - * - * @default 'https://cdn.jsdelivr.net/gh/slidevjs/slidev/assets/favicon.png' - */ - favicon?: string - /** - * Options for drawings - * - * @default {} - */ - drawings?: ResolvedDrawingsOptions - /** - * URL of PlantUML server used to render diagrams - * - * @default https://www.plantuml.com/plantuml - */ - plantUmlServer?: string - /** - * Enable slides recording - * - * @default 'dev' - */ - record?: boolean | 'dev' | 'build' - /** - * Expose the server to inbound requests (listen to `0.0.0.0`) - * - * Pass a string to set the password for accessing presenter mode. - * - * @default false - */ - remote?: string | boolean - /** - * Engine for Atomic CSS - * - * @see https://unocss.dev/ - * @deprecated - * @default 'unocss' - */ - css?: 'unocss' - /** - * Enable presenter mode - * - * @default true - */ - presenter?: boolean | 'dev' | 'build' - /** - * Attributes to apply to the HTML element - * - * @default {} - */ - htmlAttrs?: Record - /** - * Page transition, powered by Vue's - * - * Built-in transitions: - * - fade - * - fade-out - * - slide-left - * - slide-right - * - slide-up - * - slide-down - * - * @see https://sli.dev/guide/animations.html#pages-transitions - * @see https://vuejs.org/guide/built-ins/transition.html - */ - transition?: BuiltinSlideTransition | string | TransitionGroupProps | null - /** - * Suppport MDC syntax - * - * @see https://github.com/antfu/markdown-it-mdc - * @see https://content.nuxtjs.org/guide/writing/mdc - * @experimental - * @default false - */ - mdc?: boolean - /** - * Enable built-in editor - * - * @default true - */ - editor?: boolean - /** - * Enable context menu - * - * @default true - */ - contextMenu?: boolean | 'dev' | 'build' | null - /** - * Enable wake lock - */ - wakeLock?: boolean | 'dev' | 'build' - /** - * Options for export - * - * @default {} - */ - export?: ResolvedExportOptions - /** - * Force the filename used when exporting the presentation. - * The extension, e.g. .pdf, gets automatically added. - * - * @default '' - */ - exportFilename?: string | null - /** - * Enable Monaco - * - * @see https://sli.dev/custom/config-monaco.html - * @default true - */ - monaco?: boolean | 'dev' | 'build' - /** - * Where to load monaco types from - * - * - `cdn` - load from CDN with `@typescript/ata` - * - `local` - load from local node_modules - * - * @default 'local' - */ - monacoTypesSource?: 'cdn' | 'local' | 'none' - /** - * Additional node packages to load as monaco types - * - * @default [] - */ - monacoTypesAdditionalPackages?: string[] - /** - * Packages to ignore when loading monaco types - * - * @default [] - */ - monacoTypesIgnorePackages?: string[] - /** - * Additional local modules to load as dependencies of monaco runnable - * - * @default [] - */ - monacoRunAdditionalDeps?: string[] +export interface ResolvedSlidevConfigSub { + export: ResolvedExportOptions + drawings: ResolvedDrawingsOptions + fonts: ResolvedFontOptions } -export interface SlidevConfig extends Required { -} - -export interface FontOptions { - /** - * Sans serif fonts (default fonts for most text) - */ - sans?: string | string[] - /** - * Serif fonts - */ - serif?: string | string[] - /** - * Monospace fonts, for code blocks and etc. - */ - mono?: string | string[] - /** - * Load webfonts for custom CSS (does not apply anywhere by default) - */ - custom?: string | string[] - /** - * Weights for fonts - * - * @default [200, 400, 600] - */ - weights?: string | (string | number)[] - /** - * Import italic fonts - * - * @default false - */ - italic?: boolean - /** - * @default 'google' - */ - provider?: 'none' | 'google' - /** - * Specify web fonts names, will detect from `sans`, `mono`, `serif` if not provided - */ - webfonts?: string[] - /** - * Specify local fonts names, be excluded from webfonts - */ - local?: string[] - /** - * Use fonts fallback - * - * @default true - */ - fallbacks?: boolean -} - -export interface DrawingsOptions { - /** - * Persist the drawings to disk - * Passing string to specify the directory (default to `.slidev/drawings`) - * - * @default false - */ - persist?: boolean | string - - /** - * @default true - */ - enabled?: boolean | 'dev' | 'build' - - /** - * Only allow drawing from presenter mode - * - * @default false - */ - presenterOnly?: boolean - - /** - * Sync drawing for all instances - * - * @default true - */ - syncAll?: boolean +export interface SlidevConfig extends + Omit, keyof ResolvedSlidevConfigSub>, + ResolvedSlidevConfigSub { } export interface ResolvedFontOptions { @@ -365,5 +35,3 @@ export interface ResolvedExportOptions extends Omit + /** + * Suppport MDC syntax + * + * See https://github.com/antfu/markdown-it-mdc + * + * See https://content.nuxtjs.org/guide/writing/mdc + * + * @default false + */ + mdc?: boolean + /** + * Enable built-in editor + * + * @default true + */ + editor?: boolean + /** + * Enable context menu + * + * @default true + */ + contextMenu?: boolean | 'dev' | 'build' | null + /** + * Enable wake lock + */ + wakeLock?: boolean | 'dev' | 'build' + /** + * Force the filename used when exporting the presentation. + * The extension, e.g. .pdf, gets automatically added. + * + * @default '' + */ + exportFilename?: string | null + /** + * Enable Monaco + * + * See https://sli.dev/custom/config-monaco.html + * @default true + */ + monaco?: boolean | 'dev' | 'build' + /** + * Where to load monaco types from + * + * - `cdn` - load from CDN with `@typescript/ata` + * - `local` - load from local node_modules + * + * @default 'local' + */ + monacoTypesSource?: 'cdn' | 'local' | 'none' + /** + * Additional node packages to load as monaco types + * + * @default [] + */ + monacoTypesAdditionalPackages?: string[] + /** + * Packages to ignore when loading monaco types + * + * @default [] + */ + monacoTypesIgnorePackages?: string[] + /** + * Additional local modules to load as dependencies of monaco runnable + * + * @default [] + */ + monacoRunAdditionalDeps?: string[] +} + +export interface Frontmatter extends TransitionOptions { + /** + * Slide layout to use + * + * Default to 'cover' for the first slide, 'default' for the rest + */ + layout?: BuiltinLayouts | string + /** + * Custom class added to the slide root element + */ + class?: string | string[] | Record + /** + * Manually specified the total clicks needed to this slide + * + * When not specified, the clicks will be calculated by the usage of v-clicks + * + * See https://sli.dev/guide/animations + */ + clicks?: number + /** + * Manually specified the total clicks needed to this slide to start + * + * @default 0 + */ + clicksStart?: number + /** + * Preload the slide when the previous slide is active + * @default true + */ + preload?: boolean + /** + * Completely hide and disable the slide + */ + hide?: boolean + /** + * Same as `hide`, completely hide and disable the slide + */ + disabled?: boolean + /** + * hide the slide for the `` components + * + * See https://sli.dev/builtin/components#toc + */ + hideInToc?: boolean + /** + * Override the title level for the and components + * Only if `title` has also been declared + */ + level?: number + /** + * Create a route alias that can be used in the URL or with the component + */ + routeAlias?: string + /** + * Custom zoom level for the slide + * @default 1 + */ + zoom?: number + /** + * Store the positions of draggable elements + * Normally you don't need to set this manually + * + * See https://sli.dev/features/draggable + */ + dragPos?: Record[] + /** + * Includes a markdown file + * + * See https://sli.dev/guide/syntax.html#importing-slides + */ + src?: string +} + +export interface DrawingsOptions { + /** + * Persist the drawings to disk + * Passing string to specify the directory (default to `.slidev/drawings`) + * + * @default false + */ + persist?: boolean | string + + /** + * @default true + */ + enabled?: boolean | 'dev' | 'build' + + /** + * Only allow drawing from presenter mode + * + * @default false + */ + presenterOnly?: boolean + + /** + * Sync drawing for all instances + * + * @default true + */ + syncAll?: boolean +} + +export interface FontOptions { + /** + * Sans serif fonts (default fonts for most text) + */ + sans?: string | string[] + /** + * Serif fonts + */ + serif?: string | string[] + /** + * Monospace fonts, for code blocks and etc. + */ + mono?: string | string[] + /** + * Load webfonts for custom CSS (does not apply anywhere by default) + */ + custom?: string | string[] + /** + * Weights for fonts + * + * @default [200, 400, 600] + */ + weights?: string | (string | number)[] + /** + * Import italic fonts + * + * @default false + */ + italic?: boolean + /** + * @default 'google' + */ + provider?: 'none' | 'google' + /** + * Specify web fonts names, will detect from `sans`, `mono`, `serif` if not provided + */ + webfonts?: string[] + /** + * Specify local fonts names, be excluded from webfonts + */ + local?: string[] + /** + * Use fonts fallback + * + * @default true + */ + fallbacks?: boolean +} + +export type BuiltinSlideTransition = 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'fade' | 'zoom' | 'none' + +export interface TransitionOptions { + /** + * Page transition, powered by Vue's `` + * + * Built-in transitions: + * - fade + * - fade-out + * - slide-left + * - slide-right + * - slide-up + * - slide-down + * + * See https://sli.dev/guide/animations.html#pages-transitions + * + * See https://vuejs.org/guide/built-ins/transition.html + */ + transition?: BuiltinSlideTransition | string | TransitionGroupProps | null +} + +export interface TransitionGroupProps { + appear?: boolean + persisted?: boolean + tag?: string + moveClass?: string + css?: boolean + duration?: number | { + enter: number + leave: number + } + enterFromClass?: string + enterActiveClass?: string + enterToClass?: string + appearFromClass?: string + appearActiveClass?: string + appearToClass?: string + leaveFromClass?: string + leaveActiveClass?: string + leaveToClass?: string +} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 801917c1d6..dbaa1f38cb 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -10,3 +10,4 @@ export * from './options' export * from './vite' export * from './transform' export * from './clicks' +export * from './frontmatter' diff --git a/packages/types/src/vite.ts b/packages/types/src/vite.ts index f2618d42c6..c84bda1644 100644 --- a/packages/types/src/vite.ts +++ b/packages/types/src/vite.ts @@ -29,7 +29,7 @@ declare module 'vite' { /** * Custom internal plugin options for Slidev (advanced) * - * @see https://github.com/slidevjs/slidev/blob/main/packages/slidev/node/options.ts#L50 + * See https://github.com/slidevjs/slidev/blob/main/packages/slidev/node/options.ts#L50 */ slidev?: SlidevPluginOptions } diff --git a/packages/vscode/language-server/index.ts b/packages/vscode/language-server/index.ts index c55bea1300..d848bdd3e5 100644 --- a/packages/vscode/language-server/index.ts +++ b/packages/vscode/language-server/index.ts @@ -22,11 +22,19 @@ connection.onInitialize((params) => { isKubernetes: false, validate: true, yamlVersion: '1.2', + parentSkeletonSelectedFirst: false, + disableDefaultProperties: true, schemas: [ { + priority: 3, fileMatch: ['volar-embedded-content://frontmatter_0/**/*.md'], uri: fileURLToPath(new URL('../schema/headmatter.json', import.meta.url)), }, + { + priority: 2, + fileMatch: ['volar-embedded-content://**/*.md'], + uri: fileURLToPath(new URL('../schema/frontmatter.json', import.meta.url)), + }, ], } }, diff --git a/packages/vscode/schema/frontmatter.json b/packages/vscode/schema/frontmatter.json new file mode 100644 index 0000000000..9803e295c6 --- /dev/null +++ b/packages/vscode/schema/frontmatter.json @@ -0,0 +1,217 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$ref": "#/definitions/Frontmatter", + "definitions": { + "Frontmatter": { + "type": "object", + "properties": { + "transition": { + "anyOf": [ + { + "$ref": "#/definitions/BuiltinSlideTransition" + }, + { + "type": "string" + }, + { + "$ref": "#/definitions/TransitionGroupProps" + }, + { + "type": "null" + } + ], + "description": "Page transition, powered by Vue's ``\n\nBuilt-in transitions:\n- fade\n- fade-out\n- slide-left\n- slide-right\n- slide-up\n- slide-down\n\nSee https://sli.dev/guide/animations.html#pages-transitions\n\nSee https://vuejs.org/guide/built-ins/transition.html" + }, + "layout": { + "anyOf": [ + { + "$ref": "#/definitions/BuiltinLayouts" + }, + { + "type": "string" + } + ], + "description": "Slide layout to use\n\nDefault to 'cover' for the first slide, 'default' for the rest" + }, + "class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "object", + "additionalProperties": {} + } + ], + "description": "Custom class added to the slide root element" + }, + "clicks": { + "type": "number", + "description": "Manually specified the total clicks needed to this slide\n\nWhen not specified, the clicks will be calculated by the usage of v-clicks\n\nSee https://sli.dev/guide/animations" + }, + "clicksStart": { + "type": "number", + "description": "Manually specified the total clicks needed to this slide to start", + "default": 0 + }, + "preload": { + "type": "boolean", + "description": "Preload the slide when the previous slide is active", + "default": true + }, + "hide": { + "type": "boolean", + "description": "Completely hide and disable the slide" + }, + "disabled": { + "type": "boolean", + "description": "Same as `hide`, completely hide and disable the slide" + }, + "hideInToc": { + "type": "boolean", + "description": "hide the slide for the `` components\n\nSee https://sli.dev/builtin/components#toc" + }, + "level": { + "type": "number", + "description": "Override the title level for the and components Only if `title` has also been declared" + }, + "routeAlias": { + "type": "string", + "description": "Create a route alias that can be used in the URL or with the component" + }, + "zoom": { + "type": "number", + "description": "Custom zoom level for the slide", + "default": 1 + }, + "dragPos": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": "Store the positions of draggable elements Normally you don't need to set this manually\n\nSee https://sli.dev/features/draggable" + }, + "src": { + "type": "string", + "description": "Includes a markdown file\n\nSee https://sli.dev/guide/syntax.html#importing-slides" + } + } + }, + "BuiltinSlideTransition": { + "type": "string", + "enum": [ + "slide-up", + "slide-down", + "slide-left", + "slide-right", + "fade", + "zoom", + "none" + ] + }, + "TransitionGroupProps": { + "type": "object", + "properties": { + "appear": { + "type": "boolean" + }, + "persisted": { + "type": "boolean" + }, + "tag": { + "type": "string" + }, + "moveClass": { + "type": "string" + }, + "css": { + "type": "boolean" + }, + "duration": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "object", + "properties": { + "enter": { + "type": "number" + }, + "leave": { + "type": "number" + } + }, + "required": [ + "enter", + "leave" + ] + } + ] + }, + "enterFromClass": { + "type": "string" + }, + "enterActiveClass": { + "type": "string" + }, + "enterToClass": { + "type": "string" + }, + "appearFromClass": { + "type": "string" + }, + "appearActiveClass": { + "type": "string" + }, + "appearToClass": { + "type": "string" + }, + "leaveFromClass": { + "type": "string" + }, + "leaveActiveClass": { + "type": "string" + }, + "leaveToClass": { + "type": "string" + } + } + }, + "BuiltinLayouts": { + "type": "string", + "enum": [ + "404", + "center", + "cover", + "default", + "end", + "error", + "fact", + "full", + "iframe-left", + "iframe-right", + "iframe", + "image-left", + "image-right", + "image", + "intro", + "none", + "quote", + "section", + "statement", + "two-cols-header", + "two-cols" + ] + } + } +} diff --git a/packages/vscode/schema/headmatter.json b/packages/vscode/schema/headmatter.json index 6fa425e06d..525db7db5c 100644 --- a/packages/vscode/schema/headmatter.json +++ b/packages/vscode/schema/headmatter.json @@ -5,6 +5,105 @@ "Headmatter": { "type": "object", "properties": { + "transition": { + "anyOf": [ + { + "$ref": "#/definitions/BuiltinSlideTransition" + }, + { + "type": "string" + }, + { + "$ref": "#/definitions/TransitionGroupProps" + }, + { + "type": "null" + } + ], + "description": "Page transition, powered by Vue's ``\n\nBuilt-in transitions:\n- fade\n- fade-out\n- slide-left\n- slide-right\n- slide-up\n- slide-down\n\nSee https://sli.dev/guide/animations.html#pages-transitions\n\nSee https://vuejs.org/guide/built-ins/transition.html" + }, + "layout": { + "anyOf": [ + { + "$ref": "#/definitions/BuiltinLayouts" + }, + { + "type": "string" + } + ], + "description": "Slide layout to use\n\nDefault to 'cover' for the first slide, 'default' for the rest" + }, + "class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "object", + "additionalProperties": {} + } + ], + "description": "Custom class added to the slide root element" + }, + "clicks": { + "type": "number", + "description": "Manually specified the total clicks needed to this slide\n\nWhen not specified, the clicks will be calculated by the usage of v-clicks\n\nSee https://sli.dev/guide/animations" + }, + "clicksStart": { + "type": "number", + "description": "Manually specified the total clicks needed to this slide to start", + "default": 0 + }, + "preload": { + "type": "boolean", + "description": "Preload the slide when the previous slide is active", + "default": true + }, + "hide": { + "type": "boolean", + "description": "Completely hide and disable the slide" + }, + "disabled": { + "type": "boolean", + "description": "Same as `hide`, completely hide and disable the slide" + }, + "hideInToc": { + "type": "boolean", + "description": "hide the slide for the `` components\n\nSee https://sli.dev/builtin/components#toc" + }, + "level": { + "type": "number", + "description": "Override the title level for the and components Only if `title` has also been declared" + }, + "routeAlias": { + "type": "string", + "description": "Create a route alias that can be used in the URL or with the component" + }, + "zoom": { + "type": "number", + "description": "Custom zoom level for the slide", + "default": 1 + }, + "dragPos": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": "Store the positions of draggable elements Normally you don't need to set this manually\n\nSee https://sli.dev/features/draggable" + }, + "src": { + "type": "string", + "description": "Includes a markdown file\n\nSee https://sli.dev/guide/syntax.html#importing-slides" + }, "title": { "type": "string", "description": "Title of the slides" @@ -16,7 +115,7 @@ }, "theme": { "type": "string", - "description": "Theme to use for the slides", + "description": "Theme to use for the slides\n\nSee https://sli.dev/themes/use.html", "default": "default" }, "addons": { @@ -71,7 +170,7 @@ "shiki", "prism" ], - "description": "Prefer highlighter", + "description": "Prefer highlighter\n\nSee https://sli.dev/custom/config-highlighter.html", "default": "shiki" }, "twoslash": { @@ -137,7 +236,7 @@ "default": {} }, "fonts": { - "$ref": "#/definitions/ResolvedFontOptions", + "$ref": "#/definitions/FontOptions", "description": "Configure fonts for the slides and app", "default": {} }, @@ -147,7 +246,7 @@ "default": "https://cdn.jsdelivr.net/gh/slidevjs/slidev/assets/favicon.png" }, "drawings": { - "$ref": "#/definitions/ResolvedDrawingsOptions", + "$ref": "#/definitions/DrawingsOptions", "description": "Options for drawings", "default": {} }, @@ -184,7 +283,7 @@ "css": { "type": "string", "const": "unocss", - "description": "Engine for Atomic CSS", + "description": "Engine for Atomic CSS\n\nSee https://unocss.dev/", "deprecated": true, "default": "unocss" }, @@ -213,26 +312,9 @@ "description": "Attributes to apply to the HTML element", "default": {} }, - "transition": { - "anyOf": [ - { - "$ref": "#/definitions/BuiltinSlideTransition" - }, - { - "type": "string" - }, - { - "$ref": "#/definitions/TransitionGroupProps" - }, - { - "type": "null" - } - ], - "description": "Page transition, powered by Vue's \n\nBuilt-in transitions:\n- fade\n- fade-out\n- slide-left\n- slide-right\n- slide-up\n- slide-down" - }, "mdc": { "type": "boolean", - "description": "Suppport MDC syntax", + "description": "Suppport MDC syntax\n\nSee https://github.com/antfu/markdown-it-mdc\n\nSee https://content.nuxtjs.org/guide/writing/mdc", "default": false }, "editor": { @@ -276,11 +358,6 @@ ], "description": "Enable wake lock" }, - "export": { - "$ref": "#/definitions/ResolvedExportOptions", - "description": "Options for export", - "default": {} - }, "exportFilename": { "type": [ "string", @@ -303,7 +380,7 @@ "const": "build" } ], - "description": "Enable Monaco", + "description": "Enable Monaco\n\nSee https://sli.dev/custom/config-monaco.html", "default": true }, "monacoTypesSource": { @@ -339,116 +416,12 @@ }, "description": "Additional local modules to load as dependencies of monaco runnable", "default": [] - } - } - }, - "SlidevThemeConfig": { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number" - ] - } - }, - "ResolvedFontOptions": { - "type": "object", - "properties": { - "sans": { - "type": "array", - "items": { - "type": "string" - } - }, - "mono": { - "type": "array", - "items": { - "type": "string" - } - }, - "serif": { - "type": "array", - "items": { - "type": "string" - } - }, - "weights": { - "type": "array", - "items": { - "type": "string" - } }, - "italic": { - "type": "boolean" - }, - "provider": { - "type": "string", - "enum": [ - "none", - "google" - ] - }, - "webfonts": { - "type": "array", - "items": { - "type": "string" - } - }, - "local": { - "type": "array", - "items": { - "type": "string" - } + "defaults": { + "$ref": "#/definitions/Frontmatter", + "description": "Default frontmatter options applied to all slides" } - }, - "required": [ - "sans", - "mono", - "serif", - "weights", - "italic", - "provider", - "webfonts", - "local" - ] - }, - "ResolvedDrawingsOptions": { - "type": "object", - "properties": { - "persist": { - "type": "boolean", - "enum": [ - false - ] - }, - "enabled": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string", - "const": "dev" - }, - { - "type": "string", - "const": "build" - } - ] - }, - "presenterOnly": { - "type": "boolean" - }, - "syncAll": { - "type": "boolean" - } - }, - "required": [ - "persist", - "enabled", - "presenterOnly", - "syncAll" - ] + } }, "BuiltinSlideTransition": { "type": "string", @@ -465,22 +438,18 @@ "TransitionGroupProps": { "type": "object", "properties": { + "appear": { + "type": "boolean" + }, + "persisted": { + "type": "boolean" + }, "tag": { "type": "string" }, "moveClass": { "type": "string" }, - "name": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "transition", - "animation" - ] - }, "css": { "type": "boolean" }, @@ -532,86 +501,299 @@ }, "leaveToClass": { "type": "string" - }, - "appear": {}, - "persisted": {}, - "onBeforeEnter": {}, - "onEnter": {}, - "onAfterEnter": {}, - "onEnterCancelled": {}, - "onBeforeLeave": {}, - "onLeave": {}, - "onAfterLeave": {}, - "onLeaveCancelled": {}, - "onBeforeAppear": {}, - "onAppear": {}, - "onAfterAppear": {}, - "onAppearCancelled": {} - }, - "required": [ - "appear", - "onAfterAppear", - "onAfterEnter", - "onAfterLeave", - "onAppear", - "onAppearCancelled", - "onBeforeAppear", - "onBeforeEnter", - "onBeforeLeave", - "onEnter", - "onEnterCancelled", - "onLeave", - "onLeaveCancelled", - "persisted" + } + } + }, + "BuiltinLayouts": { + "type": "string", + "enum": [ + "404", + "center", + "cover", + "default", + "end", + "error", + "fact", + "full", + "iframe-left", + "iframe-right", + "iframe", + "image-left", + "image-right", + "image", + "intro", + "none", + "quote", + "section", + "statement", + "two-cols-header", + "two-cols" ] }, - "ResolvedExportOptions": { + "SlidevThemeConfig": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number" + ] + } + }, + "FontOptions": { "type": "object", "properties": { - "output": { - "type": "string" + "sans": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "Sans serif fonts (default fonts for most text)" }, - "format": { - "type": "string" + "serif": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "Serif fonts" }, - "timeout": { - "type": "number" + "mono": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "Monospace fonts, for code blocks and etc." }, - "wait": { - "type": "number" + "custom": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "Load webfonts for custom CSS (does not apply anywhere by default)" }, - "wait-until": { - "type": "string" + "weights": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": [ + "string", + "number" + ] + } + } + ], + "description": "Weights for fonts", + "default": [ + 200, + 400, + 600 + ] }, - "range": { - "type": "string" + "italic": { + "type": "boolean", + "description": "Import italic fonts", + "default": false }, - "dark": { - "type": "boolean" + "provider": { + "type": "string", + "enum": [ + "none", + "google" + ], + "default": "google" }, - "with-clicks": { - "type": "boolean" + "webfonts": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify web fonts names, will detect from `sans`, `mono`, `serif` if not provided" }, - "executable-path": { - "type": "string" + "local": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Specify local fonts names, be excluded from webfonts" }, - "with-toc": { - "type": "boolean" + "fallbacks": { + "type": "boolean", + "description": "Use fonts fallback", + "default": true + } + } + }, + "DrawingsOptions": { + "type": "object", + "properties": { + "persist": { + "type": [ + "boolean", + "string" + ], + "description": "Persist the drawings to disk Passing string to specify the directory (default to `.slidev/drawings`)", + "default": false }, - "per-slide": { - "type": "boolean" + "enabled": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "string", + "const": "dev" + }, + { + "type": "string", + "const": "build" + } + ], + "default": true }, - "scale": { - "type": "number" + "presenterOnly": { + "type": "boolean", + "description": "Only allow drawing from presenter mode", + "default": false }, - "withClicks": { - "type": "boolean" + "syncAll": { + "type": "boolean", + "description": "Sync drawing for all instances", + "default": true + } + } + }, + "Frontmatter": { + "type": "object", + "properties": { + "transition": { + "anyOf": [ + { + "$ref": "#/definitions/BuiltinSlideTransition" + }, + { + "type": "string" + }, + { + "$ref": "#/definitions/TransitionGroupProps" + }, + { + "type": "null" + } + ], + "description": "Page transition, powered by Vue's ``\n\nBuilt-in transitions:\n- fade\n- fade-out\n- slide-left\n- slide-right\n- slide-up\n- slide-down\n\nSee https://sli.dev/guide/animations.html#pages-transitions\n\nSee https://vuejs.org/guide/built-ins/transition.html" }, - "executablePath": { - "type": "string" + "layout": { + "anyOf": [ + { + "$ref": "#/definitions/BuiltinLayouts" + }, + { + "type": "string" + } + ], + "description": "Slide layout to use\n\nDefault to 'cover' for the first slide, 'default' for the rest" }, - "withToc": { - "type": "boolean" + "class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "object", + "additionalProperties": {} + } + ], + "description": "Custom class added to the slide root element" + }, + "clicks": { + "type": "number", + "description": "Manually specified the total clicks needed to this slide\n\nWhen not specified, the clicks will be calculated by the usage of v-clicks\n\nSee https://sli.dev/guide/animations" + }, + "clicksStart": { + "type": "number", + "description": "Manually specified the total clicks needed to this slide to start", + "default": 0 + }, + "preload": { + "type": "boolean", + "description": "Preload the slide when the previous slide is active", + "default": true + }, + "hide": { + "type": "boolean", + "description": "Completely hide and disable the slide" + }, + "disabled": { + "type": "boolean", + "description": "Same as `hide`, completely hide and disable the slide" + }, + "hideInToc": { + "type": "boolean", + "description": "hide the slide for the `` components\n\nSee https://sli.dev/builtin/components#toc" + }, + "level": { + "type": "number", + "description": "Override the title level for the and components Only if `title` has also been declared" + }, + "routeAlias": { + "type": "string", + "description": "Create a route alias that can be used in the URL or with the component" + }, + "zoom": { + "type": "number", + "description": "Custom zoom level for the slide", + "default": 1 + }, + "dragPos": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "description": "Store the positions of draggable elements Normally you don't need to set this manually\n\nSee https://sli.dev/features/draggable" + }, + "src": { + "type": "string", + "description": "Includes a markdown file\n\nSee https://sli.dev/guide/syntax.html#importing-slides" } } } diff --git a/packages/vscode/scripts/schema.ts b/packages/vscode/scripts/schema.ts index c192800720..fef084d41a 100644 --- a/packages/vscode/scripts/schema.ts +++ b/packages/vscode/scripts/schema.ts @@ -3,10 +3,23 @@ import tsj from 'ts-json-schema-generator' const program = tsj .createGenerator({ - path: '../../packages/types/src/config.ts', + path: '../../packages/types/src/frontmatter.ts', tsconfig: '../../tsconfig.json', additionalProperties: true, + jsDoc: 'extended', + skipTypeCheck: true, }) - .createSchema('Headmatter') -await fs.writeFile('./schema/headmatter.json', JSON.stringify(program, null, 2)) +await Promise.all([ + fs.writeFile('./schema/headmatter.json', JSON.stringify( + program.createSchema('Headmatter'), + null, + 2, + )), + + fs.writeFile('./schema/frontmatter.json', JSON.stringify( + program.createSchema('Frontmatter'), + null, + 2, + )), +]) diff --git a/scripts/gen-layouts.ts b/scripts/gen-layouts.ts new file mode 100644 index 0000000000..4f6614e7ae --- /dev/null +++ b/scripts/gen-layouts.ts @@ -0,0 +1,12 @@ +import { fileURLToPath } from 'node:url' +import fs from 'node:fs/promises' +import fg from 'fast-glob' + +const files = await fg('*.vue', { + cwd: fileURLToPath(new URL('../packages/client/layouts', import.meta.url)), +}) + +await fs.writeFile(new URL('../packages/types/src/builtin-layouts.ts', import.meta.url), ` +export type BuiltinLayouts = +${files.sort().map(i => ` | '${i.replace('.vue', '')}'`).join('\n')} +`, 'utf-8')