打包好的livecode,版本v-46

This commit is contained in:
yangxin
2025-06-11 22:23:49 +08:00
commit 1214258379
1323 changed files with 133464 additions and 0 deletions

78
docs/sdk/headless.html.md Normal file
View File

@@ -0,0 +1,78 @@
# Headless Mode
import LiveCodes from '../../src/components/LiveCodes.tsx';
The LiveCodes [SDK](../sdk/index.html.md) can be used to create playgrounds in headless mode. In this mode, no visible output is displayed in the embedding web page. However, all [SDK methods](../sdk/js-ts.html.md)#sdk-methods) are accessible (e.g. for [updating code](./js-ts.html.md)#setconfig), [getting compiled code](./js-ts.html.md)#getcode), console output, [result HTML](./js-ts.html.md)#getcode), [shareable URLs](./js-ts.html.md)#getshareurl), [formatting code](./js-ts.html.md)#format), [running tests](./js-ts.html.md)#runtests), etc).
This provides the power of leveraging the wide range of features and language support offered by LiveCodes, while retaining full control over the UI.
## Usage
To create a headless playground, set the [embed option](./js-ts.html.md)#embed-options) [`headless`](../sdk/js-ts.html.md)#headless) to `true`.
Please note that in headless mode, the first parameter (`container`) of the function [`createPlayground`](../sdk/js-ts.html.md)#createplayground) is optional and can be omitted.
<div style={{ clear: 'both' }}></div>
Example:
```js
import { createPlayground } from 'livecodes';
createPlayground({
view: 'headless',
config: {
markup: {
language: 'markdown',
content: '# Hello World!',
},
},
}).then(async (playground) => {
const code = await playground.getCode();
console.log(code.markup.compiled); // "<h1>Hello World!</h1>"
console.log(code.result); // (result page HTML)
});
```
## Examples
The following examples show how to use the headless mode to make a Markdown editor, an MDX editor and a Python interpreter.
:::tip
You may want to view the following playgrounds in full screen (using the full screen button in the top right of each playground).
:::
### Markdown Editor
In this demo, code changes are watched using the SDK method [`watch('code', callback)`](./js-ts.html.md)#watch). The callback function accepts an argument which is an object with the properties `code` and `config` (see [`getCode`](./js-ts.html.md)#getcode) and [`getConfig`](./js-ts.html.md)#getconfig)). The compiled code is obtained as `code.markup.compiled`.
<!-- prettier-ignore -->
export const mdDemo = { markup: { language: 'html', content: `<textarea id="editor" style="display: none;"></textarea>\n<div id="output">Loading...</div>\n\n\x3Cscript type="module">\n import { createPlayground } from "https://cdn.jsdelivr.net/npm/livecodes@0.2.0";\n import debounce from "https://jspm.dev/debounce";\n\n const initialCode = "# Hello, LiveCodes!\\n\\n";\n\n // the code editor\n const editor = CodeMirror.fromTextArea(document.getElementById("editor"), {\n lineNumbers: true,\n mode: "markdown",\n });\n editor.setSize("100%", 200);\n editor.setValue(initialCode);\n\n // the playground\n const options = {\n view: "headless",\n };\n\n const livecodes = await createPlayground(options);\n await livecodes.load();\n\n const compile = async () => {\n await livecodes.setConfig({\n autoupdate: false,\n markup: {\n language: "markdown",\n content: editor.doc.getValue(),\n },\n });\n };\n\n // watch for changes\n editor.on("change", debounce(compile, 1000));\n livecodes.watch("code", ({ code, config }) => {\n createSandbox(document.querySelector("#output"), code.markup.compiled);\n });\n\n await compile();\n\n // create a sandbox for safe execution of compiled code\n function createSandbox (container, html) {\n const iframe = document.createElement("iframe");\n iframe.src = "https://livecodes-sandbox.pages.dev/v7/";\n iframe.sandbox =\n "allow-same-origin allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-presentation allow-scripts";\n iframe.onload = () => {\n iframe.contentWindow.postMessage({ html }, "*");\n };\n container.innerHTML = "";\n container.appendChild(iframe);\n return iframe;\n };\n\x3C/script>\n\n<link rel="stylesheet" href="https://unpkg.com/codemirror@5.65.15/lib/codemirror.css" />\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/lib/codemirror.js">\x3C/script>\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/mode/markdown/markdown.js">\x3C/script>\n\n<style>\n * {\n margin: 0;\n padding: 0;\n }\n body {\n display: flex;\n flex-direction: column;\n height: 100vh;\n overflow: hidden;\n }\n #output {\n flex: 1;\n }\n #output iframe {\n width: 100%;\n height: 100%;\n border: none;\n }\n</style>\n` }}
<LiveCodes config={mdDemo} height="80vh"></LiveCodes>
### MDX Editor
In this demo, code changes are watched using the SDK method [`watch('code', callback)`](./js-ts.html.md)#watch). The callback function accepts an argument which is an object with the properties `code` and `config` (see [`getCode`](./js-ts.html.md)#getcode) and [`getConfig`](./js-ts.html.md)#getconfig)). The result HTML is obtained as `code.result`.
:::tip
If you do not want to run the result page in the headless playground and only want to get the generated result HTML, you can set the configuration option [`autoupdate](../configuration/configuration-object.html.md)#autoupdate) to `false`.
:::
<!-- prettier-ignore -->
export const mdxDemo = { markup: { language: 'html', content: `<textarea id="editor" style="display: none;"></textarea>\n<div id="output">Loading...</div>\n\n\x3Cscript type="module">\n import { createPlayground } from "https://cdn.jsdelivr.net/npm/livecodes@0.2.0";\n import debounce from "https://jspm.dev/debounce";\n\n const initialCode = \`import { useState, useEffect } from 'react';\n\nexport const Hello = ({name}) => {\n const [count, setCount] = useState(0);\n return (\n <>\n <h1>Hello, {name}!</h1>\n <p>You clicked {count} times.</p>\n <button onClick={() => setCount(count + 1)}>Click me</button>\n </>\n );\n};\n\n<Hello name="LiveCodes"></Hello>\n\n## MDX in short\n\n- ❤️ Powerful\n- 💻 Everything is a component\n- 🔧 Customizable\n- 📚 Markdown-based\n- 🔥 Blazingly blazing fast\n\n> from [mdxjs.com](https://mdxjs.com/)\n\`;\n\n // the code editor\n const editor = CodeMirror.fromTextArea(document.getElementById("editor"), {\n lineNumbers: true,\n mode: "markdown",\n });\n editor.setSize("100%", 200);\n editor.setValue(initialCode);\n\n // the playground\n const options = {\n view: "headless",\n config: { autoupdate: false },\n };\n\n const livecodes = await createPlayground(options);\n await livecodes.load();\n\n const compile = async () => {\n await livecodes.setConfig({\n autoupdate: false,\n markup: {\n language: "mdx",\n content: editor.doc.getValue(),\n },\n });\n };\n\n // watch for changes\n editor.on("change", debounce(compile, 1000));\n livecodes.watch("code", ({ code, config }) => {\n createSandbox(document.querySelector("#output"), code.result);\n });\n\n await compile();\n\n // create a sandbox for safe execution of compiled code\n function createSandbox (container, html) {\n const iframe = document.createElement("iframe");\n iframe.src = "https://livecodes-sandbox.pages.dev/v7/";\n iframe.sandbox =\n "allow-same-origin allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-presentation allow-scripts";\n iframe.onload = () => {\n iframe.contentWindow.postMessage({ html }, "*");\n };\n container.innerHTML = "";\n container.appendChild(iframe);\n return iframe;\n };\n\x3C/script>\n\n<link rel="stylesheet" href="https://unpkg.com/codemirror@5.65.15/lib/codemirror.css" />\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/lib/codemirror.js">\x3C/script>\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/mode/markdown/markdown.js">\x3C/script>\n\n<style>\n * {\n margin: 0;\n padding: 0;\n }\n body {\n display: flex;\n flex-direction: column;\n height: 100vh;\n overflow: hidden;\n }\n #output {\n flex: 1;\n }\n #output iframe {\n width: 100%;\n height: 100%;\n border: none;\n }\n</style>\n` }}
<LiveCodes config={mdxDemo} height="80vh"></LiveCodes>
### Python Interpreter
In this demo, console output is obtained using the SDK method [`watch('code', callback)`](./js-ts.html.md)#watch). The callback function accepts an argument which is an object with the properties `method` and `args` indicating the console method and the arguments that were passed (as an array).
<!-- prettier-ignore -->
export const pyDemo = { markup: { language: 'html', content: `<textarea id="editor" style="display: none"></textarea>\n<div id="output">Loading...</div>\n\n\x3Cscript type="module">\n import { createPlayground } from "https://cdn.jsdelivr.net/npm/livecodes@0.2.0";\n import debounce from "https://jspm.dev/debounce";\n\n const initialCode = \`def say_hello(name):\n return f"Hello, {name}!"\n\nprint(say_hello("LiveCodes"))\n\`;\n\n // the code editor\n const editor = CodeMirror.fromTextArea(document.getElementById("editor"), {\n lineNumbers: true,\n mode: "python",\n });\n editor.setSize("100%", 250);\n editor.setValue(initialCode);\n\n // the playground\n const options = {\n view: "headless",\n };\n\n const livecodes = await createPlayground(options);\n await livecodes.load();\n\n const run = async () => {\n await livecodes.setConfig({\n autoupdate: true,\n script: {\n language: "python",\n content: editor.doc.getValue(),\n },\n });\n };\n\n // watch for changes\n editor.on("change", debounce(run, 1000));\n livecodes.watch("console", ({ method, args }) => {\n const output = document.querySelector("#output");\n output.innerHTML = args.join("\\n");\n if (method === "error") {\n output.style.color = "red";\n } else {\n output.style.color = "unset";\n }\n });\n\n await run();\n\x3C/script>\n\n<link rel="stylesheet" href="https://unpkg.com/codemirror@5.65.15/lib/codemirror.css" />\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/lib/codemirror.js">\x3C/script>\n\x3Cscript src="https://unpkg.com/codemirror@5.65.15/mode/python/python.js">\x3C/script>\n\n<style>\n * {\n margin: 0;\n padding: 0;\n }\n body {\n display: flex;\n flex-direction: column;\n height: 100vh;\n overflow: hidden;\n }\n #output {\n flex: 1;\n margin: 1em;\n white-space: pre;\n font-family: monospace;\n }\n #output iframe {\n width: 100%;\n height: 100%;\n border: none;\n }\n</style>\n` }}
<LiveCodes config={pyDemo} height="80vh"></LiveCodes>

