diff --git a/README.md b/README.md index c576761708..836b43f13a 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,14 @@ const superdoc = new SuperDoc({ }); ``` +Optional layered CSS mode: + +```css +@layer reset, superdoc, app; +@import 'superdoc/style.layered.css'; +@import 'your-app.css' layer(app); +``` + Or use the CDN: ```html diff --git a/apps/docs/editor/theming/overview.mdx b/apps/docs/editor/theming/overview.mdx index 7872f4a3c0..058c315272 100644 --- a/apps/docs/editor/theming/overview.mdx +++ b/apps/docs/editor/theming/overview.mdx @@ -19,6 +19,22 @@ document.documentElement.classList.add(theme); Five properties theme the entire UI. +## Optional layered stylesheet + +Default usage remains: + +```javascript +import 'superdoc/style.css'; +``` + +If your application uses CSS cascade layers and you want explicit layer ordering, use: + +```css +@layer reset, superdoc, app; +@import 'superdoc/style.layered.css'; +@import 'your-app.css' layer(app); +``` + ## `createTheme()` Pass a config object, get back a CSS class name. Apply it to ``. diff --git a/apps/docs/getting-started/theming.mdx b/apps/docs/getting-started/theming.mdx index 94d065f900..ca2ee29385 100644 --- a/apps/docs/getting-started/theming.mdx +++ b/apps/docs/getting-started/theming.mdx @@ -33,6 +33,22 @@ new SuperDoc({ selector: '#editor', document: 'contract.docx' }); Toolbar buttons, comments sidebar, dropdowns, context menu, search bar, dialog surfaces. Any chrome SuperDoc renders. The document content itself (paragraphs, headings, tables) renders with its own styles from the DOCX. +## Optional layered stylesheet + +By default, you can keep using: + +```javascript +import 'superdoc/style.css'; +``` + +If your app uses cascade layers and you want SuperDoc styles in a named layer, use the optional layered entrypoint: + +```css +@layer reset, superdoc, app; +@import 'superdoc/style.layered.css'; +@import 'your-app.css' layer(app); +``` + ## When to drop to CSS variables `createTheme()` covers the common case. For component-level overrides, use the `vars` option or set raw `--sd-*` variables in your stylesheet: diff --git a/packages/superdoc/AGENTS.md b/packages/superdoc/AGENTS.md index 46498dd4c4..f90de5497f 100644 --- a/packages/superdoc/AGENTS.md +++ b/packages/superdoc/AGENTS.md @@ -134,6 +134,19 @@ const theme = createTheme({ document.documentElement.classList.add(theme); ``` +CSS entrypoints: + +- `superdoc/style.css` — standard stylesheet. +- `superdoc/style.layered.css` — optional layered stylesheet wrapped in `@layer superdoc`. + +Recommended layered setup: + +```css +@layer reset, superdoc, app; +@import 'superdoc/style.layered.css'; +@import 'your-app.css' layer(app); +``` + Docs: https://docs.superdoc.dev/getting-started/theming ## Document Engine — programmatic access diff --git a/packages/superdoc/package.json b/packages/superdoc/package.json index e3f1535c9d..f63ce1daa2 100644 --- a/packages/superdoc/package.json +++ b/packages/superdoc/package.json @@ -82,7 +82,8 @@ "types": "./dist/superdoc/src/public/legacy/file-zipper.d.ts", "import": "./dist/super-editor/file-zipper.es.js" }, - "./style.css": "./dist/style.css" + "./style.css": "./dist/style.css", + "./style.layered.css": "./dist/style.layered.css" }, "types": "./dist/superdoc/src/public/index.d.ts", "typesVersions": { diff --git a/packages/superdoc/scripts/type-surface.config.cjs b/packages/superdoc/scripts/type-surface.config.cjs index 9deba19a4d..2dd646ef71 100644 --- a/packages/superdoc/scripts/type-surface.config.cjs +++ b/packages/superdoc/scripts/type-surface.config.cjs @@ -288,6 +288,7 @@ const publicContract = { ], asset: [ { subpath: './style.css', tier: 'asset', note: 'CSS bundle; no types' }, + { subpath: './style.layered.css', tier: 'asset', note: 'Layered CSS bundle; no types' }, ], deprecated: [], }; diff --git a/packages/superdoc/vite-plugin-layered-css.mjs b/packages/superdoc/vite-plugin-layered-css.mjs new file mode 100644 index 0000000000..02be65b8f8 --- /dev/null +++ b/packages/superdoc/vite-plugin-layered-css.mjs @@ -0,0 +1,32 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +export default function layeredCssPlugin() { + return { + name: 'superdoc-layered-css', + writeBundle(outputOptions, bundle) { + const cssAssets = Object.entries(bundle).filter(([, chunk]) => { + return chunk.type === 'asset' && typeof chunk.fileName === 'string' && chunk.fileName.endsWith('.css'); + }); + + if (cssAssets.length === 0) { + return; + } + + const targetAsset = + cssAssets.find(([fileName]) => fileName === 'style.css') ?? + cssAssets[0]; + + const [, chunk] = targetAsset; + const source = typeof chunk.source === 'string' + ? chunk.source + : Buffer.from(chunk.source).toString('utf8'); + + const layeredCss = `@layer superdoc{${source}}\n`; + const outDir = outputOptions.dir ?? path.dirname(outputOptions.file ?? ''); + const layeredFilePath = path.join(outDir, 'style.layered.css'); + + fs.writeFileSync(layeredFilePath, layeredCss); + }, + }; +} diff --git a/packages/superdoc/vite.config.cdn.js b/packages/superdoc/vite.config.cdn.js index c797e18df2..d069c53d72 100644 --- a/packages/superdoc/vite.config.cdn.js +++ b/packages/superdoc/vite.config.cdn.js @@ -2,6 +2,7 @@ import vue from '@vitejs/plugin-vue'; import { defineConfig } from 'vite'; import { version } from './package.json'; import { getAliases } from './vite.config.js'; +import layeredCssPlugin from './vite-plugin-layered-css.mjs'; // Standalone browser bundle for CDN /