From ca59519a737a3ac49f88868383a4004c2f542242 Mon Sep 17 00:00:00 2001 From: erkamyaman Date: Mon, 19 Oct 2026 19:03:37 +0000 Subject: [PATCH 01/19] docs: document the interface language, theme settings, slide links and titles --- src/content/built-in/cli.md | 4 + src/content/built-in/components.md | 5 +- src/content/built-in/headmatter.md | 6 +- src/content/customize/directory-structure.md | 2 + src/content/customize/setup-hooks.md | 2 +- src/content/customize/themes.md | 30 +++++++- src/content/customize/writing-a-theme.md | 19 ++++- src/content/features/interface-language.md | 78 ++++++++++++++++++++ src/content/features/routing.md | 2 +- src/content/features/seo-meta.md | 2 +- src/content/features/speaker-notes.md | 1 + src/content/features/table-of-contents.md | 2 +- src/content/guide/export.md | 4 + src/content/guide/styling.md | 2 +- src/content/guide/syntax.md | 21 ++++++ src/content/migrating/from-slidev.md | 6 +- src/content/migrating/not-supported.md | 5 +- src/ngmd.config.ts | 1 + 18 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 src/content/features/interface-language.md diff --git a/src/content/built-in/cli.md b/src/content/built-in/cli.md index 372de73..acf21f0 100644 --- a/src/content/built-in/cli.md +++ b/src/content/built-in/cli.md @@ -26,6 +26,7 @@ Starts the dev server. This is the default command. | `--log error\|warn\|info\|silent` | How much of the child programs' output to show. Default `info`. `error` and `silent` hide it. | | `--force`, `-f` | Clear the build cache. | | `--theme`, `-t` | A theme name or path, instead of the headmatter's. | +| `--lang ` | Use this language (`tr`, `pt-BR`) instead of the headmatter's `lang`: the interface, the locale of dates and numbers, and ``. See [Interface language](../features/interface-language.md). | `--tunnel` and `--base` are refused with a message. The dev server always runs at `/`. @@ -45,6 +46,7 @@ Makes a static site. See [Hosting](../guide/hosting.md). | `--allow-local` | Let the page Chromium renders reach loopback and private addresses. They are blocked otherwise. | | `--timeout` | Timeout in milliseconds for each page Chromium renders. | | `--theme`, `-t` | A theme name or path. | +| `--lang ` | Use this language instead of the headmatter's `lang`, for one deck in several languages: `slide-ng build slides.tr.md --out dist/tr`. | ## export @@ -71,6 +73,7 @@ Makes a PDF, PNG, PPTX or Markdown file. See [Export](../guide/export.md). | `--url
` | Export a running server, for example the dev server. | | `--base` | The base path the deck is served under, for `--dist`. | | `--theme`, `-t` | A theme name or path. | +| `--lang ` | Use this language instead of the headmatter's `lang`. | `export` takes one entry file per run. A `--range` that picks no slide fails before the deck is built. @@ -124,6 +127,7 @@ Makes a new deck folder. `--force`, `-f` adds the files that are missing to a fo | --- | --- | | `CHROME_PATH` | The Chromium that export, `--download`, `pwa` icons and `ogImage: auto` use. | | `SLIDE_NG_THEME` | A theme name or path that overrides the headmatter. `--theme` sets it. | +| `SLIDE_NG_LANG` | The same as `--lang`. | | `SLIDE_NG_NO_SANDBOX` | `1` is the same as `--no-sandbox`. | | `SLIDE_NG_PASSWORD` | The password for `dev --remote`. It keeps the password out of the shell history. | | `SLIDES_FILE` | The entry file, when no argument names one. | diff --git a/src/content/built-in/components.md b/src/content/built-in/components.md index a1c687d..0ea7fd3 100644 --- a/src/content/built-in/components.md +++ b/src/content/built-in/components.md @@ -14,6 +14,7 @@ These tags work in every slide. The generator imports a component only into the | `` | Table of contents from slide titles and levels. Options: `columns`, `listClass`, `listStyle`, `start`, `minDepth`, `maxDepth`, `mode`. See [Table of contents](../features/table-of-contents.md). | | `` | The number of the slide it is on. | | `` | The number of slides. | +| `` | The title of the slide it is on, as HTML: its inline markdown and `$math$` are drawn. `no="3"` shows the title of slide 3. Raw HTML in a title is shown as text. Slidev's `TitleRenderer`. | | `text` | A link to slide 3, or to a `routeAlias`. It has the prefix because `link` is a built-in HTML tag. The link has the slide's real address, so Ctrl or Cmd + click opens it in a new tab. `title="Details"` is the text when the tag has none. | | `` | Shows `
...
` in dark mode and `
...
` in light mode. | | `` | Content only where the slide is drawn: `slide`, `presenter`, `print`, `overview`, or `main` (slide or presenter). `[context]="['slide','overview']"` takes several. Content marked `
` shows everywhere else. | @@ -42,7 +43,7 @@ These tags work in every slide. The generator imports a component only into the | Tag | What it does | | --- | --- | -| `` | An embedded YouTube video. `id` is the video id. There are no start time or playlist options. | +| `` | An embedded YouTube video. `id` is the video id, optionally followed by YouTube's embed options, as in Slidev: `?start=60&end=90`, `list`, `loop`, `autoplay`, `mute` and the other documented ones. Other options are dropped. `start` (seconds) and `list` (a playlist id) can also be attributes, and they win over the same option in `id`. | | `` | A video that plays when its slide, or its `slide-ng-click`, comes. `autoplay="once"` plays once. `timestamp` starts at a second. Put `` tags inside. | | `` | An embedded tweet. Loads Twitter's script, so it needs the network. | | `` | An embedded Bluesky post, needs the network. `uri` can also be the post's web address. | @@ -63,4 +64,4 @@ These tags work in every slide. The generator imports a component only into the ## Not there -Slidev's `PoweredBySlidev` badge and `TitleRenderer` are not available. Slide titles are plain text, except that `$math$` in a title is drawn in ``. Your own components work like these, see [Layouts and components](../customize/layouts-components.md). +Slidev's `PoweredBySlidev` badge is not available. Your own components work like these, see [Layouts and components](../customize/layouts-components.md). diff --git a/src/content/built-in/headmatter.md b/src/content/built-in/headmatter.md index b0c7199..b6c34a0 100644 --- a/src/content/built-in/headmatter.md +++ b/src/content/built-in/headmatter.md @@ -42,6 +42,7 @@ The first block of YAML in `slides.md` is the headmatter. It describes the deck. | `zoom` | Scale every slide. | | `routerMode` | `history` (default) or `hash`. | | `fonts` | Web fonts. See [Fonts](../features/fonts.md). | +| `themeConfig` | Settings for the theme, such as `themeConfig: { primary: '#5d8392' }`. Each text or number key becomes the CSS variable `--slidev-theme-`. See [Themes and addons](../customize/themes.md#theme-settings). | | `customElements` | Web component tags the slides may use, such as `[model-viewer, sl-*]`. A name ending in `*` is a prefix, and `true` allows any tag with a dash. See [Layouts and components](../customize/layouts-components.md#web-components). | ### Code and diagrams @@ -71,7 +72,8 @@ The first block of YAML in `slides.md` is the headmatter. It describes the deck. | Key | What it does | | --- | --- | -| `titleTemplate`, `author`, `keywords`, `favicon`, `lang`, `htmlAttrs`, `seoMeta` | The page's ``. See [Page head and SEO](../features/seo-meta.md). | +| `titleTemplate`, `author`, `keywords`, `favicon`, `htmlAttrs`, `seoMeta` | The page's ``. See [Page head and SEO](../features/seo-meta.md). | +| `lang`, `uiLang` | `lang` is ``, the interface language and the locale of the `date`, `number` and `currency` pipes. `ar`, `he`, `fa` and `ur` mirror the page. `uiLang` changes the interface language only. See [Interface language](../features/interface-language.md). | | `download` | A PDF button: `true`, a file name or an address. With `true`, `slide-ng build` makes the PDF. Without a working Chromium it warns and the button stays disabled. | | `exportFilename` | The name of exported files, without the extension. | | `export` | Defaults for `slide-ng export`. See [Export](../guide/export.md). | @@ -81,4 +83,4 @@ The first block of YAML in `slides.md` is the headmatter. It describes the deck. ## Not read -These Slidev keys are accepted in the file but have no effect: `selectable`, `themeConfig`, `preload`, `clickAnimation`, `overviewSnapshots`, `browserExporter`, `notesAutoRuby`, `monacoTypesSource`, and `colorSchema: all`. `mdc: true` and `comark: true` have no effect, and the generator warns that MDC syntax stays text. `highlighter: prism` warns too, because code is always highlighted with Shiki. The `monaco` and `twoslash` switches of Slidev are not read either: a `{monaco}` or `twoslash` code fence is what turns them on. A key a theme brings through `theme.json` is merged under the deck's headmatter, except a fixed `colorSchema`, see [Themes and addons](../customize/themes.md). +These Slidev keys are accepted in the file but have no effect: `selectable`, `preload`, `clickAnimation`, `overviewSnapshots`, `browserExporter`, `notesAutoRuby`, `monacoTypesSource`, and `colorSchema: all`. `mdc: true` and `comark: true` have no effect, and the generator warns that MDC syntax stays text. `highlighter: prism` warns too, because code is always highlighted with Shiki. The `monaco` and `twoslash` switches of Slidev are not read either: a `{monaco}` or `twoslash` code fence is what turns them on. A key a theme brings through `theme.json` is merged under the deck's headmatter, except a fixed `colorSchema`, see [Themes and addons](../customize/themes.md). diff --git a/src/content/customize/directory-structure.md b/src/content/customize/directory-structure.md index 60c0dc9..1f06818 100644 --- a/src/content/customize/directory-structure.md +++ b/src/content/customize/directory-structure.md @@ -16,6 +16,7 @@ my-deck/ styles/index.css CSS added after the app's styles public/ files served from the site root (/logo.png) setup/ setup hooks: shiki.ts, katex.ts, mermaid.ts, shortcuts.ts, ... + locales/ translations of the interface: tr.json, de.json, ... uno.config.mjs UnoCSS settings theme.json inputs and slots of your own layouts snippets/ anything you import with <<< @@ -42,6 +43,7 @@ So a deck can put a `layouts/cover.ts` next to `slides.md` and it beats the them | `styles/index.css` | CSS, added after the app's styles. | | `public/` | Files served from the site root. The later root wins on the same name. | | `setup/*.ts` | [Setup hooks](./setup-hooks.md). | +| `locales/.json` | Translations of the interface, flat `"key": "text"` pairs. Merged key by key, the later root wins. See [Interface language](../features/interface-language.md). | | `uno.config.mjs` | UnoCSS settings, default export. `presets`, `rules`, `safelist` and `variants` are added to the app's. `shortcuts` and `theme` are merged key by key. | | `theme.json` | Name, default headmatter and layout inputs and slots. A deck's own folder can have one too, for its own layouts. See [Writing a theme](./writing-a-theme.md). | diff --git a/src/content/customize/setup-hooks.md b/src/content/customize/setup-hooks.md index 9fd17c9..846637a 100644 --- a/src/content/customize/setup-hooks.md +++ b/src/content/customize/setup-hooks.md @@ -135,7 +135,7 @@ See [Shortcuts](../built-in/shortcuts.md). The roots are chained: each gets the ## Context menu -`setup/context-menu.ts` gets the entries of the right-click menu and returns the list to show. An entry is `{ icon, label, run, disabled? }`, and `icon` is an icon class such as `i-carbon:star`. The roots are chained. +`setup/context-menu.ts` gets the entries of the right-click menu and returns the list to show. An entry is `{ icon, label, run, disabled? }`, and `icon` is an icon class such as `i-carbon:star`. The roots are chained. The built-in labels are in the deck's [interface language](../features/interface-language.md), so pick an entry by its `icon`, not its label. ```ts // setup/context-menu.ts diff --git a/src/content/customize/themes.md b/src/content/customize/themes.md index 83ffe13..6f20483 100644 --- a/src/content/customize/themes.md +++ b/src/content/customize/themes.md @@ -48,6 +48,35 @@ A theme can bring layouts, components, layers, CSS, public files, UnoCSS setting The one exception is `colorSchema`. A theme that sets `light` or `dark` has colours for that mode only, so every deck that uses it keeps that mode, as in Slidev. The toggle is gone, and when the deck's headmatter asks for another mode the generator says that it is not used. Of the official themes, `bricks` is light only and `shibainu` dark only. +## Theme settings + +`themeConfig` holds the values a theme offers to change, as in Slidev. Each key with a text or number value becomes the CSS variable `--slidev-theme-` on ``, with the key as written: `primary` is `--slidev-theme-primary`, `accentDark` is `--slidev-theme-accentDark`. It is there in the page, the presenter, the PDF and offline builds. + +```md +--- +themeConfig: + primary: '#5d8392' +--- +``` + +`primary` recolours the built-in accent: `text-primary`, `bg-primary`, `border-primary`, the progress bar and the controls. Other keys do what the theme makes of them. + +- The theme's `theme.json` can give defaults. The deck's keys win, key by key, and so do an addon's. +- A key must be letters, digits, `-` and `_`. A value that could leave the CSS declaration (`;`, `{`, `}`, `<`, `>`, `\`, a comment, a line break, quotes or brackets that do not close) is skipped with a warning. +- There is one value for both colour modes, as in Slidev. +- A slide reads the whole map as `themeConfig`, for example `{{ themeConfig['primary'] }}`. The brackets are needed because the map has no fixed keys. Lists and objects are kept there, but they are not CSS variables. +- A theme's component reads it with `inject(THEME_CONFIG)` from `slide-ng/lib/theme-config`. See [Writing a theme](./writing-a-theme.md#5-default-settings). + +## Translating the interface + +A theme or an addon can translate slide.ng's own interface (the bar, the menus, the presenter) with a `locales/` folder. `locales/tr.json`, or `pt.json` and `pt-BR.json`, holds flat `"key": "text"` pairs with their `{name}` placeholders kept: + +```json +{ "nav.next": "Sonraki slayta git", "presenter.noNotes": "{no}. slayt için not yok." } +``` + +The deck's `lang` or `uiLang` picks the file. The built-in translations come first, then the theme, the addons and the deck, key by key, so a deck can change one text of its theme. A theme's own components can show the same texts with the `t` pipe: import `T` from `slide-ng/i18n/t`, then write `{{ 'nav.next' | t }}`. See [Interface language](../features/interface-language.md). + ## Eject a theme ```sh @@ -63,7 +92,6 @@ The built-in styles still load before the ejected `styles/index.css`. Your copy - There is no versioning or compatibility check between a theme and the app. - A layout's inputs are not read from the component, because Angular decorators are not parsed. They come from the built-in layout or from `theme.json`. - Class names in a theme are found by UnoCSS in `.ts` files of the roots and in the deck's markdown, not in CSS files. -- `themeConfig` is not read. - `@apply` in a theme's CSS does nothing, because there is no UnoCSS directive transformer. The generator warns. Write the CSS out, or put the classes on the elements. - A theme package whose `files` leaves its folders out installs empty. The generator warns, instead of failing later with "is not a known element". diff --git a/src/content/customize/writing-a-theme.md b/src/content/customize/writing-a-theme.md index 6277242..aa396d1 100644 --- a/src/content/customize/writing-a-theme.md +++ b/src/content/customize/writing-a-theme.md @@ -18,6 +18,7 @@ my-theme/ layers/ optional: global-top.ts, global-bottom.ts, slide-top.ts, slide-bottom.ts setup/ optional: setup hooks public/ optional: pictures and fonts, served from / + locales/ optional: translations of the interface, tr.json, de.json, ... uno.config.mjs optional: UnoCSS shortcuts and rules ``` @@ -86,9 +87,23 @@ Dark mode is the class `dark` on ``: write `html.dark .my-quote { ... }` f - A `colorSchema` of `light` or `dark` says the theme has colours for that mode only: every deck that uses it keeps that mode, and the generator warns when a deck asks for another. Leave it out when the theme styles both. - `layouts.`: `props` are the frontmatter keys that become inputs, `slots` are the names accepted after `::name::`, and `classProp: true` sends the slide's `class` to the input `contentClass` instead of the tag. +Settings a deck may change, such as the accent colour, go in `themeConfig`, as in Slidev. Each one is the CSS variable `--slidev-theme-` on ``, and the deck's `themeConfig: { accent: '#22c55e' }` replaces your default: + +```json +{ "headmatter": { "themeConfig": { "accent": "#f59e0b" } } } +``` + +```css +.my-quote { + border-left: 4px solid var(--slidev-theme-accent); +} +``` + +The variables are written after the roots' style sheets, so they win over a value you set on `:root` or `html.dark`. Use them in rules on the elements, or alias them on `body` or below: an alias on `:root` is worked out before the variable exists there. `primary` is the colour of the built-in accent (`text-primary`, the progress bar). In a component, `inject(THEME_CONFIG)` from `slide-ng/lib/theme-config` gives the whole map, lists and objects too. There is one value for both colour modes, so a theme that wants another dark colour can offer a second key, such as `primaryDark`, and use it under `html.dark`. The rules for values are in [Themes and addons](./themes.md#theme-settings). + Keys other than `name`, `headmatter` and `layouts` are not read, and the generator says so: settings such as `colorSchema` and `fonts` go under `headmatter`. A value of the wrong type is reported and ignored. A deck's own folder can have a `theme.json` too, to describe the inputs and slots of its own layouts. -Pictures go in `public/`. +Pictures go in `public/`. Translations of slide.ng's interface go in `locales/.json`, see [Themes and addons](./themes.md#translating-the-interface). ## A footer or page number @@ -114,7 +129,7 @@ A theme is a folder, so publish it as an npm package with these folders at the t "version": "1.0.0", "license": "MIT", "keywords": ["slide-ng-theme", "slide-ng"], - "files": ["layouts", "components", "layers", "styles", "public", "setup", "theme.json", "uno.config.mjs"], + "files": ["layouts", "components", "layers", "styles", "public", "setup", "locales", "theme.json", "uno.config.mjs"], "peerDependencies": { "@slide-ng/core": "*" } } ``` diff --git a/src/content/features/interface-language.md b/src/content/features/interface-language.md new file mode 100644 index 0000000..44fa20a --- /dev/null +++ b/src/content/features/interface-language.md @@ -0,0 +1,78 @@ +--- +title: Interface language +description: Show the bar, the menus and the presenter in the deck's language, and translate them with a JSON file. +--- + +# Interface language + +slide.ng's own interface is in English: the bar and its tooltips, the settings menu, the overview, the go-to box, the right-click menu, the presenter, the info dialog and the drawing toolbar. The headmatter's `lang` picks another language. Turkish is built in. + +```md +--- +lang: tr # , the interface in Turkish, dates and numbers written the Turkish way +uiLang: en # optional: the interface in another language than the slides +--- +``` + +| Key | What it does | +| --- | --- | +| `lang` | The language of the deck: ``, the interface language and the locale of the `date`, `number`, `currency` and `percent` pipes. | +| `uiLang` | The interface language only. It wins over `lang`. | + +A tag is written the usual way: `pt_br` is read as `pt-BR`. Without either key the interface is English. + +## Translate it + +For a language that is not built in, put `locales/.json` next to `slides.md`. It is flat JSON, with the keys you translate: + +```json +{ "nav.next": "Nächste Folie", "presenter.noNotes": "Keine Notizen für Folie {no}." } +``` + +The keys and their English text are listed in [UI-STRINGS.md](https://github.com/slide-ng/slide.ng/blob/main/docs/UI-STRINGS.md) in the slide.ng repository. Keep the `{name}` placeholders, in any order the sentence needs. + +- A key that no file translates stays English, and so does a language without a file. +- A theme or an addon can have a `locales/` folder too. The built-in translations come first, then the theme, the addons and the deck, key by key, so a deck can change one text of its theme. See [Themes and addons](../customize/themes.md#translating-the-interface). +- In each folder the shorter tag is read first: `de.json`, then `de-AT.json`. +- The generator warns about a key that does not exist, a value that is not text and a placeholder that was lost or added. That key stays English. A file that is not JSON stops the build. + +## Dates and numbers + +`lang` also sets Angular's `LOCALE_ID`, so the pipes in a slide write for that language: + +```md +{{ price | currency: 'EUR' }} · {{ day | date }} · {{ n | number }} +``` + +Only that locale's data goes into the build. `pt-BR` uses Angular's `pt-BR` data, or else `pt`. A language Angular has no data for is written the English way, and the generator says so. `uiLang` does not change the locale. The date on the notes PDF follows `lang` too. + +## Right to left + +`ar`, `he`, `fa` and `ur` set `dir="rtl"` on the page, unless `htmlAttrs.dir` says otherwise. The bar, the menus, the go-to box and the presenter are mirrored. + +## One deck in several languages + +Write one entry file per language, and import the slides that are the same in every language with `src:`: + +``` +slides.md lang: en +slides.tr.md lang: tr, its own translated slides, and src: ./pages/demo.md for a shared one +pages/demo.md +``` + +Build each into its own folder: + +```sh +slide-ng build slides.md --out dist/en +slide-ng build slides.tr.md --out dist/tr +``` + +`--lang tr` on `dev`, `build` and `export` sets `lang` for one run without changing the file. `SLIDE_NG_LANG` does the same. See the [CLI reference](../built-in/cli.md). + +## Limits + +- Turkish is the only built-in translation. +- Error messages that come from the browser (camera, recording, screen sharing) and the generator's warnings stay English. +- In a right-to-left deck the arrow keys, swipes and the position of the drawing toolbar are not mirrored. +- The language cannot be switched while presenting. Build one deck per language instead. +- The built-in context menu labels follow the language, so a `setup/context-menu.ts` should pick an entry by its `icon`, not its label. diff --git a/src/content/features/routing.md b/src/content/features/routing.md index 83eefb0..211fd17 100644 --- a/src/content/features/routing.md +++ b/src/content/features/routing.md @@ -17,7 +17,7 @@ routeAlias: intro --- ``` -Now `/intro` opens the slide. `` links to it, see [Components](../built-in/components.md). +Now `/intro` opens the slide. `` links to it, see [Components](../built-in/components.md), and so does the markdown link `[intro](/intro)`, see [Links](../guide/syntax.md#links). ## Hash or history diff --git a/src/content/features/seo-meta.md b/src/content/features/seo-meta.md index e54bc59..0c73e5a 100644 --- a/src/content/features/seo-meta.md +++ b/src/content/features/seo-meta.md @@ -29,7 +29,7 @@ seoMeta: | `title`, `titleTemplate` | The browser tab. `%s` is the title. | | `info` | Markdown for the info dialog. With the markup taken out and cut at 300 characters, it is also the page description and the PDF's subject. | | `author`, `keywords` | Meta tags. `keywords` is a list or a comma separated text. | -| `lang`, `htmlAttrs` | Attributes on ``. | +| `lang`, `htmlAttrs` | Attributes on ``. `lang` also picks the [interface language](./interface-language.md) and the locale of dates and numbers, and `ar`, `he`, `fa` and `ur` add `dir="rtl"` unless `htmlAttrs.dir` is set. | | `favicon` | A file of `public/`, or a web address. | | `seoMeta` | Open Graph and Twitter tags: `ogTitle`, `ogDescription`, `ogImage`, `ogUrl`, `twitterCard` and so on. | diff --git a/src/content/features/speaker-notes.md b/src/content/features/speaker-notes.md index d8591b6..0146259 100644 --- a/src/content/features/speaker-notes.md +++ b/src/content/features/speaker-notes.md @@ -18,4 +18,5 @@ In a note, `[click]` marks where the next click starts, and `[click:3]` moves th - `/notes` shows only the notes and follows the presenter. - `slide-ng export-notes` writes a PDF of the notes. - `slide-ng build --without-notes` leaves the notes out of the built site. +- A link to a web page in a note opens a new tab, so the presenter view stays. A link to a slide stays a plain address, and a click on it loads that page. - The notes are plain text. Ruby annotations for Japanese (`notesAutoRuby`) are not supported. diff --git a/src/content/features/table-of-contents.md b/src/content/features/table-of-contents.md index de3d088..9bb90b6 100644 --- a/src/content/features/table-of-contents.md +++ b/src/content/features/table-of-contents.md @@ -23,4 +23,4 @@ Leave a slide out with `hideInToc: true`. | `minDepth`, `maxDepth` | Which levels to list. | | `mode` | `all`, `onlyCurrentTree` (the path to the current slide and what is below it) or `onlySiblings` (the lists that contain the current slide). | -The slide's title is plain text: the markup of links, code and HTML tags in a heading is taken out, also in the tab title, the go-to box and the PDF outline. `$math$` in a title is drawn with KaTeX here. Slidev's `TitleRenderer`, which shows a title as HTML, is not there. +The list shows each title as HTML: inline markdown such as `**bold**` and `code` is drawn, and `$math$` with KaTeX. Raw HTML in a title is shown as text. `` shows one title the same way anywhere, see [Components](../built-in/components.md). The tab title, the go-to box and the PDF outline use the plain text, with the markup taken out. diff --git a/src/content/guide/export.md b/src/content/guide/export.md index bbfd148..645ae91 100644 --- a/src/content/guide/export.md +++ b/src/content/guide/export.md @@ -26,6 +26,10 @@ Export opens the deck in Chromium. slide.ng never downloads a browser, so set `C In a PDF, a slide that has clicks shows its last state. `--with-clicks` makes a page for every click step. A `@defer` block that waits (`on timer`, `on viewport`) may still show its placeholder when the page is captured: give `export` a `--wait`. `` shows content only on paper, see [Components](../built-in/components.md). +## Links in a PDF + +A link to a slide, written in markdown (`[x](5)`) or as ``, points at the first page of that slide in the PDF, so a click jumps there instead of opening the local server's address. It works only when the target slide is in the same file: with `--per-slide`, or with a `--range` that leaves the slide out, a link to another slide is no link. Links to web pages stay links. + ## Choosing slides and looks ```sh diff --git a/src/content/guide/styling.md b/src/content/guide/styling.md index d8c3709..f5e57c5 100644 --- a/src/content/guide/styling.md +++ b/src/content/guide/styling.md @@ -42,4 +42,4 @@ The core styles follow Slidev's: code is 12px (`--slidev-code-font-size`), and t ## Shortcuts and icons -slide.ng defines a few of Slidev's utility shortcuts, such as `bg-main`, `text-primary` and `border-main`. Icons are classes or tags, see [Icons](../features/icons.md). A theme or deck can add its own UnoCSS settings in `uno.config.mjs`, see [Directory structure](../customize/directory-structure.md). +slide.ng defines a few of Slidev's utility shortcuts, such as `bg-main`, `text-primary` and `border-main`. `themeConfig: { primary: '#5d8392' }` in the headmatter changes the colour of `text-primary`, see [Theme settings](../customize/themes.md#theme-settings). Icons are classes or tags, see [Icons](../features/icons.md). A theme or deck can add its own UnoCSS settings in `uno.config.mjs`, see [Directory structure](../customize/directory-structure.md). diff --git a/src/content/guide/syntax.md b/src/content/guide/syntax.md index 3d887c4..8648650 100644 --- a/src/content/guide/syntax.md +++ b/src/content/guide/syntax.md @@ -42,6 +42,27 @@ The last HTML comment of a slide is its speaker note. It is stored with the slid ``` +## Links + +As in Slidev, a markdown link to a slide moves inside the deck, and a link to a web page opens a new tab: + +```md +[go to slide 5](5), or [5](/5), [5](./5), [5](#/5) +[pricing](/pricing) goes to the slide with routeAlias: pricing +[results](#results) goes to a heading of this slide +[the docs](https://example.org) opens in a new tab +``` + +- An address of only digits, or `/`, `./` or `#/` followed by a slide number or a `routeAlias`, becomes a ``. A click moves to that slide without loading the page again, with history or hash routing, a base or an offline folder. Ctrl or Cmd + click opens it in a new tab. A number past the last slide goes to the last slide. +- Other addresses that start with `/` or `./`, such as `/file.pdf` or a name that is no `routeAlias`, stay plain links. +- `#id` and `./#id` scroll to that element of the slide. `#5` is such an anchor too: write `5` or `#/5` for slide 5. +- An `http:` or `https:` address gets `target="_blank" rel="noopener"`. `mailto:` and other links stay as they are. +- An `` written as HTML is left as written. Use `` for a link to a slide in HTML. +- In speaker notes a web page opens a new tab too, but a link to a slide stays a plain address. +- In an exported PDF a link to a slide points at that slide's page, see [Export](./export.md#links-in-a-pdf). + +The differences with Slidev are on the [differences page](../migrating/from-slidev.md). + ## Slots A line with only `::name::` starts a named part of the slide, which a layout can place somewhere: diff --git a/src/content/migrating/from-slidev.md b/src/content/migrating/from-slidev.md index 5639ec2..c083675 100644 --- a/src/content/migrating/from-slidev.md +++ b/src/content/migrating/from-slidev.md @@ -24,7 +24,8 @@ slide.ng reads the same markdown file format as *Slidev, with the same slide spl | ` + + + + +``` + +- The inside of its `` goes into the page's head, after the tags made from the headmatter. The inside of its `` goes after the app: out of sight, but screen readers read it. The parts of every root are added in order: theme, addons, deck. +- A `` or a `<meta>` with the same name and `media` as one made from the headmatter replaces it, as Slidev's head manager does. Tags meant to repeat, such as several `og:image`, are all kept. While the deck runs, the tab's title still follows the slides. +- The attributes of its `<html>` and `<body>` are added to the page's. The headmatter's `htmlAttrs` win, and `class` values are joined. `lang` comes from the headmatter only, because it also picks the interface language, so the `lang` of an `index.html` is ignored with a warning. +- A root address such as `src="/analytics.js"` gets the base in front, like `/x.svg` in a slide. +- The file is the deck's own code: it is copied as it is, and its scripts run in `dev`, in a build, in an offline folder and in an export. In an offline folder a `<script type="module" src>` does not run; use a plain `<script>`. + +`slide-ng build` moves its inline scripts into files, see [Hosting](../guide/hosting.md#content-security-policy). Rename the file if it was not meant for the deck. diff --git a/src/content/guide/hosting.md b/src/content/guide/hosting.md index 40f8d4c..083cb3f 100644 --- a/src/content/guide/hosting.md +++ b/src/content/guide/hosting.md @@ -14,17 +14,25 @@ slide-ng build --out public-html # another output folder slide-ng build --download # also writes the PDF and adds the download button slide-ng build --without-notes # speaker notes are not shipped slide-ng build --offline # a folder that opens from disk +slide-ng build a.md b.md --base /x/ # several decks: dist/a at /x/a/, dist/b at /x/b/ ``` ## Safe output folders The build empties its output folder. To make sure it never wipes something of yours, it only does so when the folder is new, empty, or has a `.slide-ng-build` file written by an earlier build. Any other folder with files in it is refused. The current folder, your home folder and `/` are always refused. +## Several decks + +With several entries each deck is built in turn into its own folder of `--out`, named after its file without `.md`, and served under that name below `--base`, as Slidev's multiple builds. The rest of `--out` is emptied, so it holds only these folders. Each folder is a whole site with its own `404.html` and `_redirects`. A host that serves one folder per site needs one site per deck, or a rule that sends `/x/a/*` to `/x/a/index.html`. With a deck at the root as well, the rule of each deck under the sub-path must come before the root's catch-all. + +Decks on one origin, such as these folders or the project sites of one GitHub Pages user, keep to themselves: the windows that follow each other, the drawings and the settings kept in the browser belong to the deck's base path. Only dark mode is shared. A deck at `/` keeps the names of 1.x; settings that a deck under a sub-path saved with 1.x are not read. + ## What is in the build | File | What for | | --- | --- | | `index.html`, `main-*.js`, `chunk-*.js`, `styles-*.css` | The app. Monaco, Mermaid and the like are separate chunks, fetched only when a slide uses them. | +| `inline-*.js` | The inline scripts of `index.html`, as files, see [Content-Security-Policy](#content-security-policy). | | `404.html` | A copy of `index.html`. GitHub Pages shows it for unknown paths, so `/talk/3` opens the app. | | `_redirects` | The same rule for Netlify. | | `<exportFilename>.pdf` | Only with `--download` or `download: true`. With `download: true` alone, a build without a working Chromium warns and leaves it out. | @@ -40,6 +48,8 @@ The deck lives at the base. Every slide is `<base><number>` in history mode, the - History mode needs the host to answer unknown paths with `index.html`. `404.html`, `_redirects` and the examples below do that. - Hash mode needs nothing from the host. Use it where you cannot change the server, such as a plain file share. +- Memory mode, `routerMode: memory`, never changes the address, for a kiosk or a deck inside another page. See [Slide addresses](../features/routing.md#memory-mode). +- `--router-mode` picks the mode for one build, without changing the headmatter. - `--base` is a path such as `/talk/`, not a full address. Build for the prefix you will serve under. ## GitHub Pages @@ -109,6 +119,28 @@ server { Under a sub-path build with `--base /talk/`, put the files in `/usr/share/nginx/html/talk/` and use `try_files $uri $uri/ /talk/index.html;`. +## Content-Security-Policy + +`index.html` has no inline script. The few lines Angular adds there, and the inline scripts of the deck's own [`index.html`](../features/seo-meta.md#your-own-index-html), are written to `inline-*.js` files next to it. A `type="module"` script stays a module, and other attributes such as `data-cfasync="false"` are kept. Data blocks (`application/ld+json`) stay inline. An inline import map or `speculationrules` cannot be a file, so the build leaves it and warns. A host that sends a strict policy therefore runs the deck, as long as styles may be inline: + +``` +Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data: +``` + +Add what the slides load from elsewhere: `img-src https:` for remote pictures, `frame-src` for `<slide-ng-youtube>` and other frames, `font-src` and `style-src` for a web font provider. Only `slide-ng build` moves the scripts, not `--offline`. Trusted Types are not supported: with them Mermaid diagrams are not drawn. + +## Embedding the deck in another page + +A built deck works in an `<iframe>`. Give the frame `allow="fullscreen"`, or the fullscreen button is left out: + +```html +<iframe src="https://you.github.io/talk/" allow="fullscreen" width="960" height="540"></iframe> +``` + +The wake lock, which keeps the screen from going to sleep, is on by default. In a frame the deck asks for it only once the reader clicks, taps or presses a key in the deck, or makes it full screen, so a reader who only scrolls past it is not kept awake. To let an embedded deck keep the screen awake, add `screen-wake-lock` to `allow`. For a deck that is mostly shown embedded, `wakeLock: false` in the headmatter turns it off. + +A host that sends `frame-ancestors` or `X-Frame-Options` must allow the page that embeds the deck. `routerMode: memory` keeps the address of a deck in a frame unchanged. + ## Size A deck without heavy features is about 450 kB at startup, about 110 kB compressed. Decks that use Monaco or KaTeX add their style sheets to that. Every slide is in the first bundle, and highlighted code compiles to a lot of markup, so a long workshop with code on every slide can pass 3 MB. The build warns above 6 MB at startup and fails only above 100 MB. Monaco, Mermaid and Magic Move are lazy chunks and do not count. diff --git a/src/content/guide/layouts.md b/src/content/guide/layouts.md index fb36b2c..b595e04 100644 --- a/src/content/guide/layouts.md +++ b/src/content/guide/layouts.md @@ -18,7 +18,7 @@ image: /photo.png Text next to the picture. ``` -slide.ng has all the layouts of Slidev, with the same names and props, plus `404` and `error`. The first slide is `cover` and every other slide is `default` unless you say otherwise. An unknown name prints a warning that lists the real names and uses `default`. +slide.ng has all the layouts of Slidev, with the same names and props, plus `404` and `error`. The first slide is `cover` and every other slide is `default` unless you say otherwise. An unknown name prints a warning that names the nearest layout, lists the real names and uses `default`. <ngmd-image src="/images/layouts/two-cols.png" alt="A slide with two columns" caption="The two-cols layout" width="480"></ngmd-image> diff --git a/src/content/guide/offline.md b/src/content/guide/offline.md index 2702c23..d516cb8 100644 --- a/src/content/guide/offline.md +++ b/src/content/guide/offline.md @@ -24,7 +24,7 @@ Copy `talk-offline` to the presenting machine, or to a USB stick, and open `talk What the flag does: - One classic script holds the app and all its lazy chunks (Mermaid, Monaco, KaTeX). Chromium does not run module scripts or `import()` from `file://`, so a normal build shows a blank page there. -- Addresses are relative and there is no `<base>`, so the folder works from any place on disk. The slide is after a `#`, as in `index.html#/3`, and `routerMode` is forced to `hash`. +- Addresses are relative and there is no `<base>`, so the folder works from any place on disk. The slide is after a `#`, as in `index.html#/3`, and `routerMode` is forced to `hash`: `--router-mode memory` is refused, and a headmatter `routerMode: memory` is replaced with a warning. A `<script type="module" src>` in the deck's own `index.html` does not run there; use a plain `<script>`. - There is no service worker, because browsers do not allow one on `file://`. `pwa` is ignored. - Pictures from other servers are downloaded into the folder, unless the deck says `remoteAssets: false`. - Web fonts are downloaded into the folder, unless the deck says `fonts: { selfHost: false }`. From 7afdc79d2eda240581878052144ef55a5182c8f9 Mon Sep 17 00:00:00 2001 From: erkamyaman <erkamyaman35@gmail.com> Date: Thu, 22 Oct 2026 22:40:55 +0000 Subject: [PATCH 13/19] docs: add an accessibility page --- src/content/guide/accessibility.md | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/content/guide/accessibility.md diff --git a/src/content/guide/accessibility.md b/src/content/guide/accessibility.md new file mode 100644 index 0000000..f11ac51 --- /dev/null +++ b/src/content/guide/accessibility.md @@ -0,0 +1,51 @@ +--- +title: Accessibility +description: What slide.ng does for screen readers, keyboards, contrast and motion, and what a deck has to do itself. +--- + +# Accessibility + +This page lists what the slides, the presenter and the other pages do for people who use a screen reader, a keyboard, high contrast or less motion. The second half is what a deck author has to do, because slide.ng cannot do it for you. + +## Screen readers + +- Each new slide is announced with its number and title, in a polite live region. A title is read as plain text: its markdown marks go, and `$math$` is its TeX, with TeX's one-character escapes undone, so `$400\%$` is "400%". +- Elements that wait for a click are hidden from screen readers until they show. They are inert too: their links and buttons take no focus, also with the `fade` preset, where they are visible but dimmed. +- The slide, with the bar, is the main landmark of the audience page. The presenter, `/overview` and `/notes` each have a main landmark and a level-one heading, and `/entry`, `/notes-edit` and the notes print page have a main landmark. +- The presenter page has three named regions: Current slide, Next step and Notes. The next-step picture is skipped, so headings are not read twice. Line numbers of code and of Magic Move are skipped too. +- The quick overview, the right-click menu and the "go to" box are named dialogs, with all their controls inside. Each overview card is named "Go to slide N: title". +- The progress bar is a `progressbar` named "Progress through the slides". +- Math is read as its TeX source, in the slide and in a title drawn by `<slide-ng-title-renderer>` or the table of contents. +- An exported PDF is tagged for screen readers and has the deck's language. `--per-slide` loses the tags. + +## Keyboard + +- In the quick overview (`o`) the arrow keys move the focus from card to card. +- The right-click menu opens with Shift+F10 or the menu key, see [Shortcuts](../built-in/shortcuts.md#mouse). +- Escape in the settings menu, the sync menu and the drawing toolbar closes it and gives the focus back to its button. After Edit Notes, Escape gives the focus back to the Edit Notes button. +- The borders of the presenter's notes pane are Tab stops that the arrow keys move. +- In the presenter's [click preview](./presenter-mode.md#click-preview) the badges are buttons named "Go to click N". +- On `/overview`, while the dev server runs, each note says it can be edited, and a live region says how a save ended. + +## Contrast, size and zoom + +- The interface's text is at least 4.5:1, or 3:1 for large text, in light and dark mode. That includes the notes of later clicks, which are faded once, and the "No notes." placeholder. +- Icon buttons are at least 24 by 24 pixels, also the click preview's badges and the timer's buttons. +- The settings and sync menus and the info dialog stay inside the window down to 320 by 180 pixels, which is 400% zoom, and scroll. +- In forced colors mode, such as Windows high contrast, the icons are drawn in the text colour and the progress bars in the system's highlight colour. + +A theme that changes the colours, or `.slidev-note-fade`, has to keep these contrasts. + +## Less motion + +When the system asks for less motion (`prefers-reduced-motion: reduce`), slide transitions, click animations, `slide-ng-motion` and Magic Move change at once. A transition with a fixed `duration` ends at once too. JavaScript timers in your own components are not changed: check `matchMedia('(prefers-reduced-motion: reduce)')` there. + +## What the deck has to do + +- Give every picture a text alternative: `![A red bridge at night](/bridge.jpg)` or `<img alt="...">`. A picture given as `image:` or `background:` in the frontmatter is a CSS background and cannot have one. When it carries meaning, put an `<img alt>` in the slide or say it in the text. +- Give each slide a title, with a heading or `title:`. It is what screen readers announce and what the "go to" box finds. +- Set `lang` in the headmatter to the language of the slides. It is `<html lang>`, the PDF's language and the [interface language](../features/interface-language.md). +- In a Mermaid diagram, `accTitle: ...` and `accDescr: ...` lines become the title and description of the SVG. +- Say a formula in words, in the text or the notes, when the audience needs it. Math is read as TeX, not as "a over b". +- Use `slide-ng-click` rather than `@if ($clicks() > 1)` for content that appears: it stays on the page, hidden and inert, and the click preview shows it. +- Check the colours of your own components in both modes. From 2eb7141d32b7c88f80ecf6e56694f37316f1b3f0 Mon Sep 17 00:00:00 2001 From: erkamyaman <erkamyaman35@gmail.com> Date: Thu, 22 Oct 2026 22:40:55 +0000 Subject: [PATCH 14/19] docs: add the upgrade guide to 2.0 and list the new pages --- src/content/getting-started/install.md | 4 +- src/content/migrating/from-slidev.md | 16 ++--- src/content/migrating/not-supported.md | 21 +++---- src/content/migrating/upgrading-to-2.md | 80 +++++++++++++++++++++++++ src/content/welcome.md | 2 +- src/ngmd.config.ts | 23 ++++--- 6 files changed, 115 insertions(+), 31 deletions(-) create mode 100644 src/content/migrating/upgrading-to-2.md diff --git a/src/content/getting-started/install.md b/src/content/getting-started/install.md index 91dff10..0a09cfb 100644 --- a/src/content/getting-started/install.md +++ b/src/content/getting-started/install.md @@ -5,6 +5,8 @@ description: Requirements and how to get slide.ng running today. # Install +These pages describe slide.ng 2.0. The commands below install the newest version. A deck that uses 1.x keeps working with it: to move it to 2.0, read [Upgrading from 1.x to 2.0](../migrating/upgrading-to-2.md), or pin the old version with `npm install -D @slide-ng/core@^1`. + ## Requirements - Node 22.22.3 or newer. The `engines` field of the package says `>=22.22.3`. @@ -29,7 +31,7 @@ npm install -D @slide-ng/core npx slide-ng dev ``` -The command is `slide-ng`, described in [The command line](./cli.md). [Your first deck](./first-deck.md) shows what to do next. +`npx slide-ng --version` prints the version you have. The command is `slide-ng`, described in [The command line](./cli.md). [Your first deck](./first-deck.md) shows what to do next. ## From a checkout diff --git a/src/content/migrating/from-slidev.md b/src/content/migrating/from-slidev.md index 3e32c57..4615d4a 100644 --- a/src/content/migrating/from-slidev.md +++ b/src/content/migrating/from-slidev.md @@ -19,6 +19,8 @@ slide.ng reads the same markdown file format as *Slidev, with the same slide spl ## Added in slide.ng - A click preview on the presenter page: the eye button or `u` shows what the later clicks of the current slide show, greyed out, and a click on a part goes to its click. See [Presenter mode](../guide/presenter-mode.md#click-preview). +- A progress bar on the slides, `progressBar` or `<slide-ng-progress-bar />`. Slidev has one on its presenter page only. See [Progress bar](../features/progress-bar.md). +- A built-in Turkish interface and `locales/<lang>.json` to translate the interface. See [Interface language](../features/interface-language.md). ## Syntax differences @@ -27,20 +29,19 @@ slide.ng reads the same markdown file format as *Slidev, with the same slide spl | Vue template syntax: `{{ x }}`, `v-if`, `v-for`, `v-bind` | Angular template syntax: `{{ x }}`, `@if`, `@for`, `@switch`, `@let`, `[prop]="x"`, `(event)="y"` | | `<script setup>` for state | No equivalent. State lives in components, and parts of a slide share state with `#ref` and `@let` | | `v-click`, `v-after`, `v-click-hide`, `<v-clicks>`, `<v-click-gap>`, `<v-switch>`, `v-mark`, `v-motion`, `v-drag`, `<v-drag>`, `<v-drag-arrow>` | The same name with the `slide-ng-` prefix: `slide-ng-click`, `slide-ng-after`, `slide-ng-click-hide`, `<slide-ng-clicks>`, `<slide-ng-click-gap>`, `<slide-ng-switch>`, `slide-ng-mark`, `slide-ng-motion`, `slide-ng-drag`, `<slide-ng-drag>`, `<slide-ng-drag-arrow>`. The old names stop the generator | -| `v-click="[2, 4]"` | `[slide-ng-click]="[2, 4]"`, because Angular reads a plain attribute as text. `slide-ng-click="3"` and `"+2"` are fine as they are | +| `v-click="[2, 4]"` | `slide-ng-click="[2, 4]"` is bound for you, and `[slide-ng-click]="[2, 4]"` is the Angular binding. `slide-ng-click="3"` and `"+2"` are fine as they are | | PascalCase components: `<Toc />`, `<TitleRenderer />`, `<Link>`, `<Youtube>`, `<SlidevVideo>`, `<AutoFitText>`, `<LightOrDark>`, `<RenderWhen>`, `<SlideCurrentNo>`, `<SlidesTotal>`, `<Transform>`, `<Arrow>`, `<VDragArrow>` | kebab-case tags with the `slide-ng-` prefix: `<slide-ng-toc />`, `<slide-ng-title-renderer />`, `<slide-ng-link>`, `<slide-ng-youtube>`, `<slide-ng-video>`, `<slide-ng-auto-fit-text>`, `<slide-ng-light-or-dark>`, `<slide-ng-render-when>`, `<slide-ng-current-no />`, `<slide-ng-total />`, `<slide-ng-transform>`, `<slide-ng-arrow>`, `<slide-ng-drag-arrow>` | -| `{{ $slidev.themeConfigs.primary }}` | `{{ themeConfig['primary'] }}`. The CSS variables `--slidev-theme-<key>` are the same | -| `$slidev`, `$nav`, `$clicks`, `$page` | Angular injection: `Nav`, `ClicksContext`, `SLIDE_NO`, `RENDER_CONTEXT` from `slide-ng/lib/...`. There is no global in markdown: a small component exposes the value and a `#ref` reads it | -| Slide hooks `onSlideEnter`, `onSlideLeave` | Not available. A component can inject `Nav` or `ClicksContext` and use signals | +| `{{ $clicks }}`, `{{ $page }}`, `$nav.currentPage` | The same names, but the values that change are Angular signals, so they are called: `{{ $clicks() }}`, `{{ $page() }}`, `$nav.currentPage()`. The generator warns about the uncalled forms. `$frontmatter`, `$slidev.configs` and `$slidev.themeConfigs` are read as they are. See [Angular in markdown](../guide/angular-templates.md#the-global-context) | +| `{{ $slidev.themeConfigs.primary }}` | The same, or `{{ themeConfig['primary'] }}`. The CSS variables `--slidev-theme-<key>` are the same | +| Slide hooks `onSlideEnter`, `onSlideLeave`, `useIsSlideActive` | `onSlideEnter`, `onSlideLeave` and `isSlideActive()` from `slide-ng/lib/slide-hooks`, called in a component. See [Layouts and components](../customize/layouts-components.md#slide-hooks) | | Your own components in `components/`, written in Vue | Standalone Angular components in `components/`, found by their `selector` | | Layouts in `layouts/*.vue` | Layouts in `layouts/*.ts`, see [Layouts and components](../customize/layouts-components.md) | | UnoCSS config in `uno.config.ts` | `uno.config.mjs` | | `v-pre` for a literal `{{ }}` | `ngNonBindable` on the element, or `\{\{` or `{{` in text | | `<template #1>` children of `<v-switch>`, `<template #dark>` of `<LightOrDark>` | `<div at="1">` children of `<slide-ng-switch>`, and `<div dark>` or `<div light>` in `<slide-ng-light-or-dark>`. A `<template #...>` slot renders nothing, and the generator reports it | | A named slot of your own component, `<template #title>` | An element with an attribute, `<span slot-title>`, and `<ng-content select="[slot-title]" />` in the component | -| `@click="$slidev.nav.next"` | A small component that injects `Nav` and calls `nav.next()` | +| `@click="$slidev.nav.next"` | `(click)="$nav.next()"` | | Self-closing HTML tags, `<div />` | `<div></div>`. Angular stops with NG5002 otherwise. Components, `<img />` and `<br />` are fine | -| `@apply` in CSS | Does nothing, and the generator warns. Write the CSS out, or put the classes on the elements | | Windi's comma in arbitrary values, `grid-cols-[80px,1fr]` | `_` as in UnoCSS, `grid-cols-[80px_1fr]` | | Any `/x` or `./x` markdown link is a link inside the deck | Only a slide number or a `routeAlias` is: `[x](5)`, `/5`, `./5`, `#/5`, `/alias`. Other addresses, such as `/file.pdf`, stay plain links. See [Links](../guide/syntax.md#links) | | `[x](#5)` goes to slide 5 | `#5` is an anchor on the slide. Write `5` or `#/5` | @@ -56,7 +57,6 @@ slide.ng reads the same markdown file format as *Slidev, with the same slide spl | `slidev build --base /talk/` | `slide-ng build --base /talk/` | | `slidev dev --base` | Refused. The dev server always runs at `/` | | `slidev --tunnel` | Refused. Use `--remote` on your network | -| `slidev export` with several entries | One entry per run | | `slidev export --format pptx-editable` | Not made. `pptx` holds pictures and notes | | `npm init slidev` | `slide-ng create <folder>` | @@ -74,7 +74,7 @@ Slidev's setup files use `define...Setup` helpers and get Vue and Vite objects. 1. Run `slide-ng` on the deck and read the warnings. Unknown layouts, a missing theme and unknown slots are all reported. 2. Replace `v-if`, `v-for` and `<script setup>` with Angular's control flow and with components. -3. Rename component tags to kebab-case with the `slide-ng-` prefix, `v-click` and the other `v-` names to `slide-ng-click` and so on, and `v-click` ranges to `[slide-ng-click]`. Search for `v-click`, `v-after`, `v-mark`, `v-motion`, `v-drag` and `<v-`. +3. Rename component tags to kebab-case with the `slide-ng-` prefix, and `v-click` and the other `v-` names to `slide-ng-click` and so on. The generator stops on the old names, Slidev's PascalCase components (`<Toc />`, `<VClicks>`, `<Youtube>`, ...) included, and lists every one of them with its new name in one run. 4. Replace the theme with an official one, or write one. A Slidev theme name such as `seriph` is looked up as `@slide-ng/theme-seriph` and stops the build when that is not installed. 5. Pictures next to `slides.md` (`./images/x.png`) in a slide's markup are copied into the build. Move the ones that components, CSS `url()` and the frontmatter name into `public/`. 6. Put each component file directly in `components/`. Sub-folders are not read. diff --git a/src/content/migrating/not-supported.md b/src/content/migrating/not-supported.md index 99908a1..975f9cb 100644 --- a/src/content/migrating/not-supported.md +++ b/src/content/migrating/not-supported.md @@ -13,33 +13,28 @@ This list is taken from the parity table that is kept with the slide.ng source, - Comark or MDC syntax (`comark: true`, `mdc: true`). The generator warns, and the syntax stays text. - `:emoji:` shortcodes. Type the emoji itself. - `v-pre`. Use Angular's `ngNonBindable`, or write `{{` for a literal `{{`. -- `@apply` and UnoCSS's directive transformer. The generator warns. -- Slidev's sync mode menu (send only, receive only, off). Windows and devices always follow the presenter. -- Slide hooks `onSlideEnter`, `onSlideLeave` and `useIsSlideActive`. -- Custom transitions given as an object, `clickAnimation`, `preloadImages` and slide `preload`. -- `selectable` and `notesAutoRuby`. -- `dev --base`, `dev --tunnel`, `dev --inspect` and `build --router-mode`. -- `export` with several entries, and `export --format pptx-editable`. +- `selectable`. +- `dev --base`, `dev --tunnel` and `dev --inspect`. +- `export --format pptx-editable`. - A Prettier plugin, a converter from Vue syntax, `overviewSnapshots` and the browser exporter page. These are left out on purpose. - A released VS Code extension. A first version is in the slide-ng/vscode-extension repository; it is not released and was not run inside VS Code. - Theme and addon galleries, and community themes. -- `memory` router mode and `setup/routes.ts`. - `setup/vite.config.ts` and `setup/vue.ts`, which are about Vite and Vue. - Monaco type loading (`monacoTypesSource`), markdown-it plugins in transformers, and a run context for code runners. -- The `~icon~` title syntax and automatic file icons of code groups. - `mhchem` in KaTeX. ## Only in part - `slide-ng-motion`: CSS transitions between states, no spring physics or presets. - Recording: no separate camera file, no mp4 or mkv, no cloud upload. -- Links to slides: in speaker notes a link to a slide is a plain address, so a click in the presenter view loads the page again. In a PDF made with `--per-slide`, or with a `--range` that leaves the slide out, a link to another slide is no link. -- The interface language: Turkish is the only built-in translation, browser error messages stay English, and in a right-to-left deck the arrow keys, swipes and the drawing toolbar are not mirrored. See [Interface language](../features/interface-language.md). +- Links to slides: in a PDF made with `--per-slide`, or with a `--range` that leaves the slide out, a link to another slide is no link. A link to a slide in the notes moves the presenter page only; in `/notes` it opens the address. +- Markdown links: only a slide number or a `routeAlias` becomes a link inside the deck, and only `http` and `https` links open a new tab. See [What differs from Slidev](./from-slidev.md#syntax-differences). +- The interface language: Turkish is the only built-in translation, and browser error messages and the generator's warnings stay English. See [Interface language](../features/interface-language.md). +- `routerMode: memory`: only the print pages and a slide link's `#/<number>` are read from the address, so the presenter and the other pages of the app cannot be opened by address. +- `setup/routes.ts`: a page of your own is not behind the `--remote` password, and the build cannot warn when its path is also a `routeAlias`. - `fonts`: loaded from the provider like Slidev's, plus `selfHost`, which is tested against a fake provider only. -- Magic Move: `magicMoveDuration` and `magicMoveCopy` are read, the other `shiki.magicMove` options are not. - `colorSchema`: `auto`, `light` and `dark` work, `all` does not. - Touch: swiping works, but pinch zoom and touch tuning for drawing and `slide-ng-drag` were not tried on a real device. -- Keyboard and screen reader use of the menus: Escape does not always give focus back, the overview moves a highlight instead of the focus, and the context menu has no arrow keys. - `addons`: resolution and merge order are tested, but no deck was built with an addon end to end. - Raw HTML: HTML and `<style>` work, `<script setup>` has no equivalent. diff --git a/src/content/migrating/upgrading-to-2.md b/src/content/migrating/upgrading-to-2.md new file mode 100644 index 0000000..7f2ff81 --- /dev/null +++ b/src/content/migrating/upgrading-to-2.md @@ -0,0 +1,80 @@ +--- +title: Upgrading from 1.x to 2.0 +description: How to move a deck from slide.ng 1.x to 2.0, and the changes that can alter a deck that 1.x showed correctly. +--- + +# Upgrading from 1.x to 2.0 + +slide.ng 2.0 needs the same Node (22.22.3 or newer) and the same Angular (22.2) as 1.x. Update the package in the deck's folder: + +```sh +npm install -D @slide-ng/core@^2.0.0 +npx slide-ng dev +``` + +Then read the warnings in the terminal and step through the deck once. Most decks need no change. The list below is what can alter a deck that 1.x showed correctly, and how to keep the old behaviour. + +## Changes that can alter a deck + +### Addresses and links + +- `routeAlias: overview`, `entry` or `notes-edit` stops `build` and `dev`: they are pages of the app now. Rename the alias. A markdown link `[x](/overview)` opens the app's [overview page](../features/overview-pages.md) instead of that slide, with a full page load. +- A `routeAlias` that is a number, that is empty, that has `/`, `.`, `?`, `#` or `\`, or that is on two slides stops the build, naming the slides. +- Markdown links to `http` and `https` addresses open in a new tab. To keep one in the same tab, write it as HTML: `<a href="https://example.com">x</a>` is left as written. +- An `<a href="/3">` written as HTML with attributes other than `class`, `id` or `style`, such as `target`, is left as written, with a warning. In a `routerMode: hash` deck it loads `/3` from the server. Write a markdown link, `[x](3)`, or `<slide-ng-link to="3">`. A plain `<a href="/3">` goes to the slide, as in 1.x. +- The address leaves out `?clicks=0`: slide 2 at its first click is `/2`. An address with `?clicks=0` still opens. + +See [Links](../guide/syntax.md#links) and [Slide addresses](../features/routing.md). + +### Language + +- `lang` now also sets the locale of the `date`, `number` and `currency` pipes: `lang: en-GB` writes "30 September 2026", and `pt_br` writes `1.234.567,891`. Give a pipe its own locale argument to keep the old format, such as `{{ day | date: 'mediumDate' : '' : 'en-US' }}`. +- `<html lang>` is written in the usual spelling: `lang: pt_br` gives `pt-BR`. +- `lang` picks the language of the interface too. See [Interface language](../features/interface-language.md). + +### Styling + +- Attributify reads plain HTML attributes as utilities: `<table border="1">` gets a border, `<span font="bold">` is bold, `<div m="4">` gets a margin. `unocss: { attributify: false }` in the headmatter turns it off. See [UnoCSS](../features/unocss.md). +- `themeConfig` is applied as CSS variables, `--slidev-theme-<key>`, so a `themeConfig.primary` recolours `text-primary`, the progress bar and the controls. See [Theme settings](../customize/themes.md#theme-settings). +- The speaker notes get the typography preset's `prose` styles: body colour and spacing. + +### Files next to the deck + +- An `index.html` next to `slides.md` is merged into the page: its `<title>`, `<meta>` and scripts now count, and what its `<body>` holds is added to the page after the slides, out of sight but read by screen readers. Rename it if it was not meant for the deck. See [Your own index.html](../features/seo-meta.md#your-own-index-html). + +### Clicks and code + +- `slide-ng-click.hide` and `slide-ng-after.hide` hide the element at its click instead of being ignored. That click counts, so the slide has one more click, and `export --with-clicks` one more page. +- `slide-ng-click-hide="3"` hides at click 3 instead of at the next click, and `slide-ng-click="2" slide-ng-click-hide="3"` shows at click 2 and hides at click 3. +- A click range written as text, `slide-ng-click="[2, 4]"`, is a range. In 1.x it was ignored and the element was always visible. +- `{monaco-run}` code runs in strict mode: assigning a name that was never declared stops with a `ReferenceError`. Declare it, or set `monacoRunUseStrict: false`. + +See [Clicks and transitions](../guide/animations.md) and [Running code](../features/monaco-run.md). + +### Loading and the screen + +- Pictures of the next slides are loaded ahead. `preloadImages: false` turns it off. See [Loading pictures ahead](../features/preload-images.md). +- The screen wake lock is on by default. `wakeLock: false` turns it off; a choice already stored in the browser is kept, so a viewer who used 1.x may have to turn it on once in the settings menu. + +### Builds and the browser + +- Several decks on one origin, such as the project sites of one GitHub Pages user, no longer share their slides, drawings and stored settings: they belong to the deck's base path. A deck at `/` keeps its old keys, but settings that a deck under a sub-path stored with 1.x are not read. +- A static build no longer contains the side editor, the dev server's sync and drag saving, or the `/notes-edit` page. They only ever worked with the dev server. +- In a PDF made by `export` or `build --download`, links to other addresses of the deck's own site, such as `/file.pdf`, are text without a link. + +## What is new + +The full list is in the [release notes](https://github.com/slide-ng/slide.ng/blob/main/CHANGELOG.md). The new pages of this site: + +- [Interface language](../features/interface-language.md), with right-to-left decks and one deck in several languages +- [Click animations](../features/click-animations.md) and transitions of your own, see [Clicks and transitions](../guide/animations.md#your-own-transition) +- [Progress bar](../features/progress-bar.md) +- [Overview and notes pages](../features/overview-pages.md), the sync mode menu and the click preview, see [Presenter mode](../guide/presenter-mode.md) +- [UnoCSS](../features/unocss.md): attributify, variant groups, `prose` and directives +- [Loading pictures ahead](../features/preload-images.md) +- [Accessibility](../guide/accessibility.md) +- Memory routing and `build --router-mode`, see [Slide addresses](../features/routing.md#memory-mode) +- Several decks in one `build` or `export`, see [Hosting](../guide/hosting.md#several-decks) +- Slide hooks and the global context, see [Layouts and components](../customize/layouts-components.md#slide-hooks) and [Angular in markdown](../guide/angular-templates.md#the-global-context) +- `setup/routes.ts` and `setup/mermaid-renderer.ts`, see [Setup hooks](../customize/setup-hooks.md) +- MCP over HTTP from the dev server, see [MCP server](../features/mcp.md#over-http-from-the-dev-server) diff --git a/src/content/welcome.md b/src/content/welcome.md index 9e7b1dd..a177be9 100644 --- a/src/content/welcome.md +++ b/src/content/welcome.md @@ -50,6 +50,6 @@ Every page that shows a deck embeds a real build of it. You can also open them d <ngmd-callout type="warning" title="Status"> -slide.ng is early. Version 0.1.0 is on npm as `@slide-ng/core`, and some Slidev features are missing. The [list of what is not supported](./migrating/not-supported.md) is kept honest. +These pages describe slide.ng 2.0, which is on npm as `@slide-ng/core`. A deck made with 1.x: read [Upgrading from 1.x to 2.0](./migrating/upgrading-to-2.md). Some Slidev features are missing, and the [list of what is not supported](./migrating/not-supported.md) is kept honest. </ngmd-callout> diff --git a/src/ngmd.config.ts b/src/ngmd.config.ts index 1e75a61..7bfe8cf 100644 --- a/src/ngmd.config.ts +++ b/src/ngmd.config.ts @@ -209,14 +209,15 @@ const config: NgmdConfig = { {label: 'Syntax', href: '/guide/syntax'}, {label: 'Angular in markdown', href: '/guide/angular-templates'}, {label: 'Layouts', href: '/guide/layouts'}, - {label: 'Clicks and transitions', href: '/guide/animations'}, + {label: 'Clicks and transitions', href: '/guide/animations', status: 'updated'}, {label: 'Code', href: '/guide/code'}, {label: 'Diagrams and math', href: '/guide/diagrams-math'}, {label: 'Styling', href: '/guide/styling'}, - {label: 'Presenter mode', href: '/guide/presenter-mode'}, + {label: 'Presenter mode', href: '/guide/presenter-mode', status: 'updated'}, {label: 'Drawing and recording', href: '/guide/drawing-recording'}, {label: 'Export', href: '/guide/export'}, - {label: 'Hosting', href: '/guide/hosting'}, + {label: 'Hosting', href: '/guide/hosting', status: 'updated'}, + {label: 'Accessibility', href: '/guide/accessibility', status: 'new'}, {label: 'Presenting offline', href: '/guide/offline'}, {label: 'Agents and the skill', href: '/guide/agents'}, ], @@ -230,10 +231,11 @@ const config: NgmdConfig = { {label: 'Slots', href: '/features/slots'}, {label: 'Scoped styles', href: '/features/scoped-styles'}, {label: 'Speaker notes', href: '/features/speaker-notes'}, - {label: 'Slide addresses', href: '/features/routing'}, + {label: 'Slide addresses', href: '/features/routing', status: 'updated'}, {label: 'Table of contents', href: '/features/table-of-contents'}, {label: 'Icons', href: '/features/icons'}, {label: 'Markdown extras', href: '/features/markdown-extras'}, + {label: 'UnoCSS', href: '/features/unocss', status: 'new'}, {label: 'Canvas size', href: '/features/canvas-size'}, {label: 'Zoom', href: '/features/zoom'}, {label: 'Transform', href: '/features/transform'}, @@ -241,6 +243,8 @@ const config: NgmdConfig = { {label: 'Global layers', href: '/features/global-layers'}, {label: 'Draggable elements', href: '/features/draggable'}, {label: 'Marks', href: '/features/marks'}, + {label: 'Click animations', href: '/features/click-animations', status: 'new'}, + {label: 'Progress bar', href: '/features/progress-bar', status: 'new'}, {label: 'Motion', href: '/features/motion'}, ], }, @@ -265,13 +269,15 @@ const config: NgmdConfig = { { label: 'Features: presenting', items: [ + {label: 'Overview and notes pages', href: '/features/overview-pages', status: 'new'}, {label: 'Timer', href: '/features/timer'}, {label: 'Remote access', href: '/features/remote-access'}, {label: 'Side editor', href: '/features/side-editor'}, {label: 'Drawing', href: '/features/drawing'}, {label: 'Recording', href: '/features/recording'}, {label: 'Context menu', href: '/features/context-menu'}, - {label: 'Interface language', href: '/features/interface-language'}, + {label: 'Interface language', href: '/features/interface-language', status: 'new'}, + {label: 'Loading pictures ahead', href: '/features/preload-images', status: 'new'}, ], }, { @@ -282,7 +288,7 @@ const config: NgmdConfig = { {label: 'Page head and SEO', href: '/features/seo-meta'}, {label: 'Fonts', href: '/features/fonts'}, {label: 'Offline and PWA', href: '/features/pwa'}, - {label: 'MCP server', href: '/features/mcp'}, + {label: 'MCP server', href: '/features/mcp', status: 'updated'}, {label: 'Formatting', href: '/features/format'}, ], }, @@ -317,9 +323,10 @@ const config: NgmdConfig = { ], }, { - label: 'Migrating from Slidev', + label: 'Migrating', items: [ - {label: 'What differs', href: '/migrating/from-slidev'}, + {label: 'Upgrading from 1.x', href: '/migrating/upgrading-to-2', status: 'new'}, + {label: 'What differs from Slidev', href: '/migrating/from-slidev'}, {label: 'Not supported', href: '/migrating/not-supported'}, ], }, From 92602d4b1751c72ae64864880345310ffd08750b Mon Sep 17 00:00:00 2001 From: erkamyaman <erkamyaman35@gmail.com> Date: Thu, 22 Oct 2026 23:30:59 +0000 Subject: [PATCH 15/19] docs: say what mirrors in a right-to-left deck --- src/content/features/interface-language.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/features/interface-language.md b/src/content/features/interface-language.md index eea75da..ebfba46 100644 --- a/src/content/features/interface-language.md +++ b/src/content/features/interface-language.md @@ -50,7 +50,7 @@ The "go to" box (`g`) compares titles by the rules of the deck's language and wi ## Right to left -`ar`, `he`, `fa` and `ur` set `dir="rtl"` on the page, unless `htmlAttrs.dir` says otherwise. The bar, the menus, the go-to box and the presenter are mirrored. +`ar`, `he`, `fa` and `ur` set `dir="rtl"` on the page, unless `htmlAttrs.dir` says otherwise. The bar, the menus, the go-to box and the presenter are mirrored, and so are a blockquote's line and the progress bar's minutes. Mermaid drawings stay left to right, as Mermaid lays them out; their Arabic or Hebrew labels still read right to left. - The keys stay physical, as in Slidev: right and space go to the next click, left to the one before. A selected `slide-ng-drag` element moves the way the arrow points. - In the quick overview the arrow keys follow the mirrored grid: left goes to the next card, which is on the left. In the sync menu ArrowLeft goes to the next mode. From 10535eb09e7b454277b63c56b30c23cff4bcd5e8 Mon Sep 17 00:00:00 2001 From: erkamyaman <erkamyaman35@gmail.com> Date: Thu, 22 Oct 2026 23:34:08 +0000 Subject: [PATCH 16/19] docs: ask themes for logical sides --- src/content/customize/writing-a-theme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/customize/writing-a-theme.md b/src/content/customize/writing-a-theme.md index d68b3af..0b9a417 100644 --- a/src/content/customize/writing-a-theme.md +++ b/src/content/customize/writing-a-theme.md @@ -71,6 +71,8 @@ UnoCSS's directives work in this CSS, as in Slidev: `@apply p-4 text-red-500;`, Dark mode is the class `dark` on `<html>`: write `html.dark .my-quote { ... }` for the dark palette. The core styles dim the paragraph right after a heading (`h1 + p`, a subtitle). Set its `opacity` in your CSS if your theme should not. +Write sides with logical properties (`border-inline-start`, `padding-inline-start`, `ms-4`, `ps-4`) rather than `left` and `right`, so the theme mirrors in a right-to-left deck (`lang: ar`, `he`, `fa` or `ur`). The core blockquote line is a `border-inline-start`: a theme that sets `border-left` on a blockquote shows both lines in such a deck. + ## 5. Default settings `theme.json` can set headmatter defaults and describe layouts: From a096453d28d51e44cb53cd1e97e344e4ef152beb Mon Sep 17 00:00:00 2001 From: erkamyaman <erkamyaman35@gmail.com> Date: Fri, 23 Oct 2026 11:18:18 +0000 Subject: [PATCH 17/19] docs: say that dev moves to the next free port --- src/content/built-in/cli.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/built-in/cli.md b/src/content/built-in/cli.md index 366f3ed..32b1823 100644 --- a/src/content/built-in/cli.md +++ b/src/content/built-in/cli.md @@ -21,7 +21,7 @@ Starts the dev server. This is the default command. | Flag | Meaning | | --- | --- | -| `--port`, `-p` | Port. Default 4230. | +| `--port`, `-p` | Port. Default 4230, or the next free one when 4230 is taken. A port given here that is taken stops the server, with a free one to try. | | `--open`, `-o` | Open the deck in a browser. | | `--remote[=password]` | Listen on every address so other devices can open the deck and follow the presenter. Always with a password: the one given, `SLIDE_NG_PASSWORD`, a prompt on a terminal, or a random one that is printed. See [Remote access](../features/remote-access.md). | | `--bind <address>` | The address to listen on with `--remote`. Default `0.0.0.0`. | @@ -42,7 +42,7 @@ In a terminal the dev server reads keys, as Slidev's does, and prints a line tha | `q` | Quit. Ctrl+C works too. | | `c` | With `--remote`, print a QR code of the private address for each network address. Without it, say how to start with it. | -- One deck runs one dev server. A second `slide-ng dev` on the same deck stops before it changes anything, whatever its `--port`, and names the running one. A port in use stops it too. Run two decks side by side from their own folders, each with its own `--port`. +- One deck runs one dev server. A second `slide-ng dev` on the same deck stops before it changes anything, whatever its `--port`, and names the running one. When the default port 4230 is taken by something else, the server takes the next free one and says so (`port 4230 is in use, so the dev server uses 4231`). A `--port` that is taken stops it, with a free port to try. Run two decks side by side from their own folders: the second one moves to the next port by itself. - When the first Angular build fails, the port shows a page with the error until the build works, and an open tab then loads the slides by itself. - The dev server keeps watching after an editor saves by renaming a new file over the old one (vim, JetBrains, `git checkout`). - It also serves MCP over HTTP at `/__mcp`, see [MCP server](../features/mcp.md#over-http-from-the-dev-server). From 099aa96632ad0aa6089ca3c99610593b8f74ba5e Mon Sep 17 00:00:00 2001 From: erkamyaman <erkamyaman35@gmail.com> Date: Fri, 23 Oct 2026 11:33:35 +0000 Subject: [PATCH 18/19] docs: say what the port shows during the first build --- src/content/built-in/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/built-in/cli.md b/src/content/built-in/cli.md index 32b1823..c0f4dd5 100644 --- a/src/content/built-in/cli.md +++ b/src/content/built-in/cli.md @@ -43,7 +43,7 @@ In a terminal the dev server reads keys, as Slidev's does, and prints a line tha | `c` | With `--remote`, print a QR code of the private address for each network address. Without it, say how to start with it. | - One deck runs one dev server. A second `slide-ng dev` on the same deck stops before it changes anything, whatever its `--port`, and names the running one. When the default port 4230 is taken by something else, the server takes the next free one and says so (`port 4230 is in use, so the dev server uses 4231`). A `--port` that is taken stops it, with a free port to try. Run two decks side by side from their own folders: the second one moves to the next port by itself. -- When the first Angular build fails, the port shows a page with the error until the build works, and an open tab then loads the slides by itself. +- During the first build the port shows a "Building the slides" page, so the port is taken from the start. When that build fails, the page shows the error until the build works, and an open tab then loads the slides by itself. - The dev server keeps watching after an editor saves by renaming a new file over the old one (vim, JetBrains, `git checkout`). - It also serves MCP over HTTP at `/__mcp`, see [MCP server](../features/mcp.md#over-http-from-the-dev-server). From c8a214521bad93f7c052be5b70ffc633b791cabb Mon Sep 17 00:00:00 2001 From: erkamyaman <erkamyaman35@gmail.com> Date: Fri, 23 Oct 2026 21:10:58 +0000 Subject: [PATCH 19/19] docs: say that a stuck monaco-run holds up nothing else --- src/content/features/monaco-run.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/features/monaco-run.md b/src/content/features/monaco-run.md index b75322b..fa72088 100644 --- a/src/content/features/monaco-run.md +++ b/src/content/features/monaco-run.md @@ -15,7 +15,7 @@ console.log('runs on a click and the result appears') - `autorun` is `true`, `false` or `'once'`. - `showOutputAt:'+1'` shows the output after a click. -- The code runs in a sandboxed frame with no access to the slides, and stops after 5 seconds. Pressing run again, or leaving the slide, stops a run that is still going at once, such as an endless loop. +- The code runs in a worker of a sandboxed frame, with no access to the slides, and stops after 5 seconds. A run stuck in an endless loop holds up nothing else, and pressing run again or leaving the slide stops it at once. `console` works; the worker has no `document`, `parent` or `alert`. - The code runs in strict mode, as in Slidev: `total = 1` without `let` or `const` stops with "ReferenceError: total is not defined". `monacoRunUseStrict: false` in the headmatter runs it without `"use strict"`. - The output takes its click in document order: an output at `showOutputAt:'+1'` followed by a `slide-ng-click` shows first. - TypeScript is turned into JavaScript for you.