File diff suppressed because one or more lines are too long

58
docs/sdk/index.html Normal file

File diff suppressed because one or more lines are too long

117
docs/sdk/index.html.md Normal file
View File

@@ -0,0 +1,117 @@
# LiveCodes SDK
import LiveCodes from '../../src/components/LiveCodes.tsx';
The Software Development Kit (SDK) provides an easy, yet powerful, interface to embed and communicate with LiveCodes playgrounds.
The SDK is provided as a light-weight ([less than 5kb gzipped](https://bundlephobia.com/package/livecodes)), zero-dependencies [npm package](#npm-package), that is also available from [CDNs](#cdn). It can be used to create playgrounds with a wide variety of [configurations](../configuration/configuration-object.html.md) and [embed options](js-ts.html.md)#embed-options). In addition, [SDK methods](js-ts.html.md)#sdk-methods) allow programmatic communication and control of the playgrounds during runtime.
The [JavaScript SDK](js-ts.html.md) is framework/library agnostic. However, wrapper components are also provided for popular libraries (currently [React](react.html.md) and [Vue](vue.html.md)). The SDK can be used in [Svelte](svelte.html.md) directly without wrappers. [TypeScript support](js-ts.html.md)#typescript-types) provides type-safety and a great developer experience.
## SDK Demo
This is an example of an editable embedded playground using the SDK.
<LiveCodes
config={{
markup: { language: 'markdown', content: '# Hello World!' },
script: { language: 'javascript', content: 'console.log("Hello, from JS!");' },
tools: { active: 'console', status: 'open' },
}}
></LiveCodes>
## Installation
### NPM Package
This is a single npm package for the SDK which supports JavaScript/TypeScript, React, Vue and Svelte.
Install the library from npm:
```bash npm2yarn
npm install livecodes
```
then it can be used like that:
```js title="index.js"
import { createPlayground } from 'livecodes';
createPlayground('#container', {
// embed options
});
```
### CDN
Alternatively, it can just be loaded from a CDN.
ESM:
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import CodeBlock from '@theme/CodeBlock';
export const ESMCode = () => {
const { siteConfig } = useDocusaurusContext();
return (
<CodeBlock title="index.html" language="html">
{`<div id="container"></div>\n<script type="module">
${' '}import { createPlayground } from 'https://cdn.jsdelivr.net/npm/livecodes@${siteConfig.customFields.sdkVersion}';\n
${' '.repeat(2)}createPlayground('#container', {
${' '.repeat(4)}// embed options
${' '.repeat(2)}});
</script>`}
</CodeBlock>
);
};
<ESMCode />
UMD:
export const UMDCode = () => {
const { siteConfig } = useDocusaurusContext();
return (
<CodeBlock title="index.html" language="html">
{`<div id="container"></div>\n<script src="https://cdn.jsdelivr.net/npm/livecodes@${siteConfig.customFields.sdkVersion}/livecodes.umd.js"></script>\n<script>\n // the UMD version provides the global object \`livecodes\`
${' '.repeat(2)}livecodes.createPlayground('#container', {
${' '.repeat(4)}// embed options
${' '.repeat(2)}});
</script>
`}
</CodeBlock>
);
};
<UMDCode />
:::info
In the full [standalone app](../getting-started.html.md)#standalone-app), the JavaScript SDK is accessible via the global variable `livecodes`, which can be interacted with in the browser console.
:::
## Usage
The SDK is currently provided in the following variations:
- [JavaScript/TypeScript](./js-ts.html.md)
- [React](./react.html.md)
- [Vue](./vue.html.md)
- [Svelte](./svelte.html.md)
## Headless Mode
The SDK also has a [headless mode](./headless.html.md). In this mode, no visible output is displayed in the embedding web page. However, all [SDK methods](../sdk/js-ts.html.md)#sdk-methods) are accessible. This provides the power of leveraging the wide range of features and language support offered by LiveCodes, while retaining full control over the UI.
## SDK Playground!
A demo page that shows the usage of the SDK can be [found here](https://live-codes.github.io/livecodes-examples/sdk-demo.html) ([source](https://github.com/live-codes/livecodes-examples/blob/gh-pages/sdk-demo.html)).
Or edit the SDK playground in LiveCodes. How meta! :)
<LiveCodes import="id/8k6vbxitvb9" config={{ view: 'result' }} height="80vh" showCode={false} />
P.S. You may want to use the "Full Screen" button!

601
docs/sdk/js-ts.html.md Normal file
View File

@@ -0,0 +1,601 @@
# JavaScript/<wbr />TypeScript SDK
import LiveCodes from '../../src/components/LiveCodes.tsx';
import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx';
This is the core SDK on which others ([React](react.html.md), [Vue](vue.html.md), and [Svelte](svelte.html.md) SDKs) are build on top. It is a light-weight ([less than 5kb gzipped](https://bundlephobia.com/package/livecodes)), zero-dependencies library that allows creating, embedding and communication with LiveCodes playgrounds. It also allows easily creating links to playgrounds.
## Installation
Please refer to the [SDK installation](./index.html.md)#installation) section.
:::info
In the full [standalone app](../getting-started.html.md)#standalone-app), the JavaScript SDK is accessible via the global variable `livecodes`, which can be interacted with in the browser console.
:::
## TypeScript Types
TypeScript types are [documented here](../api/globals.md) and can be imported from the library.
```ts
import type { EmbedOptions, Playground } from 'livecodes';
```
The following 2 functions are exported by the library:
## `createPlayground`
Type: [`(container: string | Element, options?: EmbedOptions) => Promise<Playground>`](../api/functions/createPlayground.md)
The library exports the function `createPlayground` which has 2 parameters:
- `container` (required): `HTMLElement` or a string representing a CSS selector. This is the container where the playground is rendered.
If not found, an error is thrown (except in [headless mode](./headless.html.md), in which this parameter is optional and can be omitted).
- `options` (optional): an object with embed options ([EmbedOptions](../api/interfaces/EmbedOptions.md)).
The `createPlayground` function returns a promise which resolves to an object that exposes the SDK methods ([Playground](../api/interfaces/Playground.md)).
```ts
import { createPlayground, type EmbedOptions } from 'livecodes';
const options: EmbedOptions = {
// appUrl: ...
// config: ...
// headless: ...
// import: ...
// loading: ...
// params: ...
// template: ...
};
createPlayground('#container', options).then((playground) => {
// the `playground` object exposes the SDK methods
// e.g. playground.run()
});
```
:::caution Throws
The `createPlayground` function throws an error (promise is rejected) in any of the following conditions:
- The first parameter ([`container`](#createplayground)) is not an element or not found (by CSS selector), except in [headless mode](./headless.html.md).
- The embed option [`appUrl`](#appurl) is supplied and is not a valid URL.
- The embed option [`config`](#config) is supplied and is not an object or a valid URL.
- Any of the [SDK methods](#sdk-methods) was called after calling the [`destroy`](#destroy) method.
:::
### Multiple Sources
When multiple sources are provided in the [embed options](#embed-options), each is converted to a [configuration object](../configuration/configuration-object.html.md) and the properties are merged.
In case there are conflicts between the properties of the configurations, they are overridden in the following order:
- [`template`](#template) (lowest precedence)
- [`import`](#import)
- [`config`](#config)
- [`params`](#params) (highest precedence)
## `getPlaygroundUrl`
Type: [`(options?: EmbedOptions) => string`](../api/functions/getPlaygroundUrl.md)
Gets the URL to playground (as a string) from the provided [options](#embed-options). This can be useful for providing links to run code in playgrounds.
Example:
```html
<pre><code class="language-markdown"># Hello World!</code></pre>
<a href="#" id="playground-link" target="_blank">Open in playground</a>
<script type="module">
// highlight-next-line
import { getPlaygroundUrl } from 'livecodes';
const config = {
markup: {
language: 'markdown',
content: '# Hello World!',
},
};
// highlight-next-line
const url = getPlaygroundUrl({ config });
document.querySelector('#playground-link').href = url;
</script>
```
export const getPlaygroundUrlDemo = {
html: `<pre><code\nclass="language-markdown"># Hello World!</code></pre>\n<a href="#" id="playground-link" target="_blank">Open in playground</a>\n<script type="module">\n import { getPlaygroundUrl } from 'livecodes';\n const config = {\n markup: {\n language: 'markdown',\n content: '# Hello World!',\n },\n };\n const url = getPlaygroundUrl({ config });\n document.querySelector('#playground-link').href = url;\n</script>`,
};
<RunInLiveCodes params={getPlaygroundUrlDemo} />
## Embed Options
Type: [`EmbedOptions`](../api/interfaces/EmbedOptions.md)
The [`createPlayground`](#createplayground) and [`getPlaygroundUrl`](#getplaygroundurl) functions accept an optional object that allows providing different options to the playground. This object can have the following optional properties:
### `appUrl`
Type: [`string`](../api/interfaces/EmbedOptions.md#appurl)
Default: `"https://livecodes.io/"`
Allows loading the playground from a custom URL (e.g. a [self-hosted app](../features/self-hosting.html.md) or a [permanent URL](../features/permanent-url.html.md)).
If supplied with an invalid URL, an error is thrown.
### `config`
Type: [`string | Partial<Config>`](../api/interfaces/EmbedOptions.md#config)
Default: `{}`
A [configuration object](../configuration/configuration-object.html.md) or a URL to a JSON file representing a configuration object to load.
If supplied and is not an object or a valid URL, an error is thrown.
### `headless`
Type: [`boolean`](../api/interfaces/EmbedOptions.md#headless)
Default: `false`
When set to `true`, the playground is loaded in [headless mode](./headless.html.md).
### `import`
Type: [`string`](../api/interfaces/EmbedOptions.md#import)
A resource to [import](../features/import.html.md) (from any of the supported [sources](../features/import.html.md)#sources)).
### `loading`
Type: [`"eager" | "lazy" | "click"`](../api/interfaces/EmbedOptions.md#loading)
Default: `"lazy"`
Sets how the playground loads:
- `"eager"`: The playground loads immediately.
- `"lazy"`: A playground embedded low down in the page will not load until the user scrolls so that it approaches the viewport.
- `"click"`: The playground does not load automatically. Instead, a "Click-to-load" screen is shown.
### `params`
Type: [`UrlQueryParams`](../api/interfaces/EmbedOptions.md#params)
An object that represents [URL Query parameters](../configuration/query-params.html.md), that can be used to configure the playground.
These 2 snippets produce similar output:
```js
import { createPlayground } from 'livecodes';
// use config
createPlayground('#container', {
config: {
markup: {
language: 'markdown',
content: '# Hello World!',
},
},
});
// use params
createPlayground('#container', { params: { md: '# Hello World!' } });
```
### `template`
Type: [`TemplateName`](../api/interfaces/EmbedOptions.md#template)
A [starter template](../features/templates.html.md) to load. Allowed valued can be found [here](../api/interfaces/EmbedOptions.md#template).
## SDK Methods
The [`createPlayground`](#createplayground) function returns a promise which resolves to an object ([`Playground`](../api/interfaces/Playground.md)) that exposes some useful SDK methods that can be used to interact with the playground. These methods include:
### `load`
Type: [`() => Promise<void>`](../api/interfaces/Playground.md#load)
When the embed option `loading` is set to `click`, the playground is not loaded automatically. Instead, a screen is shown with "Click to load" button.
Calling the SDK method `load()` allows loading the playground.
If the playground was not loaded, calling any other method will load the playground first before executing.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
await playground.load();
// playground loaded
});
```
### `run`
Type: [`() => Promise<void>`](../api/interfaces/Playground.md#run)
Runs the [result page](../features/result.html.md) (after any required compilation for code).
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
await playground.run();
// new result page is displayed
});
```
### `format`
Type: [`(allEditors?: boolean) => Promise<void>`](../api/interfaces/Playground.md#format)
[Formats the code](../features/code-format.html.md).
By default, the code in all editors (markup, style and script) is formatted.
If you wish to format only the active editor, pass the value `false` as an argument.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
await playground.format();
// code in editors is formatted
});
```
### `getShareUrl`
Type: [`(shortUrl?: boolean) => Promise<string>`](../api/interfaces/Playground.md#getshareurl)
Gets a [share url](../features/share.html.md) for the current project.
By default, the url has a long query string representing the compressed encoded config object. If the argument `shortUrl` was set to `true`, a short url is generated.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
const longUrl = await playground.getShareUrl();
const shortUrl = await playground.getShareUrl(true);
});
```
### `getConfig`
Type: [`(contentOnly?: boolean) => Promise<Config>`](../api/interfaces/Playground.md#getconfig)
Gets a config object representing the playground state. This can be used to restore state if passed as [embed option](#createplayground) property on creating playground, or can be manipulated and loaded in run-time using [`setConfig`](#setconfig) method.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
const config = await playground.getConfig();
});
```
### `setConfig`
Type: [`(config: Partial<Config>) => Promise<Config>`](../api/interfaces/Playground.md#setconfig)
Loads a new project using the passed configuration object.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
const config = {
markup: {
language: 'html',
content: 'Hello World!',
},
};
const newConfig = await playground.setConfig(config);
// new project loaded
});
```
### `getCode`
Type: [`() => Promise<Code>`](../api/interfaces/Playground.md#getcode)
Gets the playground code (including source code, source language and compiled code) for each editor (`markup`, `style`, `script`), in addition to result page HTML.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
const code = await playground.getCode();
// source code, language and compiled code for the script editor
const { content, language, compiled } = code.script;
// result page HTML
const result = code.result;
});
```
### `show`
Type: [`(panel: 'editor' | 'markup' | 'style' | 'script' | 'console' | 'compiled' | 'tests' | 'result' | 'toggle-result', options?: { full?: boolean; line?: number; column?: number; zoom?: 1 | 0.5 | 0.25 }) => Promise<void>`](../api/interfaces/Playground.md#show)
Shows the selected panel, which is either:
- Active Editor: `editor`
- Specific Editor: `markup`, `style` or `script`
- Tool: `console`, `compiled` or `tests`
- Result page: `result` or `toggle-result`
The second optional argument is an object:
- It may have the boolean property `full`, which If `true`, selected editor or result page will take the full vertical and horizontal space of the playground, while tools will take the full vertical and half the horizontal space, leaving some space for the active editor.
- The optional properties `line` and `column` allow scrolling to line/column number in the shown editor.
- The optional property `zoom` sets the result page [zoom level](../features/result.html.md)#result-page-zoom) (the selected panel must be `result`).
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
const delay = (duration) =>
new Promise((resolve) => {
setTimeout(resolve, duration);
});
await playground.show('toggle-result');
await delay(2000);
await playground.show('style');
await delay(2000);
await playground.show('result', { full: true });
await delay(2000);
await playground.show('script');
await delay(2000);
await playground.show('result', { zoom: 0.5 });
await delay(2000);
await playground.show('console', { full: true });
});
```
### `runTests`
Type: [`() => Promise<{ results: TestResult[] }>`](../api/interfaces/Playground.md#runtests)
Runs project [tests](./../features/tests.html.md) (if present) and gets test results.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
const { results } = await playground.runTests();
});
```
### `watch`
Type: [docs](../api/interfaces/Playground.md#watch)
```ts
((event: 'load', fn: () => void) => { remove: () => void }) &
((event: 'ready', fn: (data: { config: Config }) => void) => { remove: () => void }) &
((event: 'code', fn: (data: { code: Code; config: Config }) => void) => { remove: () => void }) &
((event: 'console', fn: (data: { method: string; args: any[] }) => void) => { remove: () => void }) &
((event: 'tests', fn: (data: { results: TestResult[]; error?: string }) => void) => { remove: () => void }) &
((event: 'destroy', fn: () => void) => { remove: () => void });
```
Allows to watch for various playground events. It takes 2 arguments: event name and a callback function that will be called on every event.
In some events, the callback function will be called with an object that supplies relevant data to the callback function (e.g. code, console output, test results).
The `watch` method returns an object with a single method `remove`, which when called will remove the callback from watching further events.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then((playground) => {
const codeWatcher = playground.watch('code', ({ code, config }) => {
// this will run on every code change
console.log('code:', code);
console.log('config:', config);
});
const consoleWatcher = playground.watch('console', ({ method, args }) => {
// this will run on every console output
console[method](...args);
});
const testsWatcher = playground.watch('tests', ({ results }) => {
// this will run when tests run
results.forEach((testResult) => {
console.log('status:', testResult.status); // "pass", "fail" or "skip"
console.log(testResult.errors); // array of errors as strings
});
});
// then later
codeWatcher.remove();
consoleWatcher.remove();
testsWatcher.remove();
// events are no longer watched
});
```
These are the events that can be watched and the description of their callback functions:
- `"load"`: Called when the playground first loads.
```ts
(
event: "load",
fn: () => void
) => { remove: () => void }
```
- `"ready"`: Called when a new project is loaded (including when [imported](../features/import.html.md)) and the playground is ready to run.
```ts
(
event: "ready",
fn: (data: { config: Config }) => void
) => { remove: () => void }
```
- `"code"`: Called when the playground "content" is changed (see [`getCode`](./js-ts.html.md)#getcode) and [`getConfig`](./js-ts.html.md)#getconfig)).
This includes changes in:
- Code (in editors)
- Editor languages
- [CSS processors](../features/css.html.md)#css-processors)
- [External resources](../features/external-resources.html.md)
- Project info (e.g. allows adding content in page head and attributes to `<html>` element)
- [Custom settings](../advanced/custom-settings.html.md) (e.g. allows changing [import maps](../features/module-resolution.html.md)#custom-module-resolution))
- Project title
- [Test](../features/tests.html.md) code
```ts
(
event: "code",
fn: (data: { code: Code; config: Config }) => void
) => { remove: () => void }
```
- `"console"`: Called when the playground console gets new outputs. The callback method is passed an object with 2 properties: `"method"` (e.g. `"log"`, `"error"`, etc.) and `"args"` (the arguments passed to the method, as an array).
```ts
(
event: "console",
fn: (data: { method: string; args: any[] }) => void
) => { remove: () => void }
```
- `"tests"`: Called when tests run and test results are available (see [`runTests`](./js-ts.html.md)#runtests)).
```ts
(
event: "tests",
fn: (data: { results: TestResult[]; error?: string }) => void
) => { remove: () => void }
```
- `"destroy"`: Called when the playground is destroyed.
```ts
(
event: "destroy",
fn: () => void
) => { remove: () => void }
```
### `onChange`
**Deprecated**: Use [`watch`](#watch) method instead.
Type: [`(fn: ChangeHandler) => { remove: () => void }`](../api/interfaces/Playground.md#onchange)
Allows to watch the playground for changes. It takes a callback function that will be called on every change.
The callback function will be called with an object that has 2 properties: `code` and `config`, representing the current codes and configuration objects (see [`getCode`](#getcode) and [`getConfig`](#getconfig)).
The `onChange` method returns an object with a single method `remove`, which when called will remove the callback from watching changes.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then((playground) => {
const watcher = playground.onChange(({ code, config }) => {
// this will run on every code change
console.log('code:', code);
console.log('config:', config);
});
// then later
watcher.remove();
// changes are no longer watched
});
```
### `exec`
Type: [`(command: APICommands, ...args: any[]) => Promise<{ output: any } | { error: string }>`](../api/interfaces/Playground.md#exec)
Execute custom commands, including:
- `"setBroadcastToken"`: Sets [broadcast `userToken`](../features/broadcast.html.md)#technical-details).
```js
// in browser console of full app (e.g. https://livecodes.io)
await livecodes.exec('setBroadcastToken', 'my-token');
```
- `"showVersion"`: Logs the current LiveCodes app version, SDK version, git commit SHA, [permanent app URL](../features/permanent-url.html.md) and SDK URL in the browser console.
```js
// in browser console of full app (e.g. https://livecodes.io)
await livecodes.exec('showVersion');
```
### `destroy`
Type: [`() => Promise<void>`](../api/interfaces/Playground.md#destroy)
Destroys the playground instance, and removes event listeners. Further call to any SDK methods throws an error.
```js
import { createPlayground } from 'livecodes';
createPlayground('#container').then(async (playground) => {
await playground.destroy();
// playground destroyed
// any further SDK call throws an error
});
```
## Styles
### Default Styles
By default, the container element is styled when the SDK is initialized (including width, height, border, etc.). To disable default styles, set the container element attribute `data-default-styles` to `"false"` before initializing.
Example:
```html
<div id="container" data-default-styles="false" class="custom"></div>
<script type="module">
import { createPlayground } from 'livecodes';
createPlayground('#container');
</script>
```
### Height
By default, the playground container height is set to `"300px"`. To change the height, either disable the default styles and override them, or simply set the `data-height` attribute to a number (in pixels) or any valid CSS value (e.g. `"100%"` to take the full height of its parent element).
Example:
```html
<div id="container" data-height="500"></div>
<script type="module">
import { createPlayground } from 'livecodes';
createPlayground('#container');
</script>
```
## Demo
export const sdkDemo = {
js: `import { createPlayground } from "livecodes";\n\nconst params = {\n html: "<h1>Hello World!</h1>",\n css: "h1 {color: blue;}",\n js: 'console.log("Hello, LiveCodes!")',\n console: "open",\n};\n\ncreatePlayground('#container', { params });\n`,
html: '<div id="container"></div>',
};
<LiveCodes params={sdkDemo} height="80vh" />
## Related
- [React SDK](./react.html.md)
- [Vue SDK](./vue.html.md)
- [Using SDK in Svelte](./svelte.html.md)
- [Embedded Playgrounds](../features/embeds.html.md)

236
docs/sdk/js-ts/index.html Normal file

File diff suppressed because one or more lines are too long

151
docs/sdk/react.html.md Normal file
View File

@@ -0,0 +1,151 @@
# React SDK
import LiveCodes from '../../src/components/LiveCodes.tsx';
The react SDK is a thin wrapper around the [JavaScript SDK](js-ts.html.md) to provide an easy to use react component, yet retaining the full power, by having access to the [SDK methods](js-ts.html.md)#sdk-methods).
It has a very simple [implementation](https://github.com/live-codes/livecodes/blob/develop/src/sdk/react.tsx) which you can easily modify in case you need.
## Installation
Please refer to the [SDK installation](./index.html.md)#installation) section.
## Usage
The react component is provided as the default export from `livecodes/react`.
```jsx title="JSX"
import LiveCodes from 'livecodes/react';
export const Playground = () => <LiveCodes />;
```
### TypeScript Support
Prop types are exported as `Props` from `livecodes/react`.
```tsx title="TSX"
import LiveCodes, { type Props } from 'livecodes/react';
const options: Props = {
// embed options
};
export const Playground = () => <LiveCodes {...options} />;
```
TypeScript types are [documented here](../api/globals.md).
### Props
All [embed options](js-ts.html.md)#embed-options) are available as props with the corresponding types.
Example:
```jsx title="JSX"
import LiveCodes from 'livecodes/react';
const config = {
markup: {
language: 'markdown',
content: '# Hello World!',
},
};
export const Playground = () => <LiveCodes config={config} view="result" />;
```
In addition, the following props are also available:
- `className`
Type: `string`.
Class name(s) to add to playground container element.
Example:
```jsx title="JSX"
import LiveCodes from 'livecodes/react';
export const Playground = () => <LiveCodes className="centered" />;
```
- `height`
Type: `string`.
Sets the height of playground container element.
Example:
```jsx title="JSX"
import LiveCodes from 'livecodes/react';
export const Playground = () => <LiveCodes height="500px" />;
```
- `style`
Type: `Record<string, string>`.
Defines styles to add to playground container element. Styles set here override the [default styles](js-ts.html.md)#default-styles).
Example:
```tsx title="JSX"
import LiveCodes from 'livecodes/react';
const style = {
margin: 'auto',
width: '80%',
};
export const Playground = () => <LiveCodes style={style} />;
```
- `sdkReady`
Type: `(sdk: Playground) => void`.
A callback function, that is provided with an instance of the [JavaScript SDK](js-ts.html.md) representing the current playground. This allows making use of full capability of the SDK by calling [SDK methods](js-ts.html.md)#sdk-methods).
Example:
```tsx title="TSX"
import { useState } from 'react';
import LiveCodes from 'livecodes/react';
import type { Playground } from 'livecodes';
export const App = () => {
const [playground, setPlayground] = useState<Playground>();
const onReady = (sdk: Playground) => {
setPlayground(sdk);
};
const run = async () => {
await playground?.run();
};
return (
<>
<LiveCodes sdkReady={onReady} />
<button onClick={run}>Run</button>
</>
);
};
```
## Demo
export const reactSDKDemo = {
jsx: `import LiveCodes from "livecodes/react";\n\nconst App = () => {\n const params = {\n html: "<h1>Hello World!</h1>",\n css: "h1 {color: blue;}",\n js: 'console.log("Hello, World!")',\n console: "open",\n };\n\n return <LiveCodes params={params} />;\n};\n\nexport default App;\n`,
};
<LiveCodes params={reactSDKDemo} height="80vh" />
## Related
- [SDK Installation](./index.html.md)#installation)
- [JS/TS SDK](./js-ts.html.md)
- [Vue SDK](./vue.html.md)
- [Using SDK in Svelte](./svelte.html.md)
- [Embedded Playgrounds](../features/embeds.html.md)

69
docs/sdk/react/index.html Normal file

File diff suppressed because one or more lines are too long

100
docs/sdk/svelte.html.md Normal file
View File

@@ -0,0 +1,100 @@
# Svelte
import LiveCodes from '../../src/components/LiveCodes.tsx';
import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx';
The [JS/TS SDK](js-ts.html.md) can be used directly in Svelte components without the need for any wrappers.
## Installation
Please refer to the [SDK installation](./index.html.md)#installation) section.
## Usage
This is an example of using the LiveCodes JS SDK in a Svelte component:
```html title="Component.svelte"
<script>
import { onMount } from 'svelte';
import { createPlayground } from 'livecodes';
// Embed Options
const options = {
params: {
html: '<h1>Hello World!</h1>',
css: 'h1 {color: blue;}',
js: 'console.log("Hello, Svelte!")',
console: 'open',
},
};
let container;
let playground = $state(null);
onMount(() => {
createPlayground(container, options).then((p) => {
playground = p; // now the SDK is available
});
// cleanup when the component is destroyed
return () => playground?.destroy();
});
</script>
<div bind:this="{container}"></div>
```
export const svelteSDKDemo = {
svelte: `\x3Cscript>\n import { onMount } from 'svelte';\n import { createPlayground } from 'livecodes';\n\n // Embed Options\n const options = {\n params: {\n html: '<h1>Hello World!</h1>',\n css: 'h1 {color: blue;}',\n js: 'console.log("Hello, Svelte!")',\n console: 'open',\n },\n };\n\n let container;\n let playground = $state(null);\n onMount(() => {\n createPlayground(container, options).then((p) => {\n playground = p; // now the SDK is available\n });\n // cleanup when the component is destroyed\n return () => playground?.destroy();\n });\n\x3C/script>\n\n<div bind:this="{container}"></div>\n`,
};
<RunInLiveCodes params={svelteSDKDemo}></RunInLiveCodes>
[Embed options](./js-ts.html.md)#embed-options), [SDK methods](./js-ts.html.md)#sdk-methods) and [TypeScript types](./js-ts.html.md)#typescript-types) are available as described in the [JS/TS SDK documentations](./js-ts.html.md).
Alternatively, the SDK function [`createPlayground`](./js-ts.html.md)#createplayground) can be used as an [action](https://learn.svelte.dev/tutorial/actions).
Example:
```html title="Component.svelte"
<script>
import { createPlayground } from 'livecodes';
let options = {
// embed options
};
</script>
<div use:createPlayground="{options}"></div>
```
However, it is recommended to cleanup when the node is unmounted, like that:
```html title="Component.svelte"
<script>
import { createPlayground } from 'livecodes';
let options = {
// embed options
};
const livecodes = (node, opts) => {
let playground = $state(null);
const ready = new Promise(async (res) => {
playground = await createPlayground(node, opts);
res();
});
return { destroy: () => ready.then(() => playground?.destroy()) };
};
</script>
<div use:livecodes="{options}"></div>
```
## Demo
<LiveCodes params={svelteSDKDemo} height="80vh" />
## Related
- [SDK Installation](./index.html.md)#installation)
- [JS/TS SDK](./js-ts.html.md)
- [React SDK](./react.html.md)
- [Vue SDK](./vue.html.md)
- [Embedded Playgrounds](../features/embeds.html.md)

File diff suppressed because one or more lines are too long

166
docs/sdk/vue.html.md Normal file
View File

@@ -0,0 +1,166 @@
# Vue SDK
import LiveCodes from '../../src/components/LiveCodes.tsx';
The vue SDK is a thin wrapper around the [JavaScript SDK](js-ts.html.md) to provide an easy to use vue component, yet retaining the full power, by having access to the [SDK methods](js-ts.html.md)#sdk-methods).
It has a very simple [implementation](https://github.com/live-codes/livecodes/blob/develop/src/sdk/vue.ts) which you can easily modify in case you need.
## Installation
Please refer to the [SDK installation](./index.html.md)#installation) section.
## Usage
The vue component is provided as the default export from `livecodes/vue`.
```html title="App.vue"
<script setup>
import LiveCodes from 'livecodes/vue';
</script>
<template>
<LiveCodes />
</template>
```
### TypeScript Support
Prop types are exported as `Props` from `livecodes/vue`.
```html title="App.vue"
<script setup lang="ts">
import LiveCodes, { type Props } from 'livecodes/vue';
const options: Props = {
// embed options
};
</script>
<template>
<LiveCodes v-bind="options" />
</template>
```
TypeScript types are [documented here](../api/globals.md).
### Props
All [embed options](js-ts.html.md)#embed-options) are available as props with the corresponding types.
Example:
```html title="App.vue"
<script setup>
import LiveCodes from 'livecodes/vue';
const config = {
markup: {
language: 'markdown',
content: '# Hello World!',
},
};
</script>
<template>
<LiveCodes :config="config" view="result" />
</template>
```
In addition, the following prop is also available:
- `height`
Type: `string`.
Sets the [height of playground container](js-ts.html.md)#height) element.
Example:
```html title="App.vue"
<script setup>
import LiveCodes from 'livecodes/vue';
</script>
<template>
<LiveCodes height="500px" />
</template>
```
### Events
- `"sdkReady"`
Type: `(sdk: Playground) => void`.
When the playground initializes, the event `"sdkReady"` is emitted. The event handler function is provided with an instance of the [JavaScript SDK](js-ts.html.md) representing the current playground. This allows making use of full capability of the SDK by calling [SDK methods](js-ts.html.md)#sdk-methods).
Example:
```html title="App.vue"
<script setup lang="ts">
import type { Playground } from 'livecodes';
import LiveCodes, { type Props } from 'livecodes/vue';
const options: Props = {
config: {
markup: {
language: 'html',
content: '<h1>Hello World!</h1>',
},
},
};
let playground: Playground | undefined;
const onReady = (sdk: Playground) => {
playground = sdk;
};
const run = async () => {
await playground?.run();
};
</script>
<template>
<LiveCodes v-bind="options" @sdk-ready="onReady" />
<button @click="run">run</button>
</template>
```
### Styles
Styles can be applied to the component [as usual](https://vuejs.org/guide/essentials/class-and-style.html#binding-html-classes).
By default, a set of [default styles](js-ts.html.md)#default-styles) are applied to the playground container. Styles passed to the component override these default styles.
Example:
```html title="App.vue"
<script setup>
import LiveCodes from 'livecodes/vue';
const style = {
margin: 'auto',
width: '80%',
};
</script>
<template>
<LiveCodes :style="style" />
</template>
```
## Demo
export const vueSDKDemo = {
vue: `<script setup>\n import LiveCodes from 'livecodes/vue';\n \n const params = {\n html: '<h1>Hello World!</h1>',\n css: 'h1 {color: blue;}',\n js: 'console.log("Hello, Svelte!")',\n console: 'open',\n };\n</script>\n\n<template>\n <LiveCodes :params="params" />\n</template>\n`,
};
<LiveCodes params={vueSDKDemo} height="80vh" />
## Related
- [SDK Installation](./index.html.md)#installation)
- [JS/TS SDK](./js-ts.html.md)
- [React SDK](./react.html.md)
- [Using SDK in Svelte](./svelte.html.md)
- [Embedded Playgrounds](../features/embeds.html.md)

63
docs/sdk/vue/index.html Normal file

File diff suppressed because one or more lines are too long