diff --git a/.gitignore b/.gitignore index 116eaa75d..28d7ff87f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,11 @@ docs/typedoc/ # Bundled files *.bundle.js +# Generated files + +*.autogenerated.ts +*.autogenerated.js + # .gitignore for deploying to Firebase hosting # Logs logs diff --git a/README.md b/README.md index abc03ee00..bbf4738a6 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ import 'js-draw/bundledStyles'; const editor = new Editor(document.body); ``` -`js-draw/bundledStyles` is a version of the editor's stylesheets pre-processed by `Webpack`. As such, `import`ing or including it with a `` tag applies editor-specific CSS to the document. +`js-draw/bundledStyles` is a version of the editor's stylesheets pre-processed by `es-build`. As such, `import`ing or including it with a `` tag applies editor-specific CSS to the document. ### Without a bundler diff --git a/docs/doc-pages/README.md b/docs/doc-pages/README.md index b7a4bdef0..a705bd07f 100644 --- a/docs/doc-pages/README.md +++ b/docs/doc-pages/README.md @@ -1,5 +1,7 @@ -This folder contains additional documention for `js-draw`, including like migration guides and examples that describe how to use specific features. +# doc-pages -Before reading these guides, it may be helpful to review the examples in `js-draw`'s [`README`](../). +This folder includes Markdown documents that are rendered as a part of the documentation. -Additional examples can be found in the [examples/](https://github.com/personalizedrefrigerator/js-draw/tree/main/docs/examples) directory on GitHub. A directory of all inline runnable examples in the documentation can be found at [assets/doctest.html](../assets/doctest.html). +`inline-examples/` includes files that can be `[include:...]`ed in other documents. + +`guides/` includes tutorials and migration guides. diff --git a/docs/doc-pages/package.json b/docs/doc-pages/package.json deleted file mode 100644 index af6b9d824..000000000 --- a/docs/doc-pages/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "Guides", - "description": "Not a real package -- used to include markdown files in generated typedoc output", - "private": true, - "version": "0.0.0", - "dependencies": { - "@js-draw/math": "^1.22.0", - "js-draw": "^1.22.0" - } -} diff --git a/docs/doc-pages/pages/guides.md b/docs/doc-pages/pages/guides.md new file mode 100644 index 000000000..634d84c5d --- /dev/null +++ b/docs/doc-pages/pages/guides.md @@ -0,0 +1,18 @@ +--- +title: Guides +category: Guides +children: + - ./guides/setup.md + - ./guides/writing-a-theme.md + - ./guides/customizing-tools.md + - ./guides/updating-the-view.md + - ./guides/positioning-an-element-above-the-editor.md +--- + +# Tutorials + +This folder contains additional documention for `js-draw`. + +Before reading these guides, it may be helpful to review the examples in `js-draw`'s [`README`](../#api). + +Additional examples can be found in the [examples/](https://github.com/personalizedrefrigerator/js-draw/tree/main/docs/examples) directory on GitHub. A directory of all inline runnable examples in the documentation can be found at [assets/doctest.html](../assets/doctest.html). diff --git a/docs/doc-pages/guides/customizing-tools.md b/docs/doc-pages/pages/guides/customizing-tools.md similarity index 99% rename from docs/doc-pages/guides/customizing-tools.md rename to docs/doc-pages/pages/guides/customizing-tools.md index 9bc194bab..a035cd2aa 100644 --- a/docs/doc-pages/guides/customizing-tools.md +++ b/docs/doc-pages/pages/guides/customizing-tools.md @@ -1,6 +1,5 @@ --- title: Customizing existing tools -category: Guides --- # Customizing existing tools diff --git a/docs/doc-pages/guides/positioning-an-element-above-the-editor.md b/docs/doc-pages/pages/guides/positioning-an-element-above-the-editor.md similarity index 99% rename from docs/doc-pages/guides/positioning-an-element-above-the-editor.md rename to docs/doc-pages/pages/guides/positioning-an-element-above-the-editor.md index bda6b731f..d74fbc3bc 100644 --- a/docs/doc-pages/guides/positioning-an-element-above-the-editor.md +++ b/docs/doc-pages/pages/guides/positioning-an-element-above-the-editor.md @@ -1,6 +1,5 @@ --- title: Positioning an element above the editor -category: Guides --- # Positioning an element above the editor diff --git a/docs/doc-pages/pages/guides/setup.md b/docs/doc-pages/pages/guides/setup.md new file mode 100644 index 000000000..72fd0126f --- /dev/null +++ b/docs/doc-pages/pages/guides/setup.md @@ -0,0 +1,92 @@ +--- +title: Getting started +--- + +# Getting started + +There are two main ways of adding `js-draw` to a project: + +- With a JavaScript bundler (e.g. [ESBuild](https://esbuild.github.io/) or [Webpack](https://webpack.js.org/)). +- Using a CDN (e.g. jsdelivr). + +> [!NOTE] +> +> Similar information can also be found in the [README](../). + +## With a bundler + +A JavaScript bundlers take the source files of your project (JavaScript, CSS, etc.), and convert them into a form that can be loaded by a browser. When used with a tool like `npm`, bundlers can simplify dependency management. + +If you don't plan on adding a bundler to your project, skip to the [pre-bundled version](#using-a-pre-bundled-version) section. + +### Adding `js-draw` as a dependency + +From the same directory as your project's `package.json`, [npm install] js-draw: + +```bash +$ npm install --save-dev js-draw +``` + +To also add the material icons dependency, also [npm install] `@js-draw/material-icons`: + +```bash +$ npm install --save-dev @js-draw/material-icons +``` + +[npm install]: https://docs.npmjs.com/cli/v11/commands/npm-install + +### With a bundler that supports importing `.css` files + +To create a new `Editor` and add it as a child of `document.body`, use the [Editor](https://personalizedrefrigerator.github.io/js-draw/typedoc/classes/js-draw.Editor.html#constructor) constructor: + +```ts,runnable +import Editor from 'js-draw'; +import 'js-draw/styles'; + +const editor = new Editor(document.body); +editor.addToolbar(); +``` + +The `import js-draw/styles` step requires a bundler that can import `.css` files. For example, [`webpack` with `css-loader`.](https://webpack.js.org/loaders/css-loader/) + +### With a bundler that doesn't support importing `.css` files + +Import the pre-bundled version of the editor to apply CSS after loading the page. + +```ts,runnable +import Editor from 'js-draw'; +import 'js-draw/bundledStyles'; + +const editor = new Editor(document.body); +editor.addToolbar(); +``` + +`js-draw/bundledStyles` is a version of the editor's stylesheets pre-processed by `es-build`. As such, `import`ing or including it with a `` tag applies editor-specific CSS to the document. + +## Using a pre-bundled version + +### CDN setup + +While not recommended for production builds, using a CDN can make it easier to get started with `js-draw`. + +```html,runnable + + + +``` + +**Note**: To ensure the CDN-hosted version of `js-draw` hasn't been tampered with, consider [including an `integrity="..."` attribute](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity). [Read more about using SRI with JSDelivr](https://www.jsdelivr.com/using-sri-with-dynamic-files). + +Of course, you can also self-host `bundle.js`. + +## Next steps + +See: + +- {@link js-draw! | The README} includes an overview of several of the most significant `js-draw` APIs (e.g. loading and saving, adding a toolbar). +- {@link @js-draw/material-icons! | Changing the icon theme}. diff --git a/docs/doc-pages/guides/updating-the-view.md b/docs/doc-pages/pages/guides/updating-the-view.md similarity index 99% rename from docs/doc-pages/guides/updating-the-view.md rename to docs/doc-pages/pages/guides/updating-the-view.md index de4c9cd85..8f88ba04a 100644 --- a/docs/doc-pages/guides/updating-the-view.md +++ b/docs/doc-pages/pages/guides/updating-the-view.md @@ -1,6 +1,5 @@ --- title: Updating the viewport -category: Guides --- # Updating the editor's viewport diff --git a/docs/doc-pages/guides/writing-a-theme.md b/docs/doc-pages/pages/guides/writing-a-theme.md similarity index 96% rename from docs/doc-pages/guides/writing-a-theme.md rename to docs/doc-pages/pages/guides/writing-a-theme.md index 1608c693f..a797641d9 100644 --- a/docs/doc-pages/guides/writing-a-theme.md +++ b/docs/doc-pages/pages/guides/writing-a-theme.md @@ -1,6 +1,5 @@ --- title: Writing a theme -category: Guides --- # Writing a theme @@ -109,5 +108,5 @@ the defaults. **See also** -- **To auto-adjust theme colors to improve contrast:** {@link js-draw.adjustEditorThemeForContrast} -- **To customize the icons used by `js-draw`**: {@link js-draw.IconProvider} and {@link "@js-draw/material-icons"} +- **To auto-adjust theme colors to improve contrast:** {@link js-draw!adjustEditorThemeForContrast} +- **To customize the icons used by `js-draw`**: {@link js-draw!IconProvider} and {@link "@js-draw/material-icons"} diff --git a/docs/doc-pages/pages/migrations.md b/docs/doc-pages/pages/migrations.md new file mode 100644 index 000000000..b72c97864 --- /dev/null +++ b/docs/doc-pages/pages/migrations.md @@ -0,0 +1,16 @@ +--- +title: Migrations +group: Migrations +children: + - ./migrations/migrating-to-v1.md +--- + +# Updating js-draw + +In general, `js-draw` releases follow [Semantic Versioning (semver)](https://github.com/semver/semver/blob/master/semver.md). This means that version numbers are broken up into three parts: + +- The major version (e.g. 2 in **2**.1.0). +- The minor version (e.g. 1 in 2.**1**.0). +- The patch version (e.g. 0 in 2.1.**0**). + +Only major version updates should include breaking changes. When a new major version is released, a new document should be added under this "Migrations" section. diff --git a/docs/doc-pages/guides/migrating-to-v1.md b/docs/doc-pages/pages/migrations/migrating-to-v1.md similarity index 100% rename from docs/doc-pages/guides/migrating-to-v1.md rename to docs/doc-pages/pages/migrations/migrating-to-v1.md diff --git a/docs/doc-pages/typedoc.json b/docs/doc-pages/typedoc.json index 66dc104cd..389feb7c4 100644 --- a/docs/doc-pages/typedoc.json +++ b/docs/doc-pages/typedoc.json @@ -1,6 +1,6 @@ { "extends": ["../../typedoc.base.json"], "entryPoints": [], - "projectDocuments": ["./guides/*.md"], + "projectDocuments": [], "includeVersion": false } diff --git a/package.json b/package.json index 6f9765f94..23c4689e4 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "lint-staged": "13.2.3", "prettier": "3.3.3", "ts-jest": "29.1.2", - "typedoc": "0.27.3", + "typedoc": "0.27.6", "typescript": "5.7.2", "typescript-eslint": "8.17.0" }, diff --git a/packages/js-draw/src/image/EditorImage.ts b/packages/js-draw/src/image/EditorImage.ts index 45a90e9f7..a1ee718bf 100644 --- a/packages/js-draw/src/image/EditorImage.ts +++ b/packages/js-draw/src/image/EditorImage.ts @@ -37,7 +37,7 @@ export type PreRenderComponentCallback = ( let debugMode = false; /** - * @summary Handles lookup/storage of elements in the image. + * Handles lookup/storage of elements in the image. * * `js-draw` images are made up of a collection of {@link AbstractComponent}s (which * includes {@link Stroke}s, {@link TextComponent}s, etc.). An `EditorImage` diff --git a/packages/typedoc-extensions/package.json b/packages/typedoc-extensions/package.json index 31ffd3d1f..ae876b911 100644 --- a/packages/typedoc-extensions/package.json +++ b/packages/typedoc-extensions/package.json @@ -31,9 +31,10 @@ "typedoc": "0.26.x" }, "devDependencies": { - "@codemirror/lang-css": "6.3.0", + "@codemirror/lang-css": "6.3.1", + "@codemirror/lang-html": "6.4.9", "@codemirror/lang-javascript": "6.2.2", - "@codemirror/language": "6.10.3", + "@codemirror/language": "6.10.8", "@js-draw/build-tool": "^1.27.2", "@js-draw/material-icons": "^1.27.2", "@js-draw/math": "^1.27.2", diff --git a/packages/typedoc-extensions/src/browser/browser.scss b/packages/typedoc-extensions/src/browser/browser.scss index 16d8b5d35..b27e4865c 100644 --- a/packages/typedoc-extensions/src/browser/browser.scss +++ b/packages/typedoc-extensions/src/browser/browser.scss @@ -23,6 +23,7 @@ textarea.runnable-code { --cm-paren-color: var(--hl-1, gray); --cm-varname-color: var(--hl-2, black); --cm-number-color: var(--hl-16, black); + --cm-tag-color: var(--hl-9, #500); --cm-secondary-background-color: #ddd; --cm-secondary-text-color: #300; diff --git a/packages/typedoc-extensions/src/browser/editor/addCodeMirrorEditor.ts b/packages/typedoc-extensions/src/browser/editor/addCodeMirrorEditor.ts index 8a8931164..103f1bf39 100644 --- a/packages/typedoc-extensions/src/browser/editor/addCodeMirrorEditor.ts +++ b/packages/typedoc-extensions/src/browser/editor/addCodeMirrorEditor.ts @@ -3,6 +3,7 @@ import { indentUnit, syntaxHighlighting } from '@codemirror/language'; import { tags } from '@lezer/highlight'; import { javascript as jsLanguageSupport } from '@codemirror/lang-javascript'; import { css as cssLanguageSupport } from '@codemirror/lang-css'; +import { html as htmlLanguageSupport } from '@codemirror/lang-html'; import { HighlightStyle } from '@codemirror/language'; // See https://codemirror.net/examples/styling/ @@ -66,12 +67,14 @@ const codeMirrorHighlightStyle = HighlightStyle.define([ { tag: tags.number, color: 'var(--cm-number-color)' }, { tag: tags.integer, color: 'var(--cm-number-color)' }, { tag: tags.float, color: 'var(--cm-number-color)' }, + { tag: tags.tagName, color: 'var(--cm-tag-color)' }, ]); export enum EditorLanguage { JavaScript, TypeScript, CSS, + HTML, } const addCodeMirrorEditor = ( @@ -83,6 +86,8 @@ const addCodeMirrorEditor = ( if (language === EditorLanguage.CSS) { languagePlugin = cssLanguageSupport(); + } else if (language === EditorLanguage.HTML) { + languagePlugin = htmlLanguageSupport(); } else { languagePlugin = jsLanguageSupport({ typescript: language === EditorLanguage.TypeScript, diff --git a/packages/typedoc-extensions/src/browser/editor/replaceElementWithRunnableCode.ts b/packages/typedoc-extensions/src/browser/editor/replaceElementWithRunnableCode.ts index d5ac9de12..3dc99b3fd 100644 --- a/packages/typedoc-extensions/src/browser/editor/replaceElementWithRunnableCode.ts +++ b/packages/typedoc-extensions/src/browser/editor/replaceElementWithRunnableCode.ts @@ -23,6 +23,7 @@ const replaceElementWithRunnableCode = (elementToReplace: HTMLElement) => { css: EditorLanguage.CSS, js: EditorLanguage.JavaScript, ts: EditorLanguage.TypeScript, + html: EditorLanguage.HTML, }; const language = languageCodeToLanguage[languageCode] ?? EditorLanguage.TypeScript; @@ -93,6 +94,7 @@ const replaceElementWithRunnableCode = (elementToReplace: HTMLElement) => { let js = ''; let css = ''; + let html = ''; if (language === EditorLanguage.TypeScript) { js = typeScriptToJS(editorText); @@ -101,12 +103,14 @@ const replaceElementWithRunnableCode = (elementToReplace: HTMLElement) => { } else if (language === EditorLanguage.CSS) { css = editorText; js = defaultJS; + } else if (language === EditorLanguage.HTML) { + html = editorText; } else { const exhaustivenessCheck: never = language; return exhaustivenessCheck; } - return { js, css }; + return { js, css, html }; }; let removeMessageListener: (() => void) | null = null; @@ -131,7 +135,7 @@ const replaceElementWithRunnableCode = (elementToReplace: HTMLElement) => { const iframePreviewSetup = await loadIframePreviewScript(); - const { js, css } = getContentToRun(); + const { js, css, html } = getContentToRun(); previewFrame = document.createElement('iframe'); previewFrame.src = 'about:blank'; @@ -160,7 +164,7 @@ const replaceElementWithRunnableCode = (elementToReplace: HTMLElement) => { - ${bodyHTML} + ${bodyHTML}${html}